Example #1
0
 def assert_proper_col_class(obj, obj_tuple):
     # Iterate over all attributes, and if they are lists or mappings
     # in the original, assert they are the same class in the dumped.
     for index, field in enumerate(fields(obj.__class__)):
         field_val = getattr(obj, field.name)
         if has(field_val.__class__):
             # This field holds a class, recurse the assertions.
             assert_proper_col_class(field_val, obj_tuple[index])
         elif isinstance(field_val, (list, tuple)):
             # This field holds a sequence of something.
             expected_type = type(obj_tuple[index])
             assert type(field_val) is expected_type  # noqa: E721
             for obj_e, obj_tuple_e in zip(field_val, obj_tuple[index]):
                 if has(obj_e.__class__):
                     assert_proper_col_class(obj_e, obj_tuple_e)
         elif isinstance(field_val, dict):
             orig = field_val
             tupled = obj_tuple[index]
             assert type(orig) is type(tupled)  # noqa: E721
             for obj_e, obj_tuple_e in zip(orig.items(),
                                           tupled.items()):
                 if has(obj_e[0].__class__):  # Dict key
                     assert_proper_col_class(obj_e[0], obj_tuple_e[0])
                 if has(obj_e[1].__class__):  # Dict value
                     assert_proper_col_class(obj_e[1], obj_tuple_e[1])
Example #2
0
 def assert_proper_tuple_class(obj, obj_tuple):
     assert isinstance(obj_tuple, tuple_class)
     for index, field in enumerate(fields(obj.__class__)):
         field_val = getattr(obj, field.name)
         if has(field_val.__class__):
             # This field holds a class, recurse the assertions.
             assert_proper_tuple_class(field_val, obj_tuple[index])
Example #3
0
 def assert_proper_dict_class(obj, obj_dict):
     assert isinstance(obj_dict, dict_class)
     for field in fields(obj.__class__):
         field_val = getattr(obj, field.name)
         if has(field_val.__class__):
             # This field holds a class, recurse the assertions.
             assert_proper_dict_class(field_val, obj_dict[field.name])
         elif isinstance(field_val, Sequence):
             dict_val = obj_dict[field.name]
             for item, item_dict in zip(field_val, dict_val):
                 if has(item.__class__):
                     assert_proper_dict_class(item, item_dict)
         elif isinstance(field_val, Mapping):
             # This field holds a dictionary.
             assert isinstance(obj_dict[field.name], dict_class)
             for key, val in field_val.items():
                 if has(val.__class__):
                     assert_proper_dict_class(val, obj_dict[key])
Example #4
0
    def test_positive_empty(self):
        """
        Returns `True` on decorated classes even if there are no attributes.
        """
        @attributes
        class D(object):
            pass

        assert has(D)
Example #5
0
    def test_positive_empty(self):
        """
        Returns `True` on decorated classes even if there are no attributes.
        """
        @attributes
        class D(object):
            pass

        assert has(D)
Example #6
0
 def assert_proper_dict_class(obj, obj_dict):
     assert isinstance(obj_dict, dict_class)
     for field in fields(obj.__class__):
         field_val = getattr(obj, field.name)
         if has(field_val.__class__):
             # This field holds a class, recurse the assertions.
             assert_proper_dict_class(field_val, obj_dict[field.name])
         elif isinstance(field_val, Sequence):
             dict_val = obj_dict[field.name]
             for item, item_dict in zip(field_val, dict_val):
                 if has(item.__class__):
                     assert_proper_dict_class(item, item_dict)
         elif isinstance(field_val, Mapping):
             # This field holds a dictionary.
             assert isinstance(obj_dict[field.name], dict_class)
             for key, val in field_val.items():
                 if has(val.__class__):
                     assert_proper_dict_class(val, obj_dict[key])
Example #7
0
 def test_negative(self):
     """
     Returns `False` on non-decorated classes.
     """
     assert not has(object)
Example #8
0
 def test_positive(self, C):
     """
     Returns `True` on decorated classes.
     """
     assert has(C)
Example #9
0
 def test_negative(self):
     """
     Returns `False` on non-decorated classes.
     """
     assert not has(object)
Example #10
0
 def test_positive(self, C):
     """
     Returns `True` on decorated classes.
     """
     assert has(C)
Example #11
0
def asjsonld(
    inst,
    recurse=True,
    filter=None,
    dict_factory=dict,
    retain_collection_types=False,
    export_context=True,
    basedir=None,
):
    """Dump a JSON-LD class to the JSON with generated ``@context`` field."""
    jsonld_fields = inst.__class__._jsonld_fields
    attrs = tuple(field for field in fields(inst.__class__)
                  if field.name in jsonld_fields)
    rv = dict_factory()

    def convert_value(v):
        """Convert special types."""
        if isinstance(v, Path):
            v = str(v)
            return os.path.relpath(v, str(basedir)) if basedir else v
        return v

    for a in attrs:
        v = getattr(inst, a.name)

        # skip proxies
        if isinstance(v, weakref.ReferenceType):
            continue

        # do not export context for containers
        ec = export_context and KEY_CLS not in a.metadata

        if filter is not None and not filter(a, v):
            continue
        if recurse is True:
            if has(v.__class__):
                rv[a.name] = asjsonld(
                    v,
                    recurse=True,
                    filter=filter,
                    dict_factory=dict_factory,
                    basedir=basedir,
                )
            elif isinstance(v, (tuple, list, set)):
                cf = v.__class__ if retain_collection_types is True else list
                rv[a.name] = cf([
                    asjsonld(
                        i,
                        recurse=True,
                        filter=filter,
                        dict_factory=dict_factory,
                        export_context=ec,
                        basedir=basedir,
                    ) if has(i.__class__) else i for i in v
                ])
            elif isinstance(v, dict):
                df = dict_factory
                rv[a.name] = df((asjsonld(
                    kk,
                    dict_factory=df,
                    basedir=basedir,
                ) if has(kk.__class__) else convert_value(kk),
                                 asjsonld(
                                     vv,
                                     dict_factory=df,
                                     export_context=ec,
                                     basedir=basedir,
                                 ) if has(vv.__class__) else vv)
                                for kk, vv in iteritems(v))
            else:
                rv[a.name] = convert_value(v)
        else:
            rv[a.name] = convert_value(v)

    inst_cls = type(inst)

    if export_context:
        rv['@context'] = deepcopy(inst_cls._jsonld_context)

    if inst_cls._jsonld_type:
        rv['@type'] = inst_cls._jsonld_type
    return rv
Example #12
0
def ascwl(
    inst,
    recurse=True,
    filter=None,
    dict_factory=dict,
    retain_collection_types=False,
    basedir=None,
):
    """Return the ``attrs`` attribute values of *inst* as a dict.

    Support ``jsonldPredicate`` in a field metadata for generating
    mappings from lists.

    Adapted from ``attr._funcs``.
    """
    attrs = fields(inst.__class__)
    rv = dict_factory()

    def convert_value(v):
        """Convert special types."""
        if isinstance(v, Path):
            v = str(v)
            return os.path.relpath(v, str(basedir)) if basedir else v
        return v

    for a in attrs:
        if a.name.startswith('__'):
            continue

        a_name = a.name.rstrip('_')
        v = getattr(inst, a.name)
        if filter is not None and not filter(a, v):
            continue
        if recurse is True:
            if has(v.__class__):
                rv[a_name] = ascwl(
                    v,
                    recurse=True,
                    filter=filter,
                    dict_factory=dict_factory,
                    basedir=basedir,
                )

            elif isinstance(v, (tuple, list, set)):
                cf = v.__class__ if retain_collection_types is True else list
                rv[a_name] = cf([
                    ascwl(
                        i,
                        recurse=True,
                        filter=filter,
                        dict_factory=dict_factory,
                        basedir=basedir,
                    ) if has(i.__class__) else i for i in v
                ])

                if 'jsonldPredicate' in a.metadata:
                    k = a.metadata['jsonldPredicate'].get('mapSubject')
                    if k:
                        vv = dict_factory()
                        for i in rv[a_name]:
                            kk = i.pop(k)
                            vv[kk] = i
                        rv[a_name] = vv

            elif isinstance(v, dict):
                df = dict_factory
                rv[a_name] = df((ascwl(
                    kk,
                    dict_factory=df,
                    basedir=basedir,
                ) if has(kk.__class__) else convert_value(kk),
                                 ascwl(
                                     vv,
                                     dict_factory=df,
                                     basedir=basedir,
                                 ) if has(vv.__class__) else vv)
                                for kk, vv in iteritems(v))
            else:
                rv[a_name] = convert_value(v)
        else:
            rv[a_name] = convert_value(v)

    if isinstance(inst, CWLClass):
        rv['class'] = inst.__class__.__name__

    return rv
Example #13
0
def asjsonld(
    inst,
    recurse=True,
    filter=None,
    dict_factory=dict,
    retain_collection_types=False,
    export_context=True,
):
    """Dump a JSON-LD class to the JSON with generated ``@context`` field."""
    attrs = fields(inst.__class__)
    rv = dict_factory()

    def convert_value(v):
        """Convert special types."""
        if isinstance(v, Path):
            return str(v)
        return v

    for a in attrs:
        v = getattr(inst, a.name)
        # do not export context for containers
        ec = export_context and KEY_CLS not in a.metadata

        if filter is not None and not filter(a, v):
            continue
        if recurse is True:
            if has(v.__class__):
                rv[a.name] = asjsonld(v,
                                      recurse=True,
                                      filter=filter,
                                      dict_factory=dict_factory)
            elif isinstance(v, (tuple, list, set)):
                cf = v.__class__ if retain_collection_types is True else list
                rv[a.name] = cf([
                    asjsonld(
                        i,
                        recurse=True,
                        filter=filter,
                        dict_factory=dict_factory,
                        export_context=ec,
                    ) if has(i.__class__) else i for i in v
                ])
            elif isinstance(v, dict):
                df = dict_factory
                rv[a.name] = df((
                    asjsonld(kk, dict_factory=df) if has(kk.__class__) else kk,
                    asjsonld(vv, dict_factory=df, export_context=ec
                             ) if has(vv.__class__) else vv)
                                for kk, vv in iteritems(v))
            else:
                rv[a.name] = convert_value(v)
        else:
            rv[a.name] = convert_value(v)

    inst_cls = type(inst)

    if export_context:
        rv['@context'] = deepcopy(inst_cls._jsonld_context)

    if inst_cls._jsonld_type:
        rv['@type'] = inst_cls._jsonld_type
    return rv
Example #14
0
def asjsonld(
    inst,
    recurse=True,
    filter=None,
    dict_factory=dict,
    retain_collection_types=False,
    add_context=True,
    use_scoped_type_form=False,
    basedir=None,
):
    """Dump a JSON-LD class to the JSON with generated ``@context`` field."""
    jsonld_fields = inst.__class__._jsonld_fields
    attrs = tuple(
        field
        for field in fields(inst.__class__) if field.name in jsonld_fields
    )
    rv = dict_factory()

    def convert_value(value):
        """Convert non-serializable types."""
        if isinstance(value, Path):
            result = str(value)
            if basedir:
                result = os.path.relpath(result, str(basedir))
            return result

        if isinstance(value, datetime):
            if not value.tzinfo:
                # set timezone to local timezone
                tz = datetime.now(timezone.utc).astimezone().tzinfo
                value = value.replace(tzinfo=tz)
            return value.isoformat()

        return value

    inst_cls = type(inst)

    for a in attrs:
        v = getattr(inst, a.name)
        scoped = a.name in inst_cls._scoped_properties

        # skip proxies
        if isinstance(v, weakref.ReferenceType):
            continue

        if filter is not None and not filter(a, v):
            continue
        if recurse is True:
            if has(v.__class__):
                rv[a.name] = asjsonld(
                    v,
                    recurse=True,
                    filter=filter,
                    dict_factory=dict_factory,
                    add_context=False,
                    use_scoped_type_form=scoped,
                    basedir=basedir,
                )
            elif isinstance(v, (tuple, list, set)):
                cf = v.__class__ if retain_collection_types is True else list
                rv[a.name] = cf([
                    asjsonld(
                        i,
                        recurse=True,
                        filter=filter,
                        dict_factory=dict_factory,
                        add_context=False,
                        use_scoped_type_form=scoped,
                        basedir=basedir,
                    ) if has(i.__class__) else i for i in v
                ])
            elif isinstance(v, dict):
                df = dict_factory
                rv[a.name] = df((
                    asjsonld(
                        kk,
                        dict_factory=df,
                        add_context=False,
                        basedir=basedir,
                    ) if has(kk.__class__) else convert_value(kk),
                    asjsonld(
                        vv,
                        dict_factory=df,
                        add_context=False,
                        basedir=basedir,
                    ) if has(vv.__class__) else vv
                ) for kk, vv in iteritems(v))
            else:
                rv[a.name] = convert_value(v)
        else:
            rv[a.name] = convert_value(v)

    if add_context:
        rv['@context'] = deepcopy(inst_cls._jsonld_context)

    rv_type = []
    if inst_cls._jsonld_type:
        if isinstance(inst_cls._jsonld_type, (list, tuple, set)):
            rv_type.extend(inst_cls._jsonld_type)
        else:
            rv_type.append(inst_cls._jsonld_type)

        if use_scoped_type_form:
            rv_type = [
                '{}_{}'.format(inst_cls._renku_type, t) for t in rv_type
            ]

        rv['@type'] = rv_type[0] if len(rv_type) == 1 else rv_type

    return rv