17db96d56Sopenharmony_ciimport textwrap 27db96d56Sopenharmony_ciimport types 37db96d56Sopenharmony_ciimport unittest 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_cidef global_function(): 77db96d56Sopenharmony_ci def inner_function(): 87db96d56Sopenharmony_ci class LocalClass: 97db96d56Sopenharmony_ci pass 107db96d56Sopenharmony_ci global inner_global_function 117db96d56Sopenharmony_ci def inner_global_function(): 127db96d56Sopenharmony_ci def inner_function2(): 137db96d56Sopenharmony_ci pass 147db96d56Sopenharmony_ci return inner_function2 157db96d56Sopenharmony_ci return LocalClass 167db96d56Sopenharmony_ci return lambda: inner_function 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ciclass FuncAttrsTest(unittest.TestCase): 207db96d56Sopenharmony_ci def setUp(self): 217db96d56Sopenharmony_ci class F: 227db96d56Sopenharmony_ci def a(self): 237db96d56Sopenharmony_ci pass 247db96d56Sopenharmony_ci def b(): 257db96d56Sopenharmony_ci return 3 267db96d56Sopenharmony_ci self.fi = F() 277db96d56Sopenharmony_ci self.F = F 287db96d56Sopenharmony_ci self.b = b 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci def cannot_set_attr(self, obj, name, value, exceptions): 317db96d56Sopenharmony_ci try: 327db96d56Sopenharmony_ci setattr(obj, name, value) 337db96d56Sopenharmony_ci except exceptions: 347db96d56Sopenharmony_ci pass 357db96d56Sopenharmony_ci else: 367db96d56Sopenharmony_ci self.fail("shouldn't be able to set %s to %r" % (name, value)) 377db96d56Sopenharmony_ci try: 387db96d56Sopenharmony_ci delattr(obj, name) 397db96d56Sopenharmony_ci except exceptions: 407db96d56Sopenharmony_ci pass 417db96d56Sopenharmony_ci else: 427db96d56Sopenharmony_ci self.fail("shouldn't be able to del %s" % name) 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_ciclass FunctionPropertiesTest(FuncAttrsTest): 467db96d56Sopenharmony_ci # Include the external setUp method that is common to all tests 477db96d56Sopenharmony_ci def test_module(self): 487db96d56Sopenharmony_ci self.assertEqual(self.b.__module__, __name__) 497db96d56Sopenharmony_ci 507db96d56Sopenharmony_ci def test_dir_includes_correct_attrs(self): 517db96d56Sopenharmony_ci self.b.known_attr = 7 527db96d56Sopenharmony_ci self.assertIn('known_attr', dir(self.b), 537db96d56Sopenharmony_ci "set attributes not in dir listing of method") 547db96d56Sopenharmony_ci # Test on underlying function object of method 557db96d56Sopenharmony_ci self.F.a.known_attr = 7 567db96d56Sopenharmony_ci self.assertIn('known_attr', dir(self.fi.a), "set attribute on function " 577db96d56Sopenharmony_ci "implementations, should show up in next dir") 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci def test_duplicate_function_equality(self): 607db96d56Sopenharmony_ci # Body of `duplicate' is the exact same as self.b 617db96d56Sopenharmony_ci def duplicate(): 627db96d56Sopenharmony_ci 'my docstring' 637db96d56Sopenharmony_ci return 3 647db96d56Sopenharmony_ci self.assertNotEqual(self.b, duplicate) 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ci def test_copying___code__(self): 677db96d56Sopenharmony_ci def test(): pass 687db96d56Sopenharmony_ci self.assertEqual(test(), None) 697db96d56Sopenharmony_ci test.__code__ = self.b.__code__ 707db96d56Sopenharmony_ci self.assertEqual(test(), 3) # self.b always returns 3, arbitrarily 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci def test___globals__(self): 737db96d56Sopenharmony_ci self.assertIs(self.b.__globals__, globals()) 747db96d56Sopenharmony_ci self.cannot_set_attr(self.b, '__globals__', 2, 757db96d56Sopenharmony_ci (AttributeError, TypeError)) 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci def test___builtins__(self): 787db96d56Sopenharmony_ci self.assertIs(self.b.__builtins__, __builtins__) 797db96d56Sopenharmony_ci self.cannot_set_attr(self.b, '__builtins__', 2, 807db96d56Sopenharmony_ci (AttributeError, TypeError)) 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci # bpo-42990: If globals is specified and has no "__builtins__" key, 837db96d56Sopenharmony_ci # a function inherits the current builtins namespace. 847db96d56Sopenharmony_ci def func(s): return len(s) 857db96d56Sopenharmony_ci ns = {} 867db96d56Sopenharmony_ci func2 = type(func)(func.__code__, ns) 877db96d56Sopenharmony_ci self.assertIs(func2.__globals__, ns) 887db96d56Sopenharmony_ci self.assertIs(func2.__builtins__, __builtins__) 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci # Make sure that the function actually works. 917db96d56Sopenharmony_ci self.assertEqual(func2("abc"), 3) 927db96d56Sopenharmony_ci self.assertEqual(ns, {}) 937db96d56Sopenharmony_ci 947db96d56Sopenharmony_ci # Define functions using exec() with different builtins, 957db96d56Sopenharmony_ci # and test inheritance when globals has no "__builtins__" key 967db96d56Sopenharmony_ci code = textwrap.dedent(""" 977db96d56Sopenharmony_ci def func3(s): pass 987db96d56Sopenharmony_ci func4 = type(func3)(func3.__code__, {}) 997db96d56Sopenharmony_ci """) 1007db96d56Sopenharmony_ci safe_builtins = {'None': None} 1017db96d56Sopenharmony_ci ns = {'type': type, '__builtins__': safe_builtins} 1027db96d56Sopenharmony_ci exec(code, ns) 1037db96d56Sopenharmony_ci self.assertIs(ns['func3'].__builtins__, safe_builtins) 1047db96d56Sopenharmony_ci self.assertIs(ns['func4'].__builtins__, safe_builtins) 1057db96d56Sopenharmony_ci self.assertIs(ns['func3'].__globals__['__builtins__'], safe_builtins) 1067db96d56Sopenharmony_ci self.assertNotIn('__builtins__', ns['func4'].__globals__) 1077db96d56Sopenharmony_ci 1087db96d56Sopenharmony_ci def test___closure__(self): 1097db96d56Sopenharmony_ci a = 12 1107db96d56Sopenharmony_ci def f(): print(a) 1117db96d56Sopenharmony_ci c = f.__closure__ 1127db96d56Sopenharmony_ci self.assertIsInstance(c, tuple) 1137db96d56Sopenharmony_ci self.assertEqual(len(c), 1) 1147db96d56Sopenharmony_ci # don't have a type object handy 1157db96d56Sopenharmony_ci self.assertEqual(c[0].__class__.__name__, "cell") 1167db96d56Sopenharmony_ci self.cannot_set_attr(f, "__closure__", c, AttributeError) 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_ci def test_cell_new(self): 1197db96d56Sopenharmony_ci cell_obj = types.CellType(1) 1207db96d56Sopenharmony_ci self.assertEqual(cell_obj.cell_contents, 1) 1217db96d56Sopenharmony_ci 1227db96d56Sopenharmony_ci cell_obj = types.CellType() 1237db96d56Sopenharmony_ci msg = "shouldn't be able to read an empty cell" 1247db96d56Sopenharmony_ci with self.assertRaises(ValueError, msg=msg): 1257db96d56Sopenharmony_ci cell_obj.cell_contents 1267db96d56Sopenharmony_ci 1277db96d56Sopenharmony_ci def test_empty_cell(self): 1287db96d56Sopenharmony_ci def f(): print(a) 1297db96d56Sopenharmony_ci try: 1307db96d56Sopenharmony_ci f.__closure__[0].cell_contents 1317db96d56Sopenharmony_ci except ValueError: 1327db96d56Sopenharmony_ci pass 1337db96d56Sopenharmony_ci else: 1347db96d56Sopenharmony_ci self.fail("shouldn't be able to read an empty cell") 1357db96d56Sopenharmony_ci a = 12 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci def test_set_cell(self): 1387db96d56Sopenharmony_ci a = 12 1397db96d56Sopenharmony_ci def f(): return a 1407db96d56Sopenharmony_ci c = f.__closure__ 1417db96d56Sopenharmony_ci c[0].cell_contents = 9 1427db96d56Sopenharmony_ci self.assertEqual(c[0].cell_contents, 9) 1437db96d56Sopenharmony_ci self.assertEqual(f(), 9) 1447db96d56Sopenharmony_ci self.assertEqual(a, 9) 1457db96d56Sopenharmony_ci del c[0].cell_contents 1467db96d56Sopenharmony_ci try: 1477db96d56Sopenharmony_ci c[0].cell_contents 1487db96d56Sopenharmony_ci except ValueError: 1497db96d56Sopenharmony_ci pass 1507db96d56Sopenharmony_ci else: 1517db96d56Sopenharmony_ci self.fail("shouldn't be able to read an empty cell") 1527db96d56Sopenharmony_ci with self.assertRaises(NameError): 1537db96d56Sopenharmony_ci f() 1547db96d56Sopenharmony_ci with self.assertRaises(UnboundLocalError): 1557db96d56Sopenharmony_ci print(a) 1567db96d56Sopenharmony_ci 1577db96d56Sopenharmony_ci def test___name__(self): 1587db96d56Sopenharmony_ci self.assertEqual(self.b.__name__, 'b') 1597db96d56Sopenharmony_ci self.b.__name__ = 'c' 1607db96d56Sopenharmony_ci self.assertEqual(self.b.__name__, 'c') 1617db96d56Sopenharmony_ci self.b.__name__ = 'd' 1627db96d56Sopenharmony_ci self.assertEqual(self.b.__name__, 'd') 1637db96d56Sopenharmony_ci # __name__ and __name__ must be a string 1647db96d56Sopenharmony_ci self.cannot_set_attr(self.b, '__name__', 7, TypeError) 1657db96d56Sopenharmony_ci # __name__ must be available when in restricted mode. Exec will raise 1667db96d56Sopenharmony_ci # AttributeError if __name__ is not available on f. 1677db96d56Sopenharmony_ci s = """def f(): pass\nf.__name__""" 1687db96d56Sopenharmony_ci exec(s, {'__builtins__': {}}) 1697db96d56Sopenharmony_ci # Test on methods, too 1707db96d56Sopenharmony_ci self.assertEqual(self.fi.a.__name__, 'a') 1717db96d56Sopenharmony_ci self.cannot_set_attr(self.fi.a, "__name__", 'a', AttributeError) 1727db96d56Sopenharmony_ci 1737db96d56Sopenharmony_ci def test___qualname__(self): 1747db96d56Sopenharmony_ci # PEP 3155 1757db96d56Sopenharmony_ci self.assertEqual(self.b.__qualname__, 'FuncAttrsTest.setUp.<locals>.b') 1767db96d56Sopenharmony_ci self.assertEqual(FuncAttrsTest.setUp.__qualname__, 'FuncAttrsTest.setUp') 1777db96d56Sopenharmony_ci self.assertEqual(global_function.__qualname__, 'global_function') 1787db96d56Sopenharmony_ci self.assertEqual(global_function().__qualname__, 1797db96d56Sopenharmony_ci 'global_function.<locals>.<lambda>') 1807db96d56Sopenharmony_ci self.assertEqual(global_function()().__qualname__, 1817db96d56Sopenharmony_ci 'global_function.<locals>.inner_function') 1827db96d56Sopenharmony_ci self.assertEqual(global_function()()().__qualname__, 1837db96d56Sopenharmony_ci 'global_function.<locals>.inner_function.<locals>.LocalClass') 1847db96d56Sopenharmony_ci self.assertEqual(inner_global_function.__qualname__, 'inner_global_function') 1857db96d56Sopenharmony_ci self.assertEqual(inner_global_function().__qualname__, 'inner_global_function.<locals>.inner_function2') 1867db96d56Sopenharmony_ci self.b.__qualname__ = 'c' 1877db96d56Sopenharmony_ci self.assertEqual(self.b.__qualname__, 'c') 1887db96d56Sopenharmony_ci self.b.__qualname__ = 'd' 1897db96d56Sopenharmony_ci self.assertEqual(self.b.__qualname__, 'd') 1907db96d56Sopenharmony_ci # __qualname__ must be a string 1917db96d56Sopenharmony_ci self.cannot_set_attr(self.b, '__qualname__', 7, TypeError) 1927db96d56Sopenharmony_ci 1937db96d56Sopenharmony_ci def test___code__(self): 1947db96d56Sopenharmony_ci num_one, num_two = 7, 8 1957db96d56Sopenharmony_ci def a(): pass 1967db96d56Sopenharmony_ci def b(): return 12 1977db96d56Sopenharmony_ci def c(): return num_one 1987db96d56Sopenharmony_ci def d(): return num_two 1997db96d56Sopenharmony_ci def e(): return num_one, num_two 2007db96d56Sopenharmony_ci for func in [a, b, c, d, e]: 2017db96d56Sopenharmony_ci self.assertEqual(type(func.__code__), types.CodeType) 2027db96d56Sopenharmony_ci self.assertEqual(c(), 7) 2037db96d56Sopenharmony_ci self.assertEqual(d(), 8) 2047db96d56Sopenharmony_ci d.__code__ = c.__code__ 2057db96d56Sopenharmony_ci self.assertEqual(c.__code__, d.__code__) 2067db96d56Sopenharmony_ci self.assertEqual(c(), 7) 2077db96d56Sopenharmony_ci # self.assertEqual(d(), 7) 2087db96d56Sopenharmony_ci try: 2097db96d56Sopenharmony_ci b.__code__ = c.__code__ 2107db96d56Sopenharmony_ci except ValueError: 2117db96d56Sopenharmony_ci pass 2127db96d56Sopenharmony_ci else: 2137db96d56Sopenharmony_ci self.fail("__code__ with different numbers of free vars should " 2147db96d56Sopenharmony_ci "not be possible") 2157db96d56Sopenharmony_ci try: 2167db96d56Sopenharmony_ci e.__code__ = d.__code__ 2177db96d56Sopenharmony_ci except ValueError: 2187db96d56Sopenharmony_ci pass 2197db96d56Sopenharmony_ci else: 2207db96d56Sopenharmony_ci self.fail("__code__ with different numbers of free vars should " 2217db96d56Sopenharmony_ci "not be possible") 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_ci def test_blank_func_defaults(self): 2247db96d56Sopenharmony_ci self.assertEqual(self.b.__defaults__, None) 2257db96d56Sopenharmony_ci del self.b.__defaults__ 2267db96d56Sopenharmony_ci self.assertEqual(self.b.__defaults__, None) 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ci def test_func_default_args(self): 2297db96d56Sopenharmony_ci def first_func(a, b): 2307db96d56Sopenharmony_ci return a+b 2317db96d56Sopenharmony_ci def second_func(a=1, b=2): 2327db96d56Sopenharmony_ci return a+b 2337db96d56Sopenharmony_ci self.assertEqual(first_func.__defaults__, None) 2347db96d56Sopenharmony_ci self.assertEqual(second_func.__defaults__, (1, 2)) 2357db96d56Sopenharmony_ci first_func.__defaults__ = (1, 2) 2367db96d56Sopenharmony_ci self.assertEqual(first_func.__defaults__, (1, 2)) 2377db96d56Sopenharmony_ci self.assertEqual(first_func(), 3) 2387db96d56Sopenharmony_ci self.assertEqual(first_func(3), 5) 2397db96d56Sopenharmony_ci self.assertEqual(first_func(3, 5), 8) 2407db96d56Sopenharmony_ci del second_func.__defaults__ 2417db96d56Sopenharmony_ci self.assertEqual(second_func.__defaults__, None) 2427db96d56Sopenharmony_ci try: 2437db96d56Sopenharmony_ci second_func() 2447db96d56Sopenharmony_ci except TypeError: 2457db96d56Sopenharmony_ci pass 2467db96d56Sopenharmony_ci else: 2477db96d56Sopenharmony_ci self.fail("__defaults__ does not update; deleting it does not " 2487db96d56Sopenharmony_ci "remove requirement") 2497db96d56Sopenharmony_ci 2507db96d56Sopenharmony_ci 2517db96d56Sopenharmony_ciclass InstancemethodAttrTest(FuncAttrsTest): 2527db96d56Sopenharmony_ci 2537db96d56Sopenharmony_ci def test___class__(self): 2547db96d56Sopenharmony_ci self.assertEqual(self.fi.a.__self__.__class__, self.F) 2557db96d56Sopenharmony_ci self.cannot_set_attr(self.fi.a, "__class__", self.F, TypeError) 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_ci def test___func__(self): 2587db96d56Sopenharmony_ci self.assertEqual(self.fi.a.__func__, self.F.a) 2597db96d56Sopenharmony_ci self.cannot_set_attr(self.fi.a, "__func__", self.F.a, AttributeError) 2607db96d56Sopenharmony_ci 2617db96d56Sopenharmony_ci def test___self__(self): 2627db96d56Sopenharmony_ci self.assertEqual(self.fi.a.__self__, self.fi) 2637db96d56Sopenharmony_ci self.cannot_set_attr(self.fi.a, "__self__", self.fi, AttributeError) 2647db96d56Sopenharmony_ci 2657db96d56Sopenharmony_ci def test___func___non_method(self): 2667db96d56Sopenharmony_ci # Behavior should be the same when a method is added via an attr 2677db96d56Sopenharmony_ci # assignment 2687db96d56Sopenharmony_ci self.fi.id = types.MethodType(id, self.fi) 2697db96d56Sopenharmony_ci self.assertEqual(self.fi.id(), id(self.fi)) 2707db96d56Sopenharmony_ci # Test usage 2717db96d56Sopenharmony_ci try: 2727db96d56Sopenharmony_ci self.fi.id.unknown_attr 2737db96d56Sopenharmony_ci except AttributeError: 2747db96d56Sopenharmony_ci pass 2757db96d56Sopenharmony_ci else: 2767db96d56Sopenharmony_ci self.fail("using unknown attributes should raise AttributeError") 2777db96d56Sopenharmony_ci # Test assignment and deletion 2787db96d56Sopenharmony_ci self.cannot_set_attr(self.fi.id, 'unknown_attr', 2, AttributeError) 2797db96d56Sopenharmony_ci 2807db96d56Sopenharmony_ci 2817db96d56Sopenharmony_ciclass ArbitraryFunctionAttrTest(FuncAttrsTest): 2827db96d56Sopenharmony_ci def test_set_attr(self): 2837db96d56Sopenharmony_ci self.b.known_attr = 7 2847db96d56Sopenharmony_ci self.assertEqual(self.b.known_attr, 7) 2857db96d56Sopenharmony_ci try: 2867db96d56Sopenharmony_ci self.fi.a.known_attr = 7 2877db96d56Sopenharmony_ci except AttributeError: 2887db96d56Sopenharmony_ci pass 2897db96d56Sopenharmony_ci else: 2907db96d56Sopenharmony_ci self.fail("setting attributes on methods should raise error") 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci def test_delete_unknown_attr(self): 2937db96d56Sopenharmony_ci try: 2947db96d56Sopenharmony_ci del self.b.unknown_attr 2957db96d56Sopenharmony_ci except AttributeError: 2967db96d56Sopenharmony_ci pass 2977db96d56Sopenharmony_ci else: 2987db96d56Sopenharmony_ci self.fail("deleting unknown attribute should raise TypeError") 2997db96d56Sopenharmony_ci 3007db96d56Sopenharmony_ci def test_unset_attr(self): 3017db96d56Sopenharmony_ci for func in [self.b, self.fi.a]: 3027db96d56Sopenharmony_ci try: 3037db96d56Sopenharmony_ci func.non_existent_attr 3047db96d56Sopenharmony_ci except AttributeError: 3057db96d56Sopenharmony_ci pass 3067db96d56Sopenharmony_ci else: 3077db96d56Sopenharmony_ci self.fail("using unknown attributes should raise " 3087db96d56Sopenharmony_ci "AttributeError") 3097db96d56Sopenharmony_ci 3107db96d56Sopenharmony_ci 3117db96d56Sopenharmony_ciclass FunctionDictsTest(FuncAttrsTest): 3127db96d56Sopenharmony_ci def test_setting_dict_to_invalid(self): 3137db96d56Sopenharmony_ci self.cannot_set_attr(self.b, '__dict__', None, TypeError) 3147db96d56Sopenharmony_ci from collections import UserDict 3157db96d56Sopenharmony_ci d = UserDict({'known_attr': 7}) 3167db96d56Sopenharmony_ci self.cannot_set_attr(self.fi.a.__func__, '__dict__', d, TypeError) 3177db96d56Sopenharmony_ci 3187db96d56Sopenharmony_ci def test_setting_dict_to_valid(self): 3197db96d56Sopenharmony_ci d = {'known_attr': 7} 3207db96d56Sopenharmony_ci self.b.__dict__ = d 3217db96d56Sopenharmony_ci # Test assignment 3227db96d56Sopenharmony_ci self.assertIs(d, self.b.__dict__) 3237db96d56Sopenharmony_ci # ... and on all the different ways of referencing the method's func 3247db96d56Sopenharmony_ci self.F.a.__dict__ = d 3257db96d56Sopenharmony_ci self.assertIs(d, self.fi.a.__func__.__dict__) 3267db96d56Sopenharmony_ci self.assertIs(d, self.fi.a.__dict__) 3277db96d56Sopenharmony_ci # Test value 3287db96d56Sopenharmony_ci self.assertEqual(self.b.known_attr, 7) 3297db96d56Sopenharmony_ci self.assertEqual(self.b.__dict__['known_attr'], 7) 3307db96d56Sopenharmony_ci # ... and again, on all the different method's names 3317db96d56Sopenharmony_ci self.assertEqual(self.fi.a.__func__.known_attr, 7) 3327db96d56Sopenharmony_ci self.assertEqual(self.fi.a.known_attr, 7) 3337db96d56Sopenharmony_ci 3347db96d56Sopenharmony_ci def test_delete___dict__(self): 3357db96d56Sopenharmony_ci try: 3367db96d56Sopenharmony_ci del self.b.__dict__ 3377db96d56Sopenharmony_ci except TypeError: 3387db96d56Sopenharmony_ci pass 3397db96d56Sopenharmony_ci else: 3407db96d56Sopenharmony_ci self.fail("deleting function dictionary should raise TypeError") 3417db96d56Sopenharmony_ci 3427db96d56Sopenharmony_ci def test_unassigned_dict(self): 3437db96d56Sopenharmony_ci self.assertEqual(self.b.__dict__, {}) 3447db96d56Sopenharmony_ci 3457db96d56Sopenharmony_ci def test_func_as_dict_key(self): 3467db96d56Sopenharmony_ci value = "Some string" 3477db96d56Sopenharmony_ci d = {} 3487db96d56Sopenharmony_ci d[self.b] = value 3497db96d56Sopenharmony_ci self.assertEqual(d[self.b], value) 3507db96d56Sopenharmony_ci 3517db96d56Sopenharmony_ci 3527db96d56Sopenharmony_ciclass FunctionDocstringTest(FuncAttrsTest): 3537db96d56Sopenharmony_ci def test_set_docstring_attr(self): 3547db96d56Sopenharmony_ci self.assertEqual(self.b.__doc__, None) 3557db96d56Sopenharmony_ci docstr = "A test method that does nothing" 3567db96d56Sopenharmony_ci self.b.__doc__ = docstr 3577db96d56Sopenharmony_ci self.F.a.__doc__ = docstr 3587db96d56Sopenharmony_ci self.assertEqual(self.b.__doc__, docstr) 3597db96d56Sopenharmony_ci self.assertEqual(self.fi.a.__doc__, docstr) 3607db96d56Sopenharmony_ci self.cannot_set_attr(self.fi.a, "__doc__", docstr, AttributeError) 3617db96d56Sopenharmony_ci 3627db96d56Sopenharmony_ci def test_delete_docstring(self): 3637db96d56Sopenharmony_ci self.b.__doc__ = "The docstring" 3647db96d56Sopenharmony_ci del self.b.__doc__ 3657db96d56Sopenharmony_ci self.assertEqual(self.b.__doc__, None) 3667db96d56Sopenharmony_ci 3677db96d56Sopenharmony_ci 3687db96d56Sopenharmony_cidef cell(value): 3697db96d56Sopenharmony_ci """Create a cell containing the given value.""" 3707db96d56Sopenharmony_ci def f(): 3717db96d56Sopenharmony_ci print(a) 3727db96d56Sopenharmony_ci a = value 3737db96d56Sopenharmony_ci return f.__closure__[0] 3747db96d56Sopenharmony_ci 3757db96d56Sopenharmony_cidef empty_cell(empty=True): 3767db96d56Sopenharmony_ci """Create an empty cell.""" 3777db96d56Sopenharmony_ci def f(): 3787db96d56Sopenharmony_ci print(a) 3797db96d56Sopenharmony_ci # the intent of the following line is simply "if False:"; it's 3807db96d56Sopenharmony_ci # spelt this way to avoid the danger that a future optimization 3817db96d56Sopenharmony_ci # might simply remove an "if False:" code block. 3827db96d56Sopenharmony_ci if not empty: 3837db96d56Sopenharmony_ci a = 1729 3847db96d56Sopenharmony_ci return f.__closure__[0] 3857db96d56Sopenharmony_ci 3867db96d56Sopenharmony_ci 3877db96d56Sopenharmony_ciclass CellTest(unittest.TestCase): 3887db96d56Sopenharmony_ci def test_comparison(self): 3897db96d56Sopenharmony_ci # These tests are here simply to exercise the comparison code; 3907db96d56Sopenharmony_ci # their presence should not be interpreted as providing any 3917db96d56Sopenharmony_ci # guarantees about the semantics (or even existence) of cell 3927db96d56Sopenharmony_ci # comparisons in future versions of CPython. 3937db96d56Sopenharmony_ci self.assertTrue(cell(2) < cell(3)) 3947db96d56Sopenharmony_ci self.assertTrue(empty_cell() < cell('saturday')) 3957db96d56Sopenharmony_ci self.assertTrue(empty_cell() == empty_cell()) 3967db96d56Sopenharmony_ci self.assertTrue(cell(-36) == cell(-36.0)) 3977db96d56Sopenharmony_ci self.assertTrue(cell(True) > empty_cell()) 3987db96d56Sopenharmony_ci 3997db96d56Sopenharmony_ci 4007db96d56Sopenharmony_ciclass StaticMethodAttrsTest(unittest.TestCase): 4017db96d56Sopenharmony_ci def test_func_attribute(self): 4027db96d56Sopenharmony_ci def f(): 4037db96d56Sopenharmony_ci pass 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_ci c = classmethod(f) 4067db96d56Sopenharmony_ci self.assertTrue(c.__func__ is f) 4077db96d56Sopenharmony_ci 4087db96d56Sopenharmony_ci s = staticmethod(f) 4097db96d56Sopenharmony_ci self.assertTrue(s.__func__ is f) 4107db96d56Sopenharmony_ci 4117db96d56Sopenharmony_ci 4127db96d56Sopenharmony_ciclass BuiltinFunctionPropertiesTest(unittest.TestCase): 4137db96d56Sopenharmony_ci # XXX Not sure where this should really go since I can't find a 4147db96d56Sopenharmony_ci # test module specifically for builtin_function_or_method. 4157db96d56Sopenharmony_ci 4167db96d56Sopenharmony_ci def test_builtin__qualname__(self): 4177db96d56Sopenharmony_ci import time 4187db96d56Sopenharmony_ci 4197db96d56Sopenharmony_ci # builtin function: 4207db96d56Sopenharmony_ci self.assertEqual(len.__qualname__, 'len') 4217db96d56Sopenharmony_ci self.assertEqual(time.time.__qualname__, 'time') 4227db96d56Sopenharmony_ci 4237db96d56Sopenharmony_ci # builtin classmethod: 4247db96d56Sopenharmony_ci self.assertEqual(dict.fromkeys.__qualname__, 'dict.fromkeys') 4257db96d56Sopenharmony_ci self.assertEqual(float.__getformat__.__qualname__, 4267db96d56Sopenharmony_ci 'float.__getformat__') 4277db96d56Sopenharmony_ci 4287db96d56Sopenharmony_ci # builtin staticmethod: 4297db96d56Sopenharmony_ci self.assertEqual(str.maketrans.__qualname__, 'str.maketrans') 4307db96d56Sopenharmony_ci self.assertEqual(bytes.maketrans.__qualname__, 'bytes.maketrans') 4317db96d56Sopenharmony_ci 4327db96d56Sopenharmony_ci # builtin bound instance method: 4337db96d56Sopenharmony_ci self.assertEqual([1, 2, 3].append.__qualname__, 'list.append') 4347db96d56Sopenharmony_ci self.assertEqual({'foo': 'bar'}.pop.__qualname__, 'dict.pop') 4357db96d56Sopenharmony_ci 4367db96d56Sopenharmony_ci 4377db96d56Sopenharmony_ciif __name__ == "__main__": 4387db96d56Sopenharmony_ci unittest.main() 439