| import functools |
| from enum import Enum |
| from typing import Callable, Dict, Optional, TypeVar, Union |
|
|
| from marshmallow.fields import Field as MarshmallowField |
|
|
| from dataclasses_json.stringcase import (camelcase, pascalcase, snakecase, |
| spinalcase) |
| from dataclasses_json.undefined import Undefined, UndefinedParameterError |
|
|
| T = TypeVar("T") |
|
|
|
|
| class Exclude: |
| """ |
| Pre-defined constants for exclusion. By default, fields are configured to |
| be included. |
| """ |
| ALWAYS: Callable[[object], bool] = lambda _: True |
| NEVER: Callable[[object], bool] = lambda _: False |
|
|
|
|
| |
| class _GlobalConfig: |
|
|
| def __init__(self): |
| self.encoders: Dict[Union[type, Optional[type]], Callable] = {} |
| self.decoders: Dict[Union[type, Optional[type]], Callable] = {} |
| self.mm_fields: Dict[ |
| Union[type, Optional[type]], |
| MarshmallowField |
| ] = {} |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| global_config = _GlobalConfig() |
|
|
|
|
| class LetterCase(Enum): |
| CAMEL = camelcase |
| KEBAB = spinalcase |
| SNAKE = snakecase |
| PASCAL = pascalcase |
|
|
|
|
| def config(metadata: Optional[dict] = None, *, |
| |
| |
| encoder: Optional[Callable] = None, |
| decoder: Optional[Callable] = None, |
| mm_field: Optional[MarshmallowField] = None, |
| letter_case: Union[Callable[[str], str], LetterCase, None] = None, |
| undefined: Optional[Union[str, Undefined]] = None, |
| field_name: Optional[str] = None, |
| exclude: Optional[Callable[[T], bool]] = None, |
| ) -> Dict[str, dict]: |
| if metadata is None: |
| metadata = {} |
|
|
| lib_metadata = metadata.setdefault('dataclasses_json', {}) |
|
|
| if encoder is not None: |
| lib_metadata['encoder'] = encoder |
|
|
| if decoder is not None: |
| lib_metadata['decoder'] = decoder |
|
|
| if mm_field is not None: |
| lib_metadata['mm_field'] = mm_field |
|
|
| if field_name is not None: |
| if letter_case is not None: |
| @functools.wraps(letter_case) |
| def override(_, _letter_case=letter_case, _field_name=field_name): |
| return _letter_case(_field_name) |
| else: |
| def override(_, _field_name=field_name): |
| return _field_name |
| letter_case = override |
|
|
| if letter_case is not None: |
| lib_metadata['letter_case'] = letter_case |
|
|
| if undefined is not None: |
| |
| if isinstance(undefined, str): |
| if not hasattr(Undefined, undefined.upper()): |
| valid_actions = list(action.name for action in Undefined) |
| raise UndefinedParameterError( |
| f"Invalid undefined parameter action, " |
| f"must be one of {valid_actions}") |
| undefined = Undefined[undefined.upper()] |
|
|
| lib_metadata['undefined'] = undefined |
|
|
| if exclude is not None: |
| lib_metadata['exclude'] = exclude |
|
|
| return metadata |
|
|