(root)/
Python-3.11.7/
Lib/
test/
test_funcattrs.py
       1  import textwrap
       2  import types
       3  import unittest
       4  
       5  
       6  def global_function():
       7      def inner_function():
       8          class ESC[4;38;5;81mLocalClass:
       9              pass
      10          global inner_global_function
      11          def inner_global_function():
      12              def inner_function2():
      13                  pass
      14              return inner_function2
      15          return LocalClass
      16      return lambda: inner_function
      17  
      18  
      19  class ESC[4;38;5;81mFuncAttrsTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      20      def setUp(self):
      21          class ESC[4;38;5;81mF:
      22              def a(self):
      23                  pass
      24          def b():
      25              return 3
      26          self.fi = F()
      27          self.F = F
      28          self.b = b
      29  
      30      def cannot_set_attr(self, obj, name, value, exceptions):
      31          try:
      32              setattr(obj, name, value)
      33          except exceptions:
      34              pass
      35          else:
      36              self.fail("shouldn't be able to set %s to %r" % (name, value))
      37          try:
      38              delattr(obj, name)
      39          except exceptions:
      40              pass
      41          else:
      42              self.fail("shouldn't be able to del %s" % name)
      43  
      44  
      45  class ESC[4;38;5;81mFunctionPropertiesTest(ESC[4;38;5;149mFuncAttrsTest):
      46      # Include the external setUp method that is common to all tests
      47      def test_module(self):
      48          self.assertEqual(self.b.__module__, __name__)
      49  
      50      def test_dir_includes_correct_attrs(self):
      51          self.b.known_attr = 7
      52          self.assertIn('known_attr', dir(self.b),
      53              "set attributes not in dir listing of method")
      54          # Test on underlying function object of method
      55          self.F.a.known_attr = 7
      56          self.assertIn('known_attr', dir(self.fi.a), "set attribute on function "
      57                       "implementations, should show up in next dir")
      58  
      59      def test_duplicate_function_equality(self):
      60          # Body of `duplicate' is the exact same as self.b
      61          def duplicate():
      62              'my docstring'
      63              return 3
      64          self.assertNotEqual(self.b, duplicate)
      65  
      66      def test_copying___code__(self):
      67          def test(): pass
      68          self.assertEqual(test(), None)
      69          test.__code__ = self.b.__code__
      70          self.assertEqual(test(), 3) # self.b always returns 3, arbitrarily
      71  
      72      def test___globals__(self):
      73          self.assertIs(self.b.__globals__, globals())
      74          self.cannot_set_attr(self.b, '__globals__', 2,
      75                               (AttributeError, TypeError))
      76  
      77      def test___builtins__(self):
      78          self.assertIs(self.b.__builtins__, __builtins__)
      79          self.cannot_set_attr(self.b, '__builtins__', 2,
      80                               (AttributeError, TypeError))
      81  
      82          # bpo-42990: If globals is specified and has no "__builtins__" key,
      83          # a function inherits the current builtins namespace.
      84          def func(s): return len(s)
      85          ns = {}
      86          func2 = type(func)(func.__code__, ns)
      87          self.assertIs(func2.__globals__, ns)
      88          self.assertIs(func2.__builtins__, __builtins__)
      89  
      90          # Make sure that the function actually works.
      91          self.assertEqual(func2("abc"), 3)
      92          self.assertEqual(ns, {})
      93  
      94          # Define functions using exec() with different builtins,
      95          # and test inheritance when globals has no "__builtins__" key
      96          code = textwrap.dedent("""
      97              def func3(s): pass
      98              func4 = type(func3)(func3.__code__, {})
      99          """)
     100          safe_builtins = {'None': None}
     101          ns = {'type': type, '__builtins__': safe_builtins}
     102          exec(code, ns)
     103          self.assertIs(ns['func3'].__builtins__, safe_builtins)
     104          self.assertIs(ns['func4'].__builtins__, safe_builtins)
     105          self.assertIs(ns['func3'].__globals__['__builtins__'], safe_builtins)
     106          self.assertNotIn('__builtins__', ns['func4'].__globals__)
     107  
     108      def test___closure__(self):
     109          a = 12
     110          def f(): print(a)
     111          c = f.__closure__
     112          self.assertIsInstance(c, tuple)
     113          self.assertEqual(len(c), 1)
     114          # don't have a type object handy
     115          self.assertEqual(c[0].__class__.__name__, "cell")
     116          self.cannot_set_attr(f, "__closure__", c, AttributeError)
     117  
     118      def test_cell_new(self):
     119          cell_obj = types.CellType(1)
     120          self.assertEqual(cell_obj.cell_contents, 1)
     121  
     122          cell_obj = types.CellType()
     123          msg = "shouldn't be able to read an empty cell"
     124          with self.assertRaises(ValueError, msg=msg):
     125              cell_obj.cell_contents
     126  
     127      def test_empty_cell(self):
     128          def f(): print(a)
     129          try:
     130              f.__closure__[0].cell_contents
     131          except ValueError:
     132              pass
     133          else:
     134              self.fail("shouldn't be able to read an empty cell")
     135          a = 12
     136  
     137      def test_set_cell(self):
     138          a = 12
     139          def f(): return a
     140          c = f.__closure__
     141          c[0].cell_contents = 9
     142          self.assertEqual(c[0].cell_contents, 9)
     143          self.assertEqual(f(), 9)
     144          self.assertEqual(a, 9)
     145          del c[0].cell_contents
     146          try:
     147              c[0].cell_contents
     148          except ValueError:
     149              pass
     150          else:
     151              self.fail("shouldn't be able to read an empty cell")
     152          with self.assertRaises(NameError):
     153              f()
     154          with self.assertRaises(UnboundLocalError):
     155              print(a)
     156  
     157      def test___name__(self):
     158          self.assertEqual(self.b.__name__, 'b')
     159          self.b.__name__ = 'c'
     160          self.assertEqual(self.b.__name__, 'c')
     161          self.b.__name__ = 'd'
     162          self.assertEqual(self.b.__name__, 'd')
     163          # __name__ and __name__ must be a string
     164          self.cannot_set_attr(self.b, '__name__', 7, TypeError)
     165          # __name__ must be available when in restricted mode. Exec will raise
     166          # AttributeError if __name__ is not available on f.
     167          s = """def f(): pass\nf.__name__"""
     168          exec(s, {'__builtins__': {}})
     169          # Test on methods, too
     170          self.assertEqual(self.fi.a.__name__, 'a')
     171          self.cannot_set_attr(self.fi.a, "__name__", 'a', AttributeError)
     172  
     173      def test___qualname__(self):
     174          # PEP 3155
     175          self.assertEqual(self.b.__qualname__, 'FuncAttrsTest.setUp.<locals>.b')
     176          self.assertEqual(FuncAttrsTest.setUp.__qualname__, 'FuncAttrsTest.setUp')
     177          self.assertEqual(global_function.__qualname__, 'global_function')
     178          self.assertEqual(global_function().__qualname__,
     179                           'global_function.<locals>.<lambda>')
     180          self.assertEqual(global_function()().__qualname__,
     181                           'global_function.<locals>.inner_function')
     182          self.assertEqual(global_function()()().__qualname__,
     183                           'global_function.<locals>.inner_function.<locals>.LocalClass')
     184          self.assertEqual(inner_global_function.__qualname__, 'inner_global_function')
     185          self.assertEqual(inner_global_function().__qualname__, 'inner_global_function.<locals>.inner_function2')
     186          self.b.__qualname__ = 'c'
     187          self.assertEqual(self.b.__qualname__, 'c')
     188          self.b.__qualname__ = 'd'
     189          self.assertEqual(self.b.__qualname__, 'd')
     190          # __qualname__ must be a string
     191          self.cannot_set_attr(self.b, '__qualname__', 7, TypeError)
     192  
     193      def test___code__(self):
     194          num_one, num_two = 7, 8
     195          def a(): pass
     196          def b(): return 12
     197          def c(): return num_one
     198          def d(): return num_two
     199          def e(): return num_one, num_two
     200          for func in [a, b, c, d, e]:
     201              self.assertEqual(type(func.__code__), types.CodeType)
     202          self.assertEqual(c(), 7)
     203          self.assertEqual(d(), 8)
     204          d.__code__ = c.__code__
     205          self.assertEqual(c.__code__, d.__code__)
     206          self.assertEqual(c(), 7)
     207          # self.assertEqual(d(), 7)
     208          try:
     209              b.__code__ = c.__code__
     210          except ValueError:
     211              pass
     212          else:
     213              self.fail("__code__ with different numbers of free vars should "
     214                        "not be possible")
     215          try:
     216              e.__code__ = d.__code__
     217          except ValueError:
     218              pass
     219          else:
     220              self.fail("__code__ with different numbers of free vars should "
     221                        "not be possible")
     222  
     223      def test_blank_func_defaults(self):
     224          self.assertEqual(self.b.__defaults__, None)
     225          del self.b.__defaults__
     226          self.assertEqual(self.b.__defaults__, None)
     227  
     228      def test_func_default_args(self):
     229          def first_func(a, b):
     230              return a+b
     231          def second_func(a=1, b=2):
     232              return a+b
     233          self.assertEqual(first_func.__defaults__, None)
     234          self.assertEqual(second_func.__defaults__, (1, 2))
     235          first_func.__defaults__ = (1, 2)
     236          self.assertEqual(first_func.__defaults__, (1, 2))
     237          self.assertEqual(first_func(), 3)
     238          self.assertEqual(first_func(3), 5)
     239          self.assertEqual(first_func(3, 5), 8)
     240          del second_func.__defaults__
     241          self.assertEqual(second_func.__defaults__, None)
     242          try:
     243              second_func()
     244          except TypeError:
     245              pass
     246          else:
     247              self.fail("__defaults__ does not update; deleting it does not "
     248                        "remove requirement")
     249  
     250  
     251  class ESC[4;38;5;81mInstancemethodAttrTest(ESC[4;38;5;149mFuncAttrsTest):
     252  
     253      def test___class__(self):
     254          self.assertEqual(self.fi.a.__self__.__class__, self.F)
     255          self.cannot_set_attr(self.fi.a, "__class__", self.F, TypeError)
     256  
     257      def test___func__(self):
     258          self.assertEqual(self.fi.a.__func__, self.F.a)
     259          self.cannot_set_attr(self.fi.a, "__func__", self.F.a, AttributeError)
     260  
     261      def test___self__(self):
     262          self.assertEqual(self.fi.a.__self__, self.fi)
     263          self.cannot_set_attr(self.fi.a, "__self__", self.fi, AttributeError)
     264  
     265      def test___func___non_method(self):
     266          # Behavior should be the same when a method is added via an attr
     267          # assignment
     268          self.fi.id = types.MethodType(id, self.fi)
     269          self.assertEqual(self.fi.id(), id(self.fi))
     270          # Test usage
     271          try:
     272              self.fi.id.unknown_attr
     273          except AttributeError:
     274              pass
     275          else:
     276              self.fail("using unknown attributes should raise AttributeError")
     277          # Test assignment and deletion
     278          self.cannot_set_attr(self.fi.id, 'unknown_attr', 2, AttributeError)
     279  
     280  
     281  class ESC[4;38;5;81mArbitraryFunctionAttrTest(ESC[4;38;5;149mFuncAttrsTest):
     282      def test_set_attr(self):
     283          self.b.known_attr = 7
     284          self.assertEqual(self.b.known_attr, 7)
     285          try:
     286              self.fi.a.known_attr = 7
     287          except AttributeError:
     288              pass
     289          else:
     290              self.fail("setting attributes on methods should raise error")
     291  
     292      def test_delete_unknown_attr(self):
     293          try:
     294              del self.b.unknown_attr
     295          except AttributeError:
     296              pass
     297          else:
     298              self.fail("deleting unknown attribute should raise TypeError")
     299  
     300      def test_unset_attr(self):
     301          for func in [self.b, self.fi.a]:
     302              try:
     303                  func.non_existent_attr
     304              except AttributeError:
     305                  pass
     306              else:
     307                  self.fail("using unknown attributes should raise "
     308                            "AttributeError")
     309  
     310  
     311  class ESC[4;38;5;81mFunctionDictsTest(ESC[4;38;5;149mFuncAttrsTest):
     312      def test_setting_dict_to_invalid(self):
     313          self.cannot_set_attr(self.b, '__dict__', None, TypeError)
     314          from collections import UserDict
     315          d = UserDict({'known_attr': 7})
     316          self.cannot_set_attr(self.fi.a.__func__, '__dict__', d, TypeError)
     317  
     318      def test_setting_dict_to_valid(self):
     319          d = {'known_attr': 7}
     320          self.b.__dict__ = d
     321          # Test assignment
     322          self.assertIs(d, self.b.__dict__)
     323          # ... and on all the different ways of referencing the method's func
     324          self.F.a.__dict__ = d
     325          self.assertIs(d, self.fi.a.__func__.__dict__)
     326          self.assertIs(d, self.fi.a.__dict__)
     327          # Test value
     328          self.assertEqual(self.b.known_attr, 7)
     329          self.assertEqual(self.b.__dict__['known_attr'], 7)
     330          # ... and again, on all the different method's names
     331          self.assertEqual(self.fi.a.__func__.known_attr, 7)
     332          self.assertEqual(self.fi.a.known_attr, 7)
     333  
     334      def test_delete___dict__(self):
     335          try:
     336              del self.b.__dict__
     337          except TypeError:
     338              pass
     339          else:
     340              self.fail("deleting function dictionary should raise TypeError")
     341  
     342      def test_unassigned_dict(self):
     343          self.assertEqual(self.b.__dict__, {})
     344  
     345      def test_func_as_dict_key(self):
     346          value = "Some string"
     347          d = {}
     348          d[self.b] = value
     349          self.assertEqual(d[self.b], value)
     350  
     351  
     352  class ESC[4;38;5;81mFunctionDocstringTest(ESC[4;38;5;149mFuncAttrsTest):
     353      def test_set_docstring_attr(self):
     354          self.assertEqual(self.b.__doc__, None)
     355          docstr = "A test method that does nothing"
     356          self.b.__doc__ = docstr
     357          self.F.a.__doc__ = docstr
     358          self.assertEqual(self.b.__doc__, docstr)
     359          self.assertEqual(self.fi.a.__doc__, docstr)
     360          self.cannot_set_attr(self.fi.a, "__doc__", docstr, AttributeError)
     361  
     362      def test_delete_docstring(self):
     363          self.b.__doc__ = "The docstring"
     364          del self.b.__doc__
     365          self.assertEqual(self.b.__doc__, None)
     366  
     367  
     368  def cell(value):
     369      """Create a cell containing the given value."""
     370      def f():
     371          print(a)
     372      a = value
     373      return f.__closure__[0]
     374  
     375  def empty_cell(empty=True):
     376      """Create an empty cell."""
     377      def f():
     378          print(a)
     379      # the intent of the following line is simply "if False:";  it's
     380      # spelt this way to avoid the danger that a future optimization
     381      # might simply remove an "if False:" code block.
     382      if not empty:
     383          a = 1729
     384      return f.__closure__[0]
     385  
     386  
     387  class ESC[4;38;5;81mCellTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     388      def test_comparison(self):
     389          # These tests are here simply to exercise the comparison code;
     390          # their presence should not be interpreted as providing any
     391          # guarantees about the semantics (or even existence) of cell
     392          # comparisons in future versions of CPython.
     393          self.assertTrue(cell(2) < cell(3))
     394          self.assertTrue(empty_cell() < cell('saturday'))
     395          self.assertTrue(empty_cell() == empty_cell())
     396          self.assertTrue(cell(-36) == cell(-36.0))
     397          self.assertTrue(cell(True) > empty_cell())
     398  
     399  
     400  class ESC[4;38;5;81mStaticMethodAttrsTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     401      def test_func_attribute(self):
     402          def f():
     403              pass
     404  
     405          c = classmethod(f)
     406          self.assertTrue(c.__func__ is f)
     407  
     408          s = staticmethod(f)
     409          self.assertTrue(s.__func__ is f)
     410  
     411  
     412  class ESC[4;38;5;81mBuiltinFunctionPropertiesTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     413      # XXX Not sure where this should really go since I can't find a
     414      # test module specifically for builtin_function_or_method.
     415  
     416      def test_builtin__qualname__(self):
     417          import time
     418  
     419          # builtin function:
     420          self.assertEqual(len.__qualname__, 'len')
     421          self.assertEqual(time.time.__qualname__, 'time')
     422  
     423          # builtin classmethod:
     424          self.assertEqual(dict.fromkeys.__qualname__, 'dict.fromkeys')
     425          self.assertEqual(float.__getformat__.__qualname__,
     426                           'float.__getformat__')
     427  
     428          # builtin staticmethod:
     429          self.assertEqual(str.maketrans.__qualname__, 'str.maketrans')
     430          self.assertEqual(bytes.maketrans.__qualname__, 'bytes.maketrans')
     431  
     432          # builtin bound instance method:
     433          self.assertEqual([1, 2, 3].append.__qualname__, 'list.append')
     434          self.assertEqual({'foo': 'bar'}.pop.__qualname__, 'dict.pop')
     435  
     436  
     437  if __name__ == "__main__":
     438      unittest.main()