def test_issue24097(self):
# Slot name is freed inside __getattr__ and is later used.
class S(str): # Not interned
pass
class A:
__slotnames__ = [S('spam')]
def __getattr__(self, attr):
if attr == 'spam':
A.__slotnames__[:] = [S('spam')]
return 42
else:
raise AttributeError
import copyreg
expected = (copyreg.__newobj__, (A,), (None, {'spam': 42}), None, None)
self.assertEqual(A().__reduce__(2), expected) # Shouldn't crash
python类__newobj__()的实例源码
def __reduce_ex__(self, proto):
state = (self.requires_grad, self.volatile, self._backward_hooks)
if proto > 1:
return type(self), (self.data,), state
if sys.version_info[0] == 2:
from copy_reg import __newobj__
else:
from copyreg import __newobj__
return __newobj__, (type(self), self.data), state
def __reduce_ex__(self, proto):
state = (self.requires_grad, self.volatile, self._backward_hooks)
if proto > 1:
return type(self), (self.data,), state
if sys.version_info[0] == 2:
from copy_reg import __newobj__
else:
from copyreg import __newobj__
return __newobj__, (type(self), self.data), state
def __reduce_ex__(self, proto):
state = (self.requires_grad, self.volatile, self._backward_hooks)
if proto > 1:
return type(self), (self.data,), state
if sys.version_info[0] == 2:
from copy_reg import __newobj__
else:
from copyreg import __newobj__
return __newobj__, (type(self), self.data), state
def _check_reduce(self, proto, obj, args=(), kwargs={}, state=None,
listitems=None, dictitems=None):
if proto >= 4:
reduce_value = obj.__reduce_ex__(proto)
self.assertEqual(reduce_value[:3],
(copyreg.__newobj_ex__,
(type(obj), args, kwargs),
state))
if listitems is not None:
self.assertListEqual(list(reduce_value[3]), listitems)
else:
self.assertIsNone(reduce_value[3])
if dictitems is not None:
self.assertDictEqual(dict(reduce_value[4]), dictitems)
else:
self.assertIsNone(reduce_value[4])
elif proto >= 2:
reduce_value = obj.__reduce_ex__(proto)
self.assertEqual(reduce_value[:3],
(copyreg.__newobj__,
(type(obj),) + args,
state))
if listitems is not None:
self.assertListEqual(list(reduce_value[3]), listitems)
else:
self.assertIsNone(reduce_value[3])
if dictitems is not None:
self.assertDictEqual(dict(reduce_value[4]), dictitems)
else:
self.assertIsNone(reduce_value[4])
else:
base_type = type(obj).__base__
reduce_value = (copyreg._reconstructor,
(type(obj),
base_type,
None if base_type is object else base_type(obj)))
if state is not None:
reduce_value += (state,)
self.assertEqual(obj.__reduce_ex__(proto), reduce_value)
self.assertEqual(obj.__reduce__(), reduce_value)
def __reduce_ex__(self, proto):
state = (self.requires_grad, False, self._backward_hooks)
if proto > 1:
return type(self), (self.data,), state
if sys.version_info[0] == 2:
from copy_reg import __newobj__
else:
from copyreg import __newobj__
return __newobj__, (type(self), self.data), state
def _check_reduce(self, proto, obj, args=(), kwargs={}, state=None,
listitems=None, dictitems=None):
if proto >= 4:
reduce_value = obj.__reduce_ex__(proto)
self.assertEqual(reduce_value[:3],
(copyreg.__newobj_ex__,
(type(obj), args, kwargs),
state))
if listitems is not None:
self.assertListEqual(list(reduce_value[3]), listitems)
else:
self.assertIsNone(reduce_value[3])
if dictitems is not None:
self.assertDictEqual(dict(reduce_value[4]), dictitems)
else:
self.assertIsNone(reduce_value[4])
elif proto >= 2:
reduce_value = obj.__reduce_ex__(proto)
self.assertEqual(reduce_value[:3],
(copyreg.__newobj__,
(type(obj),) + args,
state))
if listitems is not None:
self.assertListEqual(list(reduce_value[3]), listitems)
else:
self.assertIsNone(reduce_value[3])
if dictitems is not None:
self.assertDictEqual(dict(reduce_value[4]), dictitems)
else:
self.assertIsNone(reduce_value[4])
else:
base_type = type(obj).__base__
reduce_value = (copyreg._reconstructor,
(type(obj),
base_type,
None if base_type is object else base_type(obj)))
if state is not None:
reduce_value += (state,)
self.assertEqual(obj.__reduce_ex__(proto), reduce_value)
self.assertEqual(obj.__reduce__(), reduce_value)