Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix structuring of generic wildcats #15

Merged
merged 2 commits into from
Sep 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## v2.0.1

- Fixes error in structuring parameterized generic wildcats

# v2.0.0

Breaking changes:
Expand Down
17 changes: 16 additions & 1 deletion tests/test_wildcats.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import typing as ty

import pytest
from typecats import Cat
from typecats import Cat, struc
from typecats.exceptions import StructuringError

from data_utils import ld
Expand Down Expand Up @@ -243,3 +243,18 @@ class WithNested:
# Make sure that this particular case only works with wildcats
with pytest.raises(StructuringError):
WithNested.struc(dict(nested=Nested(i=6)))


def test_wildcat_structure_on_parametrized_generic():
# The wildcat.struc(CatObject) compatibility once broke with generics
T = ty.TypeVar("T")

@Cat
class TList(dict, ty.Generic[T]):
the_list: ty.List[T]

int_list = struc(TList[int], dict(the_list=[1, 2, 3]))
assert int_list.the_list == [1, 2, 3]

str_list = struc(TList[str], dict(the_list=["a", "b", "c"]))
assert str_list.the_list == ["a", "b", "c"]
2 changes: 1 addition & 1 deletion typecats/__about__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""typecats"""
__version__ = "2.0.0"
__version__ = "2.0.1"
__author__ = "Peter Gaultney"
__author_email__ = "pgaultney@xoi.io"
5 changes: 3 additions & 2 deletions typecats/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from attr import has as is_attrs_class
from cattrs.converters import GenConverter
from cattrs._compat import has_with_generic
from cattrs._compat import has_with_generic, get_origin, is_generic

from .wildcat import is_wildcat, enrich_structured_wildcat, enrich_unstructured_wildcat
from .strip_defaults import ShouldStripDefaults, strip_attrs_defaults
Expand All @@ -24,7 +24,8 @@ def structure_wildcat_factory(gen_converter: GenConverter, cls):
def structure_typecat(dictionary, Type):
try:
with _consolidate_exceptions(gen_converter, Type):
if is_wildcat(Type) and isinstance(dictionary, Type):
core_type = get_origin(Type) if is_generic(Type) else Type
if is_wildcat(Type) and isinstance(dictionary, core_type):
# Backwards compatibility for Cat.struc({"field": Wildcat(...)}) which worked with
# the legacy BaseConverter but no longer works with GenConverter
res = gen_converter.structure_attrs_fromdict(dictionary, Type)
Expand Down