Skip to content

bpo-39943: Remove unused arg from find_nfc_index() #18950

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
2 changes: 1 addition & 1 deletion Doc/c-api/exceptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ an error value).
.. c:function:: int PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, const char *format, ...)

Function similar to :c:func:`PyErr_WarnFormat`, but *category* is
:exc:`ResourceWarning` and pass *source* to :func:`warnings.WarningMessage`.
:exc:`ResourceWarning` and it passes *source* to :func:`warnings.WarningMessage`.

.. versionadded:: 3.6

Expand Down
26 changes: 26 additions & 0 deletions Doc/c-api/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,32 @@ All of the following functions must be called after :c:func:`Py_Initialize`.

.. versionadded:: 3.8

.. c:type:: PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, PyFrameObject *frame, int throwflag)

Type of a frame evaluation function.

The *throwflag* parameter is used by the ``throw()`` method of generators:
if non-zero, handle the current exception.

.. versionchanged:: 3.9
The function now takes a *tstate* parameter.

.. c:function:: _PyFrameEvalFunction _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)

Get the frame evaluation function.

See the :pep:`523` "Adding a frame evaluation API to CPython".

.. versionadded:: 3.9

.. c:function:: void _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp, _PyFrameEvalFunction eval_frame);

Set the frame evaluation function.

See the :pep:`523` "Adding a frame evaluation API to CPython".

.. versionadded:: 3.9


.. c:function:: PyObject* PyThreadState_GetDict()

Expand Down
8 changes: 6 additions & 2 deletions Doc/whatsnew/3.9.rst
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ running.
sys
---

Add a new :attr:`sys.platlitdir` attribute: name of the platform-specific
Add a new :attr:`sys.platlibdir` attribute: name of the platform-specific
library directory. It is used to build the path of platform-specific dynamic
libraries and the path of the standard library. It is equal to ``"lib"`` on
most platforms. On Fedora and SuSE, it is equal to ``"lib64"`` on 64-bit
Expand Down Expand Up @@ -407,7 +407,7 @@ Build and C API Changes
=======================

* Add ``--with-platlibdir`` option to the ``configure`` script: name of the
platform-specific library directory, stored in the new :attr:`sys.platlitdir`
platform-specific library directory, stored in the new :attr:`sys.platlibdir`
attribute. See :attr:`sys.platlibdir` attribute for more information.
(Contributed by Jan Matějek, Matěj Cepl, Charalampos Stratakis and Victor Stinner in :issue:`1294959`.)

Expand Down Expand Up @@ -487,6 +487,10 @@ Build and C API Changes

(Contributed by Victor Stinner in :issue:`38644` and :issue:`39542`.)

* ``PyInterpreterState.eval_frame`` (:pep:`523`) now requires a new mandatory
*tstate* parameter (``PyThreadState*``).
(Contributed by Victor Stinner in :issue:`38500`.)


Deprecated
==========
Expand Down
2 changes: 1 addition & 1 deletion Include/cpython/ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ PyAPI_FUNC(PyObject *) _PyEval_GetBuiltinId(_Py_Identifier *);
flag was set, else return 0. */
PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf);

PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(struct _frame *f, int exc);
PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(PyThreadState *tstate, struct _frame *f, int exc);

PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds);
PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void);
Expand Down
10 changes: 10 additions & 0 deletions Include/cpython/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,16 @@ PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);

typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_);

/* Frame evaluation API */

typedef PyObject* (*_PyFrameEvalFunction)(PyThreadState *tstate, struct _frame *, int);

PyAPI_FUNC(_PyFrameEvalFunction) _PyInterpreterState_GetEvalFrameFunc(
PyInterpreterState *interp);
PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc(
PyInterpreterState *interp,
_PyFrameEvalFunction eval_frame);

/* cross-interpreter data */

struct _xid;
Expand Down
2 changes: 1 addition & 1 deletion Include/internal/pycore_ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void _PyEval_Fini(void);
static inline PyObject*
_PyEval_EvalFrame(PyThreadState *tstate, struct _frame *f, int throwflag)
{
return tstate->interp->eval_frame(f, throwflag);
return tstate->interp->eval_frame(tstate, f, throwflag);
}

extern PyObject *_PyEval_EvalCode(
Expand Down
2 changes: 0 additions & 2 deletions Include/internal/pycore_pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ struct _ceval_runtime_state {

/* interpreter state */

typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);

#define _PY_NSMALLPOSINTS 257
#define _PY_NSMALLNEGINTS 5

Expand Down
60 changes: 25 additions & 35 deletions Lib/_aix_support.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,20 @@
"""Shared AIX support functions."""

import sys
from sysconfig import get_config_var
import sysconfig

# subprocess is not necessarily available early in the build process
# if not available, the config_vars are also definitely not available
# supply substitutes to bootstrap the build
try:
import subprocess
_have_subprocess = True
_tmp_bd = get_config_var("AIX_BUILDDATE")
_bgt = get_config_var("BUILD_GNU_TYPE")
except ImportError: # pragma: no cover
_have_subprocess = False
_tmp_bd = None
_bgt = "powerpc-ibm-aix6.1.7.0"

# if get_config_var("AIX_BUILDDATE") was unknown, provide a substitute,
# impossible builddate to specify 'unknown'
_MISSING_BD = 9898
try:
_bd = int(_tmp_bd)
except TypeError:
_bd = _MISSING_BD

# Infer the ABI bitwidth from maxsize (assuming 64 bit as the default)
_sz = 32 if sys.maxsize == (2**31-1) else 64
# _aix_support is used in distutils by setup.py to build C extensions,
# before subprocess dependencies like _posixsubprocess are available.
import _bootsubprocess as subprocess


def _aix_tag(vrtl, bd):
# type: (List[int], int) -> str
# Infer the ABI bitwidth from maxsize (assuming 64 bit as the default)
_sz = 32 if sys.maxsize == (2**31-1) else 64
# vrtl[version, release, technology_level]
return "aix-{:1x}{:1d}{:02d}-{:04d}-{}".format(vrtl[0], vrtl[1], vrtl[2], bd, _sz)

Expand All @@ -48,17 +33,12 @@ def _aix_bosmp64():
The fileset bos.mp64 is the AIX kernel. It's VRMF and builddate
reflect the current ABI levels of the runtime environment.
"""
if _have_subprocess:
# We expect all AIX systems to have lslpp installed in this location
out = subprocess.check_output(["/usr/bin/lslpp", "-Lqc", "bos.mp64"])
out = out.decode("utf-8").strip().split(":") # type: ignore
# Use str() and int() to help mypy see types
return str(out[2]), int(out[-1])
else:
from os import uname

osname, host, release, version, machine = uname()
return "{}.{}.0.0".format(version, release), _MISSING_BD
# We expect all AIX systems to have lslpp installed in this location
out = subprocess.check_output(["/usr/bin/lslpp", "-Lqc", "bos.mp64"])
out = out.decode("utf-8")
out = out.strip().split(":") # type: ignore
# Use str() and int() to help mypy see types
return (str(out[2]), int(out[-1]))


def aix_platform():
Expand Down Expand Up @@ -87,13 +67,23 @@ def aix_platform():
# extract vrtl from the BUILD_GNU_TYPE as an int
def _aix_bgt():
# type: () -> List[int]
assert _bgt
return _aix_vrtl(vrmf=_bgt)
gnu_type = sysconfig.get_config_var("BUILD_GNU_TYPE")
if not gnu_type:
raise ValueError("BUILD_GNU_TYPE is not defined")
return _aix_vrtl(vrmf=gnu_type)


def aix_buildtag():
# type: () -> str
"""
Return the platform_tag of the system Python was built on.
"""
return _aix_tag(_aix_bgt(), _bd)
# AIX_BUILDDATE is defined by configure with:
# lslpp -Lcq bos.mp64 | awk -F: '{ print $NF }'
build_date = sysconfig.get_config_var("AIX_BUILDDATE")
try:
build_date = int(build_date)
except (ValueError, TypeError):
raise ValueError(f"AIX_BUILDDATE is not defined or invalid: "
f"{build_date!r}")
return _aix_tag(_aix_bgt(), build_date)
4 changes: 4 additions & 0 deletions Lib/test/test_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2754,6 +2754,10 @@ def test_memoryview_cast_1D_ND(self):
# be 1D, at least one format must be 'c', 'b' or 'B'.
for _tshape in gencastshapes():
for char in fmtdict['@']:
# Casts to _Bool are undefined if the source contains values
# other than 0 or 1.
if char == "?":
continue
tfmt = ('', '@')[randrange(2)] + char
tsize = struct.calcsize(tfmt)
n = prod(_tshape) * tsize
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Add ``--with-platlibdir`` option to the configure script: name of the
platform-specific library directory, stored in the new :attr:`sys.platlitdir`
platform-specific library directory, stored in the new :attr:`sys.platlibdir`
attribute. It is used to build the path of platform-specific dynamic libraries
and the path of the standard library. It is equal to ``"lib"`` on most
platforms. On Fedora and SuSE, it is equal to ``"lib64"`` on 64-bit platforms.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Add a private API to get and set the frame evaluation function: add
:c:func:`_PyInterpreterState_GetEvalFrameFunc` and
:c:func:`_PyInterpreterState_SetEvalFrameFunc` C functions.
The :c:type:`_PyFrameEvalFunction` function type now takes a *tstate*
parameter.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:c:func:`PyDescr_NewMethod` and :c:func:`PyCFunction_NewEx` now include the
method name in the SystemError "bad call flags" error message to ease debug.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
AIX: Fix _aix_support module when the subprocess is not available, when
building Python from scratch. It now uses new private _bootsubprocess
module, rather than having two implementations depending if subprocess is
available or not. So _aix_support.aix_platform() result is now the same if
subprocess is available or not.
6 changes: 1 addition & 5 deletions Modules/_collectionsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2133,12 +2133,8 @@ defdict_repr(defdictobject *dd)
static PyObject*
defdict_or(PyObject* left, PyObject* right)
{
int left_is_self = PyObject_IsInstance(left, (PyObject*)&defdict_type);
if (left_is_self < 0) {
return NULL;
}
PyObject *self, *other;
if (left_is_self) {
if (PyObject_TypeCheck(left, &defdict_type)) {
self = left;
other = right;
}
Expand Down
8 changes: 4 additions & 4 deletions Modules/unicodedata.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ nfd_nfkd(PyObject *self, PyObject *input, int k)
}

static int
find_nfc_index(PyObject *self, struct reindex* nfc, Py_UCS4 code)
find_nfc_index(const struct reindex* nfc, Py_UCS4 code)
{
unsigned int index;
for (index = 0; nfc[index].start; index++) {
Expand Down Expand Up @@ -709,7 +709,7 @@ nfc_nfkc(PyObject *self, PyObject *input, int k)
}

/* code is still input[i] here */
f = find_nfc_index(self, nfc_first, code);
f = find_nfc_index(nfc_first, code);
if (f == -1) {
output[o++] = code;
i++;
Expand All @@ -732,7 +732,7 @@ nfc_nfkc(PyObject *self, PyObject *input, int k)
continue;
}
}
l = find_nfc_index(self, nfc_last, code1);
l = find_nfc_index(nfc_last, code1);
/* i1 cannot be combined with i. If i1
is a starter, we don't need to look further.
Otherwise, record the combining class. */
Expand All @@ -757,7 +757,7 @@ nfc_nfkc(PyObject *self, PyObject *input, int k)
assert(cskipped < 20);
skipped[cskipped++] = i1;
i1++;
f = find_nfc_index(self, nfc_first, output[o]);
f = find_nfc_index(nfc_first, output[o]);
if (f == -1)
break;
}
Expand Down
3 changes: 2 additions & 1 deletion Objects/descrobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,8 @@ PyDescr_NewMethod(PyTypeObject *type, PyMethodDef *method)
vectorcall = method_vectorcall_O;
break;
default:
PyErr_SetString(PyExc_SystemError, "bad call flags");
PyErr_Format(PyExc_SystemError,
"%s() method: bad call flags", method->ml_name);
return NULL;
}

Expand Down
3 changes: 2 additions & 1 deletion Objects/methodobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module)
vectorcall = cfunction_vectorcall_O;
break;
default:
PyErr_SetString(PyExc_SystemError, "bad call flags");
PyErr_Format(PyExc_SystemError,
"%s() method: bad call flags", ml->ml_name);
return NULL;
}

Expand Down
15 changes: 6 additions & 9 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,9 +725,7 @@ PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals)
PyObject *
PyEval_EvalFrame(PyFrameObject *f)
{
/* This is for backward compatibility with extension modules that
used this API; core interpreter code should call
PyEval_EvalFrameEx() */
/* Function kept for backward compatibility */
PyThreadState *tstate = _PyThreadState_GET();
return _PyEval_EvalFrame(tstate, f, 0);
}
Expand All @@ -740,8 +738,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
}

PyObject* _Py_HOT_FUNCTION
_PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
_PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
{
ensure_tstate_not_null(__func__, tstate);

#ifdef DXPAIRS
int lastopcode = 0;
#endif
Expand All @@ -756,9 +756,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
_Py_atomic_int * const eval_breaker = &ceval->eval_breaker;
PyCodeObject *co;

PyThreadState * const tstate = _PyRuntimeState_GetThreadState(runtime);
ensure_tstate_not_null(__func__, tstate);

/* when tracing we set things up so that

not (instr_lb <= current_bytecode_offset < instr_ub)
Expand Down Expand Up @@ -1181,7 +1178,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
goto error;

#ifdef Py_DEBUG
/* PyEval_EvalFrameEx() must not be called with an exception set,
/* _PyEval_EvalFrameDefault() must not be called with an exception set,
because it can clear it (directly or indirectly) and so the
caller loses its exception */
assert(!_PyErr_Occurred(tstate));
Expand Down Expand Up @@ -3702,7 +3699,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
f->f_executing = 0;
tstate->frame = f->f_back;

return _Py_CheckFunctionResult(tstate, NULL, retval, "PyEval_EvalFrameEx");
return _Py_CheckFunctionResult(tstate, NULL, retval, __func__);
}

static void
Expand Down
Loading