def build_schema(cls: typing.Type[A], mixin, infer_missing, partial) -> typing.Type[SchemaType]: Meta = type( 'Meta', (), { 'fields': tuple(field.name for field in dc_fields(cls) if field.name != 'dataclass_json_config') }) @post_load def make_instance(self, kvs): return _decode_dataclass(cls, kvs, partial) def dumps(self, *args, **kwargs): if 'cls' not in kwargs: kwargs['cls'] = _ExtendedEncoder return Schema.dumps(self, *args, **kwargs) schema_ = schema(cls, mixin, infer_missing) DataClassSchema: typing.Type[SchemaType] = type( f'{cls.__name__.capitalize()}Schema', (Schema, ), { 'Meta': Meta, f'make_{cls.__name__.lower()}': make_instance, 'dumps': dumps, **schema_ }) return DataClassSchema
def schema(cls, mixin, infer_missing): schema = {} for field in dc_fields(cls): if 'dc_json' in (field.metadata or {}): schema[field.name] = field.metadata['dc_json'].get('mm_field') else: type_ = field.type options = {} missing_key = 'missing' if infer_missing else 'default' if field.default is not MISSING: options[missing_key] = field.default elif field.default_factory is not MISSING: options[missing_key] = field.default_factory if options.get(missing_key, ...) is None: options['allow_none'] = True if _is_optional(type_): options.setdefault(missing_key, None) type_ = type_.__args__[0] options['allow_none'] = True t = build_type(type_, options, mixin, field, cls) #if type(t) is not fields.Field: # If we use `isinstance` we would return nothing. schema[field.name] = t return schema
def schema(cls, mixin, infer_missing): schema = {} for field in dc_fields(cls): metadata = (field.metadata or {}).get('dataclasses_json', {}) if 'mm_field' in metadata: schema[field.name] = metadata['mm_field'] else: type_ = field.type options = {} missing_key = 'missing' if infer_missing else 'default' if field.default is not MISSING: options[missing_key] = field.default elif field.default_factory is not MISSING: options[missing_key] = field.default_factory if options.get(missing_key, ...) is None: options['allow_none'] = True if _is_optional(type_): options.setdefault(missing_key, None) options['allow_none'] = True if len(type_.__args__) == 2: # Union[str, int, None] is optional too, but it has more than 1 typed field. type_ = type_.__args__[0] t = build_type(type_, options, mixin, field, cls) # if type(t) is not fields.Field: # If we use `isinstance` we would return nothing. schema[field.name] = t return schema
def parse_gpg_errors(status_out): # type: (str) -> t.Iterator[GpgBaseError] for line in status_out.splitlines(): if not line: continue try: _dummy, status, remainder = line.split(maxsplit=2) except ValueError: _dummy, status = line.split(maxsplit=1) remainder = None try: cls = GPG_ERROR_MAP[status] except KeyError: continue fields = [status] if remainder: fields.extend( remainder.split( None, len(dc_fields(cls)) - 2 ) ) yield cls(*fields)
def build_schema(cls: typing.Type[A], mixin, infer_missing, partial) -> typing.Type[SchemaType]: Meta = type( 'Meta', (), { 'fields': tuple(field.name for field in dc_fields(cls) if field.name != 'dataclass_json_config' and field.type != typing.Optional[CatchAllVar]), # TODO #180 # 'render_module': global_config.json_module }) @post_load def make_instance(self, kvs, **kwargs): return _decode_dataclass(cls, kvs, partial) def dumps(self, *args, **kwargs): if 'cls' not in kwargs: kwargs['cls'] = _ExtendedEncoder return Schema.dumps(self, *args, **kwargs) def dump(self, obj, *, many=None): many = self.many if many is None else bool(many) dumped = Schema.dump(self, obj, many=many) # TODO This is hacky, but the other option I can think of is to generate a different schema # depending on dump and load, which is even more hacky # The only problem is the catch all field, we can't statically create a schema for it # so we just update the dumped dict if many: for i, _obj in enumerate(obj): dumped[i].update( _handle_undefined_parameters_safe(cls=_obj, kvs={}, usage="dump")) else: dumped.update( _handle_undefined_parameters_safe(cls=obj, kvs={}, usage="dump")) return dumped schema_ = schema(cls, mixin, infer_missing) DataClassSchema: typing.Type[SchemaType] = type( f'{cls.__name__.capitalize()}Schema', (Schema, ), { 'Meta': Meta, f'make_{cls.__name__.lower()}': make_instance, 'dumps': dumps, 'dump': dump, **schema_ }) return DataClassSchema
def _get_schema_dict(schema: Type[Schema], settings: _SchemaGenSettings) -> Dict[str, Any]: """Monkey-patches marshmallow fields to schema""" class_dict: Dict[str, Any] = dict() if sys.version_info[:2] >= (3, 7): class_typevar_mapping(settings.data_class, settings.type_var_index) this_field: DCField for this_field in dc_fields(settings.data_class): class_dict[this_field.name] = _convert_type(this_field, settings) if issubclass(schema, DataSchemaConcrete): class_dict["__model__"] = settings.data_class f: DCField class_dict["_dump_only"] = [ f.name for f in dc_fields(settings.data_class) if f.metadata is not None and f.metadata.get("garams", Garams()).dump_only ] return class_dict
def build_schema(cls, mixin, infer_missing, partial): Meta = type('Meta', (), {'fields': tuple(field.name for field in dc_fields(cls))}) @post_load def make_instance(self, kvs): return _decode_dataclass(cls, kvs, partial) schema_ = schema(cls, mixin, infer_missing) DataClassSchema = type(f'{cls.__name__.capitalize()}Schema', (Schema, ), { 'Meta': Meta, f'make_{cls.__name__.lower()}': make_instance, **schema_ }) return DataClassSchema
def create_simple_dataclass_from_dict( input_dict: Dict, dataclass: Type) -> Any: buffer = {} for field in dc_fields(dataclass): value = input_dict.get(field.name, MISSING) typ = field.type if value is MISSING: if hasattr(typ, '__args__') and type(None) in typ.__args__: buffer[field.name] = None continue if hasattr(typ, '__args__'): typ = typ.__args__[0] if typ in (str, int, float, bool): value = typ(value) buffer[field.name] = value return dataclass(**buffer)
def schema(cls, mixin, infer_missing): schema = {} overrides = _user_overrides(cls) # TODO check the undefined parameters and add the proper schema action # https://marshmallow.readthedocs.io/en/stable/quickstart.html for field in dc_fields(cls): metadata = (field.metadata or {}).get('dataclasses_json', {}) metadata = overrides[field.name] if metadata.mm_field is not None: schema[field.name] = metadata.mm_field else: type_ = field.type options = {} missing_key = 'missing' if infer_missing else 'default' if field.default is not MISSING: options[missing_key] = field.default elif field.default_factory is not MISSING: options[missing_key] = field.default_factory if options.get(missing_key, ...) is None: options['allow_none'] = True if _is_optional(type_): options.setdefault(missing_key, None) options['allow_none'] = True if len(type_.__args__) == 2: # Union[str, int, None] is optional too, but it has more than 1 typed field. type_ = type_.__args__[0] if metadata.letter_case is not None: options['data_key'] = metadata.letter_case(field.name) t = build_type(type_, options, mixin, field, cls) # if type(t) is not fields.Field: # If we use `isinstance` we would return nothing. if field.type != typing.Optional[CatchAllVar]: schema[field.name] = t return schema
def __post_init__(self): for field in dc_fields(self): super(GpgBaseError, self).__setattr__(field.name, field.type(getattr(self, field.name)))
def data_class_fields(class_or_instance: Any): x = extract_type_from_possible_optional_type( possible_optional_type=class_or_instance) return dc_fields(class_or_instance=x)