From d73cf7ca85fb60b739e671597aabe72cc36d397a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 26 Sep 2020 12:48:41 +0200 Subject: bpo-41428: Fix compiler warning in unionobject.c (GH-22416) Use Py_ssize_t type rather than int, to store lengths in unionobject.c. Fix the warning: Objects\unionobject.c(205,1): warning C4244: 'initializing': conversion from 'Py_ssize_t' to 'int', possible loss of data --- Objects/unionobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/unionobject.c b/Objects/unionobject.c index e055a55e91..8cfb2a6647 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -202,8 +202,8 @@ flatten_args(PyObject* args) PyTypeObject* arg_type = Py_TYPE(arg); if (arg_type == &_Py_UnionType) { PyObject* nested_args = ((unionobject*)arg)->args; - int nested_arg_length = PyTuple_GET_SIZE(nested_args); - for (int j = 0; j < nested_arg_length; j++) { + Py_ssize_t nested_arg_length = PyTuple_GET_SIZE(nested_args); + for (Py_ssize_t j = 0; j < nested_arg_length; j++) { PyObject* nested_arg = PyTuple_GET_ITEM(nested_args, j); Py_INCREF(nested_arg); PyTuple_SET_ITEM(flattened_args, pos, nested_arg); @@ -231,7 +231,7 @@ dedup_and_flatten_args(PyObject* args) return NULL; } // Add unique elements to an array. - int added_items = 0; + Py_ssize_t added_items = 0; for (Py_ssize_t i = 0; i < arg_length; i++) { int is_duplicate = 0; PyObject* i_element = PyTuple_GET_ITEM(args, i); -- cgit v1.2.1 From a195bceff7b552c5f86dec7894ff24dcc87235da Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Tue, 29 Sep 2020 01:16:21 +0900 Subject: bpo-41870: Use PEP 590 vectorcall to speed up bool() (GH-22427) * bpo-41870: Use PEP 590 vectorcall to speed up bool() * bpo-41870: Add NEWS.d --- Objects/boolobject.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'Objects') diff --git a/Objects/boolobject.c b/Objects/boolobject.c index 720835b98a..ab7669cb24 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -55,6 +55,30 @@ bool_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return PyBool_FromLong(ok); } +static PyObject * +bool_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + long ok = 0; + if (!_PyArg_NoKwnames("bool", kwnames)) { + return NULL; + } + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("bool", nargs, 0, 1)) { + return NULL; + } + + assert(PyType_Check(type)); + if (nargs) { + ok = PyObject_IsTrue(args[0]); + } + if (ok < 0) { + return NULL; + } + return PyBool_FromLong(ok); +} + /* Arithmetic operations redefined to return bool if both args are bool. */ static PyObject * @@ -170,6 +194,7 @@ PyTypeObject PyBool_Type = { 0, /* tp_init */ 0, /* tp_alloc */ bool_new, /* tp_new */ + .tp_vectorcall = bool_vectorcall, }; /* The objects representing bool values False and True */ -- cgit v1.2.1 From e8acc355d430b45f1c3ff83312e72272262a854f Mon Sep 17 00:00:00 2001 From: Dennis Sweeney <36520290+sweeneyde@users.noreply.github.com> Date: Mon, 28 Sep 2020 20:55:52 -0400 Subject: bpo-41873: Add vectorcall for float() (GH-22432) --- Objects/floatobject.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'Objects') diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 0606f29ff5..d0af0ea1a9 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1649,6 +1649,24 @@ float_subtype_new(PyTypeObject *type, PyObject *x) return newobj; } +static PyObject * +float_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + if (!_PyArg_NoKwnames("float", kwnames)) { + return NULL; + } + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("float", nargs, 0, 1)) { + return NULL; + } + + PyObject *x = nargs >= 1 ? args[0] : _PyLong_Zero; + return float_new_impl((PyTypeObject *)type, x); +} + + /*[clinic input] float.__getnewargs__ [clinic start generated code]*/ @@ -1937,6 +1955,7 @@ PyTypeObject PyFloat_Type = { 0, /* tp_init */ 0, /* tp_alloc */ float_new, /* tp_new */ + .tp_vectorcall = (vectorcallfunc)float_vectorcall, }; int -- cgit v1.2.1 From fa7ce080175f65d678a7d5756c94f82887fc9803 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Thu, 1 Oct 2020 13:50:40 +0900 Subject: bpo-41870: Avoid the test when nargs=0 (GH-22462) --- Objects/boolobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Objects') diff --git a/Objects/boolobject.c b/Objects/boolobject.c index ab7669cb24..b786966533 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -72,9 +72,9 @@ bool_vectorcall(PyObject *type, PyObject * const*args, assert(PyType_Check(type)); if (nargs) { ok = PyObject_IsTrue(args[0]); - } - if (ok < 0) { - return NULL; + if (ok < 0) { + return NULL; + } } return PyBool_FromLong(ok); } -- cgit v1.2.1 From 58a7da9e125422323f79c4ee95ac5549989d8162 Mon Sep 17 00:00:00 2001 From: Robert Smallshire Date: Thu, 1 Oct 2020 18:30:08 +0200 Subject: bpo-26680: Incorporate is_integer in all built-in and standard library numeric types (GH-6121) * bpo-26680: Adds support for int.is_integer() for compatibility with float.is_integer(). The int.is_integer() method always returns True. * bpo-26680: Adds a test to ensure that False.is_integer() and True.is_integer() are always True. * bpo-26680: Adds Real.is_integer() with a trivial implementation using conversion to int. This default implementation is intended to reduce the workload for subclass implementers. It is not robust in the presence of infinities or NaNs and may have suboptimal performance for other types. * bpo-26680: Adds Rational.is_integer which returns True if the denominator is one. This implementation assumes the Rational is represented in it's lowest form, as required by the class docstring. * bpo-26680: Adds Integral.is_integer which always returns True. * bpo-26680: Adds tests for Fraction.is_integer called as an instance method. The tests for the Rational abstract base class use an unbound method to sidestep the inability to directly instantiate Rational. These tests check that everything works correct as an instance method. * bpo-26680: Updates documentation for Real.is_integer and built-ins int and float. The call x.is_integer() is now listed in the table of operations which apply to all numeric types except complex, with a reference to the full documentation for Real.is_integer(). Mention of is_integer() has been removed from the section 'Additional Methods on Float'. The documentation for Real.is_integer() describes its purpose, and mentions that it should be overridden for performance reasons, or to handle special values like NaN. * bpo-26680: Adds Decimal.is_integer to the Python and C implementations. The C implementation of Decimal already implements and uses mpd_isinteger internally, we just expose the existing function to Python. The Python implementation uses internal conversion to integer using to_integral_value(). In both cases, the corresponding context methods are also implemented. Tests and documentation are included. * bpo-26680: Updates the ACKS file. * bpo-26680: NEWS entries for int, the numeric ABCs and Decimal. Co-authored-by: Robert Smallshire --- Objects/clinic/longobject.c.h | 20 +++++++++++++++++++- Objects/longobject.c | 14 ++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h index 4bd47b116f..16e6f7e619 100644 --- a/Objects/clinic/longobject.c.h +++ b/Objects/clinic/longobject.c.h @@ -121,6 +121,24 @@ exit: return return_value; } +PyDoc_STRVAR(int_is_integer__doc__, +"is_integer($self, /)\n" +"--\n" +"\n" +"Returns True for all integers."); + +#define INT_IS_INTEGER_METHODDEF \ + {"is_integer", (PyCFunction)int_is_integer, METH_NOARGS, int_is_integer__doc__}, + +static PyObject * +int_is_integer_impl(PyObject *self); + +static PyObject * +int_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return int_is_integer_impl(self); +} + PyDoc_STRVAR(int___sizeof____doc__, "__sizeof__($self, /)\n" "--\n" @@ -367,4 +385,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=ea18e51af5b53591 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=022614978e2fcdf3 input=a9049054013a1b77]*/ diff --git a/Objects/longobject.c b/Objects/longobject.c index 92514d4154..bc5b49dcf8 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -5233,6 +5233,19 @@ int___round___impl(PyObject *self, PyObject *o_ndigits) return result; } +/*[clinic input] +int.is_integer + +Returns True for all integers. +[clinic start generated code]*/ + +static PyObject * +int_is_integer_impl(PyObject *self) +/*[clinic end generated code: output=90f8e794ce5430ef input=1c1a86957301d26d]*/ +{ + Py_RETURN_TRUE; +} + /*[clinic input] int.__sizeof__ -> Py_ssize_t @@ -5547,6 +5560,7 @@ static PyMethodDef long_methods[] = { {"__ceil__", long_long_meth, METH_NOARGS, "Ceiling of an Integral returns itself."}, INT___ROUND___METHODDEF + INT_IS_INTEGER_METHODDEF INT___GETNEWARGS___METHODDEF INT___FORMAT___METHODDEF INT___SIZEOF___METHODDEF -- cgit v1.2.1 From 583ee5a5b1971a18ebeb877948ce6264da0cc8aa Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 2 Oct 2020 14:49:00 +0200 Subject: bpo-41692: Deprecate PyUnicode_InternImmortal() (GH-22486) The PyUnicode_InternImmortal() function is now deprecated and will be removed in Python 3.12: use PyUnicode_InternInPlace() instead. --- Objects/unicodeobject.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f32ab417c3..cf72238a8d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -15764,6 +15764,15 @@ PyUnicode_InternInPlace(PyObject **p) void PyUnicode_InternImmortal(PyObject **p) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "PyUnicode_InternImmortal() is deprecated; " + "use PyUnicode_InternInPlace() instead", 1) < 0) + { + // The function has no return value, the exception cannot + // be reported to the caller, so just log it. + PyErr_WriteUnraisable(NULL); + } + PyUnicode_InternInPlace(p); if (PyUnicode_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) { _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL; -- cgit v1.2.1 From d646e91f5c4f4b76f96494103d440ed0b6257425 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 4 Oct 2020 02:16:56 +0900 Subject: bpo-41922: Use PEP 590 vectorcall to speed up reversed() (GH-22523) --- Objects/enumobject.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'Objects') diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 4a83bb45aa..9d8449bb30 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -314,6 +314,24 @@ reversed_new_impl(PyTypeObject *type, PyObject *seq) return (PyObject *)ro; } +static PyObject * +reversed_vectorcall(PyObject *type, PyObject * const*args, + size_t nargsf, PyObject *kwnames) +{ + assert(PyType_Check(type)); + + if (!_PyArg_NoKwnames("reversed", kwnames)) { + return NULL; + } + + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + if (!_PyArg_CheckPositional("reversed", nargs, 1, 1)) { + return NULL; + } + + return reversed_new_impl((PyTypeObject *)type, args[0]); +} + static void reversed_dealloc(reversedobject *ro) { @@ -445,4 +463,5 @@ PyTypeObject PyReversed_Type = { PyType_GenericAlloc, /* tp_alloc */ reversed_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ + .tp_vectorcall = (vectorcallfunc)reversed_vectorcall, }; -- cgit v1.2.1 From 9ece9cd65cdeb0a1f6e60475bbd0219161c348ac Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 5 Oct 2020 00:55:57 +0300 Subject: bpo-41909: Enable previously disabled recursion checks. (GH-22536) Enable recursion checks which were disabled when get __bases__ of non-type objects in issubclass() and isinstance() and when intern strings. It fixes a stack overflow when getting __bases__ leads to infinite recursion. Originally recursion checks was disabled for PyDict_GetItem() which silences all errors including the one raised in case of detected recursion and can return incorrect result. But now the code uses PyDict_GetItemWithError() and PyDict_SetDefault() instead. --- Objects/abstract.c | 2 -- Objects/unicodeobject.c | 2 -- 2 files changed, 4 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index c471f184f6..c30fb4eb6a 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2336,9 +2336,7 @@ abstract_get_bases(PyObject *cls) _Py_IDENTIFIER(__bases__); PyObject *bases; - Py_ALLOW_RECURSION (void)_PyObject_LookupAttrId(cls, &PyId___bases__, &bases); - Py_END_ALLOW_RECURSION if (bases != NULL && !PyTuple_Check(bases)) { Py_DECREF(bases); return NULL; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index cf72238a8d..6ae06a508c 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -15734,9 +15734,7 @@ PyUnicode_InternInPlace(PyObject **p) } PyObject *t; - Py_ALLOW_RECURSION t = PyDict_SetDefault(interned, s, s); - Py_END_ALLOW_RECURSION if (t == NULL) { PyErr_Clear(); -- cgit v1.2.1 From f90dc36c15d7fee0efaf6d39e97be0bdf2683e93 Mon Sep 17 00:00:00 2001 From: Stefan Pochmann <609905+pochmann@users.noreply.github.com> Date: Wed, 7 Oct 2020 16:12:52 +0200 Subject: Fix comment about PyObject_IsTrue. (GH-22343) The `for` statement doesn't use a condition and this function, the `while` statement does. --- Objects/object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index fe3734404f..9889503cfd 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1387,7 +1387,7 @@ PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) } -/* Test a value used as condition, e.g., in a for or if statement. +/* Test a value used as condition, e.g., in a while or if statement. Return -1 if an error occurred */ int -- cgit v1.2.1 From 4e0ce820586e93cfcefb16c2a3df8eaefc54cbca Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 7 Oct 2020 16:43:44 -0700 Subject: Revert "bpo-26680: Incorporate is_integer in all built-in and standard library numeric types (GH-6121)" (GH-22584) This reverts commit 58a7da9e125422323f79c4ee95ac5549989d8162. --- Objects/clinic/longobject.c.h | 20 +------------------- Objects/longobject.c | 14 -------------- 2 files changed, 1 insertion(+), 33 deletions(-) (limited to 'Objects') diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h index 16e6f7e619..4bd47b116f 100644 --- a/Objects/clinic/longobject.c.h +++ b/Objects/clinic/longobject.c.h @@ -121,24 +121,6 @@ exit: return return_value; } -PyDoc_STRVAR(int_is_integer__doc__, -"is_integer($self, /)\n" -"--\n" -"\n" -"Returns True for all integers."); - -#define INT_IS_INTEGER_METHODDEF \ - {"is_integer", (PyCFunction)int_is_integer, METH_NOARGS, int_is_integer__doc__}, - -static PyObject * -int_is_integer_impl(PyObject *self); - -static PyObject * -int_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return int_is_integer_impl(self); -} - PyDoc_STRVAR(int___sizeof____doc__, "__sizeof__($self, /)\n" "--\n" @@ -385,4 +367,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=022614978e2fcdf3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ea18e51af5b53591 input=a9049054013a1b77]*/ diff --git a/Objects/longobject.c b/Objects/longobject.c index bc5b49dcf8..92514d4154 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -5233,19 +5233,6 @@ int___round___impl(PyObject *self, PyObject *o_ndigits) return result; } -/*[clinic input] -int.is_integer - -Returns True for all integers. -[clinic start generated code]*/ - -static PyObject * -int_is_integer_impl(PyObject *self) -/*[clinic end generated code: output=90f8e794ce5430ef input=1c1a86957301d26d]*/ -{ - Py_RETURN_TRUE; -} - /*[clinic input] int.__sizeof__ -> Py_ssize_t @@ -5560,7 +5547,6 @@ static PyMethodDef long_methods[] = { {"__ceil__", long_long_meth, METH_NOARGS, "Ceiling of an Integral returns itself."}, INT___ROUND___METHODDEF - INT_IS_INTEGER_METHODDEF INT___GETNEWARGS___METHODDEF INT___FORMAT___METHODDEF INT___SIZEOF___METHODDEF -- cgit v1.2.1 From 77f0a23e7a9fb247101b9b14a060c4ba1c4b87a5 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Fri, 9 Oct 2020 00:38:36 +0300 Subject: Fix the attribute names in the docstring of GenericAlias (GH-22594) --- Objects/genericaliasobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index ab56e1c4bf..6508c69cbf 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -582,7 +582,7 @@ PyTypeObject Py_GenericAliasType = { .tp_name = "types.GenericAlias", .tp_doc = "Represent a PEP 585 generic type\n" "\n" - "E.g. for t = list[int], t.origin is list and t.args is (int,).", + "E.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).", .tp_basicsize = sizeof(gaobject), .tp_dealloc = ga_dealloc, .tp_repr = ga_repr, -- cgit v1.2.1 From e2ec0b27c02a158d0007c11dcc1f2d7a95948712 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 9 Oct 2020 14:14:37 +0300 Subject: bpo-41974: Remove complex.__float__, complex.__floordiv__, etc (GH-22593) Remove complex special methods __int__, __float__, __floordiv__, __mod__, __divmod__, __rfloordiv__, __rmod__ and __rdivmod__ which always raised a TypeError. --- Objects/abstract.c | 10 ++++----- Objects/bytesobject.c | 2 +- Objects/complexobject.c | 59 +++++++++---------------------------------------- Objects/floatobject.c | 2 +- Objects/unicodeobject.c | 2 +- 5 files changed, 19 insertions(+), 56 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index c30fb4eb6a..2ab3371a3f 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -747,10 +747,10 @@ done: int PyNumber_Check(PyObject *o) { - return o && Py_TYPE(o)->tp_as_number && - (Py_TYPE(o)->tp_as_number->nb_index || - Py_TYPE(o)->tp_as_number->nb_int || - Py_TYPE(o)->tp_as_number->nb_float); + if (o == NULL) + return 0; + PyNumberMethods *nb = Py_TYPE(o)->tp_as_number; + return nb && (nb->nb_index || nb->nb_int || nb->nb_float || PyComplex_Check(o)); } /* Binary operators */ @@ -1461,7 +1461,7 @@ PyNumber_Long(PyObject *o) } return type_error("int() argument must be a string, a bytes-like object " - "or a number, not '%.200s'", o); + "or a real number, not '%.200s'", o); } PyObject * diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 836a736037..990730cd8c 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -522,7 +522,7 @@ formatlong(PyObject *v, int flags, int prec, int type) PyErr_Format(PyExc_TypeError, "%%%c format: %s is required, not %.200s", type, (type == 'o' || type == 'x' || type == 'X') ? "an integer" - : "a number", + : "a real number", Py_TYPE(v)->tp_name); return NULL; } diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 69f6c17b4a..5ab839a9e9 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -509,23 +509,6 @@ complex_div(PyObject *v, PyObject *w) return PyComplex_FromCComplex(quot); } -static PyObject * -complex_remainder(PyObject *v, PyObject *w) -{ - PyErr_SetString(PyExc_TypeError, - "can't mod complex numbers."); - return NULL; -} - - -static PyObject * -complex_divmod(PyObject *v, PyObject *w) -{ - PyErr_SetString(PyExc_TypeError, - "can't take floor or mod of complex number."); - return NULL; -} - static PyObject * complex_pow(PyObject *v, PyObject *w, PyObject *z) { @@ -562,14 +545,6 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z) return PyComplex_FromCComplex(p); } -static PyObject * -complex_int_div(PyObject *v, PyObject *w) -{ - PyErr_SetString(PyExc_TypeError, - "can't take floor of complex number."); - return NULL; -} - static PyObject * complex_neg(PyComplexObject *v) { @@ -668,22 +643,6 @@ Unimplemented: Py_RETURN_NOTIMPLEMENTED; } -static PyObject * -complex_int(PyObject *v) -{ - PyErr_SetString(PyExc_TypeError, - "can't convert complex to int"); - return NULL; -} - -static PyObject * -complex_float(PyObject *v) -{ - PyErr_SetString(PyExc_TypeError, - "can't convert complex to float"); - return NULL; -} - /*[clinic input] complex.conjugate @@ -966,7 +925,9 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) } nbr = Py_TYPE(r)->tp_as_number; - if (nbr == NULL || (nbr->nb_float == NULL && nbr->nb_index == NULL)) { + if (nbr == NULL || + (nbr->nb_float == NULL && nbr->nb_index == NULL && !PyComplex_Check(r))) + { PyErr_Format(PyExc_TypeError, "complex() first argument must be a string or a number, " "not '%.200s'", @@ -978,7 +939,9 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) } if (i != NULL) { nbi = Py_TYPE(i)->tp_as_number; - if (nbi == NULL || (nbi->nb_float == NULL && nbi->nb_index == NULL)) { + if (nbi == NULL || + (nbi->nb_float == NULL && nbi->nb_index == NULL && !PyComplex_Check(i))) + { PyErr_Format(PyExc_TypeError, "complex() second argument must be a number, " "not '%.200s'", @@ -1057,8 +1020,8 @@ static PyNumberMethods complex_as_number = { (binaryfunc)complex_add, /* nb_add */ (binaryfunc)complex_sub, /* nb_subtract */ (binaryfunc)complex_mul, /* nb_multiply */ - (binaryfunc)complex_remainder, /* nb_remainder */ - (binaryfunc)complex_divmod, /* nb_divmod */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ (ternaryfunc)complex_pow, /* nb_power */ (unaryfunc)complex_neg, /* nb_negative */ (unaryfunc)complex_pos, /* nb_positive */ @@ -1070,9 +1033,9 @@ static PyNumberMethods complex_as_number = { 0, /* nb_and */ 0, /* nb_xor */ 0, /* nb_or */ - complex_int, /* nb_int */ + 0, /* nb_int */ 0, /* nb_reserved */ - complex_float, /* nb_float */ + 0, /* nb_float */ 0, /* nb_inplace_add */ 0, /* nb_inplace_subtract */ 0, /* nb_inplace_multiply*/ @@ -1083,7 +1046,7 @@ static PyNumberMethods complex_as_number = { 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ - (binaryfunc)complex_int_div, /* nb_floor_divide */ + 0, /* nb_floor_divide */ (binaryfunc)complex_div, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ diff --git a/Objects/floatobject.c b/Objects/floatobject.c index d0af0ea1a9..828bde18df 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -215,7 +215,7 @@ PyFloat_FromString(PyObject *v) } else { PyErr_Format(PyExc_TypeError, - "float() argument must be a string or a number, not '%.200s'", + "float() argument must be a string or a real number, not '%.200s'", Py_TYPE(v)->tp_name); return NULL; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 6ae06a508c..01e5c728b3 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -14839,7 +14839,7 @@ wrongtype: break; default: PyErr_Format(PyExc_TypeError, - "%%%c format: a number is required, " + "%%%c format: a real number is required, " "not %.200s", type, Py_TYPE(v)->tp_name); break; -- cgit v1.2.1 From 9975cc5008c795e069ce11e2dbed2110cc12e74e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 9 Oct 2020 23:00:45 +0300 Subject: bpo-41985: Add _PyLong_FileDescriptor_Converter and AC converter for "fildes". (GH-22620) --- Objects/fileobject.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Objects') diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 1c6ecaf82c..9b89448006 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -223,6 +223,17 @@ PyObject_AsFileDescriptor(PyObject *o) return fd; } +int +_PyLong_FileDescriptor_Converter(PyObject *o, void *ptr) +{ + int fd = PyObject_AsFileDescriptor(o); + if (fd == -1) { + return 0; + } + *(int *)ptr = fd; + return 1; +} + /* ** Py_UniversalNewlineFgets is an fgets variation that understands ** all of \r, \n and \r\n conventions. -- cgit v1.2.1 From 037245c5ac46c3436f617a1f5d965929754be239 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 9 Oct 2020 17:15:15 -0700 Subject: bpo-41756: Add PyIter_Send function (#22443) --- Objects/abstract.c | 24 ++++++++++++++++++++++++ Objects/genobject.c | 8 +------- 2 files changed, 25 insertions(+), 7 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index 2ab3371a3f..502a2d64e2 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2669,6 +2669,30 @@ PyIter_Next(PyObject *iter) return result; } +PySendResult +PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) +{ + _Py_IDENTIFIER(send); + assert(result != NULL); + + if (PyGen_CheckExact(iter) || PyCoro_CheckExact(iter)) { + return PyGen_Send((PyGenObject *)iter, arg, result); + } + + if (arg == Py_None && PyIter_Check(iter)) { + *result = Py_TYPE(iter)->tp_iternext(iter); + } + else { + *result = _PyObject_CallMethodIdOneArg(iter, &PyId_send, arg); + } + if (*result != NULL) { + return PYGEN_NEXT; + } + if (_PyGen_FetchStopIterationValue(result) == 0) { + return PYGEN_RETURN; + } + return PYGEN_ERROR; +} /* * Flatten a sequence of bytes() objects into a C array of diff --git a/Objects/genobject.c b/Objects/genobject.c index f0943ae847..eb134ebf4b 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -308,12 +308,6 @@ gen_send(PyGenObject *gen, PyObject *arg) return gen_send_ex(gen, arg, 0, 0); } -PyObject * -_PyGen_Send(PyGenObject *gen, PyObject *arg) -{ - return gen_send(gen, arg); -} - PyDoc_STRVAR(close_doc, "close() -> raise GeneratorExit inside generator."); @@ -1012,7 +1006,7 @@ PyDoc_STRVAR(coro_close_doc, "close() -> raise GeneratorExit inside coroutine."); static PyMethodDef coro_methods[] = { - {"send",(PyCFunction)_PyGen_Send, METH_O, coro_send_doc}, + {"send",(PyCFunction)gen_send, METH_O, coro_send_doc}, {"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc}, {"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc}, {NULL, NULL} /* Sentinel */ -- cgit v1.2.1 From 98c4433a81a4cd88c7438adbee1f2aa486188ca3 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 10 Oct 2020 22:23:42 +0300 Subject: bpo-41991: Remove _PyObject_HasAttrId (GH-22629) It can silence arbitrary exceptions. --- Objects/object.c | 11 ----------- Objects/unionobject.c | 13 +++++++------ 2 files changed, 7 insertions(+), 17 deletions(-) (limited to 'Objects') diff --git a/Objects/object.c b/Objects/object.c index 9889503cfd..7bc3e48d40 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -854,17 +854,6 @@ _PyObject_GetAttrId(PyObject *v, _Py_Identifier *name) return result; } -int -_PyObject_HasAttrId(PyObject *v, _Py_Identifier *name) -{ - int result; - PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ - if (!oname) - return -1; - result = PyObject_HasAttr(v, oname); - return result; -} - int _PyObject_SetAttrId(PyObject *v, _Py_Identifier *name, PyObject *w) { diff --git a/Objects/unionobject.c b/Objects/unionobject.c index 8cfb2a6647..89fdaf4256 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -311,21 +311,22 @@ union_repr_item(_PyUnicodeWriter *writer, PyObject *p) _Py_IDENTIFIER(__args__); PyObject *qualname = NULL; PyObject *module = NULL; + PyObject *tmp; PyObject *r = NULL; int err; - int has_origin = _PyObject_HasAttrId(p, &PyId___origin__); - if (has_origin < 0) { + if (_PyObject_LookupAttrId(p, &PyId___origin__, &tmp) < 0) { goto exit; } - if (has_origin) { - int has_args = _PyObject_HasAttrId(p, &PyId___args__); - if (has_args < 0) { + if (tmp) { + Py_DECREF(tmp); + if (_PyObject_LookupAttrId(p, &PyId___args__, &tmp) < 0) { goto exit; } - if (has_args) { + if (tmp) { // It looks like a GenericAlias + Py_DECREF(tmp); goto use_repr; } } -- cgit v1.2.1 From 24a54c0bd48d9f6f1a1289ca57afb381bc4b280e Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 12 Oct 2020 12:10:42 -0700 Subject: Delete PyGen_Send (#22663) --- Objects/abstract.c | 25 ------------------------- Objects/genobject.c | 24 ++++++++++++++++++++---- 2 files changed, 20 insertions(+), 29 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index 502a2d64e2..562549876b 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2669,31 +2669,6 @@ PyIter_Next(PyObject *iter) return result; } -PySendResult -PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) -{ - _Py_IDENTIFIER(send); - assert(result != NULL); - - if (PyGen_CheckExact(iter) || PyCoro_CheckExact(iter)) { - return PyGen_Send((PyGenObject *)iter, arg, result); - } - - if (arg == Py_None && PyIter_Check(iter)) { - *result = Py_TYPE(iter)->tp_iternext(iter); - } - else { - *result = _PyObject_CallMethodIdOneArg(iter, &PyId_send, arg); - } - if (*result != NULL) { - return PYGEN_NEXT; - } - if (_PyGen_FetchStopIterationValue(result) == 0) { - return PYGEN_RETURN; - } - return PYGEN_ERROR; -} - /* * Flatten a sequence of bytes() objects into a C array of * NULL terminated string pointers with a NULL char* terminating the array. diff --git a/Objects/genobject.c b/Objects/genobject.c index eb134ebf4b..c1b26e9da3 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -269,13 +269,29 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, } PySendResult -PyGen_Send(PyGenObject *gen, PyObject *arg, PyObject **result) +PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result) { - assert(PyGen_CheckExact(gen) || PyCoro_CheckExact(gen)); - assert(result != NULL); + _Py_IDENTIFIER(send); assert(arg != NULL); + assert(result != NULL); + + if (PyGen_CheckExact(iter) || PyCoro_CheckExact(iter)) { + return gen_send_ex2((PyGenObject *)iter, arg, result, 0, 0); + } - return gen_send_ex2(gen, arg, result, 0, 0); + if (arg == Py_None && PyIter_Check(iter)) { + *result = Py_TYPE(iter)->tp_iternext(iter); + } + else { + *result = _PyObject_CallMethodIdOneArg(iter, &PyId_send, arg); + } + if (*result != NULL) { + return PYGEN_NEXT; + } + if (_PyGen_FetchStopIterationValue(result) == 0) { + return PYGEN_RETURN; + } + return PYGEN_ERROR; } static PyObject * -- cgit v1.2.1 From 04b8631d84a870dda456ef86039c1baf34d08500 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Mon, 12 Oct 2020 23:06:19 +0200 Subject: bpo-42015: Reorder dereferencing calls in meth_dealloc, to make sure m_self is kept alive long enough (GH-22670) --- Objects/methodobject.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 5659f2143d..7b430416c5 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -164,9 +164,11 @@ meth_dealloc(PyCFunctionObject *m) if (m->m_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*) m); } + // Dereference class before m_self: PyCFunction_GET_CLASS accesses + // PyMethodDef m_ml, which could be kept alive by m_self + Py_XDECREF(PyCFunction_GET_CLASS(m)); Py_XDECREF(m->m_self); Py_XDECREF(m->m_module); - Py_XDECREF(PyCFunction_GET_CLASS(m)); PyObject_GC_Del(m); } @@ -243,9 +245,9 @@ meth_get__qualname__(PyCFunctionObject *m, void *closure) static int meth_traverse(PyCFunctionObject *m, visitproc visit, void *arg) { + Py_VISIT(PyCFunction_GET_CLASS(m)); Py_VISIT(m->m_self); Py_VISIT(m->m_module); - Py_VISIT(PyCFunction_GET_CLASS(m)); return 0; } -- cgit v1.2.1 From c13b847a6f913b72eeb71651ff626390b738d973 Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Wed, 14 Oct 2020 18:44:07 -0700 Subject: bpo-41984: GC track all user classes (GH-22701) --- Objects/typeobject.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'Objects') diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 3bb2c338fe..36c7662e08 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2612,10 +2612,10 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) slots = NULL; /* Initialize tp_flags */ + // All heap types need GC, since we can create a reference cycle by storing + // an instance on one of its parents: type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | - Py_TPFLAGS_BASETYPE; - if (base->tp_flags & Py_TPFLAGS_HAVE_GC) - type->tp_flags |= Py_TPFLAGS_HAVE_GC; + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC; /* Initialize essential fields */ type->tp_as_async = &et->as_async; @@ -2815,21 +2815,11 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) } type->tp_dealloc = subtype_dealloc; - /* Enable GC unless this class is not adding new instance variables and - the base class did not use GC. */ - if ((base->tp_flags & Py_TPFLAGS_HAVE_GC) || - type->tp_basicsize > base->tp_basicsize) - type->tp_flags |= Py_TPFLAGS_HAVE_GC; - /* Always override allocation strategy to use regular heap */ type->tp_alloc = PyType_GenericAlloc; - if (type->tp_flags & Py_TPFLAGS_HAVE_GC) { - type->tp_free = PyObject_GC_Del; - type->tp_traverse = subtype_traverse; - type->tp_clear = subtype_clear; - } - else - type->tp_free = PyObject_Del; + type->tp_free = PyObject_GC_Del; + type->tp_traverse = subtype_traverse; + type->tp_clear = subtype_clear; /* store type in class' cell if one is supplied */ cell = _PyDict_GetItemIdWithError(dict, &PyId___classcell__); -- cgit v1.2.1 From 3635388f52b42e5280229104747962117104c453 Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Sat, 17 Oct 2020 13:38:21 -0700 Subject: bpo-42065: Fix incorrectly formatted _codecs.charmap_decode error message (GH-19940) --- Objects/unicodeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects') diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 01e5c728b3..c4e73ebd45 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -8304,7 +8304,7 @@ charmap_decode_mapping(const char *s, goto Undefined; if (value < 0 || value > MAX_UNICODE) { PyErr_Format(PyExc_TypeError, - "character mapping must be in range(0x%lx)", + "character mapping must be in range(0x%x)", (unsigned long)MAX_UNICODE + 1); goto onError; } -- cgit v1.2.1 From a0c603cb9d4dbb9909979313a88bcd1f5fde4f62 Mon Sep 17 00:00:00 2001 From: Ma Lin Date: Sun, 18 Oct 2020 22:48:38 +0800 Subject: bpo-38252: Use 8-byte step to detect ASCII sequence in 64bit Windows build (GH-16334) --- Objects/bytes_methods.c | 20 ++++++++++---------- Objects/stringlib/codecs.h | 30 +++++++++++++++--------------- Objects/stringlib/find_max_char.h | 20 ++++++++++---------- Objects/unicodeobject.c | 34 +++++++++++++++++----------------- 4 files changed, 52 insertions(+), 52 deletions(-) (limited to 'Objects') diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 72daa1fdd5..1512086e61 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -100,14 +100,14 @@ Return True if B is empty or all characters in B are ASCII,\n\ False otherwise."); // Optimization is copied from ascii_decode in unicodeobject.c -/* Mask to quickly check whether a C 'long' contains a +/* Mask to quickly check whether a C 'size_t' contains a non-ASCII, UTF8-encoded char. */ -#if (SIZEOF_LONG == 8) -# define ASCII_CHAR_MASK 0x8080808080808080UL -#elif (SIZEOF_LONG == 4) -# define ASCII_CHAR_MASK 0x80808080UL +#if (SIZEOF_SIZE_T == 8) +# define ASCII_CHAR_MASK 0x8080808080808080ULL +#elif (SIZEOF_SIZE_T == 4) +# define ASCII_CHAR_MASK 0x80808080U #else -# error C 'long' size should be either 4 or 8! +# error C 'size_t' size should be either 4 or 8! #endif PyObject* @@ -115,20 +115,20 @@ _Py_bytes_isascii(const char *cptr, Py_ssize_t len) { const char *p = cptr; const char *end = p + len; - const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); + const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_SIZE_T); while (p < end) { /* Fast path, see in STRINGLIB(utf8_decode) in stringlib/codecs.h for an explanation. */ - if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { + if (_Py_IS_ALIGNED(p, SIZEOF_SIZE_T)) { /* Help allocation */ const char *_p = p; while (_p < aligned_end) { - unsigned long value = *(const unsigned long *) _p; + size_t value = *(const size_t *) _p; if (value & ASCII_CHAR_MASK) { Py_RETURN_FALSE; } - _p += SIZEOF_LONG; + _p += SIZEOF_SIZE_T; } p = _p; if (_p == end) diff --git a/Objects/stringlib/codecs.h b/Objects/stringlib/codecs.h index 197605b012..b6ca404b1a 100644 --- a/Objects/stringlib/codecs.h +++ b/Objects/stringlib/codecs.h @@ -6,14 +6,14 @@ #include "pycore_bitutils.h" // _Py_bswap32() -/* Mask to quickly check whether a C 'long' contains a +/* Mask to quickly check whether a C 'size_t' contains a non-ASCII, UTF8-encoded char. */ -#if (SIZEOF_LONG == 8) -# define ASCII_CHAR_MASK 0x8080808080808080UL -#elif (SIZEOF_LONG == 4) -# define ASCII_CHAR_MASK 0x80808080UL +#if (SIZEOF_SIZE_T == 8) +# define ASCII_CHAR_MASK 0x8080808080808080ULL +#elif (SIZEOF_SIZE_T == 4) +# define ASCII_CHAR_MASK 0x80808080U #else -# error C 'long' size should be either 4 or 8! +# error C 'size_t' size should be either 4 or 8! #endif /* 10xxxxxx */ @@ -26,7 +26,7 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, { Py_UCS4 ch; const char *s = *inptr; - const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); + const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_SIZE_T); STRINGLIB_CHAR *p = dest + *outpos; while (s < end) { @@ -36,19 +36,19 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, /* Fast path for runs of ASCII characters. Given that common UTF-8 input will consist of an overwhelming majority of ASCII characters, we try to optimize for this case by checking - as many characters as a C 'long' can contain. + as many characters as a C 'size_t' can contain. First, check if we can do an aligned read, as most CPUs have a penalty for unaligned reads. */ - if (_Py_IS_ALIGNED(s, SIZEOF_LONG)) { + if (_Py_IS_ALIGNED(s, SIZEOF_SIZE_T)) { /* Help register allocation */ const char *_s = s; STRINGLIB_CHAR *_p = p; while (_s < aligned_end) { - /* Read a whole long at a time (either 4 or 8 bytes), + /* Read a whole size_t at a time (either 4 or 8 bytes), and do a fast unrolled copy if it only contains ASCII characters. */ - unsigned long value = *(const unsigned long *) _s; + size_t value = *(const size_t *) _s; if (value & ASCII_CHAR_MASK) break; #if PY_LITTLE_ENDIAN @@ -56,14 +56,14 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, _p[1] = (STRINGLIB_CHAR)((value >> 8) & 0xFFu); _p[2] = (STRINGLIB_CHAR)((value >> 16) & 0xFFu); _p[3] = (STRINGLIB_CHAR)((value >> 24) & 0xFFu); -# if SIZEOF_LONG == 8 +# if SIZEOF_SIZE_T == 8 _p[4] = (STRINGLIB_CHAR)((value >> 32) & 0xFFu); _p[5] = (STRINGLIB_CHAR)((value >> 40) & 0xFFu); _p[6] = (STRINGLIB_CHAR)((value >> 48) & 0xFFu); _p[7] = (STRINGLIB_CHAR)((value >> 56) & 0xFFu); # endif #else -# if SIZEOF_LONG == 8 +# if SIZEOF_SIZE_T == 8 _p[0] = (STRINGLIB_CHAR)((value >> 56) & 0xFFu); _p[1] = (STRINGLIB_CHAR)((value >> 48) & 0xFFu); _p[2] = (STRINGLIB_CHAR)((value >> 40) & 0xFFu); @@ -79,8 +79,8 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end, _p[3] = (STRINGLIB_CHAR)(value & 0xFFu); # endif #endif - _s += SIZEOF_LONG; - _p += SIZEOF_LONG; + _s += SIZEOF_SIZE_T; + _p += SIZEOF_SIZE_T; } s = _s; p = _p; diff --git a/Objects/stringlib/find_max_char.h b/Objects/stringlib/find_max_char.h index f4e0a7761d..3319a46461 100644 --- a/Objects/stringlib/find_max_char.h +++ b/Objects/stringlib/find_max_char.h @@ -4,14 +4,14 @@ # error "find_max_char.h is specific to Unicode" #endif -/* Mask to quickly check whether a C 'long' contains a +/* Mask to quickly check whether a C 'size_t' contains a non-ASCII, UTF8-encoded char. */ -#if (SIZEOF_LONG == 8) -# define UCS1_ASCII_CHAR_MASK 0x8080808080808080UL -#elif (SIZEOF_LONG == 4) -# define UCS1_ASCII_CHAR_MASK 0x80808080UL +#if (SIZEOF_SIZE_T == 8) +# define UCS1_ASCII_CHAR_MASK 0x8080808080808080ULL +#elif (SIZEOF_SIZE_T == 4) +# define UCS1_ASCII_CHAR_MASK 0x80808080U #else -# error C 'long' size should be either 4 or 8! +# error C 'size_t' size should be either 4 or 8! #endif #if STRINGLIB_SIZEOF_CHAR == 1 @@ -21,17 +21,17 @@ STRINGLIB(find_max_char)(const STRINGLIB_CHAR *begin, const STRINGLIB_CHAR *end) { const unsigned char *p = (const unsigned char *) begin; const unsigned char *aligned_end = - (const unsigned char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); + (const unsigned char *) _Py_ALIGN_DOWN(end, SIZEOF_SIZE_T); while (p < end) { - if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { + if (_Py_IS_ALIGNED(p, SIZEOF_SIZE_T)) { /* Help register allocation */ const unsigned char *_p = p; while (_p < aligned_end) { - unsigned long value = *(const unsigned long *) _p; + size_t value = *(const size_t *) _p; if (value & UCS1_ASCII_CHAR_MASK) return 255; - _p += SIZEOF_LONG; + _p += SIZEOF_SIZE_T; } p = _p; if (p == end) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index c4e73ebd45..f963deb020 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -5025,21 +5025,21 @@ PyUnicode_DecodeUTF8(const char *s, #include "stringlib/codecs.h" #include "stringlib/undef.h" -/* Mask to quickly check whether a C 'long' contains a +/* Mask to quickly check whether a C 'size_t' contains a non-ASCII, UTF8-encoded char. */ -#if (SIZEOF_LONG == 8) -# define ASCII_CHAR_MASK 0x8080808080808080UL -#elif (SIZEOF_LONG == 4) -# define ASCII_CHAR_MASK 0x80808080UL +#if (SIZEOF_SIZE_T == 8) +# define ASCII_CHAR_MASK 0x8080808080808080ULL +#elif (SIZEOF_SIZE_T == 4) +# define ASCII_CHAR_MASK 0x80808080U #else -# error C 'long' size should be either 4 or 8! +# error C 'size_t' size should be either 4 or 8! #endif static Py_ssize_t ascii_decode(const char *start, const char *end, Py_UCS1 *dest) { const char *p = start; - const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG); + const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_SIZE_T); /* * Issue #17237: m68k is a bit different from most architectures in @@ -5049,21 +5049,21 @@ ascii_decode(const char *start, const char *end, Py_UCS1 *dest) * version" will even speed up m68k. */ #if !defined(__m68k__) -#if SIZEOF_LONG <= SIZEOF_VOID_P - assert(_Py_IS_ALIGNED(dest, SIZEOF_LONG)); - if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { +#if SIZEOF_SIZE_T <= SIZEOF_VOID_P + assert(_Py_IS_ALIGNED(dest, SIZEOF_SIZE_T)); + if (_Py_IS_ALIGNED(p, SIZEOF_SIZE_T)) { /* Fast path, see in STRINGLIB(utf8_decode) for an explanation. */ /* Help allocation */ const char *_p = p; Py_UCS1 * q = dest; while (_p < aligned_end) { - unsigned long value = *(const unsigned long *) _p; + size_t value = *(const size_t *) _p; if (value & ASCII_CHAR_MASK) break; - *((unsigned long *)q) = value; - _p += SIZEOF_LONG; - q += SIZEOF_LONG; + *((size_t *)q) = value; + _p += SIZEOF_SIZE_T; + q += SIZEOF_SIZE_T; } p = _p; while (p < end) { @@ -5078,14 +5078,14 @@ ascii_decode(const char *start, const char *end, Py_UCS1 *dest) while (p < end) { /* Fast path, see in STRINGLIB(utf8_decode) in stringlib/codecs.h for an explanation. */ - if (_Py_IS_ALIGNED(p, SIZEOF_LONG)) { + if (_Py_IS_ALIGNED(p, SIZEOF_SIZE_T)) { /* Help allocation */ const char *_p = p; while (_p < aligned_end) { - unsigned long value = *(const unsigned long *) _p; + size_t value = *(const size_t *) _p; if (value & ASCII_CHAR_MASK) break; - _p += SIZEOF_LONG; + _p += SIZEOF_SIZE_T; } p = _p; if (_p == end) -- cgit v1.2.1