MCPcopy Create free account
hub / github.com/aboutcode-org/scancode-toolkit / from_dict

Method from_dict

src/packagedcode/models.py:891–952  ·  view source on GitHub ↗

Return an instance of PackageData built from a ``mapping`` native Python data. Known attributes that store a list of objects are also "rehydrated" (such as models.Party). Unknown attributes provided in ``mapping`` that do not exist as fields in the class are

(cls, mapping)

Source from the content-addressed store, hash-verified

889
890 @classmethod
891 def from_dict(cls, mapping):
892 """
893 Return an instance of PackageData built from a ``mapping`` native Python
894 data. Known attributes that store a list of objects are also
895 "rehydrated" (such as models.Party).
896
897 Unknown attributes provided in ``mapping`` that do not exist as fields
898 in the class are kept as items in the extra_data mapping. An Exception
899 is raised if an "unknown attribute" name already exists as an extra_data
900 name.
901 """
902 # TODO: consider using a proper library for this such as cattrs,
903 # marshmallow, etc. or use the field type that we declare.
904
905 # Each of these are lists of class instances tracked here, which are stored
906 # as a list of mappings in scanc_data
907
908 # these are computed attributes serialized on a package
909 # that should not be recreated when de-serializing
910 computed_attributes = set(['purl', ])
911
912 fields_by_name = attr.fields_dict(cls)
913
914 extra_data = mapping.get('extra_data', {}) or {}
915 package_data = {}
916
917 list_fields_by_item = {
918 'parties': Party,
919 'dependencies': DependentPackage,
920 'file_references': FileReference,
921 }
922
923 for name, value in mapping.items():
924 if not value:
925 continue
926
927 if name in computed_attributes:
928 continue
929
930 field = fields_by_name.get(name)
931 if not field:
932 # keep unknown fields as extra data
933 if name not in extra_data:
934 extra_data[name] = value
935 continue
936 else:
937 raise Exception(
938 f'Invalid package "scan_data" with duplicated name: {name!r}={value!r} '
939 f'present both as attribute AND as extra_data: {name!r}={extra_data[name]!r}'
940 )
941
942 # re-hydrate lists of typed objects
943 list_item_type = is_list_field = list_fields_by_item.get(name)
944
945 if is_list_field:
946 items = list(_rehydrate_list(cls=list_item_type, values=value))
947 package_data[name] = items
948 else:

Callers

nothing calls this directly

Calls 3

_rehydrate_listFunction · 0.85
getMethod · 0.65
from_dictMethod · 0.45

Tested by

no test coverage detected