Exemplo n.º 1
0
def test_extension_version_warning():

    yaml = """
history:
  extensions:
    - !core/extension_metadata-1.0.0
      extension_class: asdf.extension.BuiltinExtension
      software: !core/software-1.0.0
        name: asdf
        version: 100.0.3
    """

    buff = yaml_to_asdf(yaml)
    with pytest.warns(
            AsdfWarning,
            match=
            "File was created with extension class 'asdf.extension.BuiltinExtension'"
    ):
        with asdf.open(buff):
            pass

    buff.seek(0)

    # Make sure suppressing the warning works too
    with assert_no_warnings():
        with asdf.open(buff, ignore_missing_extensions=True):
            pass
Exemplo n.º 2
0
def test_assert_roundtrip_with_extension(tmpdir):
    called_custom_assert_equal = [False]

    class CustomType(dict, types.CustomType):
        name = 'custom_flow'
        organization = 'nowhere.org'
        version = (1, 0, 0)
        standard = 'custom'

        @classmethod
        def assert_equal(cls, old, new):
            called_custom_assert_equal[0] = True

    class CustomTypeExtension(CustomExtension):
        @property
        def types(self):
            return [CustomType]

    tree = {'custom': CustomType({'a': 42, 'b': 43})}

    def check(ff):
        assert isinstance(ff.tree['custom'], CustomType)

    with helpers.assert_no_warnings():
        helpers.assert_roundtrip_tree(tree,
                                      tmpdir,
                                      extensions=[CustomTypeExtension()])

    assert called_custom_assert_equal[0] is True
Exemplo n.º 3
0
def test_metadata_with_custom_extension(tmpdir):
    class FractionType(types.CustomType):
        name = 'fraction'
        organization = 'nowhere.org'
        version = (1, 0, 0)
        standard = 'custom'
        types = [fractions.Fraction]

        @classmethod
        def to_tree(cls, node, ctx):
            return [node.numerator, node.denominator]

        @classmethod
        def from_tree(cls, tree, ctx):
            return fractions.Fraction(tree[0], tree[1])

    class FractionExtension(CustomExtension):
        @property
        def types(self):
            return [FractionType]

    tree = {'fraction': fractions.Fraction(2, 3)}

    tmpfile = str(tmpdir.join('custom_extension.asdf'))
    with asdf.AsdfFile(tree, extensions=FractionExtension()) as ff:
        ff.write_to(tmpfile)

    # We expect metadata about both the Builtin extension and the custom one
    with asdf.open(tmpfile, extensions=FractionExtension()) as af:
        assert len(af['history']['extensions']) == 2

    with pytest.warns(AsdfWarning, match="was created with extension"):
        with asdf.open(tmpfile, ignore_unrecognized_tag=True):
            pass

    # If we use the extension but we don't serialize any types that require it,
    # no metadata about this extension should be added to the file
    tree2 = {'x': [x for x in range(10)]}
    tmpfile2 = str(tmpdir.join('no_extension.asdf'))
    with asdf.AsdfFile(tree2, extensions=FractionExtension()) as ff:
        ff.write_to(tmpfile2)

    with asdf.open(tmpfile2) as af:
        assert len(af['history']['extensions']) == 1

    with assert_no_warnings():
        with asdf.open(tmpfile2):
            pass

    # Make sure that this works even when constructing the tree on-the-fly
    tmpfile3 = str(tmpdir.join('custom_extension2.asdf'))
    with asdf.AsdfFile(extensions=FractionExtension()) as ff:
        ff.tree['fraction'] = fractions.Fraction(4, 5)
        ff.write_to(tmpfile3)

    with asdf.open(tmpfile3, extensions=FractionExtension()) as af:
        assert len(af['history']['extensions']) == 2
Exemplo n.º 4
0
def test_mapping_supported_key_types(keys, version):
    for key in keys:
        with helpers.assert_no_warnings():
            af = asdf.AsdfFile({key: "value"}, version=version)
            buff = io.BytesIO()
            af.write_to(buff)
            buff.seek(0)
            with asdf.open(buff) as af:
                assert af[key] == "value"
Exemplo n.º 5
0
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])
Exemplo n.º 6
0
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)