Beispiel #1
0
def test_longest_match():
    class FancyComplexExtension(object):
        @property
        def types(self):
            return []

        @property
        def tag_mapping(self):
            return []

        @property
        def url_mapping(self):
            return [('http://stsci.edu/schemas/asdf/core/',
                     'FOOBAR/{url_suffix}')]

    l = extension.AsdfExtensionList(
        [extension.BuiltinExtension(), FancyComplexExtension()])

    assert l.url_mapping(
        'http://stsci.edu/schemas/asdf/core/asdf-1.0.0') == 'FOOBAR/asdf-1.0.0'
    assert l.url_mapping(
        'http://stsci.edu/schemas/asdf/transform/transform-1.0.0') != 'FOOBAR/transform-1.0.0'
Beispiel #2
0
    def __init__(self,
                 init=None,
                 schema=None,
                 extensions=None,
                 pass_invalid_values=False):
        """
        Parameters
        ----------
        init : shape tuple, file path, file object, astropy.io.fits.HDUList, numpy array, None

            - None: A default data model with no shape

            - shape tuple: Initialize with empty data of the given
              shape

            - file path: Initialize from the given file (FITS or ASDF)

            - readable file object: Initialize from the given file
              object

            - ``astropy.io.fits.HDUList``: Initialize from the given
              `~astropy.io.fits.HDUList`.

            - A numpy array: Used to initialize the data array

            - dict: The object model tree for the data model

        schema : tree of objects representing a JSON schema, or string naming a schema, optional
            The schema to use to understand the elements on the model.
            If not provided, the schema associated with this class
            will be used.

        extensions: classes extending the standard set of extensions, optional.
            If an extension is defined, the prefix used should be 'url'.

        pass_invalid_values: If true, values that do not validate the schema can
            be read and written and only a warning will be generated
        """
        # Set the extensions
        if extensions is None:
            extensions = jwst_extensions[:]
        else:
            extensions.extend(jwst_extensions)
        self._extensions = extensions

        # Override value of pass_invalid value if environment value set
        if "PASS_INVALID_VALUES" in os.environ:
            pass_invalid_values = os.environ["PASS_INVALID_VALUES"]
            try:
                pass_invalid_values = bool(int(pass_invalid_values))
            except ValueError:
                pass_invalid_values = False

        self._pass_invalid_values = pass_invalid_values

        # Construct the path to the schema files
        filename = os.path.abspath(inspect.getfile(self.__class__))
        base_url = os.path.join(os.path.dirname(filename), 'schemas', '')

        # Load the schema files
        if schema is None:
            schema_path = os.path.join(base_url, self.schema_url)
            extension_list = asdf_extension.AsdfExtensionList(self._extensions)
            schema = asdf_schema.load_schema(
                schema_path,
                resolver=extension_list.url_mapping,
                resolve_references=True)

        self._schema = mschema.flatten_combiners(schema)
        # Determine what kind of input we have (init) and execute the
        # proper code to intiailize the model
        self._files_to_close = []
        self._iscopy = False

        is_array = False
        is_shape = False
        shape = None

        if init is None:
            asdf = AsdfFile(extensions=extensions)
        elif isinstance(init, dict):
            asdf = AsdfFile(init, extensions=extensions)
        elif isinstance(init, np.ndarray):
            asdf = AsdfFile(extensions=extensions)
            shape = init.shape
            is_array = True
        elif isinstance(init, self.__class__):
            self.clone(self, init)
            return
        elif isinstance(init, DataModel):
            raise TypeError(
                "Passed in {0!r} is not of the expected subclass {1!r}".format(
                    init.__class__.__name__, self.__class__.__name__))
        elif isinstance(init, AsdfFile):
            asdf = init
        elif isinstance(init, tuple):
            for item in init:
                if not isinstance(item, int):
                    raise ValueError("shape must be a tuple of ints")
            shape = init
            asdf = AsdfFile()
            is_shape = True
        elif isinstance(init, fits.HDUList):
            asdf = fits_support.from_fits(init, self._schema, extensions,
                                          pass_invalid_values)

        elif isinstance(init, (six.string_types, bytes)):
            if isinstance(init, bytes):
                init = init.decode(sys.getfilesystemencoding())
            file_type = filetype.check(init)

            if file_type == "fits":
                hdulist = fits.open(init)
                asdf = fits_support.from_fits(hdulist, self._schema,
                                              extensions, pass_invalid_values)
                self._files_to_close.append(hdulist)

            elif file_type == "asdf":
                asdf = AsdfFile.open(init, extensions=extensions)

            else:
                # TODO handle json files as well
                raise IOError(
                    "File does not appear to be a FITS or ASDF file.")

        else:
            raise ValueError("Can't initialize datamodel using {0}".format(
                str(type(init))))

        # Initialize object fields as determined fro the code above

        self._shape = shape
        self._instance = asdf.tree
        self._asdf = asdf
        self._ctx = self

        # if the input is from a file, set the filename attribute
        if isinstance(init, six.string_types):
            self.meta.filename = os.path.basename(init)
        elif isinstance(init, fits.HDUList):
            info = init.fileinfo(0)
            if info is not None:
                filename = info.get('filename')
                if filename is not None:
                    self.meta.filename = os.path.basename(filename)

        # if the input model doesn't have a date set, use the current date/time
        if self.meta.date is None:
            self.meta.date = Time(datetime.datetime.now())
            if hasattr(self.meta.date, 'value'):
                self.meta.date.format = 'isot'
                self.meta.date = str(self.meta.date.value)

        # store the data model type, if not already set
        if hasattr(self.meta, 'model_type'):
            if self.meta.model_type is None:
                self.meta.model_type = self.__class__.__name__
        else:
            self.meta.model_type = None

        if is_array:
            primary_array_name = self.get_primary_array_name()
            if primary_array_name is None:
                raise TypeError(
                    "Array passed to DataModel.__init__, but model has "
                    "no primary array in its schema")
            setattr(self, primary_array_name, init)

        # TODO this code looks useless
        if is_shape:
            getattr(self, self.get_primary_array_name())