2
0
Эх сурвалжийг харах

showbase: Annotate `VFSImporter` functions (#1764)

WMOkiishi 4 сар өмнө
parent
commit
f00cec70e6

+ 25 - 20
direct/src/showbase/VFSImporter.py

@@ -5,9 +5,11 @@ Calling the :func:`register()` function to register the import hooks should be
 sufficient to enable this functionality.
 """
 
+from __future__ import annotations
+
 __all__ = ['register']
 
-from panda3d.core import Filename, VirtualFileSystem, VirtualFileMountSystem
+from panda3d.core import Filename, VirtualFile, VirtualFileSystem, VirtualFileMountSystem
 from panda3d.core import OFileStream, copy_stream
 import sys
 import marshal
@@ -16,14 +18,17 @@ import atexit
 from importlib.abc import Loader, SourceLoader
 from importlib.util import MAGIC_NUMBER, decode_source
 from importlib.machinery import ModuleSpec, EXTENSION_SUFFIXES, BYTECODE_SUFFIXES
+from types import ModuleType
+from typing import Any
 
 vfs = VirtualFileSystem.get_global_ptr()
 
 
-def _make_spec(fullname, loader, *, is_package):
+def _make_spec(fullname: str, loader: VFSLoader, *, is_package: bool) -> ModuleSpec:
     filename = loader._vfile.get_filename()
     spec = ModuleSpec(fullname, loader, origin=filename.to_os_specific(), is_package=is_package)
     if is_package:
+        assert spec.submodule_search_locations is not None
         spec.submodule_search_locations.append(Filename(filename.get_dirname()).to_os_specific())
     spec.has_location = True
     return spec
@@ -35,16 +40,15 @@ class VFSFinder:
     which allows loading Python source files from mounted .mf files
     (among other places). """
 
-    def __init__(self, path):
+    def __init__(self, path: str) -> None:
         self.path = path
 
-    def find_spec(self, fullname, path, target=None):
-        if path is None:
-            path = self.path
-
+    def find_spec(self, fullname: str, target: ModuleType | None = None) -> ModuleSpec | None:
         #print(f"find_spec({fullname}), dir_path = {dir_path}", file=sys.stderr)
         basename = fullname.split('.')[-1]
-        filename = Filename(Filename.from_os_specific(path), basename)
+        filename = Filename(Filename.from_os_specific(self.path), basename)
+
+        loader: VFSLoader
 
         # First, look for Python files.
         vfile = vfs.get_file(filename + '.py', True)
@@ -84,6 +88,7 @@ class VFSFinder:
         # Consider a namespace package.
         if vfs.is_directory(filename):
             spec = ModuleSpec(fullname, VFSNamespaceLoader(), is_package=True)
+            assert spec.submodule_search_locations is not None
             spec.submodule_search_locations.append(filename.to_os_specific())
             return spec
 
@@ -92,7 +97,7 @@ class VFSFinder:
 
 
 class VFSLoader(Loader):
-    def __init__(self, fullname, vfile):
+    def __init__(self, fullname: str, vfile: VirtualFile) -> None:
         self.name = fullname
         self._vfile = vfile
 
@@ -105,22 +110,22 @@ class VFSLoader(Loader):
         tail_name = fullname.rpartition('.')[2]
         return filename_base == '__init__' and tail_name != '__init__'
 
-    def create_module(self, spec):
+    def create_module(self, spec: ModuleSpec) -> ModuleType | None:
         """Use default semantics for module creation."""
 
-    def exec_module(self, module):
+    def exec_module(self, module: ModuleType) -> None:
         """Execute the module."""
-        code = self.get_code(module.__name__)
+        code = self.get_code(module.__name__)  # type: ignore[attr-defined]
         exec(code, module.__dict__)
 
-    def get_filename(self, fullname):
+    def get_filename(self, fullname: str) -> str:
         if fullname is not None and self.name != fullname:
             raise ImportError
 
         return self._vfile.get_filename().to_os_specific()
 
     @staticmethod
-    def get_data(path):
+    def get_data(path: str) -> bytes:
         vfile = vfs.get_file(Filename.from_os_specific(path))
         if vfile:
             return vfile.read_file(True)
@@ -128,7 +133,7 @@ class VFSLoader(Loader):
             raise OSError
 
     @staticmethod
-    def path_stats(path):
+    def path_stats(path: str) -> dict[str, Any]:
         vfile = vfs.get_file(Filename.from_os_specific(path))
         if vfile:
             return {'mtime': vfile.get_timestamp(), 'size': vfile.get_file_size()}
@@ -231,11 +236,11 @@ class VFSExtensionLoader(VFSLoader):
         return None
 
 
-class VFSNamespaceLoader:
-    def create_module(self, spec):
+class VFSNamespaceLoader(Loader):
+    def create_module(self, spec: ModuleSpec) -> ModuleType | None:
         """Use default semantics for module creation."""
 
-    def exec_module(self, module):
+    def exec_module(self, module: ModuleType) -> None:
         pass
 
     def is_package(self, fullname):
@@ -248,7 +253,7 @@ class VFSNamespaceLoader:
         return compile('', '<string>', 'exec', dont_inherit=True)
 
 
-def _path_hook(entry):
+def _path_hook(entry: str) -> VFSFinder:
     # If this is a directory in the VFS, create a VFSFinder for this entry.
     vfile = vfs.get_file(Filename.from_os_specific(entry), False)
     if vfile and vfile.is_directory() and not isinstance(vfile.get_mount(), VirtualFileMountSystem):
@@ -259,7 +264,7 @@ def _path_hook(entry):
 
 _registered = False
 
-def register():
+def register() -> None:
     """ Register the VFSFinder on the path_hooks, if it has not
     already been registered, so that future Python import statements
     will vector through here (and therefore will take advantage of