Some usages need to replace some standard classes, for example this Redis Cache implementation.
It is better for everyone that users don’t need to fork Tryton to extend/customize some parts.
Proposal
The proposal is inspired by the logging.config module where it is possible to define alternative classes.
We could add similar behaviour for some classes where it makes sense to be able to replace them. The configuration could be extended to support new options. For example, we could add under the cache section an option class that will replace the trytond.cache.Cache class with this kind of pattern:
class Cache(object):
...
if config.get('cache', 'class'):
from logging.config import _resolve
Cache = _resolve(config.get('cache', 'class'))
Indeed there is a common need to override some of the classes Tryton defines.
Moreover the importlib features of python3 might render this feature quite elegant.
We also need that. In our case it is for BaBI module where we register “dynamic” models and need some way to initialize them.
I must say, however, that in our case, we need a way to create such “dynamic” model in one of the trytond instances and also ensure it is registered when needed in other trytond instances of the same database.
When I read such requirements, it lights up a big in my mind because this is a tendency that leads by finally coding into the application. It also raises the complexity in such way that it will generate Heisenberg bugs.
Indeed, I think the same level of flexibility could be achieved using a table_query feature.
We did it this way because it was simple: trytond is in charge of creating the database structure, for example (babi materializes the report).
To achieve something similar using table_query we should probably use the context to know which report the user is querying and make fields_get (and fields_view_get) as well as table_query return the required information. But we should create the table ourselves (probably not a big issue, though).
But, IMHO even although the BABI module of NaN·tic were using table_query feature, it is needed to setup the model with a dynamic model in order to show views and reports, isn’t it?
In some way, I don’t really care what will be needed to do. What I care about is to prevent to have bad design in Tryton. And for me, dynamic model is bad design. Tryton tries to be only declarative based because we believed it was more robust and have less side-effect (see: PYSON, states, on_change_with etc.).
So if we come back to the original request which was to be able to have a post Pool.init, I don’t see any valid usage other than having dynamic models which is against the paradigm of Tryton.
I think for those classes a better design should be found because usually this feature will be needed by modules. So we need a way in a module to register/replace base classes. This could be done by registering in a special register those subclasses and to force all standard classes to inherit from.
I think the same or similar mechanism could be used to override the dispatcher or allowing at least to override the way exceptions are managed. This would allow, for example, using sentry without the need to patch trytond.
The idea is not only send it to sentry (or whatever service) but send the user a different message. That is replace a standard exception by a raise_user_error with custom message.
I don’t see how this could be managed with a configuration feature. For example, with sentry what you do is send a message such as “There was an application error. We’ve given tracked the error and given it the ID xxxxxxx. If you want you can phone us and give this ID as reference.”. So this ID would be given by sentry.