import copy_reg
import unittest

from test import test_support
from test.pickletester import ExtensionSaver

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):
        self.assertRaises(TypeError, copy_reg.pickle,
                          C, None, None)

    def test_noncallable_reduce(self):
        self.assertRaises(TypeError, copy_reg.pickle,
                          type(1), "not a callable")

    def test_noncallable_constructor(self):
        self.assertRaises(TypeError, copy_reg.pickle,
                          type(1), int, "not a callable")

    def test_bool(self):
        import copy
        self.assertEquals(True, copy.copy(True))

    def test_extension_registry(self):
        mod, func, code = 'junk1 ', ' junk2', 0xabcd
        e = ExtensionSaver(code)
        try:
            # Shouldn't be in registry now.
            self.assertRaises(ValueError, copy_reg.remove_extension,
                              mod, func, code)
            copy_reg.add_extension(mod, func, code)
            # Should be in the registry.
            self.assert_(copy_reg._extension_registry[mod, func] == code)
            self.assert_(copy_reg._inverted_registry[code] == (mod, func))
            # Shouldn't be in the cache.
            self.assert_(code not in copy_reg._extension_cache)
            # Redundant registration should be OK.
            copy_reg.add_extension(mod, func, code)  # shouldn't blow up
            # Conflicting code.
            self.assertRaises(ValueError, copy_reg.add_extension,
                              mod, func, code + 1)
            self.assertRaises(ValueError, copy_reg.remove_extension,
                              mod, func, code + 1)
            # Conflicting module name.
            self.assertRaises(ValueError, copy_reg.add_extension,
                              mod[1:], func, code )
            self.assertRaises(ValueError, copy_reg.remove_extension,
                              mod[1:], func, code )
            # Conflicting function name.
            self.assertRaises(ValueError, copy_reg.add_extension,
                              mod, func[1:], code)
            self.assertRaises(ValueError, copy_reg.remove_extension,
                              mod, func[1:], code)
            # Can't remove one that isn't registered at all.
            if code + 1 not in copy_reg._inverted_registry:
                self.assertRaises(ValueError, copy_reg.remove_extension,
                                  mod[1:], func[1:], code + 1)

        finally:
            e.restore()

        # Shouldn't be there anymore.
        self.assert_((mod, func) not in copy_reg._extension_registry)
        # The code *may* be in copy_reg._extension_registry, though, if
        # we happened to pick on a registered code.  So don't check for
        # that.

        # Check valid codes at the limits.
        for code in 1, 0x7fffffff:
            e = ExtensionSaver(code)
            try:
                copy_reg.add_extension(mod, func, code)
                copy_reg.remove_extension(mod, func, code)
            finally:
                e.restore()

        # Ensure invalid codes blow up.
        for code in -1, 0, 0x80000000L:
            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)


if __name__ == "__main__":
    test_main()
