tools to carefully monkeypatch classes
Project description
smart-monkeypatching
Tools to aid in monkeypatching classes. Two decorators:
@add_new_class(ExistingClass)
class MyClass: ...
will (in the module where ExistingClass is defined)
- Create
orig_ExistingClass, as a backup ofExistingClass - Create
new_ExistingClass, as a backup ofMyClass - Make
ExistingClassbenew_ExistingClass(that is,MyClass) fixing__name__and__qualname__betweennew_ExistingClassandorig_ExistingClassas well
Thenrestore_class(ExistingClass)will restore the original, andrestore_new_class(ExistingClass)will put back the new version again.
@add_to_class(ExistingClass)
def fn():...
or
@add_to_class(ExistingClass)
def new_fn():...
Both will (in ExistingClass) add a method fn. If fn already exists, the the original is backed up as orig_fn. new_fn is created and names are fixed as for @add_new_class.
@add_to_class can be combined with one of @classmethod, @staticmethod, or @property (and if property, then fn in the local namespace will be the property, so you can then do
@add_to_class(ExistingClass)
@fn@setter
def fn():...
This takes care of the following potential issues;
- Create
ExistingClass.orig_fn, as a backup ofExistingClass.fn. This way you can delegate part of the work back to the original function (calling orig_fn in your code), or undo the monkeypatching (withrestore_method(ExistingClass.fn)). - Create
ExistingClass.new_fn, as a backup offn(so you can switch back to the new version if you have restored the old, withrestore_new_method(ExistingClass.fn)). - Fixing
__name__and__qualname__between versions ofExistingClass.fn, so that whetherfnis actuallyorig_fnornew_fn, it's name will befn. - Specifically deals with special issues for
@classmethod,@staticmethod, and@property. If the function you are replacing is a classmethod, staticmethod, or property, automatically modifies your function appropriately. - Specifically deals with condition that
ExistingClass.fnwas actually defined in a parent class ofExistingClass, so we don't want to change the parent class when adjusting names, by copyingfnintoExistingClass. - Specifically deals with condition that
ExistingClass.fnis abuiltin, and can't be copied in the same way (or modified at all, even__name__) - Specifically deals with condition that
ExistingClass.fnis a Descriptor type inherited from a parent (and__code__cannot be accessed for copying). - Modifies the
__doc__to note that the function is monkeypatched. - in submodule util there is a specific function to "copy" class methods so that they will have the same interface.
You should know that monkeypatching will wreack havoc with mypy, since it does stuff you shouldn't generally do. You can get an idea of the kind of mypy issues that arise by checking out the test code # test: ignore[] annotations.
For examples, use help(...), and/or download the source package and look at the tests.
The library can be built with hatchling build, tested with tests/test_tools.py -v, and should pass mypy.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file smart_monkeypatching-1.4.0.tar.gz.
File metadata
- Download URL: smart_monkeypatching-1.4.0.tar.gz
- Upload date:
- Size: 30.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d8da20e1debcedbe2a241ab602e8212fff2cdd72bc54ea70fbb18e63b24e848
|
|
| MD5 |
9c315e313d718863cea52ed6cf5ce944
|
|
| BLAKE2b-256 |
c110d758ebd515edad1bc0e0ec3ba08953612003bb6872cd63cce6dcaa4e65d2
|
File details
Details for the file smart_monkeypatching-1.4.0-py3-none-any.whl.
File metadata
- Download URL: smart_monkeypatching-1.4.0-py3-none-any.whl
- Upload date:
- Size: 27.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0677615962ea79ecd8a6418ab06dfcf39708a92099d48f741c1793cd95854454
|
|
| MD5 |
61b6b60cd6dc8feab3e0e7ec644fe9e3
|
|
| BLAKE2b-256 |
605c69df1064d63441108729b610154c819e05c219fcc8367e41ac79e24d752f
|