Skip to content

Commit 60aa562

Browse files
committed
Merge branch 'main' into fieldrepr
* main: pythonGH-100288: Remove LOAD_ATTR_METHOD_WITH_DICT instruction. (pythonGH-100753) pythonGH-100766: Note that locale.LC_MESSAGES is not universal (pythonGH-100702) Drop myself from pathlib maintenance (python#100757) pythongh-100739: Respect mock spec when checking for unsafe prefixes (python#100740)
2 parents 7241045 + f20c553 commit 60aa562

File tree

13 files changed

+62
-100
lines changed

13 files changed

+62
-100
lines changed

.github/CODEOWNERS

+1-4
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Python/traceback.c @iritkatriel
6363
# bytecode.
6464
**/*import*.c @brettcannon @encukou @ericsnowcurrently @ncoghlan @warsaw
6565
**/*import*.py @brettcannon @encukou @ericsnowcurrently @ncoghlan @warsaw
66-
**/*importlib/resources/* @jaraco @warsaw @brettcannon @FFY00
66+
**/*importlib/resources/* @jaraco @warsaw @FFY00
6767
**/importlib/metadata/* @jaraco @warsaw
6868

6969
# Dates and times
@@ -152,8 +152,5 @@ Lib/ast.py @isidentical
152152
/Mac/ @python/macos-team
153153
**/*osx_support* @python/macos-team
154154

155-
# pathlib
156-
**/*pathlib* @brettcannon
157-
158155
# zipfile.Path
159156
**/*zipfile/*_path.py @jaraco

Doc/library/locale.rst

+3
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,9 @@ The :mod:`locale` module defines the following exception and functions:
496496
system, like those returned by :func:`os.strerror` might be affected by this
497497
category.
498498

499+
This value may not be available on operating systems not conforming to the
500+
POSIX standard, most notably Windows.
501+
499502

500503
.. data:: LC_NUMERIC
501504

Include/internal/pycore_opcode.h

+10-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/opcode.h

+16-17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/opcode.py

-1
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,6 @@ def pseudo_op(name, op, real_ops):
336336
# These will always push [unbound method, self] onto the stack.
337337
"LOAD_ATTR_METHOD_LAZY_DICT",
338338
"LOAD_ATTR_METHOD_NO_DICT",
339-
"LOAD_ATTR_METHOD_WITH_DICT",
340339
"LOAD_ATTR_METHOD_WITH_VALUES",
341340
],
342341
"LOAD_CONST": [

Lib/test/test_unittest/testmock/testmock.py

+16
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,22 @@ def test_mock_unsafe(self):
16521652
m.aseert_foo_call()
16531653
m.assrt_foo_call()
16541654

1655+
# gh-100739
1656+
def test_mock_safe_with_spec(self):
1657+
class Foo(object):
1658+
def assert_bar(self):
1659+
pass
1660+
1661+
def assertSome(self):
1662+
pass
1663+
1664+
m = Mock(spec=Foo)
1665+
m.assert_bar()
1666+
m.assertSome()
1667+
1668+
m.assert_bar.assert_called_once()
1669+
m.assertSome.assert_called_once()
1670+
16551671
#Issue21262
16561672
def test_assert_not_called(self):
16571673
m = Mock()

Lib/unittest/mock.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ def __getattr__(self, name):
652652
raise AttributeError("Mock object has no attribute %r" % name)
653653
elif _is_magic(name):
654654
raise AttributeError(name)
655-
if not self._mock_unsafe:
655+
if not self._mock_unsafe and (not self._mock_methods or name not in self._mock_methods):
656656
if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')):
657657
raise AttributeError(
658658
f"{name!r} is not a valid assertion. Use a spec "
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Remove the LOAD_ATTR_METHOD_WITH_DICT specialized instruction. Stats show it
2+
is not useful.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix ``unittest.mock.Mock`` not respecting the spec for attribute names prefixed with ``assert``.

Python/bytecodes.c

+1-28
Original file line numberDiff line numberDiff line change
@@ -2605,33 +2605,6 @@ dummy_func(
26052605
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
26062606
}
26072607

2608-
// error: LOAD_ATTR has irregular stack effect
2609-
inst(LOAD_ATTR_METHOD_WITH_DICT) {
2610-
/* Can be either a managed dict, or a tp_dictoffset offset.*/
2611-
assert(cframe.use_tracing == 0);
2612-
PyObject *self = TOP();
2613-
PyTypeObject *self_cls = Py_TYPE(self);
2614-
_PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr;
2615-
2616-
DEOPT_IF(self_cls->tp_version_tag != read_u32(cache->type_version),
2617-
LOAD_ATTR);
2618-
/* Treat index as a signed 16 bit value */
2619-
Py_ssize_t dictoffset = self_cls->tp_dictoffset;
2620-
assert(dictoffset > 0);
2621-
PyDictObject **dictptr = (PyDictObject**)(((char *)self)+dictoffset);
2622-
PyDictObject *dict = *dictptr;
2623-
DEOPT_IF(dict == NULL, LOAD_ATTR);
2624-
DEOPT_IF(dict->ma_keys->dk_version != read_u32(cache->keys_version),
2625-
LOAD_ATTR);
2626-
STAT_INC(LOAD_ATTR, hit);
2627-
PyObject *res = read_obj(cache->descr);
2628-
assert(res != NULL);
2629-
assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR));
2630-
SET_TOP(Py_NewRef(res));
2631-
PUSH(self);
2632-
JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
2633-
}
2634-
26352608
// error: LOAD_ATTR has irregular stack effect
26362609
inst(LOAD_ATTR_METHOD_NO_DICT) {
26372610
assert(cframe.use_tracing == 0);
@@ -3517,7 +3490,7 @@ family(load_attr) = {
35173490
LOAD_ATTR, LOAD_ATTR_CLASS,
35183491
LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_MODULE,
35193492
LOAD_ATTR_PROPERTY, LOAD_ATTR_SLOT, LOAD_ATTR_WITH_HINT,
3520-
LOAD_ATTR_METHOD_LAZY_DICT, LOAD_ATTR_METHOD_NO_DICT, LOAD_ATTR_METHOD_WITH_DICT,
3493+
LOAD_ATTR_METHOD_LAZY_DICT, LOAD_ATTR_METHOD_NO_DICT,
35213494
LOAD_ATTR_METHOD_WITH_VALUES };
35223495
family(load_global) = {
35233496
LOAD_GLOBAL, LOAD_GLOBAL_BUILTIN,

Python/generated_cases.c.h

-27
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/opcode_targets.h

+9-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/specialize.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -1091,9 +1091,8 @@ PyObject *descr, DescriptorClassification kind)
10911091
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_HAS_MANAGED_DICT);
10921092
goto fail;
10931093
case OFFSET_DICT:
1094-
assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX);
1095-
_py_set_opcode(instr, LOAD_ATTR_METHOD_WITH_DICT);
1096-
break;
1094+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NOT_MANAGED_DICT);
1095+
goto fail;
10971096
case LAZY_DICT:
10981097
assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX);
10991098
_py_set_opcode(instr, LOAD_ATTR_METHOD_LAZY_DICT);

0 commit comments

Comments
 (0)