(root)/
Python-3.12.0/
Lib/
test/
test_importlib/
import_/
test_helpers.py
       1  """Tests for helper functions used by import.c ."""
       2  
       3  from importlib import _bootstrap_external, machinery
       4  import os.path
       5  from types import ModuleType, SimpleNamespace
       6  import unittest
       7  import warnings
       8  
       9  from .. import util
      10  
      11  
      12  class ESC[4;38;5;81mFixUpModuleTests:
      13  
      14      def test_no_loader_but_spec(self):
      15          loader = object()
      16          name = "hello"
      17          path = "hello.py"
      18          spec = machinery.ModuleSpec(name, loader)
      19          ns = {"__spec__": spec}
      20          _bootstrap_external._fix_up_module(ns, name, path)
      21  
      22          expected = {"__spec__": spec, "__loader__": loader, "__file__": path,
      23                      "__cached__": None}
      24          self.assertEqual(ns, expected)
      25  
      26      def test_no_loader_no_spec_but_sourceless(self):
      27          name = "hello"
      28          path = "hello.py"
      29          ns = {}
      30          _bootstrap_external._fix_up_module(ns, name, path, path)
      31  
      32          expected = {"__file__": path, "__cached__": path}
      33  
      34          for key, val in expected.items():
      35              with self.subTest(f"{key}: {val}"):
      36                  self.assertEqual(ns[key], val)
      37  
      38          spec = ns["__spec__"]
      39          self.assertIsInstance(spec, machinery.ModuleSpec)
      40          self.assertEqual(spec.name, name)
      41          self.assertEqual(spec.origin, os.path.abspath(path))
      42          self.assertEqual(spec.cached, os.path.abspath(path))
      43          self.assertIsInstance(spec.loader, machinery.SourcelessFileLoader)
      44          self.assertEqual(spec.loader.name, name)
      45          self.assertEqual(spec.loader.path, path)
      46          self.assertEqual(spec.loader, ns["__loader__"])
      47  
      48      def test_no_loader_no_spec_but_source(self):
      49          name = "hello"
      50          path = "hello.py"
      51          ns = {}
      52          _bootstrap_external._fix_up_module(ns, name, path)
      53  
      54          expected = {"__file__": path, "__cached__": None}
      55  
      56          for key, val in expected.items():
      57              with self.subTest(f"{key}: {val}"):
      58                  self.assertEqual(ns[key], val)
      59  
      60          spec = ns["__spec__"]
      61          self.assertIsInstance(spec, machinery.ModuleSpec)
      62          self.assertEqual(spec.name, name)
      63          self.assertEqual(spec.origin, os.path.abspath(path))
      64          self.assertIsInstance(spec.loader, machinery.SourceFileLoader)
      65          self.assertEqual(spec.loader.name, name)
      66          self.assertEqual(spec.loader.path, path)
      67          self.assertEqual(spec.loader, ns["__loader__"])
      68  
      69  
      70  FrozenFixUpModuleTests, SourceFixUpModuleTests = util.test_both(FixUpModuleTests)
      71  
      72  
      73  class ESC[4;38;5;81mTestBlessMyLoader(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      74      # GH#86298 is part of the migration away from module attributes and toward
      75      # __spec__ attributes.  There are several cases to test here.  This will
      76      # have to change in Python 3.14 when we actually remove/ignore __loader__
      77      # in favor of requiring __spec__.loader.
      78  
      79      def test_gh86298_no_loader_and_no_spec(self):
      80          bar = ModuleType('bar')
      81          del bar.__loader__
      82          del bar.__spec__
      83          # 2022-10-06(warsaw): For backward compatibility with the
      84          # implementation in _warnings.c, this can't raise an
      85          # AttributeError.  See _bless_my_loader() in _bootstrap_external.py
      86          # If working with a module:
      87          ## self.assertRaises(
      88          ##     AttributeError, _bootstrap_external._bless_my_loader,
      89          ##     bar.__dict__)
      90          self.assertIsNone(_bootstrap_external._bless_my_loader(bar.__dict__))
      91  
      92      def test_gh86298_loader_is_none_and_no_spec(self):
      93          bar = ModuleType('bar')
      94          bar.__loader__ = None
      95          del bar.__spec__
      96          # 2022-10-06(warsaw): For backward compatibility with the
      97          # implementation in _warnings.c, this can't raise an
      98          # AttributeError.  See _bless_my_loader() in _bootstrap_external.py
      99          # If working with a module:
     100          ## self.assertRaises(
     101          ##     AttributeError, _bootstrap_external._bless_my_loader,
     102          ##     bar.__dict__)
     103          self.assertIsNone(_bootstrap_external._bless_my_loader(bar.__dict__))
     104  
     105      def test_gh86298_no_loader_and_spec_is_none(self):
     106          bar = ModuleType('bar')
     107          del bar.__loader__
     108          bar.__spec__ = None
     109          self.assertRaises(
     110              ValueError,
     111              _bootstrap_external._bless_my_loader, bar.__dict__)
     112  
     113      def test_gh86298_loader_is_none_and_spec_is_none(self):
     114          bar = ModuleType('bar')
     115          bar.__loader__ = None
     116          bar.__spec__ = None
     117          self.assertRaises(
     118              ValueError,
     119              _bootstrap_external._bless_my_loader, bar.__dict__)
     120  
     121      def test_gh86298_loader_is_none_and_spec_loader_is_none(self):
     122          bar = ModuleType('bar')
     123          bar.__loader__ = None
     124          bar.__spec__ = SimpleNamespace(loader=None)
     125          self.assertRaises(
     126              ValueError,
     127              _bootstrap_external._bless_my_loader, bar.__dict__)
     128  
     129      def test_gh86298_no_spec(self):
     130          bar = ModuleType('bar')
     131          bar.__loader__ = object()
     132          del bar.__spec__
     133          with warnings.catch_warnings():
     134              self.assertWarns(
     135                  DeprecationWarning,
     136                  _bootstrap_external._bless_my_loader, bar.__dict__)
     137  
     138      def test_gh86298_spec_is_none(self):
     139          bar = ModuleType('bar')
     140          bar.__loader__ = object()
     141          bar.__spec__ = None
     142          with warnings.catch_warnings():
     143              self.assertWarns(
     144                  DeprecationWarning,
     145                  _bootstrap_external._bless_my_loader, bar.__dict__)
     146  
     147      def test_gh86298_no_spec_loader(self):
     148          bar = ModuleType('bar')
     149          bar.__loader__ = object()
     150          bar.__spec__ = SimpleNamespace()
     151          with warnings.catch_warnings():
     152              self.assertWarns(
     153                  DeprecationWarning,
     154                  _bootstrap_external._bless_my_loader, bar.__dict__)
     155  
     156      def test_gh86298_loader_and_spec_loader_disagree(self):
     157          bar = ModuleType('bar')
     158          bar.__loader__ = object()
     159          bar.__spec__ = SimpleNamespace(loader=object())
     160          with warnings.catch_warnings():
     161              self.assertWarns(
     162                  DeprecationWarning,
     163                  _bootstrap_external._bless_my_loader, bar.__dict__)
     164  
     165      def test_gh86298_no_loader_and_no_spec_loader(self):
     166          bar = ModuleType('bar')
     167          del bar.__loader__
     168          bar.__spec__ = SimpleNamespace()
     169          self.assertRaises(
     170              AttributeError,
     171              _bootstrap_external._bless_my_loader, bar.__dict__)
     172  
     173      def test_gh86298_no_loader_with_spec_loader_okay(self):
     174          bar = ModuleType('bar')
     175          del bar.__loader__
     176          loader = object()
     177          bar.__spec__ = SimpleNamespace(loader=loader)
     178          self.assertEqual(
     179              _bootstrap_external._bless_my_loader(bar.__dict__),
     180              loader)
     181  
     182  
     183  if __name__ == "__main__":
     184      unittest.main()