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