示例#1
0
def test_warning_logged():
    '''
    warning is logged if we try to get a class from 'obj_type' that is not
    in the gnome namespace
    '''
    with LogCapture() as lc:
        with pytest.raises(AttributeError):
            class_from_objtype('os.path')

        lc.check(('gnome.gnomeobject', 'WARNING',
                  'os.path is not part of gnome namespace'))
示例#2
0
def test_warning_logged():
    '''
    warning is logged if we try to get a class from 'obj_type' that is not
    in the gnome namespace
    '''
    with LogCapture() as lc:
        with pytest.raises(AttributeError):
            class_from_objtype('os.path')

        lc.check(('gnome.gnomeobject',
                  'WARNING',
                  'os.path is not part of gnome namespace'))
示例#3
0
    def _deser(self, node, value, refs):
            if value is None:
                return None

            if type(value) is dict and 'obj_type' in value:
                id_ = value.get('id', None)

                if id_ not in refs or id_ is None:
                    obj_type = class_from_objtype(value['obj_type'])
                    obj = obj_type.new_from_dict(value)

                    log.info('Created new {} object {}'
                             .format(obj.obj_type, obj.name))

                    node.register_refs(node, obj, refs)

                    if id_ is None:
                        id_ = obj.id

                    refs[id_] = obj

                return refs[id_]
            else:
                raise TypeError('{} is not dictionary, '
                                'or does not have an obj_type'
                                .format(value))
示例#4
0
    def _deser(self, node, value, refs):
            if value is None:
                return None

            if type(value) is dict and 'obj_type' in value:
                id_ = value.get('id', None)

                if id_ not in refs or id_ is None:
                    obj_type = class_from_objtype(value['obj_type'])
                    obj = obj_type.new_from_dict(value)

                    log.info('Created new {} object {}'
                             .format(obj.obj_type, obj.name))

                    node.register_refs(node, obj, refs)

                    if id_ is None:
                        id_ = obj.id

                    refs[id_] = obj

                return refs[id_]
            else:
                raise TypeError('{} is not dictionary, '
                                'or does not have an obj_type'
                                .format(value))
示例#5
0
    def validate_input_schema(self, obj_or_json):
        '''
        Takes an object or json dict and determines if it can be represented by
        this schema instance. Returns an instance of the schema of the object,
        or raises an error if the object cannot be used with this schema.
        '''
        if type(obj_or_json) is dict:
            json_ = obj_or_json
            obj_type = class_from_objtype(json_['obj_type'])
            schema = obj_type._schema

            for s in self.acceptable_schemas:
                if schema is s or issubclass(schema, s):
                    return schema()
            else:
                raise TypeError('This type of json is not supported {}'
                                .format(schema))
        else:
            obj = obj_or_json
            schema = obj.__class__._schema

            for s in self.acceptable_schemas:
                if schema is s or issubclass(schema, s):
                    return schema()

            raise TypeError('This type of object {} is not supported. '
                            'Schema: {}'
                            .format(obj, schema))
示例#6
0
    def load(self, obj_json, saveloc=None, refs=None):
        if obj_json is None:
            raise ValueError(self.__class__.__name__ + ': Cannot load a None')
        cls = class_from_objtype(obj_json['obj_type'])
        if cls._schema is not self.__class__:
            raise TypeError('A {0} cannot save a {1}'.format(self.__class__.__name__, cls.__name__))
        if zipfile is None:
            raise ValueError('Must pass an open zipfile.Zipfile in append mode to saveloc')

        obj = self.typ.load(self, obj_json, saveloc, refs)
        return obj
示例#7
0
    def load(self, obj_json, saveloc=None, refs=None):
        if obj_json is None:
            raise ValueError('{}: Cannot load a None'
                             .format(self.__class__.__name__))

        cls = class_from_objtype(obj_json['obj_type'])

        if cls._schema is not self.__class__:
            raise TypeError('A {} cannot save a {}'
                            .format(self.__class__.__name__, cls.__name__))

        if zipfile is None:
            raise ValueError('Must pass an open zipfile.Zipfile '
                             'in append mode to saveloc')

        return self.typ.load(self, obj_json, saveloc, refs)
示例#8
0
def validate_save_json(json_, zipfile_, orig_obj):
    '''
    validates the json_ and zipfile_ of an object. In particular:

    class_from_objtype must return the original object's class when provided
    json_['obj_type']

    All save_reference attributes have a .json file referenced, and
    such files also exist in the zipfile_

    All missing=drop attributes that are None on the original object
    do not appear.  No GnomeId python objects exist in the json

    Note that this should not be used to validate cases where the object may
    be doing custom save or using a custom to_dict. If an object does
    not do this however, it should be able to pass these tests
    '''

    assert class_from_objtype(json_['obj_type']) is orig_obj.__class__

    schema = orig_obj._schema()
    save_refs = schema.get_nodes_by_attr('save_reference')
    for n in save_refs:
        if getattr(orig_obj, n) is not None:
            if isinstance(getattr(orig_obj, n), collections.Iterable):
                for i, ref in enumerate(getattr(orig_obj, n)):
                    assert json_[n][i] == ref.name + '.json'
                    assert json_[n][i] in zipfile_.namelist()
            else:
                ref = getattr(orig_obj, n)
                assert json_[n] == ref.name + '.json'
                assert json_[n] in zipfile_.namelist()


#     potential_missing = schema.get_nodes_by_attr('missing')
#     for n in potential_missing:
#         if getattr(orig_obj,n) is None:
#             assert n not in json_

    for v in json_.values():
        assert not issubclass(v.__class__, GnomeId)

    return True
示例#9
0
def validate_save_json(json_, zipfile_, orig_obj):
    '''
    validates the json_ and zipfile_ of an object. In particular:

    class_from_objtype must return the original object's class when provided
    json_['obj_type']

    All save_reference attributes have a .json file referenced, and
    such files also exist in the zipfile_

    All missing=drop attributes that are None on the original object
    do not appear.  No GnomeId python objects exist in the json

    Note that this should not be used to validate cases where the object may
    be doing custom save or using a custom to_dict. If an object does
    not do this however, it should be able to pass these tests
    '''

    assert class_from_objtype(json_['obj_type']) is orig_obj.__class__

    schema = orig_obj._schema()
    save_refs = schema.get_nodes_by_attr('save_reference')
    for n in save_refs:
        if getattr(orig_obj, n) is not None:
            if isinstance(getattr(orig_obj, n), collections.Iterable):
                for i, ref in enumerate(getattr(orig_obj, n)):
                    assert json_[n][i] == ref.name + '.json'
                    assert json_[n][i] in zipfile_.namelist()
            else:
                ref = getattr(orig_obj, n)
                assert json_[n] == ref.name + '.json'
                assert json_[n] in zipfile_.namelist()

#     potential_missing = schema.get_nodes_by_attr('missing')
#     for n in potential_missing:
#         if getattr(orig_obj,n) is None:
#             assert n not in json_

    for v in json_.values():
        assert not issubclass(v.__class__, GnomeId)

    return True
示例#10
0
    def test_serialize_from_blob_old(self):
        # this one uses the "old" name, before moving the map module.
        json_data = {
            'approximate_raster_interval':
            53.9608870724,
            'filename':
            u'/Users/chris.barker/Hazmat/GitLab/pygnome/py_gnome/tests/unit_tests/sample_data/florida_with_lake_small.bna',
            'id':
            u'b3590b7d-aab1-11ea-8899-1e00b098d304',
            'map_bounds': [(-82.8609915978, 24.5472415066),
                           (-82.8609915978, 28.1117673335),
                           (-80.0313642811, 28.1117673335),
                           (-80.0313642811, 24.5472415066)],
            'name':
            u'MapFromBNA_8',
            'obj_type':
            u'gnome.map.MapFromBNA',
            'raster_size':
            16777216.0,
            'spillable_area':
            None,
            'refloat_halflife':
            1.0
        }

        cls = class_from_objtype(json_data['obj_type'])
        #   obj = cls.load(saveloc, fname, references)

        print "found class:", cls
        map = cls.deserialize(json_data)

        # when we go to Python3 :-(
        # assert map.__class__.__qualname__ == "gnome.maps.map.MapFromBNA"
        assert map.__class__.__name__ == "MapFromBNA"
        assert map.__class__.__module__ == "gnome.maps.map"

        print map.spillable_area
        print map.land_polys

        assert map.spillable_area is None
        assert len(map.map_bounds) == 4
示例#11
0
def validate_serialize_json(json_, orig_obj):
    '''
    Takes the json_ from a gnome object's serialize function, and verifies
    that it fits the schema. In particular:
    class_from_objtype must return the original object's class when provided
    json_['obj_type']
    all schema nodes set to missing=drop and are None on the original object
    do not appear in the json_
    No GnomeId python objects exist in the json

    Note that this should not be used to validate cases where the object may
    be doing custom serialization or using a custom to_dict. If an object does
    not do this however, it should be able to pass these tests
    '''
    assert class_from_objtype(json_['obj_type']) is orig_obj.__class__

    _schema = orig_obj._schema()

    for v in json_.values():
        assert not issubclass(v.__class__, GnomeId)

    return True
示例#12
0
    def validate_input_schema(self, obj_or_json):
        '''
        Takes an object or json dict and determines if it can be represented by
        this schema instance. Returns an instance of the schema of the object,
        or raises an error if the object cannot be used with this schema.
        '''
        if type(obj_or_json) is dict:
            json_ = obj_or_json
            obj_type = class_from_objtype(json_['obj_type'])
            schema = obj_type._schema
        else:
            obj = obj_or_json
            obj_type = obj.__class__
            schema = obj.__class__._schema

        for s in self.acceptable_schemas:
            if schema is s or issubclass(schema, s):
                return schema()

        raise TypeError('This type of object {} is not supported. '
                        'Schema: {}'
                        .format(obj_type, schema))
示例#13
0
def validate_serialize_json(json_, orig_obj):
    '''
    Takes the json_ from a gnome object's serialize function, and verifies
    that it fits the schema. In particular:
    class_from_objtype must return the original object's class when provided
    json_['obj_type']
    all schema nodes set to missing=drop and are None on the original object
    do not appear in the json_
    No GnomeId python objects exist in the json

    Note that this should not be used to validate cases where the object may
    be doing custom serialization or using a custom to_dict. If an object does
    not do this however, it should be able to pass these tests
    '''
    assert class_from_objtype(json_['obj_type']) is orig_obj.__class__

    _schema = orig_obj._schema()

    for v in json_.values():
        assert not issubclass(v.__class__, GnomeId)

    return True
示例#14
0
def load(saveloc, fname='Model.json', references=None):
    '''
    read json from file and load the appropriate object
    This is a general purpose load method that looks at the json['obj_type']
    and invokes json['obj_type'].loads(json) method

    :param saveloc: path to zipfile that contains data files and json files.
        It could also be a directory containing files - keep original support
        for location files.
    :param fname: .json file to load. Default is 'Model.json'. zipfile/dir
        must contain 'fname'
    :param references=None: References object that keeps track of objects
        in a dict as they are constructed, using the filename as the key

    :returns: object constructed from the json

    .. note:: Function first assumes saveloc is a directory and looks for
        saveloc/fname. If this fails, it checks if saveloc is a zipfile. If
        this fails, it checks if saveloc is a file and loads this assuming its
        json for a gnome object. If none of these work, it just returns None.
    '''
    if zipfile.is_zipfile(saveloc):
        with zipfile.ZipFile(saveloc, 'r') as z:
            saveloc_dir = os.path.dirname(saveloc)
            folders = zipfile_folders(z)

            if len(folders) == 1:
                # we allow our model content to be in a single top-level folder
                prefix = folders[0]
                extract_zipfile(z, saveloc_dir, prefix)
            elif len(folders) == 0:
                # all datafiles are at the top-level, which is fine
                extract_zipfile(z, saveloc_dir)
            else:
                # nothing to do, zipfile does not have a good structure
                return

            saveloc = saveloc_dir

    if os.path.isdir(saveloc):
        # is a directory, look for our fname in directory
        fd = open(os.path.join(saveloc, fname), 'r')
    elif os.path.isfile(saveloc):
        fd = open(saveloc, 'r')
        saveloc, fname = os.path.split(saveloc)
    else:
        # nothing to do, saveloc is not a file or a directory
        return

    # load json data from file descriptor
    json_data = json.loads("".join([l.rstrip('\n') for l in fd]))
    fd.close()

    # create a reference to the object being loaded
    cls = class_from_objtype(json_data.pop('obj_type'))
    obj = cls.load(saveloc, fname, references)

    if obj is None:
        # object failed to load - look in log messages for clues
        return

    # after loading, add the object to references
    if references:
        references.reference(obj, fname)

    return obj
示例#15
0
def test_class_from_objtype():
    '''
    test that correct class is returned by class_from_objtype
    '''
    cls = class_from_objtype('gnome.movers.WindMover')
    assert cls is WindMover
示例#16
0
def test_class_from_objtype():
    '''
    test that correct class is returned by class_from_objtype
    '''
    cls = class_from_objtype('gnome.movers.WindMover')
    assert cls is WindMover
示例#17
0
def load(saveloc, fname='Model.json', references=None):
    '''
    read json from file and load the appropriate object
    This is a general purpose load method that looks at the json['obj_type']
    and invokes json['obj_type'].loads(json) method

    :param saveloc: path to zipfile that contains data files and json files.
        It could also be a directory containing files - keep original support
        for location files.
    :param fname: .json file to load. Default is 'Model.json'. zipfile/dir
        must contain 'fname'
    :param references=None: References object that keeps track of objects
        in a dict as they are constructed, using the filename as the key

    :returns: object constructed from the json

    .. note:: Function first assumes saveloc is a directory and looks for
        saveloc/fname. If this fails, it checks if saveloc is a zipfile. If
        this fails, it checks if saveloc is a file and loads this assuming its
        json for a gnome object. If none of these work, it just returns None.
    '''
    if zipfile.is_zipfile(saveloc):
        with zipfile.ZipFile(saveloc, 'r') as z:
            saveloc_dir = os.path.dirname(saveloc)
            folders = zipfile_folders(z)

            if len(folders) == 1:
                # we allow our model content to be in a single top-level folder
                prefix = folders[0]
                extract_zipfile(z, saveloc_dir, prefix)
            elif len(folders) == 0:
                # all datafiles are at the top-level, which is fine
                extract_zipfile(z, saveloc_dir)
            else:
                # nothing to do, zipfile does not have a good structure
                return

            saveloc = saveloc_dir

    if os.path.isdir(saveloc):
        # is a directory, look for our fname in directory
        fd = open(os.path.join(saveloc, fname), 'r')
    elif os.path.isfile(saveloc):
        fd = open(saveloc, 'r')
        saveloc, fname = os.path.split(saveloc)
    else:
        # nothing to do, saveloc is not a file or a directory
        return

    # load json data from file descriptor
    json_data = json.loads("".join([l.rstrip('\n') for l in fd]))
    fd.close()

    # create a reference to the object being loaded
    cls = class_from_objtype(json_data.pop('obj_type'))
    obj = cls.load(saveloc, fname, references)

    if obj is None:
        # object failed to load - look in log messages for clues
        return

    # after loading, add the object to references
    if references:
        references.reference(obj, fname)

    return obj