Skip to content

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

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

Closed
AlexWaygood opened this issue Mar 23, 2023 · 0 comments
Closed

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

AlexWaygood opened this issue Mar 23, 2023 · 0 comments
Assignees
Labels
3.10 only security fixes 3.11 only security fixes 3.12 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@AlexWaygood
Copy link
Member

AlexWaygood commented Mar 23, 2023

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

@AlexWaygood AlexWaygood added type-bug An unexpected behavior, bug, or error stdlib Python modules in the Lib dir 3.11 only security fixes 3.10 only security fixes 3.12 only security fixes labels Mar 23, 2023
@AlexWaygood AlexWaygood self-assigned this Mar 23, 2023
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Mar 23, 2023
…ataclass (pythonGH-102948)

(cherry picked from commit baf4eb0)

Co-authored-by: Alex Waygood <[email protected]>
AlexWaygood added a commit to AlexWaygood/cpython that referenced this issue Mar 23, 2023
miss-islington added a commit that referenced this issue Mar 23, 2023
…ss (GH-102948)

(cherry picked from commit baf4eb0)

Co-authored-by: Alex Waygood <[email protected]>
Fidget-Spinner pushed a commit to Fidget-Spinner/cpython that referenced this issue Mar 27, 2023
warsaw pushed a commit to warsaw/cpython that referenced this issue Apr 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.10 only security fixes 3.11 only security fixes 3.12 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

1 participant