Skip to content

support typing_extensions Literal #460

Closed
@petergaultney

Description

@petergaultney
  • 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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions