summaryrefslogtreecommitdiff
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c13
-rw-r--r--Objects/boolobject.c25
-rw-r--r--Objects/bytes_methods.c20
-rw-r--r--Objects/bytesobject.c2
-rw-r--r--Objects/complexobject.c59
-rw-r--r--Objects/enumobject.c19
-rw-r--r--Objects/fileobject.c11
-rw-r--r--Objects/floatobject.c21
-rw-r--r--Objects/genericaliasobject.c2
-rw-r--r--Objects/genobject.c32
-rw-r--r--Objects/methodobject.c6
-rw-r--r--Objects/object.c13
-rw-r--r--Objects/stringlib/codecs.h30
-rw-r--r--Objects/stringlib/find_max_char.h20
-rw-r--r--Objects/typeobject.c22
-rw-r--r--Objects/unicodeobject.c49
-rw-r--r--Objects/unionobject.c19
17 files changed, 198 insertions, 165 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index c471f184f6..562549876b 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 *
@@ -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;
@@ -2671,7 +2669,6 @@ PyIter_Next(PyObject *iter)
return result;
}
-
/*
* 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/boolobject.c b/Objects/boolobject.c
index 720835b98a..b786966533 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 */
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/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
@@ -510,23 +510,6 @@ complex_div(PyObject *v, PyObject *w)
}
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)
{
Py_complex p;
@@ -563,14 +546,6 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z)
}
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)
{
Py_complex neg;
@@ -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/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,
};
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.
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 0606f29ff5..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;
}
@@ -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
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,
diff --git a/Objects/genobject.c b/Objects/genobject.c
index f0943ae847..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);
- return gen_send_ex2(gen, arg, result, 0, 0);
+ if (PyGen_CheckExact(iter) || PyCoro_CheckExact(iter)) {
+ return gen_send_ex2((PyGenObject *)iter, 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 *
@@ -308,12 +324,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 +1022,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 */
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;
}
diff --git a/Objects/object.c b/Objects/object.c
index fe3734404f..7bc3e48d40 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -855,17 +855,6 @@ _PyObject_GetAttrId(PyObject *v, _Py_Identifier *name)
}
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)
{
int result;
@@ -1387,7 +1376,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
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/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__);
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index f32ab417c3..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)
@@ -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;
}
@@ -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;
@@ -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();
@@ -15764,6 +15762,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;
diff --git a/Objects/unionobject.c b/Objects/unionobject.c
index e055a55e91..89fdaf4256 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);
@@ -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;
}
}