GrahamDumpleton / wrapt

A Python module for decorators, wrappers and monkey patching.
BSD 2-Clause "Simplified" License
2.03k stars 231 forks source link

Request to be able to import both py and c wrappers #250

Closed dg-pb closed 10 months ago

dg-pb commented 11 months ago
try:
    if not os.environ.get('WRAPT_DISABLE_EXTENSIONS'):
        from ._wrappers import (ObjectProxy, CallableObjectProxy,
            PartialCallableObjectProxy, FunctionWrapper,
            BoundFunctionWrapper, _FunctionWrapperBase)
except ImportError:
    pass

This code in wrappers.py ensures that only one, but not the other implementation is imported. In my case, I want to keep using C objects with wrapt decorator, but I want to import python implementation of ObjectProxy as well for other usage. Would it be sensible to move this block to decorator so that both C and py versions of proxies can be imported?

GrahamDumpleton commented 11 months ago

Could be worthwhile have both available. I'll look at what best way of doing that might be. I may want to break apart the wrappers.py file into two files.

dg-pb commented 11 months ago

Also, this could be useful for cross-testing 2 implementations.

dg-pb commented 10 months ago

I could issue PR on this. Of course, I understand if you want to do this yourself.

GrahamDumpleton commented 10 months ago

Have been working on code today so can get a new release out. So am pondering how can come up with acceptable way of restructuring it.

I could move the pure Python components appearing before the C extension imports from wrappers.py into _wrapperspy.py with them import them into wrappers.py from there if no C extension. It would still be regarded as internal implementation detail though and you would need to import wrapt._wrapperspy to get the pure Python components. Just don't like the naming of the files at the moment with that option.

Another alternative is to move some of the stuff after the C extension import into a separate file called monkey.py indicative of their use in monkey patching, and see if that results in a better way of organising things.

dg-pb commented 10 months ago

Some thoughts.

I like the former. Doesn't break backwards compatibility. Also, creating new monkey.py feels a bit superfluous given that file would only have couple of objects left in it.

It seems that there is only 1 class in wrappers.py which inherits from either C or Py implementations. For consistency it might be good to have it with both inheritances as well.

In this case, could:

  1. Create _wrappersc.py and _wrapperspy.py.
  2. Define WeakFunctionProxyBase in _wrapperspy.py
  3. Create WeakFunctionProxy(WeakFunctionProxyBase, ObjectProxy) in both _wrappersc.py and _wrapperspy.py. _wrappersc.py would import WeakFunctionProxyBase from _wrapperspy.py
  4. Then do conditional import from wrappers.py.

This way all objects with all implementations would be possible access at the same time.

GrahamDumpleton commented 10 months ago

I did it rather differently to satisfy my ideas of what works better. Can you try:

The pure Python ObjectProxy is available using:

from wrapt.wrappers import ObjectProxy
dg-pb commented 10 months ago

Fair. All seems to be working. Thanks for this.

GrahamDumpleton commented 10 months ago

Have released 1.16.0 with this now.