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
Build Parsing.py in the limited api #5845
Changes from 2 commits
c7fe812
40503c7
4523bd9
30d7448
b3446fc
27949af
b188d8a
ef6da04
cc74491
0599937
b3421cd
7c12b4e
560169c
c16311a
cab9762
5561a15
d1979e9
709beee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,9 +52,17 @@ static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/ | |
static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) { | ||
if (t == Py_None) { | ||
__Pyx_RaiseNoneNotIterableError(); | ||
} else if (PyTuple_GET_SIZE(t) < index) { | ||
__Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t)); | ||
} else { | ||
#if CYTHON_ASSUME_SAFE_MACROS | ||
Py_ssize_t size = PyTuple_GET_SIZE(t); | ||
#else | ||
Py_ssize_t size = PyTuple_Size(t); | ||
if (unlikely(size < 0)) return; | ||
#endif | ||
if (size < index) { | ||
__Pyx_RaiseNeedMoreValuesError(size); | ||
return; | ||
} | ||
__Pyx_RaiseTooManyValuesError(index); | ||
da-woods marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
@@ -79,12 +87,17 @@ static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { | |
|
||
/////////////// UnpackTuple2.proto /////////////// | ||
|
||
#if CYTHON_ASSUME_SAFE_MACROS | ||
#define __Pyx_unpack_tuple2(tuple, value1, value2, is_tuple, has_known_size, decref_tuple) \ | ||
(likely(is_tuple || PyTuple_Check(tuple)) ? \ | ||
(likely(has_known_size || PyTuple_GET_SIZE(tuple) == 2) ? \ | ||
__Pyx_unpack_tuple2_exact(tuple, value1, value2, decref_tuple) : \ | ||
(__Pyx_UnpackTupleError(tuple, 2), -1)) : \ | ||
__Pyx_unpack_tuple2_generic(tuple, value1, value2, has_known_size, decref_tuple)) | ||
#else | ||
static CYTHON_INLINE int __Pyx_unpack_tuple2( | ||
PyObject* tuple, PyObject** value1, PyObject** value2, int is_tuple, int has_known_size, int decref_tuple); | ||
#endif | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems worth generally unfolding this lengthy macro into the inline function you wrote, and just special casing the size check. |
||
|
||
static CYTHON_INLINE int __Pyx_unpack_tuple2_exact( | ||
PyObject* tuple, PyObject** value1, PyObject** value2, int decref_tuple); | ||
|
@@ -96,6 +109,28 @@ static int __Pyx_unpack_tuple2_generic( | |
//@requires: UnpackTupleError | ||
//@requires: RaiseNeedMoreValuesToUnpack | ||
|
||
#if !CYTHON_ASSUME_SAFE_MACROS | ||
static CYTHON_INLINE int __Pyx_unpack_tuple2( | ||
PyObject* tuple, PyObject** value1, PyObject** value2, int is_tuple, int has_known_size, int decref_tuple) { | ||
if (likely(is_tuple || PyTuple_Check(tuple))) { | ||
Py_ssize_t size; | ||
if (has_known_size) { | ||
return __Pyx_unpack_tuple2_exact(tuple, value1, value2, decref_tuple); | ||
} | ||
size = PyTuple_Size(tuple); | ||
if (unlikely(size < 0)) { | ||
return -1; | ||
} else if (likely(size == 2)) { | ||
return __Pyx_unpack_tuple2_exact(tuple, value1, value2, decref_tuple); | ||
} | ||
__Pyx_UnpackTupleError(tuple, 2); | ||
return -1; | ||
} else { | ||
return __Pyx_unpack_tuple2_generic(tuple, value1, value2, has_known_size, decref_tuple); | ||
} | ||
} | ||
#endif | ||
|
||
static CYTHON_INLINE int __Pyx_unpack_tuple2_exact( | ||
PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, int decref_tuple) { | ||
PyObject *value1 = NULL, *value2 = NULL; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -361,8 +361,20 @@ static CYTHON_INLINE int __Pyx_dict_iter_next( | |
} | ||
Py_INCREF(key); | ||
Py_INCREF(value); | ||
#if CYTHON_ASSUME_SAFE_MACROS | ||
PyTuple_SET_ITEM(tuple, 0, key); | ||
PyTuple_SET_ITEM(tuple, 1, value); | ||
#else | ||
if (unlikely(PyTuple_SetItem(tuple, 0, key) < 0)) { | ||
Py_DECREF(value); // we haven't set this yet | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We haven't actually set There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'll add a comment because it isn't obvious though |
||
Py_DECREF(tuple); | ||
return -1; | ||
} | ||
if (unlikely(PyTuple_SetItem(tuple, 1, value) < 0)) { | ||
Py_DECREF(tuple); | ||
return -1; | ||
} | ||
#endif | ||
*pitem = tuple; | ||
} else { | ||
if (pkey) { | ||
|
@@ -376,16 +388,38 @@ static CYTHON_INLINE int __Pyx_dict_iter_next( | |
} | ||
return 1; | ||
} else if (PyTuple_CheckExact(iter_obj)) { | ||
Py_ssize_t pos = *ppos; | ||
if (unlikely(pos >= PyTuple_GET_SIZE(iter_obj))) return 0; | ||
Py_ssize_t pos = *ppos, iter_size; | ||
#if CYTHON_ASSUME_SAFE_MACROS | ||
iter_size = PyTuple_GET_SIZE(iter_obj); | ||
#else | ||
iter_size = PyTuple_Size(iter_obj); | ||
if (unlikely(iter_size < 0)) return -1; | ||
#endif | ||
if (unlikely(pos >= iter_size)) return 0; | ||
*ppos = pos + 1; | ||
#if CYTHON_ASSUME_SAFE_MACROS | ||
next_item = PyTuple_GET_ITEM(iter_obj, pos); | ||
#else | ||
next_item = PyTuple_GetItem(iter_obj, pos); | ||
if (unlikely(!next_item)) return -1; | ||
#endif | ||
Py_INCREF(next_item); | ||
} else if (PyList_CheckExact(iter_obj)) { | ||
Py_ssize_t pos = *ppos; | ||
if (unlikely(pos >= PyList_GET_SIZE(iter_obj))) return 0; | ||
Py_ssize_t pos = *ppos, iter_size; | ||
#if CYTHON_ASSUME_SAFE_MACROS | ||
iter_size = PyList_GET_SIZE(iter_obj); | ||
#else | ||
iter_size = PyList_Size(iter_obj); | ||
if (unlikely(iter_size < 0)) return -1; | ||
#endif | ||
if (unlikely(pos >= iter_size)) return 0; | ||
*ppos = pos + 1; | ||
#if CYTHON_ASSUME_SAFE_MACROS | ||
next_item = PyList_GET_ITEM(iter_obj, pos); | ||
#else | ||
next_item = PyList_GetItem(iter_obj, pos); | ||
if (unlikely(!next_item)) return -1; | ||
#endif | ||
Py_INCREF(next_item); | ||
} else | ||
#endif | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,7 +75,7 @@ static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 ch | |
|
||
//////////////////// PyUCS4InUnicode //////////////////// | ||
|
||
#if PY_VERSION_HEX < 0x03090000 || (defined(PyUnicode_WCHAR_KIND) && defined(PyUnicode_AS_UNICODE)) | ||
#if (PY_VERSION_HEX < 0x03090000 || (defined(PyUnicode_WCHAR_KIND) && defined(PyUnicode_AS_UNICODE)) && !CYTHON_COMPILING_IN_LIMITED_API) | ||
|
||
#if PY_VERSION_HEX < 0x03090000 | ||
#define __Pyx_PyUnicode_AS_UNICODE(op) PyUnicode_AS_UNICODE(op) | ||
|
@@ -113,6 +113,14 @@ static int __Pyx_PyUnicodeBufferContainsUCS4_BMP(Py_UNICODE* buffer, Py_ssize_t | |
#endif | ||
|
||
static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character) { | ||
#if CYTHON_COMPILING_IN_LIMITED_API | ||
// Note that from Python 3.7, the indices of FindChar account for wraparound so no | ||
// need to check the length | ||
Py_ssize_t idx = PyUnicode_FindChar(unicode, character, 0, -1, 1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could also pass Given that there's a C-API function for this, though, I wonder if we're really still faster than that. The implementation seems quite efficient. From my expecience, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've taken this to mean "just use PyUnicode_FindChar in all cases". Happy to revert if this wasn't what you mean though! |
||
if (idx == -1) return 0; // not found | ||
else if (unlikely(idx < 0)) return -1; // error | ||
else return 1; // found | ||
da-woods marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#else | ||
const int kind = PyUnicode_KIND(unicode); | ||
#ifdef PyUnicode_WCHAR_KIND | ||
if (likely(kind != PyUnicode_WCHAR_KIND)) | ||
|
@@ -144,6 +152,7 @@ static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 ch | |
|
||
} | ||
#endif | ||
#endif | ||
} | ||
|
||
|
||
|
@@ -550,12 +559,18 @@ static CYTHON_INLINE PyObject* __Pyx_decode_bytearray( | |
|
||
/////////////// PyUnicode_Substring.proto /////////////// | ||
|
||
#if !CYTHON_COMPILING_IN_LIMITED_API | ||
static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring( | ||
PyObject* text, Py_ssize_t start, Py_ssize_t stop); | ||
#else | ||
// In the limited API since 3.7 | ||
#define __Pyx_PyUnicode_Substring(text, start, stop) PyUnicode_Substring(text, start, stop) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't quite right - the |
||
#endif | ||
|
||
/////////////// PyUnicode_Substring /////////////// | ||
//@substitute: naming | ||
|
||
#if !CYTHON_COMPILING_IN_LIMITED_API | ||
static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring( | ||
PyObject* text, Py_ssize_t start, Py_ssize_t stop) { | ||
Py_ssize_t length; | ||
|
@@ -577,6 +592,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring( | |
return PyUnicode_FromKindAndData(PyUnicode_KIND(text), | ||
PyUnicode_1BYTE_DATA(text) + start*PyUnicode_KIND(text), stop-start); | ||
} | ||
#endif | ||
|
||
|
||
/////////////// py_unicode_istitle.proto /////////////// | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unfortunate, because it may lead to an unused label. In rare cases, admittedly…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can rewrite it as
so the label is never unused. That might be slightly better (provided we manage to avoid "condition always true" warnings)