usse/scrape/venv/lib/python3.10/site-packages/cattrs/gen/_generics.py

44 lines
1.5 KiB
Python
Raw Normal View History

2023-12-22 14:26:01 +00:00
from __future__ import annotations
from typing import TypeVar
from .._compat import get_args, get_origin, is_generic
def generate_mapping(cl: type, old_mapping: dict[str, type] = {}) -> dict[str, type]:
mapping = {}
origin = get_origin(cl)
if origin is not None:
# To handle the cases where classes in the typing module are using
# the GenericAlias structure but aren't a Generic and hence
# end up in this function but do not have an `__parameters__`
# attribute. These classes are interface types, for example
# `typing.Hashable`.
parameters = getattr(get_origin(cl), "__parameters__", None)
if parameters is None:
return dict(old_mapping)
for p, t in zip(parameters, get_args(cl)):
if isinstance(t, TypeVar):
continue
mapping[p.__name__] = t
if not mapping:
return dict(old_mapping)
elif is_generic(cl):
# Origin is None, so this may be a subclass of a generic class.
orig_bases = cl.__orig_bases__
for base in orig_bases:
if not hasattr(base, "__args__"):
continue
base_args = base.__args__
if not hasattr(base.__origin__, "__parameters__"):
continue
base_params = base.__origin__.__parameters__
for param, arg in zip(base_params, base_args):
mapping[param.__name__] = arg
return mapping