lidatong / dataclasses-json

Easily serialize Data Classes to and from JSON
MIT License
1.34k stars 151 forks source link

[FEATURE] V1 - Implement base SerDe case for JsonSerializer[MyType] #453

Open george-zubrienko opened 11 months ago

george-zubrienko commented 11 months ago

Description

I would like to kick off some work on new API by implementing the following:

No response

Alternatives

To be discussed in the PR

Context

Suggested reviewers: @USSX-Hares , @s-vitaliy , @matt035343 and @lidatong

USSX-Hares commented 11 months ago

I have some technical questions here.

  1. Which versions of Python should we support?
  2. Should we use some new cool typing stuff? If so, should we use backports from typing-extensions?
  3. Should we hide the type hints, type checkers, and so on behind the typing.TYPE_CHECK typing.TYPE_CHECKING parameter or in the .pyi header files?
george-zubrienko commented 11 months ago

Great questions, my thoughts below

I have some technical questions here.

  1. Which versions of Python should we support?

I'm in favour of hard-locking v1 API in >=3.8

  1. Should we use some new cool typing stuff? If so, should we use a backports from typing-extensions?

I think it depends on feature state of such stuff. Stable features, why not. Re backports, I don't think we can avoid those unless min version for v1 API is set really high like 3.10, which will make it unusable for many users imo.

  1. Should we hide the type hints, type checkers, and so on behind the typing.TYPE_CHECK parameter or in the .pyi header files?

Type hints should stay imo, python code w/o them is close to being unreadable. That said, we probably should provide pyi files anyway since they help static code analyzers

USSX-Hares commented 11 months ago

Question 3 should be read as follows:

Should we keep type hints as runtime-processed annotations (see example 1); or hide them in the non-executing blocks such as if statements, header files, or annotation comments (see examples 2, 3)?

Type Annotations Code Examples ### Example 1: Executable Annotations #### code.py ```python from typing import * A = TypeVar('A') B = TypeVar('B') @overload def fn(instance: A, data: Iterable[Callable[[A], B]]) -> B: pass @overload def fn(cls: Type[A], data: Iterable[Callable[[A], B]]) -> B: pass def fn(class_or_instance: Union[A, Type[A]], data: Iterable[Callable[[A], B]]) -> B: print("Implementation!") ``` ### Example 2: Annotations in Header Files Only #### code.pyi ```python from typing import * A = TypeVar('A') B = TypeVar('B') @overload def fn(instance: A, data: Iterable[Callable[[A], B]]) -> B: pass @overload def fn(cls: Type[A], data: Iterable[Callable[[A], B]]) -> B: pass ``` ### code.py ```python def fn(class_or_instance, data): # Simple type annotation can go here, but no fancy stuff print("Implementation!") ``` ### Example 3: Annotations in Non-executable blocks #### code.py ```python from typing import TYPE_CHECKING if (TYPE_CHECKING): from typing import * A = TypeVar('A') B = TypeVar('B') @overload def fn(instance: A, data: Iterable[Callable[[A], B]]) -> B: pass @overload def fn(cls: Type[A], data: Iterable[Callable[[A], B]]) -> B: pass def fn(class_or_instance, data): # type: (A | Type[A], Iterable[Callable[[A], B]]) -> B print("Implementation!") ```

Update 2023-08-03

Corrected typos & a small syntax error in each code snippet. Now they look as intended.