03-fix-PackageLoader.patch 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. --- contrib/python/Jinja2/py3/jinja2/loaders.py (index)
  2. +++ contrib/python/Jinja2/py3/jinja2/loaders.py (working tree)
  3. @@ -5,6 +5,7 @@ sources.
  4. import os
  5. import posixpath
  6. import sys
  7. +import pkgutil
  8. import typing as t
  9. import weakref
  10. import zipimport
  11. @@ -21,6 +22,8 @@ if t.TYPE_CHECKING:
  12. from .environment import Environment
  13. from .environment import Template
  14. +import __res as arcadia_res
  15. +
  16. def split_template_path(template: str) -> t.List[str]:
  17. """Split a path into segments and perform a sanity check. If it detects
  18. @@ -288,19 +291,22 @@ class PackageLoader(BaseLoader):
  19. # Make sure the package exists. This also makes namespace
  20. # packages work, otherwise get_loader returns None.
  21. - import_module(package_name)
  22. + package = import_module(package_name)
  23. spec = importlib.util.find_spec(package_name)
  24. assert spec is not None, "An import spec was not found for the package."
  25. loader = spec.loader
  26. assert loader is not None, "A loader was not found for the package."
  27. self._loader = loader
  28. self._archive = None
  29. + self._package = package
  30. template_root = None
  31. if isinstance(loader, zipimport.zipimporter):
  32. self._archive = loader.archive
  33. pkgdir = next(iter(spec.submodule_search_locations)) # type: ignore
  34. template_root = os.path.join(pkgdir, package_path).rstrip(os.path.sep)
  35. + elif hasattr(loader, "arcadia_source_finder"):
  36. + template_root = os.path.dirname(package.__file__).rstrip(os.path.sep)
  37. else:
  38. roots: t.List[str] = []
  39. @@ -338,7 +341,16 @@ class PackageLoader(BaseLoader):
  40. p = posixpath.join(self._template_root, *split_template_path(template))
  41. up_to_date: t.Optional[t.Callable[[], bool]]
  42. - if self._archive is None:
  43. + if self._archive is None and hasattr(self, "_package"):
  44. + try:
  45. + source = pkgutil.get_data(self.package_name, os.path.join(self.package_path, *split_template_path(template)))
  46. + except OSError:
  47. + raise TemplateNotFound(template)
  48. +
  49. + def up_to_date() -> bool:
  50. + return True
  51. +
  52. + elif self._archive is None:
  53. # Package is a directory.
  54. if not os.path.isfile(p):
  55. raise TemplateNotFound(template)
  56. @@ -368,7 +380,12 @@ class PackageLoader(BaseLoader):
  57. def list_templates(self) -> t.List[str]:
  58. results: t.List[str] = []
  59. - if self._archive is None:
  60. + if self._archive is None and hasattr(self, "_package"):
  61. + prefix = os.path.join(self._template_root, self.package_path).encode() + b"/"
  62. + for name in arcadia_res.resfs_files(prefix):
  63. + results.append(name.removeprefix(prefix).decode())
  64. +
  65. + elif self._archive is None:
  66. # Package is a directory.
  67. offset = len(self._template_root)
  68. --- contrib/python/Jinja2/py3/jinja2/loaders.py (index)
  69. +++ contrib/python/Jinja2/py3/jinja2/loaders.py (working tree)
  70. @@ -279,6 +279,7 @@ class PackageLoader(BaseLoader):
  71. package_name: str,
  72. package_path: "str" = "templates",
  73. encoding: str = "utf-8",
  74. + skip_unknown_package: bool = False,
  75. ) -> None:
  76. package_path = os.path.normpath(package_path).rstrip(os.path.sep)
  77. @@ -291,6 +292,7 @@ class PackageLoader(BaseLoader):
  78. self.package_path = package_path
  79. self.package_name = package_name
  80. self.encoding = encoding
  81. + self.skip_unknown_package = skip_unknown_package
  82. # Make sure the package exists. This also makes namespace
  83. # packages work, otherwise get_loader returns None.
  84. @@ -339,6 +341,9 @@ class PackageLoader(BaseLoader):
  85. def get_source(
  86. self, environment: "Environment", template: str
  87. ) -> t.Tuple[str, str, t.Optional[t.Callable[[], bool]]]:
  88. + if self._template_root is None and self.skip_unknown_package:
  89. + raise TemplateNotFound(template)
  90. +
  91. # Use posixpath even on Windows to avoid "drive:" or UNC
  92. # segments breaking out of the search directory. Use normpath to
  93. # convert Windows altsep to sep.
  94. @@ -386,6 +391,9 @@ class PackageLoader(BaseLoader):
  95. def list_templates(self) -> t.List[str]:
  96. results: t.List[str] = []
  97. + if self._template_root is None and self.skip_unknown_package:
  98. + return results
  99. +
  100. if self._archive is None and hasattr(self, "_package"):
  101. prefix = os.path.join(self._template_root, self.package_path).encode() + b"/"
  102. for name in arcadia_res.resfs_files(prefix):
  103. --- contrib/python/Jinja2/py3/jinja2/loaders.py (index)
  104. +++ contrib/python/Jinja2/py3/jinja2/loaders.py (working tree)
  105. @@ -296,7 +296,13 @@ class PackageLoader(BaseLoader):
  106. # Make sure the package exists. This also makes namespace
  107. # packages work, otherwise get_loader returns None.
  108. - package = import_module(package_name)
  109. + try:
  110. + package = import_module(package_name)
  111. + except ModuleNotFoundError:
  112. + if skip_unknown_package:
  113. + self._template_root = None
  114. + return
  115. + raise
  116. spec = importlib.util.find_spec(package_name)
  117. assert spec is not None, "An import spec was not found for the package."
  118. loader = spec.loader