Skip to content

Commit 603922d

Browse files
authored
Merge branch 'main' into fetch-restore
2 parents b5150cc + 2db23d1 commit 603922d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+748
-700
lines changed

.github/workflows/build.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,11 @@ jobs:
162162
- uses: actions/checkout@v3
163163
- name: Install Homebrew dependencies
164164
run: brew install pkg-config [email protected] xz gdbm tcl-tk
165-
- name: Prepare Homebrew environment variables
166-
run: |
167-
echo "CFLAGS=-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" >> $GITHUB_ENV
168-
echo "LDFLAGS=-L$(brew --prefix gdbm)/lib -I$(brew --prefix xz)/lib" >> $GITHUB_ENV
169-
echo "PKG_CONFIG_PATH=$(brew --prefix [email protected])/lib/pkgconfig:$(brew --prefix tcl-tk)/lib/pkgconfig" >> $GITHUB_ENV
170165
- name: Configure CPython
171166
run: |
167+
CFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \
168+
LDFLAGS="-L$(brew --prefix gdbm)/lib -I$(brew --prefix xz)/lib" \
169+
PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \
172170
./configure \
173171
--with-pydebug \
174172
--prefix=/opt/python-dev \

Doc/library/functions.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ are always available. They are listed here in alphabetical order.
623623
.. function:: filter(function, iterable)
624624

625625
Construct an iterator from those elements of *iterable* for which *function*
626-
returns true. *iterable* may be either a sequence, a container which
626+
is true. *iterable* may be either a sequence, a container which
627627
supports iteration, or an iterator. If *function* is ``None``, the identity
628628
function is assumed, that is, all elements of *iterable* that are false are
629629
removed.
@@ -634,7 +634,7 @@ are always available. They are listed here in alphabetical order.
634634
``None``.
635635

636636
See :func:`itertools.filterfalse` for the complementary function that returns
637-
elements of *iterable* for which *function* returns false.
637+
elements of *iterable* for which *function* is false.
638638

639639

640640
.. class:: float(x=0.0)

Doc/library/itertools.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ loops that truncate the stream.
398398
.. function:: filterfalse(predicate, iterable)
399399

400400
Make an iterator that filters elements from iterable returning only those for
401-
which the predicate is ``False``. If *predicate* is ``None``, return the items
401+
which the predicate is false. If *predicate* is ``None``, return the items
402402
that are false. Roughly equivalent to::
403403

404404
def filterfalse(predicate, iterable):
@@ -831,7 +831,7 @@ which incur interpreter overhead.
831831
return next(g, True) and not next(g, False)
832832

833833
def quantify(iterable, pred=bool):
834-
"Count how many times the predicate is true"
834+
"Count how many times the predicate is True"
835835
return sum(map(pred, iterable))
836836

837837
def ncycles(iterable, n):

Doc/library/mmap.rst

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,11 +370,19 @@ MAP_* Constants
370370
MAP_ANONYMOUS
371371
MAP_POPULATE
372372
MAP_STACK
373+
MAP_ALIGNED_SUPER
374+
MAP_CONCEAL
373375

374-
These are the various flags that can be passed to :meth:`mmap.mmap`. Note that some options might not be present on some systems.
376+
These are the various flags that can be passed to :meth:`mmap.mmap`. :data:`MAP_ALIGNED_SUPER`
377+
is only available at FreeBSD and :data:`MAP_CONCEAL` is only available at OpenBSD. Note
378+
that some options might not be present on some systems.
375379

376380
.. versionchanged:: 3.10
377-
Added MAP_POPULATE constant.
381+
Added :data:`MAP_POPULATE` constant.
378382

379383
.. versionadded:: 3.11
380-
Added MAP_STACK constant.
384+
Added :data:`MAP_STACK` constant.
385+
386+
.. versionadded:: 3.12
387+
Added :data:`MAP_ALIGNED_SUPER` constant.
388+
Added :data:`MAP_CONCEAL` constant.

Include/internal/pycore_typeobject.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
extern "C" {
55
#endif
66

7+
#include "pycore_moduleobject.h"
8+
79
#ifndef Py_BUILD_CORE
810
# error "this header requires Py_BUILD_CORE define"
911
#endif
@@ -62,6 +64,20 @@ _PyStaticType_GET_WEAKREFS_LISTPTR(static_builtin_state *state)
6264
return &state->tp_weaklist;
6365
}
6466

67+
/* Like PyType_GetModuleState, but skips verification
68+
* that type is a heap type with an associated module */
69+
static inline void *
70+
_PyType_GetModuleState(PyTypeObject *type)
71+
{
72+
assert(PyType_Check(type));
73+
assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
74+
PyHeapTypeObject *et = (PyHeapTypeObject *)type;
75+
assert(et->ht_module);
76+
PyModuleObject *mod = (PyModuleObject *)(et->ht_module);
77+
assert(mod != NULL);
78+
return mod->md_state;
79+
}
80+
6581
struct types_state {
6682
struct type_cache type_cache;
6783
size_t num_builtins_initialized;

Lib/test/test_capi/test_exceptions.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import re
2+
import sys
3+
import unittest
4+
5+
from test import support
6+
from test.support import import_helper
7+
from test.support.script_helper import assert_python_failure
8+
9+
from .test_misc import decode_stderr
10+
11+
# Skip this test if the _testcapi module isn't available.
12+
_testcapi = import_helper.import_module('_testcapi')
13+
14+
class Test_Exceptions(unittest.TestCase):
15+
16+
def test_exception(self):
17+
raised_exception = ValueError("5")
18+
new_exc = TypeError("TEST")
19+
try:
20+
raise raised_exception
21+
except ValueError as e:
22+
orig_sys_exception = sys.exception()
23+
orig_exception = _testcapi.set_exception(new_exc)
24+
new_sys_exception = sys.exception()
25+
new_exception = _testcapi.set_exception(orig_exception)
26+
reset_sys_exception = sys.exception()
27+
28+
self.assertEqual(orig_exception, e)
29+
30+
self.assertEqual(orig_exception, raised_exception)
31+
self.assertEqual(orig_sys_exception, orig_exception)
32+
self.assertEqual(reset_sys_exception, orig_exception)
33+
self.assertEqual(new_exception, new_exc)
34+
self.assertEqual(new_sys_exception, new_exception)
35+
else:
36+
self.fail("Exception not raised")
37+
38+
def test_exc_info(self):
39+
raised_exception = ValueError("5")
40+
new_exc = TypeError("TEST")
41+
try:
42+
raise raised_exception
43+
except ValueError as e:
44+
tb = e.__traceback__
45+
orig_sys_exc_info = sys.exc_info()
46+
orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None)
47+
new_sys_exc_info = sys.exc_info()
48+
new_exc_info = _testcapi.set_exc_info(*orig_exc_info)
49+
reset_sys_exc_info = sys.exc_info()
50+
51+
self.assertEqual(orig_exc_info[1], e)
52+
53+
self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb))
54+
self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info)
55+
self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info)
56+
self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None))
57+
self.assertSequenceEqual(new_sys_exc_info, new_exc_info)
58+
else:
59+
self.assertTrue(False)
60+
61+
62+
class Test_FatalError(unittest.TestCase):
63+
64+
def check_fatal_error(self, code, expected, not_expected=()):
65+
with support.SuppressCrashReport():
66+
rc, out, err = assert_python_failure('-sSI', '-c', code)
67+
68+
err = decode_stderr(err)
69+
self.assertIn('Fatal Python error: test_fatal_error: MESSAGE\n',
70+
err)
71+
72+
match = re.search(r'^Extension modules:(.*) \(total: ([0-9]+)\)$',
73+
err, re.MULTILINE)
74+
if not match:
75+
self.fail(f"Cannot find 'Extension modules:' in {err!r}")
76+
modules = set(match.group(1).strip().split(', '))
77+
total = int(match.group(2))
78+
79+
for name in expected:
80+
self.assertIn(name, modules)
81+
for name in not_expected:
82+
self.assertNotIn(name, modules)
83+
self.assertEqual(len(modules), total)
84+
85+
@support.requires_subprocess()
86+
def test_fatal_error(self):
87+
# By default, stdlib extension modules are ignored,
88+
# but not test modules.
89+
expected = ('_testcapi',)
90+
not_expected = ('sys',)
91+
code = 'import _testcapi, sys; _testcapi.fatal_error(b"MESSAGE")'
92+
self.check_fatal_error(code, expected, not_expected)
93+
94+
# Mark _testcapi as stdlib module, but not sys
95+
expected = ('sys',)
96+
not_expected = ('_testcapi',)
97+
code = """if True:
98+
import _testcapi, sys
99+
sys.stdlib_module_names = frozenset({"_testcapi"})
100+
_testcapi.fatal_error(b"MESSAGE")
101+
"""
102+
self.check_fatal_error(code, expected)
103+
104+
105+
class Test_ErrSetAndRestore(unittest.TestCase):
106+
107+
def test_err_set_raised(self):
108+
with self.assertRaises(ValueError):
109+
_testcapi.err_set_raised(ValueError())
110+
v = ValueError()
111+
try:
112+
_testcapi.err_set_raised(v)
113+
except ValueError as ex:
114+
self.assertIs(v, ex)
115+
116+
def test_err_restore(self):
117+
with self.assertRaises(ValueError):
118+
_testcapi.err_restore(ValueError)
119+
with self.assertRaises(ValueError):
120+
_testcapi.err_restore(ValueError, 1)
121+
with self.assertRaises(ValueError):
122+
_testcapi.err_restore(ValueError, 1, None)
123+
with self.assertRaises(ValueError):
124+
_testcapi.err_restore(ValueError, ValueError())
125+
try:
126+
_testcapi.err_restore(KeyError, "hi")
127+
except KeyError as k:
128+
self.assertEqual("hi", k.args[0])
129+
try:
130+
1/0
131+
except Exception as e:
132+
tb = e.__traceback__
133+
with self.assertRaises(ValueError):
134+
_testcapi.err_restore(ValueError, 1, tb)
135+
with self.assertRaises(TypeError):
136+
_testcapi.err_restore(ValueError, 1, 0)
137+
try:
138+
_testcapi.err_restore(ValueError, 1, tb)
139+
except ValueError as v:
140+
self.assertEqual(1, v.args[0])
141+
self.assertIs(tb, v.__traceback__.tb_next)
142+
143+
144+
if __name__ == "__main__":
145+
unittest.main()

0 commit comments

Comments
 (0)