Skip to content

Commit c3faf86

Browse files
xaviergmailTinche
andauthored
Fix: GenConverter syntax errors with certain types (#291)
* Fix: GenConverter syntax errors with certain types * Fix syntax error in generated code * Add test and snippet * Conditionally run test * Local import * Switch to old union syntax Co-authored-by: Tin Tvrtković <[email protected]>
1 parent 9b9205e commit c3faf86

File tree

3 files changed

+24
-6
lines changed

3 files changed

+24
-6
lines changed

HISTORY.rst

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ History
2121
* Expose all error classes in the `cattr.errors` namespace. Note that it is deprecated, just use `cattrs.errors`. (`#252 <https://github.com/python-attrs/cattrs/issues/252>`_)
2222
* ``cattrs.Converter`` and ``cattrs.BaseConverter`` can now copy themselves using the ``copy`` method.
2323
(`#284 <https://github.com/python-attrs/cattrs/pull/284>`_)
24+
* Fix generating structuring functions for types with quotes in the name. (`#291 <https://github.com/python-attrs/cattrs/issues/291>`_ `#277 <https://github.com/python-attrs/cattrs/issues/277>`_)
2425

2526
22.1.0 (2022-04-03)
2627
-------------------

src/cattrs/gen.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ def make_dict_structure_fn(
340340
lines.append(f"{i}except Exception as e:")
341341
i = f"{i} "
342342
lines.append(
343-
f"{i}e.__note__ = 'Structuring class {cl.__qualname__} @ attribute {an}'"
343+
f"{i}e.__note__ = 'Structuring class ' + {cl.__qualname__!r} + ' @ attribute {an}'"
344344
)
345345
lines.append(f"{i}errors.append(e)")
346346

@@ -352,15 +352,15 @@ def make_dict_structure_fn(
352352
]
353353

354354
post_lines.append(
355-
f" if errors: raise __c_cve('While structuring {cl.__name__}', errors, __cl)"
355+
f" if errors: raise __c_cve('While structuring ' + {cl.__name__!r}, errors, __cl)"
356356
)
357357
instantiation_lines = (
358358
[" try:"]
359359
+ [" return __cl("]
360360
+ [f" {line}" for line in invocation_lines]
361361
+ [" )"]
362362
+ [
363-
f" except Exception as exc: raise __c_cve('While structuring {cl.__name__}', [exc], __cl)"
363+
f" except Exception as exc: raise __c_cve('While structuring ' + {cl.__name__!r}, [exc], __cl)"
364364
]
365365
)
366366
else:
@@ -717,7 +717,7 @@ def make_mapping_structure_fn(
717717
lines.append(" errors.append(e)")
718718
lines.append(" if errors:")
719719
lines.append(
720-
f" raise IterableValidationError('While structuring {cl!r}', errors, __cattr_mapping_cl)"
720+
f" raise IterableValidationError('While structuring ' + {repr(cl)!r}, errors, __cattr_mapping_cl)"
721721
)
722722
else:
723723
lines.append(f" res = {{{k_s}: {v_s} for k, v in mapping.items()}}")

tests/test_gen_dict.py

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""Tests for generated dict functions."""
2-
from typing import Type
2+
from typing import Dict, Type
33

44
import pytest
55
from attr import Factory, define, field
@@ -8,7 +8,7 @@
88
from hypothesis.strategies import data, just, one_of, sampled_from
99

1010
from cattrs import BaseConverter, Converter
11-
from cattrs._compat import adapted_fields, fields
11+
from cattrs._compat import adapted_fields, fields, is_py39_plus
1212
from cattrs.errors import ClassValidationError, ForbiddenExtraKeysError
1313
from cattrs.gen import make_dict_structure_fn, make_dict_unstructure_fn, override
1414

@@ -287,3 +287,20 @@ class A:
287287
assert structured.a == 1
288288
assert structured.c == 1
289289
assert not hasattr(structured, "b")
290+
291+
292+
@pytest.mark.skipif(not is_py39_plus, reason="literals and annotated are 3.9+")
293+
def test_type_names_with_quotes():
294+
"""Types with quote characters in their reprs should work."""
295+
from typing import Annotated, Literal, Union
296+
297+
converter = Converter()
298+
299+
assert converter.structure({1: 1}, Dict[Annotated[int, "'"], int]) == {1: 1}
300+
301+
converter.register_structure_hook_func(
302+
lambda t: t is Union[Literal["a", 2, 3], Literal[4]], lambda v, _: v
303+
)
304+
assert converter.structure(
305+
{2: "a"}, Dict[Union[Literal["a", 2, 3], Literal[4]], str]
306+
) == {2: "a"}

0 commit comments

Comments
 (0)