Skip to content

Bad traceback when dataclasses.fields is called on a non-dataclass #102947

Closed
@AlexWaygood

Description

@AlexWaygood

Currently, if you call dataclasses.fields on a non-dataclass, quite a poor traceback is produced:

>>> import dataclasses
>>> dataclasses.fields(object)
Traceback (most recent call last):
  File "C:\Users\alexw\AppData\Local\Programs\Python\Python311\Lib\dataclasses.py", line 1232, in fields
    fields = getattr(class_or_instance, _FIELDS)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: type object 'object' has no attribute '__dataclass_fields__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\alexw\AppData\Local\Programs\Python\Python311\Lib\dataclasses.py", line 1234, in fields
    raise TypeError('must be called with a dataclass type or instance')
TypeError: must be called with a dataclass type or instance

There are two issues here:

  • The traceback mentions the __dataclass_fields__ attribute, which is an internal implementation detail of the dataclasses module and should be hidden from the user.
  • The "during handling of the above exception, another exception occurred" message implies to the user that there's a bug in the dataclasses module itself, rather than this being intentional behaviour.

This one-line change to dataclasses.py produces a much better traceback:

diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py
index 82b08fc017..e3fd0b3e38 100644
--- a/Lib/dataclasses.py
+++ b/Lib/dataclasses.py
@@ -1248,7 +1248,7 @@ def fields(class_or_instance):
     try:
         fields = getattr(class_or_instance, _FIELDS)
     except AttributeError:
-        raise TypeError('must be called with a dataclass type or instance')
+        raise TypeError('must be called with a dataclass type or instance') from None

With this change applied, we get this traceback instead:

>>> import dataclasses
>>> dataclasses.fields(object)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\alexw\coding\cpython\Lib\dataclasses.py", line 1251, in fields
    raise TypeError('must be called with a dataclass type or instance') from None
TypeError: must be called with a dataclass type or instance

Cc. @ericvsmith and @carljm, as dataclasses experts.

Linked PRs

Metadata

Metadata

Assignees

Labels

3.10only security fixes3.11only security fixes3.12only security fixesstdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions