python-attrs / cattrs

Composable custom class converters for attrs, dataclasses and friends.
https://catt.rs
MIT License
781 stars 108 forks source link

support typing_extensions Literal #460

Closed petergaultney closed 7 months ago

petergaultney commented 7 months ago

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.

petergaultney commented 7 months ago

maybe slightly ironically, it appears that cattrs itself still uses typing_extensions.Literal. ;)

Tinche commented 7 months ago

If you put a PR together I'd be ok with merging it in, I don't think this is a huge burden to bear if it's useful to someone.

gorkaerana commented 7 months ago

I'd be happy to help with the PR in any shape or form :)

petergaultney commented 7 months ago

thanks y'all. take a look at #467 and see what you think. Hopefully CI will pass...