Skip to content

Commit

Permalink
Merge branch 'main' into fetch-restore
Browse files Browse the repository at this point in the history
  • Loading branch information
iritkatriel authored Feb 24, 2023
2 parents b5150cc + 2db23d1 commit 603922d
Show file tree
Hide file tree
Showing 48 changed files with 748 additions and 700 deletions.
8 changes: 3 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,11 @@ jobs:
- uses: actions/checkout@v3
- name: Install Homebrew dependencies
run: brew install pkg-config openssl@1.1 xz gdbm tcl-tk
- name: Prepare Homebrew environment variables
run: |
echo "CFLAGS=-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" >> $GITHUB_ENV
echo "LDFLAGS=-L$(brew --prefix gdbm)/lib -I$(brew --prefix xz)/lib" >> $GITHUB_ENV
echo "PKG_CONFIG_PATH=$(brew --prefix openssl@1.1)/lib/pkgconfig:$(brew --prefix tcl-tk)/lib/pkgconfig" >> $GITHUB_ENV
- name: Configure CPython
run: |
CFLAGS="-I$(brew --prefix gdbm)/include -I$(brew --prefix xz)/include" \
LDFLAGS="-L$(brew --prefix gdbm)/lib -I$(brew --prefix xz)/lib" \
PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \
./configure \
--with-pydebug \
--prefix=/opt/python-dev \
Expand Down
4 changes: 2 additions & 2 deletions Doc/library/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ are always available. They are listed here in alphabetical order.
.. function:: filter(function, iterable)

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

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


.. class:: float(x=0.0)
Expand Down
4 changes: 2 additions & 2 deletions Doc/library/itertools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ loops that truncate the stream.
.. function:: filterfalse(predicate, iterable)

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

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

def quantify(iterable, pred=bool):
"Count how many times the predicate is true"
"Count how many times the predicate is True"
return sum(map(pred, iterable))

def ncycles(iterable, n):
Expand Down
14 changes: 11 additions & 3 deletions Doc/library/mmap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -370,11 +370,19 @@ MAP_* Constants
MAP_ANONYMOUS
MAP_POPULATE
MAP_STACK
MAP_ALIGNED_SUPER
MAP_CONCEAL

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

.. versionchanged:: 3.10
Added MAP_POPULATE constant.
Added :data:`MAP_POPULATE` constant.

.. versionadded:: 3.11
Added MAP_STACK constant.
Added :data:`MAP_STACK` constant.

.. versionadded:: 3.12
Added :data:`MAP_ALIGNED_SUPER` constant.
Added :data:`MAP_CONCEAL` constant.
16 changes: 16 additions & 0 deletions Include/internal/pycore_typeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
extern "C" {
#endif

#include "pycore_moduleobject.h"

#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
Expand Down Expand Up @@ -62,6 +64,20 @@ _PyStaticType_GET_WEAKREFS_LISTPTR(static_builtin_state *state)
return &state->tp_weaklist;
}

/* Like PyType_GetModuleState, but skips verification
* that type is a heap type with an associated module */
static inline void *
_PyType_GetModuleState(PyTypeObject *type)
{
assert(PyType_Check(type));
assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE);
PyHeapTypeObject *et = (PyHeapTypeObject *)type;
assert(et->ht_module);
PyModuleObject *mod = (PyModuleObject *)(et->ht_module);
assert(mod != NULL);
return mod->md_state;
}

struct types_state {
struct type_cache type_cache;
size_t num_builtins_initialized;
Expand Down
145 changes: 145 additions & 0 deletions Lib/test/test_capi/test_exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import re
import sys
import unittest

from test import support
from test.support import import_helper
from test.support.script_helper import assert_python_failure

from .test_misc import decode_stderr

# Skip this test if the _testcapi module isn't available.
_testcapi = import_helper.import_module('_testcapi')

class Test_Exceptions(unittest.TestCase):

def test_exception(self):
raised_exception = ValueError("5")
new_exc = TypeError("TEST")
try:
raise raised_exception
except ValueError as e:
orig_sys_exception = sys.exception()
orig_exception = _testcapi.set_exception(new_exc)
new_sys_exception = sys.exception()
new_exception = _testcapi.set_exception(orig_exception)
reset_sys_exception = sys.exception()

self.assertEqual(orig_exception, e)

self.assertEqual(orig_exception, raised_exception)
self.assertEqual(orig_sys_exception, orig_exception)
self.assertEqual(reset_sys_exception, orig_exception)
self.assertEqual(new_exception, new_exc)
self.assertEqual(new_sys_exception, new_exception)
else:
self.fail("Exception not raised")

def test_exc_info(self):
raised_exception = ValueError("5")
new_exc = TypeError("TEST")
try:
raise raised_exception
except ValueError as e:
tb = e.__traceback__
orig_sys_exc_info = sys.exc_info()
orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None)
new_sys_exc_info = sys.exc_info()
new_exc_info = _testcapi.set_exc_info(*orig_exc_info)
reset_sys_exc_info = sys.exc_info()

self.assertEqual(orig_exc_info[1], e)

self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb))
self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info)
self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info)
self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None))
self.assertSequenceEqual(new_sys_exc_info, new_exc_info)
else:
self.assertTrue(False)


class Test_FatalError(unittest.TestCase):

def check_fatal_error(self, code, expected, not_expected=()):
with support.SuppressCrashReport():
rc, out, err = assert_python_failure('-sSI', '-c', code)

err = decode_stderr(err)
self.assertIn('Fatal Python error: test_fatal_error: MESSAGE\n',
err)

match = re.search(r'^Extension modules:(.*) \(total: ([0-9]+)\)$',
err, re.MULTILINE)
if not match:
self.fail(f"Cannot find 'Extension modules:' in {err!r}")
modules = set(match.group(1).strip().split(', '))
total = int(match.group(2))

for name in expected:
self.assertIn(name, modules)
for name in not_expected:
self.assertNotIn(name, modules)
self.assertEqual(len(modules), total)

@support.requires_subprocess()
def test_fatal_error(self):
# By default, stdlib extension modules are ignored,
# but not test modules.
expected = ('_testcapi',)
not_expected = ('sys',)
code = 'import _testcapi, sys; _testcapi.fatal_error(b"MESSAGE")'
self.check_fatal_error(code, expected, not_expected)

# Mark _testcapi as stdlib module, but not sys
expected = ('sys',)
not_expected = ('_testcapi',)
code = """if True:
import _testcapi, sys
sys.stdlib_module_names = frozenset({"_testcapi"})
_testcapi.fatal_error(b"MESSAGE")
"""
self.check_fatal_error(code, expected)


class Test_ErrSetAndRestore(unittest.TestCase):

def test_err_set_raised(self):
with self.assertRaises(ValueError):
_testcapi.err_set_raised(ValueError())
v = ValueError()
try:
_testcapi.err_set_raised(v)
except ValueError as ex:
self.assertIs(v, ex)

def test_err_restore(self):
with self.assertRaises(ValueError):
_testcapi.err_restore(ValueError)
with self.assertRaises(ValueError):
_testcapi.err_restore(ValueError, 1)
with self.assertRaises(ValueError):
_testcapi.err_restore(ValueError, 1, None)
with self.assertRaises(ValueError):
_testcapi.err_restore(ValueError, ValueError())
try:
_testcapi.err_restore(KeyError, "hi")
except KeyError as k:
self.assertEqual("hi", k.args[0])
try:
1/0
except Exception as e:
tb = e.__traceback__
with self.assertRaises(ValueError):
_testcapi.err_restore(ValueError, 1, tb)
with self.assertRaises(TypeError):
_testcapi.err_restore(ValueError, 1, 0)
try:
_testcapi.err_restore(ValueError, 1, tb)
except ValueError as v:
self.assertEqual(1, v.args[0])
self.assertIs(tb, v.__traceback__.tb_next)


if __name__ == "__main__":
unittest.main()
Loading

0 comments on commit 603922d

Please sign in to comment.