Giter VIP home page Giter VIP logo

Comments (6)

GrahamDumpleton avatar GrahamDumpleton commented on May 25, 2024

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.

ohanar avatar ohanar commented on May 25, 2024

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.

GrahamDumpleton avatar GrahamDumpleton commented on May 25, 2024

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.

GrahamDumpleton avatar GrahamDumpleton commented on May 25, 2024

@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.

ohanar avatar ohanar commented on May 25, 2024

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.

GrahamDumpleton avatar GrahamDumpleton commented on May 25, 2024

Closing as nothing specific to wrapt that has to be changed.

from wrapt.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.