Comments (6)
What exactly are you trying to do?
The CallableObjectProxy class wouldn't be used in that way.
If that was just a bad example and what you are wanting to do was have a decorator on a base class which was then derived from, you need to use:
@mydecorator
class Blass(object):
pass
class Derived(Base.__wrapped__):
pass
If the decorator has to also apply to the derived class, then you should add it to the base class.
If you somehow want that to happen automatically, you probably should be using meta classes and not decorators.
from wrapt.
I'm working on a lazy import hook, and am using object proxies to lazily evaluate `from foo import bar`` statements (using caching), although it is still very much a work in progress. The point is when I hand off my proxied objects, I don't know how they are going to be used.
In particular, it would be nice if inner defined derived classes could be lazily evaluated, such as in
from foo import Base
class Bar:
def __init__(self):
class Derived(Base):
pass
self._derived = Derived
where Base
would be a proxy for a class object (and foo
would only be imported if an instance of Bar
was created). I can of course special case class objects in the cache and not proxy them (and hence reduce the amount of possible laziness), but obviously I would prefer not to.
Like I said, I don't really see a fix, and regardless I think that it should be documented (e.g. "an ObjectProxy
should behave in every way like the wrapped object, except for the following exceptions: [enumerate exceptions]").
P.S. I'm not actually using your ObjectProxy
class (although mine is based on top of it) because it requires the wrapped object to already exist at initialization, which breaks the whole point of laziness.
from wrapt.
For intercepting attribute access on a module, to either change what is returned, or to generate an attribute on demand, then you need to wrap the target module itself and replace the module in sys.modules.
import wrapt
class LazyModule(wrapt.ObjectProxy):
@property
def Bar(self):
print 'generate Bar'
# Generate reference to Bar some how.
# Use a nested class for this example.
class Bar(object):
def method(self):
print 'method'
return Bar
import sys
sys.modules[__name__] = LazyModule(sys.modules[__name__])
With this we then get:
>>> import lazymodule
>>> type(lazymodule)
<class 'LazyModule'>
>>> dir(lazymodule)
['LazyModule', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'sys', 'wrapt']
>>> b = lazymodule.Bar()
generate Bar
>>> b.method()
method
If the names of attributes isn't fixed list and so using a property like this cannot be done, you can override __getattr__
in the LazyModule class. That can get a little tricky if want to also overload __setattr__
at the same time.
The general case of generating the object to be wrapped lazily on demand the first time only is something have been thinking about. The issue is how to do it without having to duplicate all the existing proxy code again for that case. If can be done, idea would be that you could have:
def wrapped():
# create the object to be wrapped when called
return …
wrapper = LazyObjectProxy(wrapped)
So when the first requirement exists to need the wrapped object it is created by calling the supplied 'wrapped' function and then caching the result and using it there after.
Is doable, but suspect I need a complete separate LazyObjectProxy implementation and cannot have the existing ObjectProxy class do double duty or even harness what is done already by deriving from ObjectProxy.
Even then, I don't think you could make it a proper object proxy and there would be various issues with it. For example, you can't intercept access to certain __
attributes properly to allow you to create the value on demand after lazily creating the wrapped object instance and then grab that attribute from it. So can't be totally transparent as try to do with ObjectProxy.
Anyway, try that LazyModule example and see if that will work for what you are doing and if you think it doesn't then explain the problem and will see what else you may need to do.
from wrapt.
@ohanar Did you try the suggestion I made for a lazy module proxy object?
I will leave this issue here for the moment to remind me to document the issue about how to derive a class from a decorated one:
@mydecorator
class Base(object):
pass
class Derived(Base.__wrapped__):
pass
but when that is done will close the issue.
from wrapt.
Sorry, busy week.
What you suggest is more or less what I was already doing. However, I'm looking at implementing an import hook, so I really have no idea what the attributes of the module are (and hence doing things with __setattr__
and __getattr__
). The main issue that I've encountered is with was going one layer deep (by making the attributes of a lazy module be [lazy] object proxies) -- this is to support the from foo import bar
syntax, which should proxy bar
and only load foo
when bar
is used in some non-trivial way.
I think that with a little re-writing of your ObjectProxy class, it would be pretty trivial to add a LazyObjectProxy derivative. I'm pretty busy at the moment, but once I have a bit of time (probably in a couple of weeks) I could see about putting this together and making a pull request.
from wrapt.
Closing as nothing specific to wrapt that has to be changed.
from wrapt.
Related Issues (20)
- Methods of proxied objects are bound to the original object, not the proxy HOT 4
- PySide6 behaves differently between decorated and non-decorated function HOT 16
- Idea: Sticky/Viral ObjectProxy HOT 3
- ObjectProxy does not play well with GenericAlias, such as isinstance(proxy, Dict) HOT 12
- RFE: is it possible to start making github releases?🤔 HOT 2
- Publish cp312 wheel HOT 6
- Release 1.14.1 Py3.11 wheels HOT 7
- __doc__ property HOT 9
- Request to be able to import both py and c wrappers HOT 8
- Unable to install wrapt 1.14.1 via poetry HOT 2
- Accessing ObjectProxy __dict__ HOT 5
- Update to setup.cfg potentially required HOT 4
- Documentation isn't building? HOT 6
- Best way to associate some data with `ObjectProxy`? HOT 3
- Accessing a class attribute that is a wrapt wrapped function will try and bind the function. HOT 4
- pydevd error when debugging with wrapt HOT 28
- Add type hint annotations for user-facing code HOT 2
- classmethod tests fail with Python 3.13 (Python reverted to pre-3.9 behavior) HOT 2
- 1.16.0: pytest fails
- How to use adapter factory to change signature depending on instance HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from wrapt.