Skip to content

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

Closed

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

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    stdlibStandard Library Python modules in the Lib/ directory
    3.11only security fixes
    3.12only security fixes
    on Mar 23, 2023
  2. self-assigned this
    on Mar 23, 2023
  3. added a commit that references this issue on Mar 23, 2023
  4. added a commit that references this issue on Mar 23, 2023
  5. added a commit that references this issue on Mar 23, 2023
  6. added a commit that references this issue on Mar 23, 2023
  7. added a commit that references this issue on Mar 23, 2023
  8. added a commit that references this issue on Mar 27, 2023
  9. added a commit that references this issue on Apr 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

3.10 (EOL)end of life3.11only security fixes3.12only security fixesstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions