bpo-45663: Fix is_dataclass() for dataclasses which are subclasses of types.GenericAlias (GH-29294)

(cherry picked from commit 446be16686)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
Miss Islington (bot) 2021-12-05 13:25:43 -08:00 committed by GitHub
parent 52a9a71fe6
commit 19050711f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 1 deletions

View file

@ -1047,7 +1047,7 @@ def _is_dataclass_instance(obj):
def is_dataclass(obj): def is_dataclass(obj):
"""Returns True if obj is a dataclass or an instance of a """Returns True if obj is a dataclass or an instance of a
dataclass.""" dataclass."""
cls = obj if isinstance(obj, type) else type(obj) cls = obj if isinstance(obj, type) and not isinstance(obj, GenericAlias) else type(obj)
return hasattr(cls, _FIELDS) return hasattr(cls, _FIELDS)

View file

@ -7,6 +7,7 @@ from dataclasses import *
import pickle import pickle
import inspect import inspect
import builtins import builtins
import types
import unittest import unittest
from unittest.mock import Mock from unittest.mock import Mock
from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol
@ -1348,6 +1349,17 @@ class TestCase(unittest.TestCase):
with self.assertRaisesRegex(TypeError, 'should be called on dataclass instances'): with self.assertRaisesRegex(TypeError, 'should be called on dataclass instances'):
replace(obj, x=0) replace(obj, x=0)
def test_is_dataclass_genericalias(self):
@dataclass
class A(types.GenericAlias):
origin: type
args: type
self.assertTrue(is_dataclass(A))
a = A(list, int)
self.assertTrue(is_dataclass(type(a)))
self.assertTrue(is_dataclass(a))
def test_helper_fields_with_class_instance(self): def test_helper_fields_with_class_instance(self):
# Check that we can call fields() on either a class or instance, # Check that we can call fields() on either a class or instance,
# and get back the same thing. # and get back the same thing.

View file

@ -0,0 +1,2 @@
Fix :func:`dataclasses.is_dataclass` for dataclasses which are subclasses of
:class:`types.GenericAlias`.