server-tools/upgrade_analysis/odoo_patch/odoo_patch.py

60 lines
1.8 KiB
Python

import logging
_logger = logging.getLogger(__name__)
class OdooPatch(object):
""" Simple mechanism to apply a collection of monkeypatches using a
context manager.
Classes can register their monkeypatches by inheriting from this class.
They need to define a `target` member, referring to the object or module
that needs to be patched, and a list `method_names`. They also need to
redefine those methods under the same name.
The original method is made available on the new method as
`_original_method`.
Example:
```
from odoo import api
from odoo.addons.some_module.models.my_model import MyModel
class MyModelPatch(OdooPatch):
target = MyModel
method_names = ['do_something']
@api.model
def do_something(self):
res = MyModelPatch.do_something._original_method()
...
return res
```
Usage:
```
with OdooPatch():
do_something()
```
"""
def __enter__(self):
for cls in OdooPatch.__subclasses__():
for method_name in cls.method_names:
method = getattr(cls, method_name)
setattr(method, '_original_method',
getattr(cls.target, method_name))
setattr(cls.target, method_name, method)
def __exit__(self, exc_type, exc_value, tb):
for cls in OdooPatch.__subclasses__():
for method_name in cls.method_names:
method = getattr(cls.target, method_name)
if hasattr(method, '_original_method'):
setattr(cls.target, method_name, method._original_method)
else:
_logger.warn(
'_original_method not found on method %s of class %s',
method_name, cls.target)