1818 Set ,
1919 Tuple ,
2020 Type ,
21+ TypeVar ,
2122 Union ,
2223 get_type_hints ,
2324 overload ,
3233SerializedType = Union [str , bool , int , float , list , dict , None ]
3334
3435
35- Serializer = Callable [[Type ], SerializedType ]
36+ Serializer = Callable [[Any ], SerializedType ]
3637
3738
3839SERIALIZERS : dict [Type , Serializer ] = {}
3940SERIALIZER_TYPES : dict [Type , Type ] = {}
4041
42+ SERIALIZED_FUNCTION = TypeVar ("SERIALIZED_FUNCTION" , bound = Serializer )
4143
44+
45+ @overload
46+ def serializer (
47+ fn : None = None ,
48+ to : Type [SerializedType ] | None = None ,
49+ ) -> Callable [[SERIALIZED_FUNCTION ], SERIALIZED_FUNCTION ]: ...
50+
51+
52+ @overload
4253def serializer (
43- fn : Serializer | None = None ,
44- to : Type | None = None ,
45- ) -> Serializer :
54+ fn : SERIALIZED_FUNCTION ,
55+ to : Type [SerializedType ] | None = None ,
56+ ) -> SERIALIZED_FUNCTION : ...
57+
58+
59+ def serializer (
60+ fn : SERIALIZED_FUNCTION | None = None ,
61+ to : Any = None ,
62+ ) -> SERIALIZED_FUNCTION | Callable [[SERIALIZED_FUNCTION ], SERIALIZED_FUNCTION ]:
4663 """Decorator to add a serializer for a given type.
4764
4865 Args:
@@ -51,43 +68,44 @@ def serializer(
5168
5269 Returns:
5370 The decorated function.
54-
55- Raises:
56- ValueError: If the function does not take a single argument.
5771 """
58- if fn is None :
59- # If the function is not provided, return a partial that acts as a decorator.
60- return functools .partial (serializer , to = to ) # type: ignore
61-
62- # Check the type hints to get the type of the argument.
63- type_hints = get_type_hints (fn )
64- args = [arg for arg in type_hints if arg != "return" ]
65-
66- # Make sure the function takes a single argument.
67- if len (args ) != 1 :
68- raise ValueError ("Serializer must take a single argument." )
69-
70- # Get the type of the argument.
71- type_ = type_hints [args [0 ]]
72-
73- # Make sure the type is not already registered.
74- registered_fn = SERIALIZERS .get (type_ )
75- if registered_fn is not None and registered_fn != fn :
76- raise ValueError (
77- f"Serializer for type { type_ } is already registered as { registered_fn .__qualname__ } ."
78- )
79-
80- # Apply type transformation if requested
81- if to is not None or ((to := type_hints .get ("return" )) is not None ):
82- SERIALIZER_TYPES [type_ ] = to
83- get_serializer_type .cache_clear ()
84-
85- # Register the serializer.
86- SERIALIZERS [type_ ] = fn
87- get_serializer .cache_clear ()
88-
89- # Return the function.
90- return fn
72+
73+ def wrapper (fn : SERIALIZED_FUNCTION ) -> SERIALIZED_FUNCTION :
74+ # Check the type hints to get the type of the argument.
75+ type_hints = get_type_hints (fn )
76+ args = [arg for arg in type_hints if arg != "return" ]
77+
78+ # Make sure the function takes a single argument.
79+ if len (args ) != 1 :
80+ raise ValueError ("Serializer must take a single argument." )
81+
82+ # Get the type of the argument.
83+ type_ = type_hints [args [0 ]]
84+
85+ # Make sure the type is not already registered.
86+ registered_fn = SERIALIZERS .get (type_ )
87+ if registered_fn is not None and registered_fn != fn :
88+ raise ValueError (
89+ f"Serializer for type { type_ } is already registered as { registered_fn .__qualname__ } ."
90+ )
91+
92+ to_type = to or type_hints .get ("return" )
93+
94+ # Apply type transformation if requested
95+ if to_type :
96+ SERIALIZER_TYPES [type_ ] = to_type
97+ get_serializer_type .cache_clear ()
98+
99+ # Register the serializer.
100+ SERIALIZERS [type_ ] = fn
101+ get_serializer .cache_clear ()
102+
103+ # Return the function.
104+ return fn
105+
106+ if fn is not None :
107+ return wrapper (fn )
108+ return wrapper
91109
92110
93111@overload
0 commit comments