Update unittest to 3.14.4 (#7752)

* Update `unittest` from 3.14.4

* Update `test_unittest` to 3.14.4

* Unmark passing test
This commit is contained in:
Shahar Naveh
2026-05-01 14:06:24 +03:00
committed by GitHub
parent f6e2fcffe7
commit 9004089fd1
39 changed files with 367 additions and 175 deletions

View File

@@ -1,5 +1,4 @@
import os.path
from test.support import load_package_tests

View File

@@ -1,5 +1,4 @@
from . import load_tests
import unittest
from . import load_tests
unittest.main()

View File

@@ -14,7 +14,6 @@ import sys
import unittest
import warnings
def warnfun():
warnings.warn('rw', RuntimeWarning)

View File

@@ -0,0 +1,5 @@
import unittest
class PassingTest(unittest.TestCase):
def test_true(self):
self.assertTrue(True)

View File

@@ -0,0 +1,5 @@
import unittest
class PassingTest(unittest.TestCase):
def test_true(self):
self.assertTrue(True)

View File

@@ -0,0 +1,5 @@
import unittest
class PassingTest(unittest.TestCase):
def test_true(self):
self.assertTrue(True)

View File

@@ -0,0 +1,5 @@
import unittest
class PassingTest(unittest.TestCase):
def test_true(self):
self.assertTrue(True)

View File

@@ -1,10 +1,9 @@
import datetime
import unittest
import warnings
import weakref
from itertools import product
import unittest
from test.support import gc_collect
from itertools import product
class Test_Assertions(unittest.TestCase):

View File

@@ -1,7 +1,6 @@
import asyncio
import contextvars
import unittest
from test import support
from test.support import force_not_colorized
@@ -297,7 +296,7 @@ class TestAsyncCase(unittest.TestCase):
test.doCleanups()
self.assertEqual(events, ['asyncSetUp', 'test', 'asyncTearDown', 'cleanup2', 'cleanup1'])
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_deprecation_of_return_val_from_test(self):
# Issue 41322 - deprecate return of value that is not None from a test
class Nothing:

View File

@@ -1,10 +1,10 @@
import gc
import io
import os
import signal
import sys
import unittest
import signal
import weakref
import unittest
from test import support

View File

@@ -1,27 +1,27 @@
import contextlib
import difflib
import inspect
import logging
import pickle
import pprint
import pickle
import re
import sys
import types
import unittest
import logging
import warnings
import weakref
import inspect
import types
from collections import UserString
from copy import deepcopy
from test import support
from test.support import captured_stderr, gc_collect
import unittest
from test.test_unittest.support import (
LegacyLoggingResult,
LoggingResult,
ResultWithNoStartTestRunStopTestRun,
TestEquality,
TestHashing,
TestEquality, TestHashing, LoggingResult, LegacyLoggingResult,
ResultWithNoStartTestRunStopTestRun
)
from test.support import captured_stderr, gc_collect
log_foo = logging.getLogger('foo')
log_foobar = logging.getLogger('foo.bar')

View File

@@ -1,16 +1,16 @@
import os.path
import pickle
from os.path import abspath
import re
import sys
import types
import unittest
import unittest.mock
import pickle
from importlib._bootstrap_external import NamespaceLoader
from os.path import abspath
import test.test_unittest
from test import support
from test.support import import_helper
import unittest
import unittest.mock
import test.test_unittest
from test.test_importlib import util as test_util
@@ -884,7 +884,6 @@ class TestDiscovery(unittest.TestCase):
self.assertEqual(suite, ['/a/tests', '/b/tests'])
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_discovery_start_dir_is_namespace(self):
"""Subdirectory discovery not affected if start_dir is a namespace pkg."""
loader = unittest.TestLoader()

View File

@@ -1,8 +1,8 @@
import functools
import sys
import types
import unittest
import unittest
class Test_TestLoader(unittest.TestCase):

View File

@@ -1,10 +1,9 @@
import os
import subprocess
import sys
import unittest
import test.test_unittest
import subprocess
from test import support
import unittest
import test.test_unittest
from test.test_unittest.test_result import BufferedWriter
@@ -506,7 +505,7 @@ class TestCommandLineArgs(unittest.TestCase):
self.assertEqual(program.testNamePatterns, ['*foo*', '*bar*', '*pat*'])
@unittest.expectedFailureIf(sys.platform != 'win32', 'TODO: RUSTPYTHON')
@unittest.expectedFailureIf(sys.platform != "win32", "TODO: RUSTPYTHON")
def testSelectedTestNamesFunctionalTest(self):
def run_unittest(args):
# Use -E to ignore PYTHONSAFEPATH env var

View File

@@ -4,12 +4,8 @@ import textwrap
import traceback
import unittest
from unittest.util import strclass
from test.support import (
captured_stdout,
force_not_colorized_test_class,
warnings_helper,
)
from test.support import warnings_helper
from test.support import captured_stdout, force_not_colorized_test_class
from test.test_unittest.support import BufferedWriter

View File

@@ -1,12 +1,13 @@
import io
import os
import sys
import pickle
import subprocess
import sys
from test import support
import unittest
from unittest.case import _Outcome
from test import support
from test.test_unittest.support import (
BufferedWriter,
LoggingResult,

View File

@@ -1,5 +1,6 @@
import io
import sys
import unittest

View File

@@ -1,10 +1,11 @@
import unittest
import gc
import sys
import unittest
import weakref
from test.test_unittest.support import LoggingResult, TestEquality
### Support code for Test_TestSuite
################################################################

View File

@@ -1,9 +1,5 @@
import unittest
from unittest.util import (
safe_repr,
sorted_list_difference,
unorderable_list_difference,
)
from unittest.util import safe_repr, sorted_list_difference, unorderable_list_difference
class TestUtil(unittest.TestCase):

View File

@@ -8,14 +8,14 @@ from test import support
support.requires_working_socket(module=True)
from asyncio import run, iscoroutinefunction
from asyncio import run
from unittest import IsolatedAsyncioTestCase
from unittest.mock import (ANY, call, AsyncMock, patch, MagicMock, Mock,
create_autospec, sentinel, _CallList, seal)
def tearDownModule():
asyncio.set_event_loop_policy(None)
asyncio.events._set_event_loop_policy(None)
class AsyncClass:
@@ -60,7 +60,7 @@ class AsyncPatchDecoratorTest(unittest.TestCase):
def test_is_coroutine_function_patch(self):
@patch.object(AsyncClass, 'async_method')
def test_async(mock_method):
self.assertTrue(iscoroutinefunction(mock_method))
self.assertTrue(inspect.iscoroutinefunction(mock_method))
test_async()
def test_is_async_patch(self):
@@ -121,7 +121,7 @@ class AsyncPatchCMTest(unittest.TestCase):
def test_is_async_function_cm(self):
def test_async():
with patch.object(AsyncClass, 'async_method') as mock_method:
self.assertTrue(iscoroutinefunction(mock_method))
self.assertTrue(inspect.iscoroutinefunction(mock_method))
test_async()
@@ -155,7 +155,7 @@ class AsyncPatchCMTest(unittest.TestCase):
async def test_async():
self.assertEqual(foo['a'], 'b')
self.assertTrue(iscoroutinefunction(test_async))
self.assertTrue(inspect.iscoroutinefunction(test_async))
run(test_async())
def test_patch_dict_async_def_context(self):
@@ -170,12 +170,11 @@ class AsyncPatchCMTest(unittest.TestCase):
class AsyncMockTest(unittest.TestCase):
def test_iscoroutinefunction_default(self):
mock = AsyncMock()
self.assertTrue(iscoroutinefunction(mock))
self.assertTrue(inspect.iscoroutinefunction(mock))
def test_iscoroutinefunction_function(self):
async def foo(): pass
mock = AsyncMock(foo)
self.assertTrue(iscoroutinefunction(mock))
self.assertTrue(inspect.iscoroutinefunction(mock))
def test_isawaitable(self):
@@ -188,7 +187,6 @@ class AsyncMockTest(unittest.TestCase):
def test_iscoroutinefunction_normal_function(self):
def foo(): pass
mock = AsyncMock(foo)
self.assertTrue(iscoroutinefunction(mock))
self.assertTrue(inspect.iscoroutinefunction(mock))
def test_future_isfuture(self):
@@ -231,7 +229,6 @@ class AsyncAutospecTest(unittest.TestCase):
run(main())
self.assertTrue(iscoroutinefunction(spec))
self.assertTrue(inspect.iscoroutinefunction(spec))
self.assertTrue(asyncio.iscoroutine(awaitable))
self.assertTrue(inspect.iscoroutine(awaitable))
@@ -273,7 +270,6 @@ class AsyncAutospecTest(unittest.TestCase):
awaitable = mock_method(1, 2, c=3)
self.assertIsInstance(mock_method.mock, AsyncMock)
self.assertTrue(iscoroutinefunction(mock_method))
self.assertTrue(inspect.iscoroutinefunction(mock_method))
self.assertTrue(asyncio.iscoroutine(awaitable))
self.assertTrue(inspect.iscoroutine(awaitable))
@@ -340,7 +336,7 @@ class AsyncSpecTest(unittest.TestCase):
# only the shape of the spec at the time of mock construction matters
self.assertNotIsInstance(mock_async_instance.later_async_func_attr, AsyncMock)
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_spec_mock_type_kw(self):
def inner_test(mock_type):
async_mock = mock_type(spec=async_func)
@@ -355,7 +351,7 @@ class AsyncSpecTest(unittest.TestCase):
with self.subTest(f"test spec kwarg with {mock_type}"):
inner_test(mock_type)
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_spec_mock_type_positional(self):
def inner_test(mock_type):
async_mock = mock_type(async_func)
@@ -432,13 +428,13 @@ class AsyncSpecSetTest(unittest.TestCase):
def test_is_async_AsyncMock(self):
mock = AsyncMock(spec_set=AsyncClass.async_method)
self.assertTrue(iscoroutinefunction(mock))
self.assertTrue(inspect.iscoroutinefunction(mock))
self.assertIsInstance(mock, AsyncMock)
def test_is_child_AsyncMock(self):
mock = MagicMock(spec_set=AsyncClass)
self.assertTrue(iscoroutinefunction(mock.async_method))
self.assertFalse(iscoroutinefunction(mock.normal_method))
self.assertTrue(inspect.iscoroutinefunction(mock.async_method))
self.assertFalse(inspect.iscoroutinefunction(mock.normal_method))
self.assertIsInstance(mock.async_method, AsyncMock)
self.assertIsInstance(mock.normal_method, MagicMock)
self.assertIsInstance(mock, MagicMock)
@@ -592,24 +588,24 @@ class AsyncMagicMethods(unittest.TestCase):
def test_magicmock_has_async_magic_methods(self):
m_mock = MagicMock()
self.assertTrue(hasattr(m_mock, "__aenter__"))
self.assertTrue(hasattr(m_mock, "__aexit__"))
self.assertTrue(hasattr(m_mock, "__anext__"))
self.assertHasAttr(m_mock, "__aenter__")
self.assertHasAttr(m_mock, "__aexit__")
self.assertHasAttr(m_mock, "__anext__")
def test_asyncmock_has_sync_magic_methods(self):
a_mock = AsyncMock()
self.assertTrue(hasattr(a_mock, "__enter__"))
self.assertTrue(hasattr(a_mock, "__exit__"))
self.assertTrue(hasattr(a_mock, "__next__"))
self.assertTrue(hasattr(a_mock, "__len__"))
self.assertHasAttr(a_mock, "__enter__")
self.assertHasAttr(a_mock, "__exit__")
self.assertHasAttr(a_mock, "__next__")
self.assertHasAttr(a_mock, "__len__")
def test_magic_methods_are_async_functions(self):
m_mock = MagicMock()
self.assertIsInstance(m_mock.__aenter__, AsyncMock)
self.assertIsInstance(m_mock.__aexit__, AsyncMock)
# AsyncMocks are also coroutine functions
self.assertTrue(iscoroutinefunction(m_mock.__aenter__))
self.assertTrue(iscoroutinefunction(m_mock.__aexit__))
self.assertTrue(inspect.iscoroutinefunction(m_mock.__aenter__))
self.assertTrue(inspect.iscoroutinefunction(m_mock.__aexit__))
class AsyncContextManagerTest(unittest.TestCase):
@@ -748,11 +744,11 @@ class AsyncIteratorTest(unittest.TestCase):
mock_instance = mock_type(instance)
# Check that the mock and the real thing bahave the same
# __aiter__ is not actually async, so not a coroutinefunction
self.assertFalse(iscoroutinefunction(instance.__aiter__))
self.assertFalse(iscoroutinefunction(mock_instance.__aiter__))
self.assertFalse(inspect.iscoroutinefunction(instance.__aiter__))
self.assertFalse(inspect.iscoroutinefunction(mock_instance.__aiter__))
# __anext__ is async
self.assertTrue(iscoroutinefunction(instance.__anext__))
self.assertTrue(iscoroutinefunction(mock_instance.__anext__))
self.assertTrue(inspect.iscoroutinefunction(instance.__anext__))
self.assertTrue(inspect.iscoroutinefunction(mock_instance.__anext__))
for mock_type in [AsyncMock, MagicMock]:
with self.subTest(f"test aiter and anext corourtine with {mock_type}"):
@@ -804,12 +800,12 @@ class AsyncMockAssert(unittest.TestCase):
async def _await_coroutine(self, coroutine):
return await coroutine
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_assert_called_but_not_awaited(self):
mock = AsyncMock(AsyncClass)
with assertNeverAwaited(self):
mock.async_method()
self.assertTrue(iscoroutinefunction(mock.async_method))
self.assertTrue(inspect.iscoroutinefunction(mock.async_method))
mock.async_method.assert_called()
mock.async_method.assert_called_once()
mock.async_method.assert_called_once_with()
@@ -845,7 +841,7 @@ class AsyncMockAssert(unittest.TestCase):
self.mock.assert_called_once()
self.mock.assert_awaited_once()
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_assert_called_twice_and_awaited_once(self):
mock = AsyncMock(AsyncClass)
coroutine = mock.async_method()
@@ -860,7 +856,7 @@ class AsyncMockAssert(unittest.TestCase):
mock.async_method.assert_awaited()
mock.async_method.assert_awaited_once()
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_assert_called_once_and_awaited_twice(self):
mock = AsyncMock(AsyncClass)
coroutine = mock.async_method()
@@ -885,7 +881,7 @@ class AsyncMockAssert(unittest.TestCase):
with self.assertRaises(AssertionError):
self.mock.assert_called()
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_assert_has_calls_not_awaits(self):
kalls = [call('foo')]
with assertNeverAwaited(self):
@@ -894,7 +890,7 @@ class AsyncMockAssert(unittest.TestCase):
with self.assertRaises(AssertionError):
self.mock.assert_has_awaits(kalls)
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_assert_has_mock_calls_on_async_mock_no_spec(self):
with assertNeverAwaited(self):
self.mock()
@@ -908,7 +904,7 @@ class AsyncMockAssert(unittest.TestCase):
mock_kalls = ([call(), call('foo'), call('baz')])
self.assertEqual(self.mock.mock_calls, mock_kalls)
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_assert_has_mock_calls_on_async_mock_with_spec(self):
a_class_mock = AsyncMock(AsyncClass)
with assertNeverAwaited(self):
@@ -924,7 +920,7 @@ class AsyncMockAssert(unittest.TestCase):
self.assertEqual(a_class_mock.async_method.mock_calls, method_kalls)
self.assertEqual(a_class_mock.mock_calls, mock_kalls)
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_async_method_calls_recorded(self):
with assertNeverAwaited(self):
self.mock.something(3, fish=None)
@@ -940,7 +936,7 @@ class AsyncMockAssert(unittest.TestCase):
[("something", (6,), {'cake': sentinel.Cake})],
"method calls not recorded correctly")
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_async_arg_lists(self):
def assert_attrs(mock):
names = ('call_args_list', 'method_calls', 'mock_calls')

View File

@@ -23,21 +23,21 @@ class TestCallable(unittest.TestCase):
def test_non_callable(self):
for mock in NonCallableMagicMock(), NonCallableMock():
self.assertRaises(TypeError, mock)
self.assertFalse(hasattr(mock, '__call__'))
self.assertNotHasAttr(mock, '__call__')
self.assertIn(mock.__class__.__name__, repr(mock))
def test_hierarchy(self):
self.assertTrue(issubclass(MagicMock, Mock))
self.assertTrue(issubclass(NonCallableMagicMock, NonCallableMock))
self.assertIsSubclass(MagicMock, Mock)
self.assertIsSubclass(NonCallableMagicMock, NonCallableMock)
def test_attributes(self):
one = NonCallableMock()
self.assertTrue(issubclass(type(one.one), Mock))
self.assertIsSubclass(type(one.one), Mock)
two = NonCallableMagicMock()
self.assertTrue(issubclass(type(two.two), MagicMock))
self.assertIsSubclass(type(two.two), MagicMock)
def test_subclasses(self):
@@ -45,13 +45,13 @@ class TestCallable(unittest.TestCase):
pass
one = MockSub()
self.assertTrue(issubclass(type(one.one), MockSub))
self.assertIsSubclass(type(one.one), MockSub)
class MagicSub(MagicMock):
pass
two = MagicSub()
self.assertTrue(issubclass(type(two.two), MagicSub))
self.assertIsSubclass(type(two.two), MagicSub)
def test_patch_spec(self):

View File

@@ -8,8 +8,10 @@ from unittest.mock import (
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
@@ -43,7 +45,7 @@ class AnyTest(unittest.TestCase):
mock.assert_called_with(ANY, foo=ANY)
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_any_mock_calls_comparison_order(self):
mock = Mock()
class Foo(object):
@@ -950,7 +952,7 @@ class SpecSignatureTest(unittest.TestCase):
proxy = Foo()
autospec = create_autospec(proxy)
self.assertFalse(hasattr(autospec, '__name__'))
self.assertNotHasAttr(autospec, '__name__')
def test_autospec_signature_staticmethod(self):
@@ -1035,6 +1037,97 @@ class SpecSignatureTest(unittest.TestCase):
self.assertEqual(mock.mock_calls, [])
self.assertEqual(rv.mock_calls, [])
def test_dataclass_post_init(self):
@dataclass
class WithPostInit:
a: int = field(init=False)
b: int = field(init=False)
def __post_init__(self):
self.a = 1
self.b = 2
for mock in [
create_autospec(WithPostInit, instance=True),
create_autospec(WithPostInit()),
]:
with self.subTest(mock=mock):
self.assertIsInstance(mock, WithPostInit)
self.assertIsInstance(mock.a, int)
self.assertIsInstance(mock.b, int)
# Classes do not have these fields:
mock = create_autospec(WithPostInit)
msg = "Mock object has no attribute"
with self.assertRaisesRegex(AttributeError, msg):
mock.a
with self.assertRaisesRegex(AttributeError, msg):
mock.b
def test_dataclass_default(self):
@dataclass
class WithDefault:
a: int
b: int = 0
for mock in [
create_autospec(WithDefault, instance=True),
create_autospec(WithDefault(1)),
]:
with self.subTest(mock=mock):
self.assertIsInstance(mock, WithDefault)
self.assertIsInstance(mock.a, int)
self.assertIsInstance(mock.b, int)
def test_dataclass_with_method(self):
@dataclass
class WithMethod:
a: int
def b(self) -> int:
return 1 # pragma: no cover
for mock in [
create_autospec(WithMethod, instance=True),
create_autospec(WithMethod(1)),
]:
with self.subTest(mock=mock):
self.assertIsInstance(mock, WithMethod)
self.assertIsInstance(mock.a, int)
mock.b.assert_not_called()
def test_dataclass_with_non_fields(self):
@dataclass
class WithNonFields:
a: ClassVar[int]
b: InitVar[int]
msg = "Mock object has no attribute"
for mock in [
create_autospec(WithNonFields, instance=True),
create_autospec(WithNonFields(1)),
]:
with self.subTest(mock=mock):
self.assertIsInstance(mock, WithNonFields)
with self.assertRaisesRegex(AttributeError, msg):
mock.a
with self.assertRaisesRegex(AttributeError, msg):
mock.b
def test_dataclass_special_attrs(self):
@dataclass
class Description:
name: str
for mock in [
create_autospec(Description, instance=True),
create_autospec(Description(1)),
]:
with self.subTest(mock=mock):
self.assertIsInstance(mock, Description)
self.assertIs(mock.__class__, Description)
self.assertIsInstance(mock.__dataclass_fields__, MagicMock)
self.assertIsInstance(mock.__dataclass_params__, MagicMock)
self.assertIsInstance(mock.__match_args__, MagicMock)
self.assertIsInstance(mock.__hash__, MagicMock)
class TestCallList(unittest.TestCase):

View File

@@ -1,7 +1,7 @@
import math
import unittest
import os
from asyncio import iscoroutinefunction
from inspect import iscoroutinefunction
from unittest.mock import AsyncMock, Mock, MagicMock, _magics
@@ -10,13 +10,13 @@ class TestMockingMagicMethods(unittest.TestCase):
def test_deleting_magic_methods(self):
mock = Mock()
self.assertFalse(hasattr(mock, '__getitem__'))
self.assertNotHasAttr(mock, '__getitem__')
mock.__getitem__ = Mock()
self.assertTrue(hasattr(mock, '__getitem__'))
self.assertHasAttr(mock, '__getitem__')
del mock.__getitem__
self.assertFalse(hasattr(mock, '__getitem__'))
self.assertNotHasAttr(mock, '__getitem__')
def test_magicmock_del(self):
@@ -252,12 +252,12 @@ class TestMockingMagicMethods(unittest.TestCase):
self.assertEqual(list(mock), [1, 2, 3])
getattr(mock, '__bool__').return_value = False
self.assertFalse(hasattr(mock, '__nonzero__'))
self.assertNotHasAttr(mock, '__nonzero__')
self.assertFalse(bool(mock))
for entry in _magics:
self.assertTrue(hasattr(mock, entry))
self.assertFalse(hasattr(mock, '__imaginary__'))
self.assertHasAttr(mock, entry)
self.assertNotHasAttr(mock, '__imaginary__')
def test_magic_mock_equality(self):

View File

@@ -316,7 +316,7 @@ class MockTest(unittest.TestCase):
passed to the wrapped object and the return_value is returned instead.
"""
def my_func():
return None
return None # pragma: no cover
func_mock = create_autospec(spec=my_func, wraps=my_func)
return_value = "explicit return value"
func_mock.return_value = return_value
@@ -1743,6 +1743,13 @@ class MockTest(unittest.TestCase):
mock_method.assert_called_once_with()
self.assertRaises(TypeError, mock_method, 'extra_arg')
# gh-145754
def test_create_autospec_type_hints_typechecking(self):
def foo(x: Tuple[int, ...]) -> None:
pass
mock.create_autospec(foo)
#Issue21238
def test_mock_unsafe(self):
m = Mock()
@@ -2215,13 +2222,13 @@ class MockTest(unittest.TestCase):
def test_attribute_deletion(self):
for mock in (Mock(), MagicMock(), NonCallableMagicMock(),
NonCallableMock()):
self.assertTrue(hasattr(mock, 'm'))
self.assertHasAttr(mock, 'm')
del mock.m
self.assertFalse(hasattr(mock, 'm'))
self.assertNotHasAttr(mock, 'm')
del mock.f
self.assertFalse(hasattr(mock, 'f'))
self.assertNotHasAttr(mock, 'f')
self.assertRaises(AttributeError, getattr, mock, 'f')
@@ -2230,18 +2237,18 @@ class MockTest(unittest.TestCase):
for mock in (Mock(), MagicMock(), NonCallableMagicMock(),
NonCallableMock()):
mock.foo = 3
self.assertTrue(hasattr(mock, 'foo'))
self.assertHasAttr(mock, 'foo')
self.assertEqual(mock.foo, 3)
del mock.foo
self.assertFalse(hasattr(mock, 'foo'))
self.assertNotHasAttr(mock, 'foo')
mock.foo = 4
self.assertTrue(hasattr(mock, 'foo'))
self.assertHasAttr(mock, 'foo')
self.assertEqual(mock.foo, 4)
del mock.foo
self.assertFalse(hasattr(mock, 'foo'))
self.assertNotHasAttr(mock, 'foo')
def test_mock_raises_when_deleting_nonexistent_attribute(self):
@@ -2259,7 +2266,7 @@ class MockTest(unittest.TestCase):
mock.child = True
del mock.child
mock.reset_mock()
self.assertFalse(hasattr(mock, 'child'))
self.assertNotHasAttr(mock, 'child')
def test_class_assignable(self):

View File

@@ -366,7 +366,7 @@ class PatchTest(unittest.TestCase):
self.assertEqual(SomeClass.frooble, sentinel.Frooble)
test()
self.assertFalse(hasattr(SomeClass, 'frooble'))
self.assertNotHasAttr(SomeClass, 'frooble')
def test_patch_wont_create_by_default(self):
@@ -383,7 +383,7 @@ class PatchTest(unittest.TestCase):
@patch.object(SomeClass, 'ord', sentinel.Frooble)
def test(): pass
test()
self.assertFalse(hasattr(SomeClass, 'ord'))
self.assertNotHasAttr(SomeClass, 'ord')
def test_patch_builtins_without_create(self):
@@ -748,7 +748,7 @@ class PatchTest(unittest.TestCase):
def test_exit_idempotent(self):
patcher = patch(foo_name, 'bar', 3)
with patcher:
patcher.stop()
patcher.__exit__(None, None, None)
def test_second_start_failure(self):
@@ -1477,7 +1477,7 @@ class PatchTest(unittest.TestCase):
finally:
patcher.stop()
self.assertFalse(hasattr(Foo, 'blam'))
self.assertNotHasAttr(Foo, 'blam')
def test_patch_multiple_spec_set(self):
@@ -2012,7 +2012,7 @@ class PatchTest(unittest.TestCase):
self.assertEqual(dic2, origdic2)
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_special_attrs(self):
def foo(x=0):
"""TEST"""

View File

@@ -1,8 +1,10 @@
import sys
import time
import unittest
import threading
import concurrent.futures
from test.support import threading_helper
from test.support import setswitchinterval, threading_helper
from unittest.mock import patch, ThreadingMock
@@ -196,6 +198,102 @@ class TestThreadingMock(unittest.TestCase):
m.wait_until_any_call_with()
m.assert_called_once()
def test_call_count_thread_safe(self):
# See https://github.com/python/cpython/issues/142651.
m = ThreadingMock()
LOOPS = 100
THREADS = 10
def test_function():
for _ in range(LOOPS):
m()
oldswitchinterval = sys.getswitchinterval()
setswitchinterval(1e-6)
try:
threads = [threading.Thread(target=test_function) for _ in range(THREADS)]
with threading_helper.start_threads(threads):
pass
finally:
sys.setswitchinterval(oldswitchinterval)
self.assertEqual(m.call_count, LOOPS * THREADS)
def test_call_args_thread_safe(self):
m = ThreadingMock()
LOOPS = 100
THREADS = 10
def test_function(thread_id):
for i in range(LOOPS):
m(thread_id, i)
oldswitchinterval = sys.getswitchinterval()
setswitchinterval(1e-6)
try:
threads = [
threading.Thread(target=test_function, args=(thread_id,))
for thread_id in range(THREADS)
]
with threading_helper.start_threads(threads):
pass
finally:
sys.setswitchinterval(oldswitchinterval)
expected_calls = {
(thread_id, i)
for thread_id in range(THREADS)
for i in range(LOOPS)
}
self.assertSetEqual({call.args for call in m.call_args_list}, expected_calls)
def test_method_calls_thread_safe(self):
m = ThreadingMock()
LOOPS = 100
THREADS = 10
def test_function(thread_id):
for i in range(LOOPS):
getattr(m, f"method_{thread_id}")(i)
oldswitchinterval = sys.getswitchinterval()
setswitchinterval(1e-6)
try:
threads = [
threading.Thread(target=test_function, args=(thread_id,))
for thread_id in range(THREADS)
]
with threading_helper.start_threads(threads):
pass
finally:
sys.setswitchinterval(oldswitchinterval)
for thread_id in range(THREADS):
self.assertEqual(getattr(m, f"method_{thread_id}").call_count, LOOPS)
self.assertEqual({call.args for call in getattr(m, f"method_{thread_id}").call_args_list},
{(i,) for i in range(LOOPS)})
def test_mock_calls_thread_safe(self):
m = ThreadingMock()
LOOPS = 100
THREADS = 10
def test_function(thread_id):
for i in range(LOOPS):
m(thread_id, i)
oldswitchinterval = sys.getswitchinterval()
setswitchinterval(1e-6)
try:
threads = [
threading.Thread(target=test_function, args=(thread_id,))
for thread_id in range(THREADS)
]
with threading_helper.start_threads(threads):
pass
finally:
sys.setswitchinterval(oldswitchinterval)
expected_calls = {
(thread_id, i)
for thread_id in range(THREADS)
for i in range(LOOPS)
}
self.assertSetEqual({call.args for call in m.mock_calls}, expected_calls)
if __name__ == "__main__":
unittest.main()

View File

@@ -53,30 +53,15 @@ __all__ = ['TestResult', 'TestCase', 'IsolatedAsyncioTestCase', 'TestSuite',
__unittest = True
from .case import (
FunctionTestCase,
SkipTest,
TestCase,
addModuleCleanup,
doModuleCleanups,
enterModuleContext,
expectedFailure,
skip,
skipIf,
skipUnless,
)
from .result import TestResult
from .case import (addModuleCleanup, TestCase, FunctionTestCase, SkipTest, skip,
skipIf, skipUnless, expectedFailure, doModuleCleanups,
enterModuleContext)
from .suite import BaseTestSuite, TestSuite # noqa: F401
from .loader import TestLoader, defaultTestLoader
from .main import TestProgram, main # noqa: F401
from .result import TestResult
from .runner import TextTestResult, TextTestRunner
from .signals import (
installHandler,
registerResult,
removeHandler,
removeResult,
)
from .suite import BaseTestSuite, TestSuite # noqa: F401
from .runner import TextTestRunner, TextTestResult
from .signals import installHandler, registerResult, removeResult, removeHandler
# IsolatedAsyncioTestCase will be imported lazily.

View File

@@ -1,7 +1,6 @@
"""Main entry point"""
import sys
if sys.argv[0].endswith("__main__.py"):
import os.path
# We change sys.argv[0] to make help message more useful

View File

@@ -1,8 +1,9 @@
import collections
import logging
import collections
from .case import _BaseTestCaseContext
_LoggingWatcher = collections.namedtuple("_LoggingWatcher",
["records", "output"])

23
Lib/unittest/case.py vendored
View File

@@ -1,25 +1,20 @@
"""Test case implementation"""
import collections
import contextlib
import difflib
import sys
import functools
import difflib
import pprint
import re
import sys
import time
import traceback
import types
import warnings
import collections
import contextlib
import traceback
import time
import types
from . import result
from .util import (
_common_shorten_repr,
_count_diff_all_purpose,
_count_diff_hashable,
safe_repr,
strclass,
)
from .util import (strclass, safe_repr, _count_diff_all_purpose,
_count_diff_hashable, _common_shorten_repr)
__unittest = True

View File

@@ -1,11 +1,12 @@
"""Loading unittests."""
import functools
import os
import re
import sys
import traceback
import types
import functools
from fnmatch import fnmatch, fnmatchcase
from . import case, suite, util

View File

@@ -1,8 +1,8 @@
"""Unittest main program"""
import sys
import argparse
import os
import sys
from . import loader, runner
from .signals import installHandler

33
Lib/unittest/mock.py vendored
View File

@@ -25,20 +25,21 @@ __all__ = (
import asyncio
import builtins
import contextlib
import inspect
import io
import pkgutil
import inspect
import pprint
import sys
import threading
from dataclasses import fields, is_dataclass
from functools import partial, wraps
import builtins
import pkgutil
from inspect import iscoroutinefunction
from threading import RLock
from types import CodeType, MethodType, ModuleType
import threading
from annotationlib import Format
from dataclasses import fields, is_dataclass
from types import CodeType, ModuleType, MethodType
from unittest.util import safe_repr
from functools import wraps, partial
from threading import RLock
class InvalidSpecError(Exception):
@@ -119,7 +120,7 @@ def _get_signature_object(func, as_instance, eat_self):
else:
sig_func = func
try:
return func, inspect.signature(sig_func)
return func, inspect.signature(sig_func, annotation_format=Format.FORWARDREF)
except ValueError:
# Certain callable types are not supported by inspect.signature()
return None
@@ -1180,14 +1181,20 @@ class CallableMixin(Base):
def _increment_mock_call(self, /, *args, **kwargs):
self.called = True
self.call_count += 1
# handle call_args
# needs to be set here so assertions on call arguments pass before
# execution in the case of awaited calls
_call = _Call((args, kwargs), two=True)
self.call_args = _call
self.call_args_list.append(_call)
with NonCallableMock._lock:
# Lock is used here so that call_args_list and call_count are
# set atomically otherwise it is possible that by the time call_count
# is set another thread may have appended to call_args_list.
# The rest of this function relies on list.append being atomic and
# skips locking.
_call = _Call((args, kwargs), two=True)
self.call_args = _call
self.call_args_list.append(_call)
self.call_count = len(self.call_args_list)
# initial stuff for method_calls:
do_method_calls = self._mock_parent is not None

View File

@@ -3,9 +3,9 @@
import io
import sys
import traceback
from functools import wraps
from . import util
from functools import wraps
__unittest = True

View File

@@ -1,5 +1,6 @@
import signal
import weakref
from functools import wraps
__unittest = True

View File

@@ -2,7 +2,8 @@
import sys
from . import case, util
from . import case
from . import util
__unittest = True

View File

@@ -1,6 +1,6 @@
"""Various utility functions."""
from collections import Counter, namedtuple
from collections import namedtuple, Counter
from os.path import commonprefix
__unittest = True