From 22ec80bc4f3e66990981ca57b66b38873e2711df Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Fri, 31 Mar 2006 18:25:44 +0000 Subject: Patch #1462313, bug #1443328: the pickle modules now can handle classes that have __private names in their __slots__. --- Lib/copy_reg.py | 15 +++++++++++++-- Lib/test/test_copy_reg.py | 29 +++++++++++++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/Lib/copy_reg.py b/Lib/copy_reg.py index f499013..f87c50f 100644 --- a/Lib/copy_reg.py +++ b/Lib/copy_reg.py @@ -116,8 +116,19 @@ def _slotnames(cls): # Slots found -- gather slot names from all base classes for c in cls.__mro__: if "__slots__" in c.__dict__: - names += [name for name in c.__dict__["__slots__"] - if name not in ("__dict__", "__weakref__")] + slots = c.__dict__['__slots__'] + # if class has a single slot, it can be given as a string + if isinstance(slots, basestring): + slots = (slots,) + for name in slots: + # special descriptors + if name in ("__dict__", "__weakref__"): + continue + # mangled names + elif name.startswith('__') and not name.endswith('__'): + names.append('_%s%s' % (c.__name__, name)) + else: + names.append(name) # Cache the outcome in the class if at all possible try: diff --git a/Lib/test/test_copy_reg.py b/Lib/test/test_copy_reg.py index c41946a..c3d3964 100644 --- a/Lib/test/test_copy_reg.py +++ b/Lib/test/test_copy_reg.py @@ -8,6 +8,22 @@ class C: pass +class WithoutSlots(object): + pass + +class WithWeakref(object): + __slots__ = ('__weakref__',) + +class WithPrivate(object): + __slots__ = ('__spam',) + +class WithSingleString(object): + __slots__ = 'spam' + +class WithInherited(WithSingleString): + __slots__ = ('eggs',) + + class CopyRegTestCase(unittest.TestCase): def test_class(self): @@ -84,6 +100,19 @@ class CopyRegTestCase(unittest.TestCase): self.assertRaises(ValueError, copy_reg.add_extension, mod, func, code) + def test_slotnames(self): + self.assertEquals(copy_reg._slotnames(WithoutSlots), []) + self.assertEquals(copy_reg._slotnames(WithWeakref), []) + expected = ['_WithPrivate__spam'] + self.assertEquals(copy_reg._slotnames(WithPrivate), expected) + self.assertEquals(copy_reg._slotnames(WithSingleString), ['spam']) + expected = ['eggs', 'spam'] + expected.sort() + result = copy_reg._slotnames(WithInherited) + result.sort() + self.assertEquals(result, expected) + + def test_main(): test_support.run_unittest(CopyRegTestCase) diff --git a/Misc/NEWS b/Misc/NEWS index dc98c7a..ed48276 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -487,6 +487,9 @@ Extension Modules Library ------- +- Patch #1462313, bug #1443328: the pickle modules now can handle classes + that have __private names in their __slots__. + - Bug #1250170: mimetools now gracefully handles socket.gethostname() failures gracefully. -- cgit v0.12