def test_extension_proxy_maybe_wrap(): extension = MinimumExtension() proxy = ExtensionProxy.maybe_wrap(extension) assert proxy.delegate is extension assert ExtensionProxy.maybe_wrap(proxy) is proxy with pytest.raises(TypeError): ExtensionProxy.maybe_wrap(object())
def test_extension_proxy_hash_and_eq(): extension = MinimumExtension() proxy1 = ExtensionProxy(extension) proxy2 = ExtensionProxy(extension, package_name="foo", package_version="1.2.3") assert proxy1 == proxy2 assert hash(proxy1) == hash(proxy2) assert proxy1 != extension assert proxy2 != extension
def test_extension_version_check(installed, extension, warns): proxy = ExtensionProxy(FooExtension(), package_name="foo", package_version=installed) with config_context() as config: config.add_extension(proxy) af = asdf.AsdfFile() af._fname = 'test.asdf' tree = { 'history': { 'extensions': [ asdf.tags.core.ExtensionMetadata( extension_class='asdf.tests.test_api.FooExtension', software=asdf.tags.core.Software(name='foo', version=extension)), ] } } if warns: with pytest.warns(AsdfWarning, match="File 'test.asdf' was created with"): af._check_extensions(tree) with pytest.raises(RuntimeError) as err: af._check_extensions(tree, strict=True) err.match("^File 'test.asdf' was created with") else: af._check_extensions(tree)
def test_asdf_file_extensions(): af = AsdfFile() assert af.extensions == [] extension = TestExtension( extension_uri="asdf://somewhere.org/extensions/foo-1.0") for arg in ([extension], extension, AsdfExtensionList([extension])): af = AsdfFile(extensions=arg) assert af.extensions == [ExtensionProxy(extension)] af = AsdfFile() af.extensions = arg assert af.extensions == [ExtensionProxy(extension)] for arg in (object(), [object()]): with pytest.raises(TypeError): AsdfFile(extensions=arg)
def test_extension_proxy_repr(): proxy = ExtensionProxy(MinimumExtension(), package_name="foo", package_version="1.2.3") assert "class: asdf.tests.test_extension.MinimumExtension" in repr(proxy) assert "package: foo==1.2.3" in repr(proxy) assert "legacy: False" in repr(proxy) proxy = ExtensionProxy(MinimumExtension()) assert "class: asdf.tests.test_extension.MinimumExtension" in repr(proxy) assert "package: (none)" in repr(proxy) assert "legacy: False" in repr(proxy) proxy = ExtensionProxy(LegacyExtension(), package_name="foo", package_version="1.2.3") assert "class: asdf.tests.test_extension.LegacyExtension" in repr(proxy) assert "package: foo==1.2.3" in repr(proxy) assert "legacy: True" in repr(proxy)
def test_asdf_file_version_requirement(): extension_with_requirement = TestExtension( extension_uri="asdf://somewhere.org/extensions/foo-1.0", asdf_standard_requirement="==1.5.0", ) # No warnings if the requirement is fulfilled: with assert_no_warnings(): AsdfFile(version="1.5.0", extensions=[extension_with_requirement]) # Version doesn't match the requirement, so we should see a warning # and the extension should not be enabled: with pytest.warns(AsdfWarning, match="does not support ASDF Standard 1.4.0"): af = AsdfFile(version="1.4.0", extensions=[extension_with_requirement]) assert ExtensionProxy(extension_with_requirement) not in af.extensions # Version initially matches the requirement, but changing # the version on the AsdfFile invalidates it: af = AsdfFile(version="1.5.0", extensions=[extension_with_requirement]) assert ExtensionProxy(extension_with_requirement) in af.extensions with pytest.warns(AsdfWarning, match="does not support ASDF Standard 1.4.0"): af.version = "1.4.0" assert ExtensionProxy(extension_with_requirement) not in af.extensions # Extension registered with the config should not provoke # a warning: with config_context() as config: config.add_extension(extension_with_requirement) with assert_no_warnings(): af = AsdfFile(version="1.4.0") assert ExtensionProxy( extension_with_requirement) not in af.extensions # ... unless the user explicitly requested the invalid exception: with pytest.warns(AsdfWarning, match="does not support ASDF Standard 1.4.0"): af = AsdfFile(version="1.4.0", extensions=[extension_with_requirement])
def test_extension_proxy_tags(): """ The tags behavior is a tad complex, so they get their own test. """ foo_tag_uri = "asdf://somewhere.org/extensions/full/tags/foo-1.0" foo_tag_def = TagDefinition( foo_tag_uri, schema_uri="asdf://somewhere.org/extensions/full/schemas/foo-1.0", title="Some tag title", description="Some tag description") bar_tag_uri = "asdf://somewhere.org/extensions/full/tags/bar-1.0" bar_tag_def = TagDefinition( bar_tag_uri, schema_uri="asdf://somewhere.org/extensions/full/schemas/bar-1.0", title="Some other tag title", description="Some other tag description") # The converter should return only the tags # supported by the extension. converter = FullConverter(tags=["**"]) extension = FullExtension(tags=[foo_tag_def], converters=[converter]) proxy = ExtensionProxy(extension) assert proxy.converters[0].tags == [foo_tag_uri] # The converter should not return tags that # its patterns do not match. converter = FullConverter(tags=["**/foo-1.0"]) extension = FullExtension(tags=[foo_tag_def, bar_tag_def], converters=[converter]) proxy = ExtensionProxy(extension) assert proxy.converters[0].tags == [foo_tag_uri] # The process should still work if the extension property # contains str instead of TagDescription. converter = FullConverter(tags=["**/foo-1.0"]) extension = FullExtension(tags=[foo_tag_uri, bar_tag_uri], converters=[converter]) proxy = ExtensionProxy(extension) assert proxy.converters[0].tags == [foo_tag_uri]
def test_asdf_file_extensions(): af = AsdfFile() assert af.extensions == get_config().extensions extension = TestExtension( extension_uri="asdf://somewhere.org/extensions/foo-1.0") for arg in ([extension], extension, AsdfExtensionList([extension])): af = AsdfFile(extensions=arg) assert af.extensions[0] == ExtensionProxy(extension) assert af.extensions[1:] == get_config().extensions af = AsdfFile() af.extensions = arg assert af.extensions[0] == ExtensionProxy(extension) assert af.extensions[1:] == get_config().extensions # This use case is a little silly, but in the future it will be # possible to disable extensions globally and passing the URI # will enable them on an individual file basis. Currently all # we can do with the URI is put the extension at the head of # list so that it has priority. with config_context() as config: config.add_extension(extension) for arg in ([extension.extension_uri], extension.extension_uri): af = AsdfFile(extensions=arg) assert af.extensions[0] == ExtensionProxy(extension) af = AsdfFile() af.extensions = arg assert af.extensions[0] == ExtensionProxy(extension) for arg in (object(), [object()]): with pytest.raises(TypeError): AsdfFile(extensions=arg) with pytest.raises(KeyError): AsdfFile(extensions="not-a-URI")
def test_open_asdf_extensions(tmpdir): extension = TestExtension( extension_uri="asdf://somewhere.org/extensions/foo-1.0") path = str(tmpdir / "test.asdf") with AsdfFile() as af: af.write_to(path) with open_asdf(path) as af: assert af.extensions == [] for arg in ([extension], extension, AsdfExtensionList([extension])): with open_asdf(path, extensions=arg) as af: assert af.extensions == [ExtensionProxy(extension)] for arg in (object(), [object()]): with pytest.raises(TypeError): with open_asdf(path, extensions=arg) as af: pass
def test_extension_proxy_legacy(): extension = LegacyExtension() proxy = ExtensionProxy(extension, package_name="foo", package_version="1.2.3") assert proxy.extension_uri is None assert proxy.legacy_class_names == { "asdf.tests.test_extension.LegacyExtension" } assert proxy.asdf_standard_requirement == SpecifierSet() assert proxy.converters == [] assert proxy.tags == [] assert proxy.types == [LegacyType] assert proxy.tag_mapping == LegacyExtension.tag_mapping assert proxy.url_mapping == LegacyExtension.url_mapping assert proxy.delegate is extension assert proxy.legacy is True assert proxy.package_name == "foo" assert proxy.package_version == "1.2.3" assert proxy.class_name == "asdf.tests.test_extension.LegacyExtension"
def test_reading_extension_metadata(): extension_with_uri = ExtensionProxy( TestExtension(extension_uri="asdf://somewhere.org/extensions/foo-1.0"), package_name="foo", package_version="1.2.3", ) extension_without_uri = ExtensionProxy( TestExtension(), package_name="foo", package_version="1.2.3", ) extension_with_legacy_class_names = ExtensionProxy( TestExtension( extension_uri="asdf://somewhere.org/extensions/with-legacy-1.0", legacy_class_names={"some.legacy.class.Name"}, ), package_name="foo", package_version="1.2.3", ) with config_context() as config: config.add_extension(extension_with_uri) config.add_extension(extension_without_uri) config.add_extension(extension_with_legacy_class_names) # Test missing history: content = """ foo: bar """ buff = yaml_to_asdf(content) with assert_no_warnings(): open_asdf(buff) # Test the old history format: content = """ history: - !core/history_entry-1.0.0 description: Once upon a time, there was a carnivorous panda. - !core/history_entry-1.0.0 description: This entry intentionally left blank. foo: bar """ buff = yaml_to_asdf(content, standard_version="1.0.0") with assert_no_warnings(): open_asdf(buff) # Test legacy extension matching by actual class name: content = """ history: extensions: - !core/extension_metadata-1.0.0 extension_class: asdf.tests.test_asdf.TestExtension """ buff = yaml_to_asdf(content) with assert_no_warnings(): open_asdf(buff) # Test matching by URI: content = """ history: extensions: - !core/extension_metadata-1.0.0 extension_uri: asdf://somewhere.org/extensions/foo-1.0 extension_class: some.unrecognized.extension.class.Name """ buff = yaml_to_asdf(content) with assert_no_warnings(): open_asdf(buff) # Test matching by legacy class name: content = """ history: extensions: - !core/extension_metadata-1.0.0 extension_class: some.legacy.class.Name """ buff = yaml_to_asdf(content) with assert_no_warnings(): open_asdf(buff) # Warn when the URI is missing, even if there's # a class name match: content = """ history: extensions: - !core/extension_metadata-1.0.0 extension_uri: some-missing-URI extension_class: {} """.format(extension_with_uri.class_name) buff = yaml_to_asdf(content) with pytest.warns(AsdfWarning, match="URI 'some-missing-URI'"): open_asdf(buff) # Warn when the class name is missing: content = """ history: extensions: - !core/extension_metadata-1.0.0 extension_class: some.missing.class.Name """ buff = yaml_to_asdf(content) with pytest.warns(AsdfWarning, match="class 'some.missing.class.Name'"): open_asdf(buff) # Warn when the package version is older: content = """ history: extensions: - !core/extension_metadata-1.0.0 extension_uri: asdf://somewhere.org/extensions/foo-1.0 extension_class: some.class.Name software: !core/software-1.0.0 name: foo version: 9.2.4 """ buff = yaml_to_asdf(content) with pytest.warns(AsdfWarning, match="older package"): open_asdf(buff) # Shouldn't warn when the package version is later: content = """ history: extensions: - !core/extension_metadata-1.0.0 extension_uri: asdf://somewhere.org/extensions/foo-1.0 extension_class: some.class.Name software: !core/software-1.0.0 name: foo version: 0.1.2 """ buff = yaml_to_asdf(content) with assert_no_warnings(): open_asdf(buff) # Shouldn't receive a warning when the package # name changes, even if the version is later: content = """ history: extensions: - !core/extension_metadata-1.0.0 extension_uri: asdf://somewhere.org/extensions/foo-1.0 extension_class: some.class.Name software: !core/software-1.0.0 name: bar version: 9.4.5 """ buff = yaml_to_asdf(content) with assert_no_warnings(): open_asdf(buff)
def test_extensions(): with asdf.config_context() as config: original_extensions = config.extensions assert any( isinstance(e.delegate, BuiltinExtension) for e in original_extensions) class FooExtension: types = [] tag_mapping = [] url_mapping = [] new_extension = FooExtension() class BarExtension: extension_uri = "asdf://somewhere.org/extensions/bar-1.0" types = [] tag_mapping = [] url_mapping = [] uri_extension = BarExtension() # Add an extension: config.add_extension(new_extension) assert len(config.extensions) == len(original_extensions) + 1 assert any(e for e in config.extensions if e.delegate is new_extension) # Adding an extension should be idempotent: config.add_extension(new_extension) assert len(config.extensions) == len(original_extensions) + 1 # Even when wrapped: config.add_extension(ExtensionProxy(new_extension)) assert len(config.extensions) == len(original_extensions) + 1 # Remove an extension: config.remove_extension(new_extension) assert len(config.extensions) == len(original_extensions) # Removing should work when wrapped: config.add_extension(new_extension) config.remove_extension(ExtensionProxy(new_extension)) assert len(config.extensions) == len(original_extensions) # And also by URI: config.add_extension(uri_extension) config.remove_extension(uri_extension.extension_uri) assert len(config.extensions) == len(original_extensions) # And also by URI pattern: config.add_extension(uri_extension) config.remove_extension("asdf://somewhere.org/extensions/*") assert len(config.extensions) == len(original_extensions) # Remove by the name of the extension's package: config.add_extension(ExtensionProxy(new_extension, package_name="foo")) config.add_extension(ExtensionProxy(uri_extension, package_name="foo")) config.remove_extension(package="foo") assert len(config.extensions) == len(original_extensions) # Can combine remove filters: config.add_extension(ExtensionProxy(new_extension, package_name="foo")) config.add_extension(ExtensionProxy(uri_extension, package_name="foo")) config.remove_extension(uri_extension.extension_uri, package="foo") assert len(config.extensions) == len(original_extensions) + 1 # ... but not omit both: with pytest.raises(ValueError): config.remove_extension() # Removing an extension should be idempotent: config.add_extension(new_extension) config.remove_extension(new_extension) config.remove_extension(new_extension) assert len(config.extensions) == len(original_extensions) # Resetting should get rid of any additions: config.add_extension(new_extension) config.add_extension(FooExtension()) config.reset_extensions() assert len(config.extensions) == len(original_extensions)
def test_manifest_extension(): with config_context() as config: minimal_manifest = """%YAML 1.1 --- id: asdf://somewhere.org/manifests/foo extension_uri: asdf://somewhere.org/extensions/foo ... """ config.add_resource_mapping( {"asdf://somewhere.org/extensions/foo": minimal_manifest}) extension = ManifestExtension.from_uri( "asdf://somewhere.org/extensions/foo") assert isinstance(extension, Extension) assert extension.extension_uri == "asdf://somewhere.org/extensions/foo" assert extension.legacy_class_names == [] assert extension.asdf_standard_requirement is None assert extension.converters == [] assert extension.compressors == [] assert extension.tags == [] proxy = ExtensionProxy(extension) assert proxy.extension_uri == "asdf://somewhere.org/extensions/foo" assert proxy.legacy_class_names == set() assert proxy.asdf_standard_requirement == SpecifierSet() assert proxy.converters == [] assert proxy.compressors == [] assert proxy.tags == [] with config_context() as config: full_manifest = """%YAML 1.1 --- id: asdf://somewhere.org/manifests/foo extension_uri: asdf://somewhere.org/extensions/foo asdf_standard_requirement: gte: 1.6.0 lt: 2.0.0 tags: - asdf://somewhere.org/tags/bar - tag_uri: asdf://somewhere.org/tags/baz schema_uri: asdf://somewhere.org/schemas/baz title: Baz title description: Bar description ... """ config.add_resource_mapping( {"asdf://somewhere.org/extensions/foo": full_manifest}) class FooConverter: tags = [ "asdf://somewhere.org/tags/bar", "asdf://somewhere.org/tags/baz" ] types = [] def select_tag(self, *args): pass def to_yaml_tree(self, *args): pass def from_yaml_tree(self, *args): pass converter = FooConverter() extension = ManifestExtension.from_uri( "asdf://somewhere.org/extensions/foo", legacy_class_names=["foo.extension.LegacyExtension"], converters=[converter], compressors=[MinimalCompressor], ) assert extension.extension_uri == "asdf://somewhere.org/extensions/foo" assert extension.legacy_class_names == [ "foo.extension.LegacyExtension" ] assert extension.asdf_standard_requirement == SpecifierSet( ">=1.6.0,<2.0.0") assert extension.converters == [converter] assert extension.compressors == [MinimalCompressor] assert len(extension.tags) == 2 assert extension.tags[0] == "asdf://somewhere.org/tags/bar" assert extension.tags[1].tag_uri == "asdf://somewhere.org/tags/baz" assert extension.tags[ 1].schema_uri == "asdf://somewhere.org/schemas/baz" assert extension.tags[1].title == "Baz title" assert extension.tags[1].description == "Bar description" proxy = ExtensionProxy(extension) assert proxy.extension_uri == "asdf://somewhere.org/extensions/foo" assert proxy.legacy_class_names == {"foo.extension.LegacyExtension"} assert proxy.asdf_standard_requirement == SpecifierSet( ">=1.6.0,<2.0.0") assert proxy.converters == [ConverterProxy(converter, proxy)] assert proxy.compressors == [MinimalCompressor] assert len(proxy.tags) == 2 assert proxy.tags[0].tag_uri == "asdf://somewhere.org/tags/bar" assert proxy.tags[1].tag_uri == "asdf://somewhere.org/tags/baz" assert proxy.tags[1].schema_uri == "asdf://somewhere.org/schemas/baz" assert proxy.tags[1].title == "Baz title" assert proxy.tags[1].description == "Bar description" with config_context() as config: simple_asdf_standard_manifest = """%YAML 1.1 --- id: asdf://somewhere.org/manifests/foo extension_uri: asdf://somewhere.org/extensions/foo asdf_standard_requirement: 1.6.0 ... """ config.add_resource_mapping({ "asdf://somewhere.org/extensions/foo": simple_asdf_standard_manifest }) extension = ManifestExtension.from_uri( "asdf://somewhere.org/extensions/foo") assert extension.asdf_standard_requirement == SpecifierSet("==1.6.0") proxy = ExtensionProxy(extension) assert proxy.asdf_standard_requirement == SpecifierSet("==1.6.0")
def test_converter_proxy(): # Test the minimum set of converter methods: extension = ExtensionProxy(MinimumExtension()) converter = MinimumConverter() proxy = ConverterProxy(converter, extension) assert isinstance(proxy, Converter) assert proxy.tags == [] assert proxy.types == [] assert proxy.to_yaml_tree(None, None, None) == "to_yaml_tree result" assert proxy.from_yaml_tree(None, None, None) == "from_yaml_tree result" assert proxy.tags == [] assert proxy.delegate is converter assert proxy.extension == extension assert proxy.package_name is None assert proxy.package_version is None assert proxy.class_name == "asdf.tests.test_extension.MinimumConverter" # Check the __eq__ and __hash__ behavior: assert proxy == ConverterProxy(converter, extension) assert proxy != ConverterProxy(MinimumConverter(), extension) assert proxy != ConverterProxy(converter, MinimumExtension()) assert proxy in {ConverterProxy(converter, extension)} assert proxy not in { ConverterProxy(MinimumConverter(), extension), ConverterProxy(converter, MinimumExtension()) } # Check the __repr__: assert "class: asdf.tests.test_extension.MinimumConverter" in repr(proxy) assert "package: (none)" in repr(proxy) # Test the full set of converter methods: converter = FullConverter(tags=[ "asdf://somewhere.org/extensions/test/tags/foo-*", "asdf://somewhere.org/extensions/test/tags/bar-*", ], types=[FooType, BarType]) extension = FullExtension(tags=[ TagDefinition( "asdf://somewhere.org/extensions/test/tags/foo-1.0", schema_uri="asdf://somewhere.org/extensions/test/schemas/foo-1.0", title="Foo tag title", description="Foo tag description"), TagDefinition( "asdf://somewhere.org/extensions/test/tags/bar-1.0", schema_uri="asdf://somewhere.org/extensions/test/schemas/bar-1.0", title="Bar tag title", description="Bar tag description"), ]) extension_proxy = ExtensionProxy(extension, package_name="foo", package_version="1.2.3") proxy = ConverterProxy(converter, extension_proxy) assert len(proxy.tags) == 2 assert "asdf://somewhere.org/extensions/test/tags/foo-1.0" in proxy.tags assert "asdf://somewhere.org/extensions/test/tags/bar-1.0" in proxy.tags assert proxy.types == [FooType, BarType] assert proxy.to_yaml_tree(None, None, None) == "to_yaml_tree result" assert proxy.from_yaml_tree(None, None, None) == "from_yaml_tree result" assert proxy.select_tag(None, None) == "select_tag result" assert proxy.delegate is converter assert proxy.extension == extension_proxy assert proxy.package_name == "foo" assert proxy.package_version == "1.2.3" assert proxy.class_name == "asdf.tests.test_extension.FullConverter" # Check the __repr__ since it will contain package info now: assert "class: asdf.tests.test_extension.FullConverter" in repr(proxy) assert "package: foo==1.2.3" in repr(proxy) # Should error because object() does fulfill the Converter interface: with pytest.raises(TypeError): ConverterProxy(object(), extension) # Should fail because tags must be str: with pytest.raises(TypeError): ConverterProxy(MinimumConverter(tags=[object()]), extension) # Should fail because types must instances of type: with pytest.raises(TypeError): ConverterProxy(MinimumConverter(types=[object()]), extension)
def test_extension_manager(): converter1 = FullConverter( tags=[ "asdf://somewhere.org/extensions/full/tags/foo-*", "asdf://somewhere.org/extensions/full/tags/bar-*", ], types=[ FooType, "asdf.tests.test_extension.BarType", ], ) converter2 = FullConverter( tags=[ "asdf://somewhere.org/extensions/full/tags/baz-*", ], types=[BazType], ) converter3 = FullConverter( tags=[ "asdf://somewhere.org/extensions/full/tags/foo-*", ], types=[ FooType, BarType, ], ) extension1 = FullExtension( converters=[converter1, converter2], tags=[ "asdf://somewhere.org/extensions/full/tags/foo-1.0", "asdf://somewhere.org/extensions/full/tags/baz-1.0", ]) extension2 = FullExtension( converters=[converter3], tags=[ "asdf://somewhere.org/extensions/full/tags/foo-1.0", ]) manager = ExtensionManager([extension1, extension2]) assert manager.extensions == [ ExtensionProxy(extension1), ExtensionProxy(extension2) ] assert manager.handles_tag( "asdf://somewhere.org/extensions/full/tags/foo-1.0") is True assert manager.handles_tag( "asdf://somewhere.org/extensions/full/tags/bar-1.0") is False assert manager.handles_tag( "asdf://somewhere.org/extensions/full/tags/baz-1.0") is True assert manager.handles_type(FooType) is True # This should return True even though BarType was listed # as string class name: assert manager.handles_type(BarType) is True assert manager.handles_type(BazType) is True assert manager.get_tag_definition( "asdf://somewhere.org/extensions/full/tags/foo-1.0" ).tag_uri == "asdf://somewhere.org/extensions/full/tags/foo-1.0" assert manager.get_tag_definition( "asdf://somewhere.org/extensions/full/tags/baz-1.0" ).tag_uri == "asdf://somewhere.org/extensions/full/tags/baz-1.0" with pytest.raises(KeyError): manager.get_tag_definition( "asdf://somewhere.org/extensions/full/tags/bar-1.0") assert manager.get_converter_for_tag( "asdf://somewhere.org/extensions/full/tags/foo-1.0" ).delegate is converter1 assert manager.get_converter_for_tag( "asdf://somewhere.org/extensions/full/tags/baz-1.0" ).delegate is converter2 with pytest.raises(KeyError): manager.get_converter_for_tag( "asdf://somewhere.org/extensions/full/tags/bar-1.0") assert manager.get_converter_for_type(FooType).delegate is converter1 assert manager.get_converter_for_type(BarType).delegate is converter1 assert manager.get_converter_for_type(BazType).delegate is converter2 with pytest.raises(KeyError): manager.get_converter_for_type(object)
def test_extension_proxy(): # Test with minimum properties: extension = MinimumExtension() proxy = ExtensionProxy(extension) assert isinstance(proxy, Extension) assert isinstance(proxy, AsdfExtension) assert proxy.extension_uri == "asdf://somewhere.org/extensions/minimum-1.0" assert proxy.legacy_class_names == set() assert proxy.asdf_standard_requirement == SpecifierSet() assert proxy.converters == [] assert proxy.compressors == [] assert proxy.tags == [] assert proxy.types == [] assert proxy.tag_mapping == [] assert proxy.url_mapping == [] assert proxy.delegate is extension assert proxy.legacy is False assert proxy.package_name is None assert proxy.package_version is None assert proxy.class_name == "asdf.tests.test_extension.MinimumExtension" # The subclassed version should have the same defaults: extension = MinimumExtensionSubclassed() subclassed_proxy = ExtensionProxy(extension) assert subclassed_proxy.extension_uri == proxy.extension_uri assert subclassed_proxy.legacy_class_names == proxy.legacy_class_names assert subclassed_proxy.asdf_standard_requirement == proxy.asdf_standard_requirement assert subclassed_proxy.converters == proxy.converters assert subclassed_proxy.tags == proxy.tags assert subclassed_proxy.types == proxy.types assert subclassed_proxy.tag_mapping == proxy.tag_mapping assert subclassed_proxy.url_mapping == proxy.url_mapping assert subclassed_proxy.delegate is extension assert subclassed_proxy.legacy == proxy.legacy assert subclassed_proxy.package_name == proxy.package_name assert subclassed_proxy.package_version == proxy.package_name assert subclassed_proxy.class_name == "asdf.tests.test_extension.MinimumExtensionSubclassed" # Test with all properties present: converters = [ MinimumConverter( tags=["asdf://somewhere.org/extensions/full/tags/foo-*"], types=[]) ] extension = FullExtension( converters=converters, compressors=[MinimalCompressor], asdf_standard_requirement=">=1.4.0", tags=["asdf://somewhere.org/extensions/full/tags/foo-1.0"], legacy_class_names=["foo.extensions.SomeOldExtensionClass"]) proxy = ExtensionProxy(extension, package_name="foo", package_version="1.2.3") assert proxy.extension_uri == "asdf://somewhere.org/extensions/full-1.0" assert proxy.legacy_class_names == {"foo.extensions.SomeOldExtensionClass"} assert proxy.asdf_standard_requirement == SpecifierSet(">=1.4.0") assert proxy.converters == [ConverterProxy(c, proxy) for c in converters] assert proxy.compressors == [MinimalCompressor] assert len(proxy.tags) == 1 assert proxy.tags[ 0].tag_uri == "asdf://somewhere.org/extensions/full/tags/foo-1.0" assert proxy.types == [] assert proxy.tag_mapping == [] assert proxy.url_mapping == [] assert proxy.delegate is extension assert proxy.legacy is False assert proxy.package_name == "foo" assert proxy.package_version == "1.2.3" assert proxy.class_name == "asdf.tests.test_extension.FullExtension" # Should fail when the input is not one of the two extension interfaces: with pytest.raises(TypeError): ExtensionProxy(object) # Should fail with a bad converter: with pytest.raises(TypeError): ExtensionProxy(FullExtension(converters=[object()])) # Should fail with a bad compressor: with pytest.raises(TypeError): ExtensionProxy(FullExtension(compressors=[object()])) # Unparseable ASDF Standard requirement: with pytest.raises(ValueError): ExtensionProxy( FullExtension(asdf_standard_requirement="asdf-standard >= 1.4.0")) # Unrecognized ASDF Standard requirement type: with pytest.raises(TypeError): ExtensionProxy(FullExtension(asdf_standard_requirement=object())) # Bad tag: with pytest.raises(TypeError): ExtensionProxy(FullExtension(tags=[object()])) # Bad legacy class names: with pytest.raises(TypeError): ExtensionProxy(FullExtension(legacy_class_names=[object]))