test_Loader.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. from panda3d.core import Filename, NodePath, LoaderFileTypeRegistry
  2. from direct.showbase.Loader import Loader
  3. import pytest
  4. import sys
  5. @pytest.fixture
  6. def loader():
  7. loader = Loader(base=None)
  8. yield loader
  9. loader.destroy()
  10. @pytest.fixture
  11. def temp_model():
  12. from panda3d.core import ModelPool, ModelRoot
  13. root = ModelRoot('model')
  14. root.fullpath = '/test-model.bam'
  15. ModelPool.add_model(root.fullpath, root)
  16. yield root.fullpath
  17. ModelPool.release_model(root.fullpath)
  18. def test_load_model_filename(loader, temp_model):
  19. model = loader.load_model(Filename(temp_model))
  20. assert model
  21. assert isinstance(model, NodePath)
  22. assert model.name == 'model'
  23. def test_load_model_str(loader, temp_model):
  24. model = loader.load_model(str(temp_model))
  25. assert model
  26. assert isinstance(model, NodePath)
  27. assert model.name == 'model'
  28. def test_load_model_list(loader, temp_model):
  29. models = loader.load_model([temp_model, temp_model])
  30. assert models
  31. assert isinstance(models, list)
  32. assert len(models) == 2
  33. assert isinstance(models[0], NodePath)
  34. assert isinstance(models[1], NodePath)
  35. def test_load_model_tuple(loader, temp_model):
  36. models = loader.load_model((temp_model, temp_model))
  37. assert models
  38. assert isinstance(models, list)
  39. assert len(models) == 2
  40. assert isinstance(models[0], NodePath)
  41. assert isinstance(models[1], NodePath)
  42. def test_load_model_set(loader, temp_model):
  43. models = loader.load_model({temp_model})
  44. assert models
  45. assert isinstance(models, list)
  46. assert len(models) == 1
  47. assert isinstance(models[0], NodePath)
  48. def test_load_model_missing(loader):
  49. with pytest.raises(IOError):
  50. loader.load_model('/nonexistent.bam')
  51. def test_load_model_okmissing(loader):
  52. model = loader.load_model('/nonexistent.bam', okMissing=True)
  53. assert model is None
  54. def test_loader_entry_points(tmp_path):
  55. # A dummy loader for .fnrgl files.
  56. (tmp_path / "fnargle.py").write_text("""
  57. from panda3d.core import ModelRoot
  58. import sys
  59. sys._fnargle_loaded = True
  60. class FnargleLoader:
  61. name = "Fnargle"
  62. extensions = ['fnrgl']
  63. supports_compressed = False
  64. @staticmethod
  65. def load_file(path, options, record=None):
  66. return ModelRoot("fnargle")
  67. """)
  68. (tmp_path / "fnargle.dist-info").mkdir()
  69. (tmp_path / "fnargle.dist-info" / "METADATA").write_text("""
  70. Metadata-Version: 2.1
  71. Name: fnargle
  72. Version: 1.0.0
  73. """)
  74. (tmp_path / "fnargle.dist-info" / "entry_points.txt").write_text("""
  75. [panda3d.loaders]
  76. fnrgl = fnargle:FnargleLoader
  77. """)
  78. model_path = tmp_path / "test.fnrgl"
  79. model_path.write_text("")
  80. if sys.version_info >= (3, 11):
  81. import sysconfig
  82. stdlib = sysconfig.get_path("stdlib")
  83. platstdlib = sysconfig.get_path("platstdlib")
  84. else:
  85. from distutils import sysconfig
  86. stdlib = sysconfig.get_python_lib(False, True)
  87. platstdlib = sysconfig.get_python_lib(True, True)
  88. registry = LoaderFileTypeRegistry.get_global_ptr()
  89. prev_loaded = Loader._loadedPythonFileTypes
  90. prev_path = sys.path
  91. file_type = None
  92. try:
  93. # We do this so we don't re-register thirdparty loaders
  94. sys.path = [str(tmp_path), platstdlib, stdlib]
  95. Loader._loadedPythonFileTypes = False
  96. loader = Loader()
  97. if not Loader._loadedPythonFileTypes:
  98. Loader._loadPythonFileTypes()
  99. assert Loader._loadedPythonFileTypes
  100. # Should be registered, not yet loaded
  101. file_type = registry.get_type_from_extension('fnrgl')
  102. assert file_type is not None
  103. assert not hasattr(sys, '_fnargle_loaded')
  104. assert file_type.supports_load()
  105. assert not file_type.supports_save()
  106. assert not file_type.supports_compressed()
  107. assert file_type.get_extension() == 'fnrgl'
  108. # The above should have caused it to load
  109. assert sys._fnargle_loaded
  110. assert 'fnargle' in sys.modules
  111. # Now try loading a fnargle file
  112. model_fn = Filename(model_path)
  113. model_fn.make_true_case()
  114. model = loader.load_model(model_fn, noCache=True)
  115. assert model is not None
  116. assert model.name == "fnargle"
  117. finally:
  118. # Set everything back to what it was
  119. Loader._loadedPythonFileTypes = prev_loaded
  120. sys.path = prev_path
  121. if hasattr(sys, '_fnargle_loaded'):
  122. del sys._fnargle_loaded
  123. if 'fnargle' in sys.modules:
  124. del sys.modules['fnargle']
  125. if file_type is not None:
  126. registry.unregister_type(file_type)