question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ObjectProxy objects are not copyable

See original GitHub issue

I was trying to use ObjectProxy in a context where the object in question sometimes gets copied by copy.copy, e.g.:

from wrapt import ObjectProxy
import copy
print(copy.copy(ObjectProxy(1)))

which raises an exception:

ValueError                                Traceback (most recent call last)
<ipython-input-29-184d66a435a2> in <module>()
----> 1 print(copy.copy(ObjectProxy(1)))

/Users/ryan/.pyenv/versions/3.5.2/lib/python3.5/copy.py in copy(x)
    103                 raise Error("un(shallow)copyable object of type %s" % cls)
    104
--> 105     return _reconstruct(x, rv, 0)
    106
    107

/Users/ryan/.pyenv/versions/3.5.2/lib/python3.5/copy.py in _reconstruct(x, info, deep, memo)
    296         if deep:
    297             state = deepcopy(state, memo)
--> 298         if hasattr(y, '__setstate__'):
    299             y.__setstate__(state)
    300         else:

ValueError: wrapper has not been initialized

To fix this, I implemented the __copy__() and __deepcopy__() methods in a subclass of ObjectProxy:

from wrapt import ObjectProxy
import copy

class CopyableObjectProxy(ObjectProxy):

    def __copy__(self):
        copied_wrapped = copy.copy(self.__wrapped__)
        return self.__class__(copied_wrapped)

    def __deepcopy__(self):
        copied_wrapped = copy.deepcopy(self.__wrapped__)
        return self.__class__(copied_wrapped)

x = 1
xp = ObjectProxy(x)
xcp = CopyableObjectProxy(x)

print(copy.copy(x))
try:
    print(copy.copy(xp))
except ValueError:
    print("Copy of xp failed")
print(copy.copy(xcp))

However, this presumably will not work for more complex proxy classes that have their own state that also needs copying. Is there a way to implement this generally for any proxy object, or does every subclass of ObjectProxy need to provide a custom __copy__() method if it wants to be copyable?

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:1
  • Comments:25 (11 by maintainers)

github_iconTop GitHub Comments

3reactions
GrahamDumpletoncommented, Oct 2, 2018

Example of what custom object proxy needs to do if know it needs to be copied is:

class CustomObjectProxy(wrapt.ObjectProxy):

    def __copy__(self):
        return CustomObjectProxy(copy.copy(self.__wrapped__))

    def __deepcopy__(self, memo):
        return CustomObjectProxy(copy.deepcopy(self.__wrapped__, memo))

The reason can’t really provide these as defaults is because can’t be certain that constructor for class only takes the object to be wrapped. It may have to take extra arguments. It is arguably better to have it fail with an exception immediately, rather than it subsequently fail with an even more obscure error message.

1reaction
GrahamDumpletoncommented, Oct 2, 2018

Added default copy methods which raise not implemented error in https://github.com/GrahamDumpleton/wrapt/commit/67c09effcb2f70ac9af7dba60451ab37dd0cd8fb

Read more comments on GitHub >

github_iconTop Results From Across the Web

How do I make this C++ object non-copyable? - Stack Overflow
The typical way to make a C++ object non-copyable is to explicitly declare a copy constructor and copy-assignment operator but not implement ...
Read more >
Proxy - JavaScript - MDN Web Docs
The Proxy object enables you to create a proxy for another object, which can intercept and redefine fundamental operations for that object.
Read more >
Proxies and Wrappers — wrapt 1.13.0rc2 documentation
The object proxy class is available as wrapt.ObjectProxy . The class would not normally be used directly, but as a base class to...
Read more >
lazy-object-proxy 1.3.1 - PyPI
A fast and thorough lazy object proxy. Free software: BSD license. Note that this is based on wrapt's ObjectProxy with one big change:...
Read more >
CM-REQ-4231 Unable to create security object proxy - IBM
NEVER COPY KEYS OR FOLDERS FROM ONE INSTALL to ANOTHER. ensure all standby CM installs have proper credentials for all LDAPS, ADS etc,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found