@@ -1668,6 +1668,161 @@ def __del__(self):
16681668 self .assertEqual (["before" , "after" ], out .decode ().splitlines ())
16691669
16701670
1671+ class TestType (unittest .TestCase ):
1672+ def test_new_type (self ):
1673+ A = type ('A' , (), {})
1674+ self .assertEqual (A .__name__ , 'A' )
1675+ self .assertEqual (A .__qualname__ , 'A' )
1676+ self .assertEqual (A .__module__ , __name__ )
1677+ self .assertEqual (A .__bases__ , (object ,))
1678+ self .assertIs (A .__base__ , object )
1679+ x = A ()
1680+ self .assertIs (type (x ), A )
1681+ self .assertIs (x .__class__ , A )
1682+
1683+ class B :
1684+ def ham (self ):
1685+ return 'ham%d' % self
1686+ C = type ('C' , (B , int ), {'spam' : lambda self : 'spam%s' % self })
1687+ self .assertEqual (C .__name__ , 'C' )
1688+ self .assertEqual (C .__qualname__ , 'C' )
1689+ self .assertEqual (C .__module__ , __name__ )
1690+ self .assertEqual (C .__bases__ , (B , int ))
1691+ self .assertIs (C .__base__ , int )
1692+ self .assertIn ('spam' , C .__dict__ )
1693+ self .assertNotIn ('ham' , C .__dict__ )
1694+ x = C (42 )
1695+ self .assertEqual (x , 42 )
1696+ self .assertIs (type (x ), C )
1697+ self .assertIs (x .__class__ , C )
1698+ self .assertEqual (x .ham (), 'ham42' )
1699+ self .assertEqual (x .spam (), 'spam42' )
1700+ self .assertEqual (x .to_bytes (2 , 'little' ), b'\x2a \x00 ' )
1701+
1702+ def test_type_new_keywords (self ):
1703+ class B :
1704+ def ham (self ):
1705+ return 'ham%d' % self
1706+ C = type .__new__ (type ,
1707+ name = 'C' ,
1708+ bases = (B , int ),
1709+ dict = {'spam' : lambda self : 'spam%s' % self })
1710+ self .assertEqual (C .__name__ , 'C' )
1711+ self .assertEqual (C .__qualname__ , 'C' )
1712+ self .assertEqual (C .__module__ , __name__ )
1713+ self .assertEqual (C .__bases__ , (B , int ))
1714+ self .assertIs (C .__base__ , int )
1715+ self .assertIn ('spam' , C .__dict__ )
1716+ self .assertNotIn ('ham' , C .__dict__ )
1717+
1718+ def test_type_name (self ):
1719+ for name in 'A' , '\xc4 ' , '\U0001f40d ' , 'B.A' , '42' , '' :
1720+ with self .subTest (name = name ):
1721+ A = type (name , (), {})
1722+ self .assertEqual (A .__name__ , name )
1723+ self .assertEqual (A .__qualname__ , name )
1724+ self .assertEqual (A .__module__ , __name__ )
1725+ with self .assertRaises (ValueError ):
1726+ type ('A\x00 B' , (), {})
1727+ with self .assertRaises (ValueError ):
1728+ type ('A\udcdc B' , (), {})
1729+ with self .assertRaises (TypeError ):
1730+ type (b'A' , (), {})
1731+
1732+ C = type ('C' , (), {})
1733+ for name in 'A' , '\xc4 ' , '\U0001f40d ' , 'B.A' , '42' , '' :
1734+ with self .subTest (name = name ):
1735+ C .__name__ = name
1736+ self .assertEqual (C .__name__ , name )
1737+ self .assertEqual (C .__qualname__ , 'C' )
1738+ self .assertEqual (C .__module__ , __name__ )
1739+
1740+ A = type ('C' , (), {})
1741+ with self .assertRaises (ValueError ):
1742+ A .__name__ = 'A\x00 B'
1743+ self .assertEqual (A .__name__ , 'C' )
1744+ with self .assertRaises (ValueError ):
1745+ A .__name__ = 'A\udcdc B'
1746+ self .assertEqual (A .__name__ , 'C' )
1747+ with self .assertRaises (TypeError ):
1748+ A .__name__ = b'A'
1749+ self .assertEqual (A .__name__ , 'C' )
1750+
1751+ def test_type_qualname (self ):
1752+ A = type ('A' , (), {'__qualname__' : 'B.C' })
1753+ self .assertEqual (A .__name__ , 'A' )
1754+ self .assertEqual (A .__qualname__ , 'B.C' )
1755+ self .assertEqual (A .__module__ , __name__ )
1756+ with self .assertRaises (TypeError ):
1757+ type ('A' , (), {'__qualname__' : b'B' })
1758+ self .assertEqual (A .__qualname__ , 'B.C' )
1759+
1760+ A .__qualname__ = 'D.E'
1761+ self .assertEqual (A .__name__ , 'A' )
1762+ self .assertEqual (A .__qualname__ , 'D.E' )
1763+ with self .assertRaises (TypeError ):
1764+ A .__qualname__ = b'B'
1765+ self .assertEqual (A .__qualname__ , 'D.E' )
1766+
1767+ def test_type_doc (self ):
1768+ for doc in 'x' , '\xc4 ' , '\U0001f40d ' , 'x\x00 y' , b'x' , 42 , None :
1769+ A = type ('A' , (), {'__doc__' : doc })
1770+ self .assertEqual (A .__doc__ , doc )
1771+ with self .assertRaises (UnicodeEncodeError ):
1772+ type ('A' , (), {'__doc__' : 'x\udcdc y' })
1773+
1774+ A = type ('A' , (), {})
1775+ self .assertEqual (A .__doc__ , None )
1776+ for doc in 'x' , '\xc4 ' , '\U0001f40d ' , 'x\x00 y' , 'x\udcdc y' , b'x' , 42 , None :
1777+ A .__doc__ = doc
1778+ self .assertEqual (A .__doc__ , doc )
1779+
1780+ def test_bad_args (self ):
1781+ with self .assertRaises (TypeError ):
1782+ type ()
1783+ with self .assertRaises (TypeError ):
1784+ type ('A' , ())
1785+ with self .assertRaises (TypeError ):
1786+ type ('A' , (), {}, ())
1787+ with self .assertRaises (TypeError ):
1788+ type ('A' , (), dict = {})
1789+ with self .assertRaises (TypeError ):
1790+ type ('A' , [], {})
1791+ with self .assertRaises (TypeError ):
1792+ type ('A' , (), types .MappingProxyType ({}))
1793+ with self .assertRaises (TypeError ):
1794+ type ('A' , (None ,), {})
1795+ with self .assertRaises (TypeError ):
1796+ type ('A' , (bool ,), {})
1797+ with self .assertRaises (TypeError ):
1798+ type ('A' , (int , str ), {})
1799+
1800+ def test_bad_slots (self ):
1801+ with self .assertRaises (TypeError ):
1802+ type ('A' , (), {'__slots__' : b'x' })
1803+ with self .assertRaises (TypeError ):
1804+ type ('A' , (int ,), {'__slots__' : 'x' })
1805+ with self .assertRaises (TypeError ):
1806+ type ('A' , (), {'__slots__' : '' })
1807+ with self .assertRaises (TypeError ):
1808+ type ('A' , (), {'__slots__' : '42' })
1809+ with self .assertRaises (TypeError ):
1810+ type ('A' , (), {'__slots__' : 'x\x00 y' })
1811+ with self .assertRaises (ValueError ):
1812+ type ('A' , (), {'__slots__' : 'x' , 'x' : 0 })
1813+ with self .assertRaises (TypeError ):
1814+ type ('A' , (), {'__slots__' : ('__dict__' , '__dict__' )})
1815+ with self .assertRaises (TypeError ):
1816+ type ('A' , (), {'__slots__' : ('__weakref__' , '__weakref__' )})
1817+
1818+ class B :
1819+ pass
1820+ with self .assertRaises (TypeError ):
1821+ type ('A' , (B ,), {'__slots__' : '__dict__' })
1822+ with self .assertRaises (TypeError ):
1823+ type ('A' , (B ,), {'__slots__' : '__weakref__' })
1824+
1825+
16711826def load_tests (loader , tests , pattern ):
16721827 from doctest import DocTestSuite
16731828 tests .addTest (DocTestSuite (builtins ))
0 commit comments