|
|
@@ -1,6 +1,7 @@
|
|
|
-from panda3d.core import Filename, NodePath
|
|
|
+from panda3d.core import Filename, NodePath, LoaderFileTypeRegistry
|
|
|
from direct.showbase.Loader import Loader
|
|
|
import pytest
|
|
|
+import sys
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
@@ -68,3 +69,105 @@ def test_load_model_missing(loader):
|
|
|
def test_load_model_okmissing(loader):
|
|
|
model = loader.load_model('/nonexistent.bam', okMissing=True)
|
|
|
assert model is None
|
|
|
+
|
|
|
+
|
|
|
+def test_loader_entry_points(tmp_path):
|
|
|
+ # A dummy loader for .fnrgl files.
|
|
|
+ (tmp_path / "fnargle.py").write_text("""
|
|
|
+from panda3d.core import ModelRoot
|
|
|
+import sys
|
|
|
+
|
|
|
+sys._fnargle_loaded = True
|
|
|
+
|
|
|
+class FnargleLoader:
|
|
|
+ name = "Fnargle"
|
|
|
+ extensions = ['fnrgl']
|
|
|
+ supports_compressed = False
|
|
|
+
|
|
|
+ @staticmethod
|
|
|
+ def load_file(path, options, record=None):
|
|
|
+ return ModelRoot("fnargle")
|
|
|
+""")
|
|
|
+ (tmp_path / "fnargle.dist-info").mkdir()
|
|
|
+ (tmp_path / "fnargle.dist-info" / "METADATA").write_text("""
|
|
|
+Metadata-Version: 2.0
|
|
|
+Name: fnargle
|
|
|
+Version: 1.0.0
|
|
|
+""")
|
|
|
+ (tmp_path / "fnargle.dist-info" / "entry_points.txt").write_text("""
|
|
|
+[panda3d.loaders]
|
|
|
+fnrgl = fnargle:FnargleLoader
|
|
|
+""")
|
|
|
+
|
|
|
+ model_path = tmp_path / "test.fnrgl"
|
|
|
+ model_path.write_text("")
|
|
|
+
|
|
|
+ if sys.version_info >= (3, 11):
|
|
|
+ import sysconfig
|
|
|
+ stdlib = sysconfig.get_path("stdlib")
|
|
|
+ platstdlib = sysconfig.get_path("platstdlib")
|
|
|
+ else:
|
|
|
+ from distutils import sysconfig
|
|
|
+ stdlib = sysconfig.get_python_lib(False, True)
|
|
|
+ platstdlib = sysconfig.get_python_lib(True, True)
|
|
|
+
|
|
|
+ if sys.version_info < (3, 8):
|
|
|
+ # Older Python versions don't have importlib.metadata, so we rely on
|
|
|
+ # pkg_resources - but this caches the results once. Fortunately, it
|
|
|
+ # provides this function for reinitializing the cached entry points.
|
|
|
+ # See pypa/setuptools#373
|
|
|
+ pkg_resources = pytest.importorskip("pkg_resources")
|
|
|
+ if not hasattr(pkg_resources, "_initialize_master_working_set"):
|
|
|
+ pytest.skip("pkg_resources too old")
|
|
|
+
|
|
|
+ registry = LoaderFileTypeRegistry.get_global_ptr()
|
|
|
+ prev_loaded = Loader._loadedPythonFileTypes
|
|
|
+ prev_path = sys.path
|
|
|
+ file_type = None
|
|
|
+ try:
|
|
|
+ # We do this so we don't re-register thirdparty loaders
|
|
|
+ sys.path = [str(tmp_path), platstdlib, stdlib]
|
|
|
+ if sys.version_info < (3, 8):
|
|
|
+ pkg_resources._initialize_master_working_set()
|
|
|
+
|
|
|
+ Loader._loadedPythonFileTypes = False
|
|
|
+
|
|
|
+ # base parameter is only used for audio
|
|
|
+ loader = Loader(None)
|
|
|
+ assert Loader._loadedPythonFileTypes
|
|
|
+
|
|
|
+ # Should be registered, not yet loaded
|
|
|
+ file_type = registry.get_type_from_extension('fnrgl')
|
|
|
+ assert file_type is not None
|
|
|
+ assert not hasattr(sys, '_fnargle_loaded')
|
|
|
+
|
|
|
+ assert file_type.supports_load()
|
|
|
+ assert not file_type.supports_save()
|
|
|
+ assert not file_type.supports_compressed()
|
|
|
+ assert file_type.get_extension() == 'fnrgl'
|
|
|
+
|
|
|
+ # The above should have caused it to load
|
|
|
+ assert sys._fnargle_loaded
|
|
|
+ assert 'fnargle' in sys.modules
|
|
|
+
|
|
|
+ # Now try loading a fnargle file
|
|
|
+ model = loader.load_model(model_path)
|
|
|
+ assert model is not None
|
|
|
+ assert model.name == "fnargle"
|
|
|
+
|
|
|
+ finally:
|
|
|
+ # Set everything back to what it was
|
|
|
+ Loader._loadedPythonFileTypes = prev_loaded
|
|
|
+ sys.path = prev_path
|
|
|
+
|
|
|
+ if hasattr(sys, '_fnargle_loaded'):
|
|
|
+ del sys._fnargle_loaded
|
|
|
+
|
|
|
+ if 'fnargle' in sys.modules:
|
|
|
+ del sys.modules['fnargle']
|
|
|
+
|
|
|
+ if file_type is not None:
|
|
|
+ registry.unregister_type(file_type)
|
|
|
+
|
|
|
+ if sys.version_info < (3, 8):
|
|
|
+ pkg_resources._initialize_master_working_set()
|