python-attrs/cattrs

Bug with tracebacks on IPython when `detailed_validations=True`

Closed this issue · 3 comments

  • cattrs version: 24.1.2
  • Python version: 3.11
  • Operating System: Linux

Description

import attrs, cattrs

@attrs.define
class Test:
    a: int
    b: str

cattrs.structure({"a": "hello", "b": "world"}, Test)

The expected traceback is the following:

  + Exception Group Traceback (most recent call last):
  |   File "/tmp/test_cattrs.py", line 8, in <module>
  |     cattrs.structure({"a": "hello", "b": "world"}, Test)
  |   File "<redacted>/lib/python3.11/site-packages/cattrs/converters.py", line 558, in structure
  |     return self._structure_func.dispatch(cl)(obj, cl)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "<cattrs generated structure __main__.Test>", line 14, in structure_Test
  | cattrs.errors.ClassValidationError: While structuring Test (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "<cattrs generated structure __main__.Test>", line 5, in structure_Test
    | ValueError: invalid literal for int() with base 10: 'hello'
    | Structuring class Test @ attribute a
    +------------------------------------

⚠️ HOWEVER, if you execute this Python code within IPython or a Jupyter Notebook, the helpful traceback is lost, and we get another error that don't relate to the actual validation problem:

image
The following code is expected to raise an error:

Edit

When turning off detailed_validation, the error message is the expected one:
image

Hm, works for me:

ipython
Python 3.11.1 (main, Dec 16 2022, 13:37:35) [Clang 14.0.0 (clang-1400.0.29.202)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.28.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import attrs, cattrs
   ...:
   ...: @attrs.define
   ...: class Test:
   ...:     a: int
   ...:     b: str
   ...:
   ...: cattrs.structure({"a": "hello", "b": "world"}, Test)
  + Exception Group Traceback (most recent call last):
  |   File "/Users/tintvrtkovic/pg/cattrs/.venv/lib/python3.11/site-packages/IPython/core/interactiveshell.py", line 3577, in run_code
  |     exec(code_obj, self.user_global_ns, self.user_ns)
  |   File "<ipython-input-1-10a21ea11d1c>", line 8, in <module>
  |     cattrs.structure({"a": "hello", "b": "world"}, Test)
  |   File "/Users/tintvrtkovic/pg/cattrs/src/cattrs/converters.py", line 565, in structure
  |     return self._structure_func.dispatch(cl)(obj, cl)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |   File "<cattrs generated structure __main__.Test>", line 14, in structure_Test
  |     if errors: raise __c_cve('While structuring ' + 'Test', errors, __cl)
  |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  | cattrs.errors.ClassValidationError: While structuring Test (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "<cattrs generated structure __main__.Test>", line 5, in structure_Test
    |     res['a'] = __c_structure_a(o['a'])
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
    | ValueError: invalid literal for int() with base 10: 'hello'
    | Structuring class Test @ attribute a
    +------------------------------------

In any case, it's a question of ipython displaying exception groups properly, so if it didn't work you might try their issue tracker instead. I see support for this has been added in ipython/ipython@87828d3 though, so you might need to upgrade?

Apologies, I wasn't aware that Exception Group was a "new" Python mechanism (first time I encounter them), and thought it was a nice feature brought by the lib.

No need to apologize! 😉