-
-
Notifications
You must be signed in to change notification settings - Fork 129
Description
- cattrs version: 23.1.2
- Python version: 3.8.17
- Operating System: Linux
Description
Cattrs fails to structure an object that contains a typing_extensions.Literal.
I know cattrs only supports 3.8 and up, and typing in 3.8 has Literal, so the current support is probably considered complete. However, there's a pretty common use case that this leaves out - where an application running on 3.8 imports a library that is still targeted at 3.7-level code (or simply hasn't been upgraded/refactored to use typing.Literal).
Proposal
Could we modify _compat to do something like what typing-inspect does?
from typing import Literal
LITERALS = {Literal}
try:
from typing_extensions import Literal as te_Literal
LITERALS.add(te_Literal)
except ModuleNotFoundError:
pass
if version >= 3.9:
def is_literal(type):
return type in LITERALS or type.__class__ is _LiteralGenericAlias or (isinstance(type, _GenericAlias) and type.__origin__ in LITERALS)
else: # 3.8
def is_literal(type) -> bool:
return type in LITERALS or (isinstance(type, _GenericAlias) and type.__origin__ in LITERALS)
typing_extensions.Literal does still seem to support typing.get_args, so the rest of the code should work fine.
Maybe this opens a can of worms as far as supporting other typing_extensions things, but in my limited experience, Literal is one of the main reasons people ever used to reach for typing_extensions when static typing was a relatively new thing, so it might be nice to support handling those old-style Literals transparently instead of requiring structure hooks to be registered for all of them.