Graham Dumpleton: Status of wrapt (September 2025)
The Pythonwraptpackage recently turned 12 years old. Originally intended to be a module for monkey patching Python code, its wrapper object turned out to be a useful basis for creating Python decorators.
Back then, constructing decorators using function closures had various short comings and the resulting wrappers didn't preserve introspection and various other attributes associated with the wrapped function. Many of these issues have been resolved in updates to Python and thefunctools.wrapshelper function, butwraptbased decorators were still useful for certain use cases such as being able to create a decorator where you could work out whether it was applied to a function, instance method, class method or even a class.
Downloads of wrapt
It is hard to tell how many people directly usewrapt, but helped by it being used internally in some widely used Python packages has actually resulted inwraptmaking it into the list ofPyPi top 100 packagesby number of downloads. As I write this post it sits at position number 65, but it was at one point as high as about position 45. Either way, I am still surprised it makes it into that list at all, especially since the primary purpose ofwraptis to do something most view as dangerous, ie., monkey patch code.
Maintenance mode
As to the core problem thatwraptoriginally tried to solve, that was achieved many years ago and as such it has more or less been kept in maintenance mode ever since. Most changes over recent years have focused around ensuring it works with each new Python version and expanding on the set of Python wheels that are being released for different architectures. There are occassionaly bug fixes or tweaks but generally they relate to corner cases which have arisen due to people trying to do strange things when monkey patching code.
Version update
Even though few changes are being made, the plan is to soon release a new version. This version number for this release will jump from 1.17.X to 2.0.X.
The jump in major version isn't due to any known incompatibilities but more just to be safe since in this version all the old legacy code from Python 2 and early Python 3 versions has been removed.
PyCharm issues
The only obscure change which have any concern over relates to a specific corner case that should never occur in actual use, but does occur when using Python debugger IDEs such as PyCharm which offer live views of Python objects.
The problem in the case of PyCharm is that it can attempt to display the state of a Python object before the__init__()method has been called. Due to the wrapper object inwraptbeing implemented in C code, that there is an accessor for the__wrapped__attribute is visible, but until__init__()is called it has no value. All the same, PyCharm tries to access__wrapped__during that time resulting in an exception.
For this exception when__wrapped__is accessed in an uninitialised state aValueErrorexception was being raised on the basis that the object was in an unknown state. The problem is that PyCharm doesn't gracefully handle this exception in this case and this somehow causes problems for PyCharm users.
What PyCharm prefers in this case is to see anAttributeErrorexception which results in it simply ignoring the attribute. Because it isn't known whether raisingAttributeErrorinstead ofValueErrorwould cause issues for other existing code, I have been reticent to change the type of exception being raised.
At one point someone suggested raising a custom exception which inherits from bothAttributeErrorandValueErroras a middle ground, allowing PyCharm to work but not cause issues for existing code.
Because one can't use multiple inheritence for custom exceptions implemented in C code, a fiddle has been required whereby the C extension code ofwraptreaches back to get a reference to an exception type implemented in Python code. Not elegant but appears to work so going to go with that and see if it works. Remember that this situation where the exception is raised should not even occur normally, so it may only be PyCharm that triggers it. Fingers crossed.
Typing hints
The other notable change for the nextwraptrelease will be the addition of support for type hints.
Adding type hints has been slow coming becausewraptsupported Python 2 and older Python 3 versions well past when those versions became obsolete. Since such old versions were still supported, I didn't see it as practical to add support for type hints.
Even now, although the nextwraptversion will still support Python version 3.8 and 3.9, the support for type hints will only be available if using Python 3.10 or later. This is because I finally realised that when using.pyifiles to inject type hints, you could have version checks and only add them for selected versions. 🤦♂️
Another reason type hint support took so long to be added was simply because I wasn't that familiar with using them. Some users did propose changes to add type hints, but they seemed to me to be very minimal and not try and add support across the full APIswraptprovided. Because I didn't understand type hints enough, I didn't want to risk adding them without really understanding how they worked.
This is not to say I am now an expert on type hints, I am definitely still a newbie and know just enough to be dangerous.
The resulting type hint support I added looks plenty scary to me and unfortunately still doesn't do everything I would like it to. My current belief is that due to the complicated overloading thatwraptdoes in certain APIs, that it just isn't possible within the limits of what the type hinting system can handle to do better than what I have managed. I haven't given up, but I also don't want to delay the nextwraptrelease any further, so will release it as is and revisit it later on to see if it can be made better.
Release candidates
With that all said, a release candidate for the next version ofwrapthas been available for about a month. This can be installed by explicitly usingwrapt==2.0.0rc2or if your package installer supports it, to use unstable package versions such as release candidate versions.
After being out for a month I have not had any reports of the release candidate version causing any issues. That said, no one has said it works fine either. There has been something like 190 thousand downloads of the release candidate in that time though, so that is a good sign at least.
At this point it seems to be safe to release a 2.0.0 final version, so I will be aiming to double check everything over the coming week and get the new version released in time for Python 3.14. That said, Python 3.14 doesn't make it a priority as there was a 1.17.3 patch release version ofwrapta month ago which included Python wheels for Python 3.14, so every thing should be good to go for the new Python version.
List of changes
If you are interested in exactly what changes have made it into the next release, you can check out thedevelopbranch for thewraptdocs onReadTheDocs.