class_docstr: Load templates from a directory in a Python package.
  
  :param package_name: Import name of the package that contains the
      template directory.
  :param package_path: Directory within the imported package that
      contains the templates.
  :param encoding: Encoding of template files.
  
  The following example looks up templates in the ``pages`` directory
  within the ``project.ui`` package.
  
  .. code-block:: python
  
      loader = PackageLoader("project.ui", "pages")
  
  Only packages installed as directories (standard pip behavior) or
  zip/egg files (less common) are supported. The Python API for
  introspecting data in packages is too limited to support other
  installation methods the way this loader requires.
  
  There is limited support for :pep:`420` namespace packages. The
  template directory is assumed to only be in one namespace
  contributor. Zip files contributing to a namespace are not
  supported.
  
  .. versionchanged:: 3.0
      No longer uses ``setuptools`` as a dependency.
  
  .. versionchanged:: 3.0
      Limited PEP 420 namespace package support.
class_docstr_tok: ["Load","templates","from","a","directory","in","a","Python","package",".",":","param","package_name",":","Import","name","of","the","package","that","contains","the","template","directory",".",":","param","package_path",":","Directory","within","the","imported","package","that","contains","the","templates",".",":","param","encoding",":","Encoding","of","template","files",".","The","following","example","looks","up","templates","in","the","``","pages","``","directory","within","the","``","project.ui","``","package",".","..","code-block",":",":","python","loader","=","PackageLoader","(","``","project.ui","''",",","``","pages","''",")","Only","packages","installed","as","directories","(","standard","pip","behavior",")","or","zip\/egg","files","(","less","common",")","are","supported",".","The","Python","API","for","introspecting","data","in","packages","is","too","limited","to","support","other","installation","methods","the","way","this","loader","requires",".","There","is","limited","support","for",":","pep",":","`","420","`","namespace","packages",".","The","template","directory","is","assumed","to","only","be","in","one","namespace","contributor",".","Zip","files","contributing","to","a","namespace","are","not","supported",".","..","versionchanged",":",":","3.0","No","longer","uses","``","setuptools","``","as","a","dependency",".","..","versionchanged",":",":","3.0","Limited","PEP","420","namespace","package","support","."]
code: def list_templates(self) -> t.List[str]:
      results: t.List[str] = []
  
      if self._archive is None and hasattr(self, "_package"):
          prefix = (
              os.path.join(
                  self._template_root, self.package_path
              ).encode()
              + b"/"
          )
          for name in arcadia_res.resfs_files(prefix):
              results.append(name.removeprefix(prefix).decode())
  
      elif self._archive is None:
          # Package is a directory.
          offset = len(self._template_root)
  
          for dirpath, _, filenames in os.walk(self._template_root):
              dirpath = dirpath[offset:].lstrip(os.path.sep)
              results.extend(
                  os.path.join(dirpath, name).replace(os.path.sep, "/")
                  for name in filenames
              )
      else:
          if not hasattr(self._loader, "_files"):
              raise TypeError(
                  "This zip import does not have the required"
                  " metadata to list templates."
              )
  
          # Package is a zip file.
          prefix = (
              self._template_root[len(self._archive) :].lstrip(
                  os.path.sep
              )
              + os.path.sep
          )
          offset = len(prefix)
  
          for name in self._loader._files.keys():  # type: ignore
              # Find names under the templates directory that aren't directories.
              if name.startswith(prefix) and name[-1] != os.path.sep:
                  results.append(
                      name[offset:].replace(os.path.sep, "/")
                  )
  
      results.sort()
      return results
  
imports: import importlib.util
  import os
  import posixpath
  import sys
  import pkgutil
  import typing
  import weakref
  import zipimport
  from collections import abc
  from hashlib import sha1
  from importlib import import_module
  from types import ModuleType
  from .exceptions import TemplateNotFound
  from .utils import internalcode
  from .utils import open_if_exists
  import __res
label_desc: Use image node_id 3 for calling the PackageLoader obj's underlying member method code with example usage: obj.list_templates() and returns: results