]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-102947: Improve traceback when calling `fields()` on a non-dataclass (GH-102948)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Thu, 23 Mar 2023 14:45:59 +0000 (07:45 -0700)
committerGitHub <noreply@github.com>
Thu, 23 Mar 2023 14:45:59 +0000 (07:45 -0700)
(cherry picked from commit baf4eb083c09b323cc12b8636c28c14089b87de8)

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Lib/dataclasses.py
Lib/test/test_dataclasses.py
Misc/NEWS.d/next/Library/2023-03-23-13-34-33.gh-issue-102947.cTwcpU.rst [new file with mode: 0644]

index d2af451efed5065960f9e758b164e35d9c6eeae7..221ea2ba3e77c3a36a62d6fd7f0c5fa5f5fd29e3 100644 (file)
@@ -1234,7 +1234,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
 
     # Exclude pseudo-fields.  Note that fields is sorted by insertion
     # order, so the order of the tuple is as the fields were defined.
index 3a247776e5f42c49810abd1a902a0fd13e1a1f28..abe02e3b1ab6dfa775d534a5c5ebff2948284992 100644 (file)
@@ -5,11 +5,13 @@
 from dataclasses import *
 
 import abc
+import io
 import pickle
 import inspect
 import builtins
 import types
 import weakref
+import traceback
 import unittest
 from unittest.mock import Mock
 from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol
@@ -1500,6 +1502,16 @@ class TestCase(unittest.TestCase):
         with self.assertRaisesRegex(TypeError, 'dataclass type or instance'):
             fields(C())
 
+    def test_clean_traceback_from_fields_exception(self):
+        stdout = io.StringIO()
+        try:
+            fields(object)
+        except TypeError as exc:
+            traceback.print_exception(exc, file=stdout)
+        printed_traceback = stdout.getvalue()
+        self.assertNotIn("AttributeError", printed_traceback)
+        self.assertNotIn("__dataclass_fields__", printed_traceback)
+
     def test_helper_asdict(self):
         # Basic tests for asdict(), it should return a new dictionary.
         @dataclass
diff --git a/Misc/NEWS.d/next/Library/2023-03-23-13-34-33.gh-issue-102947.cTwcpU.rst b/Misc/NEWS.d/next/Library/2023-03-23-13-34-33.gh-issue-102947.cTwcpU.rst
new file mode 100644 (file)
index 0000000..b59c982
--- /dev/null
@@ -0,0 +1,2 @@
+Improve traceback when :func:`dataclasses.fields` is called on a
+non-dataclass. Patch by Alex Waygood