From 5dcf523ce2a28eaf6f93fae61d259dda9ad9f491 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Thu, 26 Sep 2024 19:36:35 +0300 Subject: [PATCH] Address review --- Lib/test/test_unittest/testmock/testhelpers.py | 10 ++++++---- Lib/unittest/mock.py | 9 ++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_unittest/testmock/testhelpers.py b/Lib/test/test_unittest/testmock/testhelpers.py index 54bb0f7acc2e8e..b8beeb34e72023 100644 --- a/Lib/test/test_unittest/testmock/testhelpers.py +++ b/Lib/test/test_unittest/testmock/testhelpers.py @@ -8,8 +8,10 @@ Mock, ANY, _CallList, patch, PropertyMock, _callable ) +from dataclasses import dataclass, field, InitVar from datetime import datetime from functools import partial +from typing import ClassVar class SomeClass(object): def one(self, a, b): pass @@ -1034,10 +1036,7 @@ def f(a): pass self.assertEqual(mock.mock_calls, []) self.assertEqual(rv.mock_calls, []) - def test_dataclass(self): - from dataclasses import dataclass, field, InitVar - from typing import ClassVar - + def test_dataclass_post_init(self): @dataclass class WithPostInit: a: int = field(init=False) @@ -1062,6 +1061,7 @@ def __post_init__(self): with self.assertRaisesRegex(AttributeError, msg): mock.b + def test_dataclass_default(self): @dataclass class WithDefault: a: int @@ -1075,6 +1075,7 @@ class WithDefault: self.assertIsInstance(mock.a, int) self.assertIsInstance(mock.b, int) + def test_dataclass_with_method(self): @dataclass class WithMethod: a: int @@ -1089,6 +1090,7 @@ def b(self) -> int: self.assertIsInstance(mock.a, int) mock.b.assert_not_called() + def test_dataclass_with_non_fields(self): @dataclass class WithNonFields: a: ClassVar[int] diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 53bca8f663c1ff..d68a59b1eff8e7 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -34,6 +34,7 @@ import pkgutil from inspect import iscoroutinefunction import threading +from dataclasses import fields, is_dataclass from types import CodeType, ModuleType, MethodType from unittest.util import safe_repr from functools import wraps, partial @@ -2755,12 +2756,10 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, f'[object={spec!r}]') is_async_func = _is_async_func(spec) - placeholder = object() - entries = [(entry, placeholder) for entry in dir(spec)] + entries = [(entry, _missing) for entry in dir(spec)] # Not using `is_dataclass` to avoid an import of dataclasses module # for types that don't need that. - if is_type and instance and hasattr(spec, '__dataclass_fields__'): - from dataclasses import fields + if is_type and instance and is_dataclass(spec): dataclass_fields = fields(spec) entries.extend((f.name, f.type) for f in dataclass_fields) _kwargs = {'spec': [f.name for f in dataclass_fields]} @@ -2837,7 +2836,7 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, # AttributeError on being fetched? # we could be resilient against it, or catch and propagate the # exception when the attribute is fetched from the mock - if original is placeholder: + if original is _missing: try: original = getattr(spec, entry) except AttributeError: