Commit 38ae2cd0 authored by Jason Madden's avatar Jason Madden

Address feedback: Mangle the _DERIVED attribute to prevent collisions. Delete...

Address feedback: Mangle the _DERIVED attribute to prevent collisions. Delete the traceback local when we're done with it. Properly specify the slots in the tests.
parent 5ec1f3f7
...@@ -301,7 +301,7 @@ _NOT_GIVEN = object() # marker ...@@ -301,7 +301,7 @@ _NOT_GIVEN = object() # marker
_OGA = object.__getattribute__ _OGA = object.__getattribute__
# Map from object types with slots to their generated, derived # Map from object types with slots to their generated, derived
# types # types (or None if no derived type is needed)
_wrapper_subclass_cache = weakref.WeakKeyDictionary() _wrapper_subclass_cache = weakref.WeakKeyDictionary()
def _make_wrapper_subclass_if_needed(cls, obj, container): def _make_wrapper_subclass_if_needed(cls, obj, container):
...@@ -309,14 +309,14 @@ def _make_wrapper_subclass_if_needed(cls, obj, container): ...@@ -309,14 +309,14 @@ def _make_wrapper_subclass_if_needed(cls, obj, container):
# must create a wrapper subclass that has descriptors for those # must create a wrapper subclass that has descriptors for those
# same slots. In this way, its methods that use object.__getattribute__ # same slots. In this way, its methods that use object.__getattribute__
# directly will continue to work, even when given an instance of _Wrapper # directly will continue to work, even when given an instance of _Wrapper
if getattr(cls, '_DERIVED', False): if getattr(cls, '_Wrapper__DERIVED', False):
return None return None
type_obj = type(obj) type_obj = type(obj)
wrapper_subclass = _wrapper_subclass_cache.get(type_obj, _NOT_GIVEN) wrapper_subclass = _wrapper_subclass_cache.get(type_obj, _NOT_GIVEN)
if wrapper_subclass is _NOT_GIVEN: if wrapper_subclass is _NOT_GIVEN:
slotnames = copy_reg._slotnames(type_obj) slotnames = copy_reg._slotnames(type_obj)
if slotnames and not getattr(cls, '_DERIVED', False) and not isinstance(obj, _Wrapper): if slotnames and not isinstance(obj, _Wrapper):
new_type_dict = {'_DERIVED': True} new_type_dict = {'_Wrapper__DERIVED': True}
def _make_property(slotname): def _make_property(slotname):
return property(lambda s: getattr(s._obj, slotname), return property(lambda s: getattr(s._obj, slotname),
lambda s, v: setattr(s._obj, slotname, v), lambda s, v: setattr(s._obj, slotname, v),
...@@ -741,12 +741,15 @@ class _Acquirer(ExtensionClass.Base): ...@@ -741,12 +741,15 @@ class _Acquirer(ExtensionClass.Base):
def __getattribute__(self, name): def __getattribute__(self, name):
try: try:
return super(_Acquirer,self).__getattribute__(name) return super(_Acquirer, self).__getattribute__(name)
except AttributeError: except AttributeError:
# the doctests have very specific error message # the doctests have very specific error message
# requirements (but at least we can preserve the traceback) # requirements (but at least we can preserve the traceback)
t, v, tb = sys.exc_info() _, _, tb = sys.exc_info()
_reraise(AttributeError, AttributeError(name), tb) try:
_reraise(AttributeError, AttributeError(name), tb)
finally:
del tb
def __of__(self, context): def __of__(self, context):
return type(self)._Wrapper(self, context) return type(self)._Wrapper(self, context)
......
...@@ -3163,7 +3163,7 @@ if 'Acquisition._Acquisition' not in sys.modules: ...@@ -3163,7 +3163,7 @@ if 'Acquisition._Acquisition' not in sys.modules:
def test_object_getattribute_in_rebound_method_with_slots(self): def test_object_getattribute_in_rebound_method_with_slots(self):
class Persistent(object): class Persistent(object):
__slots__ = ('__flags') __slots__ = ('__flags',)
def __init__(self): def __init__(self):
self.__flags = 42 self.__flags = 42
...@@ -3187,7 +3187,7 @@ if 'Acquisition._Acquisition' not in sys.modules: ...@@ -3187,7 +3187,7 @@ if 'Acquisition._Acquisition' not in sys.modules:
def test_type_with_slots_reused(self): def test_type_with_slots_reused(self):
class Persistent(object): class Persistent(object):
__slots__ = ('__flags') __slots__ = ('__flags',)
def __init__(self): def __init__(self):
self.__flags = 42 self.__flags = 42
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment