_importlib.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # mypy: allow-untyped-defs
  2. import _warnings
  3. import os.path
  4. # note: implementations
  5. # copied from cpython's import code
  6. # _zip_searchorder defines how we search for a module in the Zip
  7. # archive: we first search for a package __init__, then for
  8. # non-package .pyc, and .py entries. The .pyc entries
  9. # are swapped by initzipimport() if we run in optimized mode. Also,
  10. # '/' is replaced by path_sep there.
  11. _zip_searchorder = (
  12. ("/__init__.py", True),
  13. (".py", False),
  14. )
  15. # Replace any occurrences of '\r\n?' in the input string with '\n'.
  16. # This converts DOS and Mac line endings to Unix line endings.
  17. def _normalize_line_endings(source):
  18. source = source.replace(b"\r\n", b"\n")
  19. source = source.replace(b"\r", b"\n")
  20. return source
  21. def _resolve_name(name, package, level):
  22. """Resolve a relative module name to an absolute one."""
  23. bits = package.rsplit(".", level - 1)
  24. if len(bits) < level:
  25. raise ValueError("attempted relative import beyond top-level package")
  26. base = bits[0]
  27. return f"{base}.{name}" if name else base
  28. def _sanity_check(name, package, level):
  29. """Verify arguments are "sane"."""
  30. if not isinstance(name, str):
  31. raise TypeError(f"module name must be str, not {type(name)}")
  32. if level < 0:
  33. raise ValueError("level must be >= 0")
  34. if level > 0:
  35. if not isinstance(package, str):
  36. raise TypeError("__package__ not set to a string")
  37. elif not package:
  38. raise ImportError("attempted relative import with no known parent package")
  39. if not name and level == 0:
  40. raise ValueError("Empty module name")
  41. def _calc___package__(globals):
  42. """Calculate what __package__ should be.
  43. __package__ is not guaranteed to be defined or could be set to None
  44. to represent that its proper value is unknown.
  45. """
  46. package = globals.get("__package__")
  47. spec = globals.get("__spec__")
  48. if package is not None:
  49. if spec is not None and package != spec.parent:
  50. _warnings.warn( # noqa: G010
  51. f"__package__ != __spec__.parent ({package!r} != {spec.parent!r})", # noqa: G004
  52. ImportWarning,
  53. stacklevel=3,
  54. )
  55. return package
  56. elif spec is not None:
  57. return spec.parent
  58. else:
  59. _warnings.warn( # noqa: G010
  60. "can't resolve package from __spec__ or __package__, "
  61. "falling back on __name__ and __path__",
  62. ImportWarning,
  63. stacklevel=3,
  64. )
  65. package = globals["__name__"]
  66. if "__path__" not in globals:
  67. package = package.rpartition(".")[0]
  68. return package
  69. def _normalize_path(path):
  70. """Normalize a path by ensuring it is a string.
  71. If the resulting string contains path separators, an exception is raised.
  72. """
  73. parent, file_name = os.path.split(path)
  74. if parent:
  75. raise ValueError(f"{path!r} must be only a file name")
  76. else:
  77. return file_name