]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.10] gh-102947: Improve traceback when calling `fields()` on a non-dataclass (...
authorAlex Waygood <Alex.Waygood@Gmail.com>
Thu, 23 Mar 2023 15:13:05 +0000 (15:13 +0000)
committerGitHub <noreply@github.com>
Thu, 23 Mar 2023 15:13:05 +0000 (15:13 +0000)
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 9dc67fa47708aece50192b143df019769ca597c7..1742900e653a7df793ae047a26e8562b9e9caf67 100644 (file)
@@ -1195,7 +1195,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 a642ed96c7ff5d1618c163fdeb92f56ea84ab53e..d6170eba4176d41ed8f054463a3de80308fedcfc 100644 (file)
@@ -5,10 +5,12 @@
 from dataclasses import *
 
 import abc
+import io
 import pickle
 import inspect
 import builtins
 import types
+import traceback
 import unittest
 from unittest.mock import Mock
 from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol
@@ -1414,6 +1416,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