Skip to content

Commit

Permalink
Add a new utility code macro "EMPTY(bytes|tuple|...)" to inject refer…
Browse files Browse the repository at this point in the history
…ences to empty Python constants.
  • Loading branch information
scoder committed Aug 22, 2024
1 parent 00958ef commit e968415
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 45 deletions.
41 changes: 28 additions & 13 deletions Cython/Compiler/Code.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,8 +781,19 @@ def _inject_string_constant(output, matchobj):
return output.get_py_string_const(
StringEncoding.EncodedString(name), identifier=str_type == 'IDENT').cname

@add_macro_processor(
'EMPTY',
is_module_specific=True,
regex=r'EMPTY\((bytes|unicode|tuple)\)',
)
def _inject_empty_collection_constant(output, matchobj):
"""Replace 'EMPTY(bytes|tuple|...)' by a constant Python identifier cname.
"""
type_name = matchobj.group(1)
return getattr(Naming, f'empty_{type_name}')

@add_macro_processor()
def process_impl_code(_, code_string):
def process_code(_, code_string):
"""Entry point for code processors, must be defined last.
"""
return code_string
Expand All @@ -793,21 +804,25 @@ def put_code(self, output):
output.use_utility_code(dependency)
if self.proto:
writer = output[self.proto_block]
writer.putln("/* %s.proto */" % self.name)
writer.put_or_include(
self.format_code(self.proto), '%s_proto' % self.name)
writer.putln(f"/* {self.name}.proto */")
proto, result_is_module_specific = self.process_code(output, self.proto)
if result_is_module_specific:
writer.put(proto)
else:
# can be reused across modules
writer.put_or_include(proto, f'{self.name}_proto')
if self.impl:
impl, result_is_module_specific = self.process_impl_code(output, self.impl)
impl, result_is_module_specific = self.process_code(output, self.impl)
writer = output['utility_code_def']
writer.putln("/* %s */" % self.name)
if not result_is_module_specific:
# can be reused across modules
writer.put_or_include(impl, '%s_impl' % self.name)
else:
writer.putln(f"/* {self.name} */")
if result_is_module_specific:
writer.put(impl)
else:
# can be reused across modules
writer.put_or_include(impl, f'{self.name}_impl')
if self.init:
writer = output['init_globals']
writer.putln("/* %s.init */" % self.name)
writer.putln(f"/* {self.name}.init */")
if isinstance(self.init, str):
writer.put(self.format_code(self.init))
else:
Expand All @@ -818,11 +833,11 @@ def put_code(self, output):
writer.putln()
if self.cleanup and Options.generate_cleanup_code:
writer = output['cleanup_globals']
writer.putln("/* %s.cleanup */" % self.name)
writer.putln(f"/* {self.name}.cleanup */")
if isinstance(self.cleanup, str):
writer.put_or_include(
self.format_code(self.cleanup),
'%s_cleanup' % self.name)
f'{self.name}_cleanup')
else:
self.cleanup(writer, output.module_pos)

Expand Down
2 changes: 1 addition & 1 deletion Cython/Utility/Dataclasses.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ static PyObject* __Pyx_DataclassesCallHelper(PyObject *callable, PyObject *kwds)
// copy over only those arguments that are in the specification
if (__Pyx_DataclassesCallHelper_FilterToDict(callable, kwds, new_kwds, args_list, 0) == -1) goto bad;
if (__Pyx_DataclassesCallHelper_FilterToDict(callable, kwds, new_kwds, kwonly_args_list, 1) == -1) goto bad;
result = PyObject_Call(callable, $empty_tuple, new_kwds);
result = PyObject_Call(callable, EMPTY(tuple), new_kwds);
bad:
Py_XDECREF(getfullargspec_result);
Py_XDECREF(args_list);
Expand Down
2 changes: 1 addition & 1 deletion Cython/Utility/Exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject
replace = PyObject_GetAttrString(code, "replace");
if (likely(replace)) {
PyObject *result;
result = PyObject_Call(replace, $empty_tuple, scratch_dict);
result = PyObject_Call(replace, EMPTY(tuple), scratch_dict);
Py_DECREF(replace);
return result;
}
Expand Down
3 changes: 1 addition & 2 deletions Cython/Utility/FunctionArguments.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@
static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); /*proto*/

//////////////////// ArgTypeTest ////////////////////
//@substitute: naming

static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact)
{
__Pyx_TypeName type_name;
__Pyx_TypeName obj_type_name;
PyObject *extra_info = $empty_unicode;
PyObject *extra_info = EMPTY(unicode);
int from_annotation_subclass = 0;
if (unlikely(!type)) {
PyErr_SetString(PyExc_SystemError, "Missing type object");
Expand Down
15 changes: 7 additions & 8 deletions Cython/Utility/ModuleSetupCode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2180,7 +2180,6 @@ static PyObject* __Pyx_PyCode_New(
);/*proto*/

//////////////////// NewCodeObj ////////////////////////
//@substitute: naming

#if CYTHON_COMPILING_IN_LIMITED_API
// Note that the limited API doesn't know about PyCodeObject, so the type of this
Expand Down Expand Up @@ -2274,7 +2273,7 @@ static PyObject* __Pyx_PyCode_New(
#else
PyCode_NewWithPosOnlyArgs
#endif
(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, ${empty_bytes});
(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, EMPTY(bytes));
return result;
}
#elif PY_VERSION_HEX >= 0x030800B2 && !CYTHON_COMPILING_IN_PYPY
Expand Down Expand Up @@ -2360,16 +2359,16 @@ static PyObject* __Pyx_PyCode_New(
(int) descr.nlocals,
0,
(int) descr.flags,
code_bytes ? code_bytes : ${empty_bytes},
${empty_tuple},
${empty_tuple},
code_bytes ? code_bytes : EMPTY(bytes),
EMPTY(tuple),
EMPTY(tuple),
varnames_tuple_dedup,
${empty_tuple},
${empty_tuple},
EMPTY(tuple),
EMPTY(tuple),
filename,
funcname,
(int) descr.first_line,
(__PYX_LIMITED_VERSION_HEX >= 0x030b0000) ? line_table_bytes : ${empty_bytes}
(__PYX_LIMITED_VERSION_HEX >= 0x030b0000) ? line_table_bytes : EMPTY(bytes)
);

done:
Expand Down
19 changes: 7 additions & 12 deletions Cython/Utility/ObjectHandling.c
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_


/////////////// TupleAndListFromArray ///////////////
//@substitute: naming

#if !CYTHON_COMPILING_IN_CPYTHON && CYTHON_METH_FASTCALL
static CYTHON_INLINE PyObject *
Expand All @@ -807,8 +806,7 @@ __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n)
PyObject *res;
Py_ssize_t i;
if (n <= 0) {
Py_INCREF($empty_tuple);
return $empty_tuple;
return __Pyx_NewRef(EMPTY(tuple));
}
res = PyTuple_New(n);
if (unlikely(res == NULL)) return NULL;
Expand Down Expand Up @@ -836,8 +834,7 @@ __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n)
{
PyObject *res;
if (n <= 0) {
Py_INCREF($empty_tuple);
return $empty_tuple;
return __Pyx_NewRef(EMPTY(tuple));
}
res = PyTuple_New(n);
if (unlikely(res == NULL)) return NULL;
Expand Down Expand Up @@ -1841,7 +1838,6 @@ static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) {


/////////////// CallUnboundCMethod0.proto ///////////////
//@substitute: naming

CYTHON_UNUSED
static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); /*proto*/
Expand All @@ -1852,11 +1848,11 @@ static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObje
(likely((cfunc)->func) ? \
(likely((cfunc)->flag == METH_NOARGS) ? (*((cfunc)->func))(self, NULL) : \
(likely((cfunc)->flag == METH_FASTCALL) ? \
(*(__Pyx_PyCFunctionFast)(void*)(PyCFunction)(cfunc)->func)(self, &$empty_tuple, 0) : \
(*(__Pyx_PyCFunctionFast)(void*)(PyCFunction)(cfunc)->func)(self, &EMPTY(tuple), 0) : \
((cfunc)->flag == (METH_FASTCALL | METH_KEYWORDS) ? \
(*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)(cfunc)->func)(self, &$empty_tuple, 0, NULL) : \
(likely((cfunc)->flag == (METH_VARARGS | METH_KEYWORDS)) ? ((*(PyCFunctionWithKeywords)(void*)(PyCFunction)(cfunc)->func)(self, $empty_tuple, NULL)) : \
((cfunc)->flag == METH_VARARGS ? (*((cfunc)->func))(self, $empty_tuple) : \
(*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)(cfunc)->func)(self, &EMPTY(tuple), 0, NULL) : \
(likely((cfunc)->flag == (METH_VARARGS | METH_KEYWORDS)) ? ((*(PyCFunctionWithKeywords)(void*)(PyCFunction)(cfunc)->func)(self, EMPTY(tuple), NULL)) : \
((cfunc)->flag == METH_VARARGS ? (*((cfunc)->func))(self, EMPTY(tuple)) : \
__Pyx__CallUnboundCMethod0(cfunc, self)))))) : \
__Pyx__CallUnboundCMethod0(cfunc, self))
#else
Expand Down Expand Up @@ -1993,7 +1989,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObj
//@requires: PyObjectCall
//@requires: PyFunctionFastCall
//@requires: PyObjectCallMethO
//@substitute: naming

#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API
static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject **args, size_t nargs, PyObject *kwargs) {
Expand Down Expand Up @@ -2073,7 +2068,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObj
}

if (nargs == 0) {
return __Pyx_PyObject_Call(func, $empty_tuple, kwargs);
return __Pyx_PyObject_Call(func, EMPTY(tuple), kwargs);
}
#if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API
return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs);
Expand Down
12 changes: 4 additions & 8 deletions Cython/Utility/StringTools.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,6 @@ static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
/////////////// decode_c_string ///////////////
//@requires: IncludeStringH
//@requires: decode_c_string_utf16
//@substitute: naming

/* duplicate code to avoid calling strlen() if start >= 0 and stop >= 0 */
static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
Expand All @@ -468,7 +467,7 @@ static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
stop += length;
}
if (unlikely(stop <= start))
return __Pyx_NewRef($empty_unicode);
return __Pyx_NewRef(EMPTY(unicode));
length = stop - start;
cstring += start;
if (decode_func) {
Expand All @@ -487,7 +486,6 @@ static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(

/////////////// decode_c_bytes ///////////////
//@requires: decode_c_string_utf16
//@substitute: naming

static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop,
Expand All @@ -505,7 +503,7 @@ static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
if (stop > length)
stop = length;
if (unlikely(stop <= start))
return __Pyx_NewRef($empty_unicode);
return __Pyx_NewRef(EMPTY(unicode));
length = stop - start;
cstring += start;
if (decode_func) {
Expand Down Expand Up @@ -564,7 +562,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring(
PyObject* text, Py_ssize_t start, Py_ssize_t stop);

/////////////// PyUnicode_Substring ///////////////
//@substitute: naming

static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring(
PyObject* text, Py_ssize_t start, Py_ssize_t stop) {
Expand All @@ -586,7 +583,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring(
else if (stop > length)
stop = length;
if (stop <= start)
return __Pyx_NewRef($empty_unicode);
return __Pyx_NewRef(EMPTY(unicode));
if (start == 0 && stop == length)
return __Pyx_NewRef(text);
#if CYTHON_COMPILING_IN_LIMITED_API
Expand Down Expand Up @@ -903,7 +900,6 @@ static PyObject* __Pyx_PyUnicode_Join(PyObject** values, Py_ssize_t value_count,

/////////////// JoinPyUnicode ///////////////
//@requires: IncludeStringH
//@substitute: naming

static PyObject* __Pyx_PyUnicode_Join(PyObject** values, Py_ssize_t value_count, Py_ssize_t result_ulength,
Py_UCS4 max_char) {
Expand Down Expand Up @@ -981,7 +977,7 @@ static PyObject* __Pyx_PyUnicode_Join(PyObject** values, Py_ssize_t value_count,
Py_INCREF(values[i]);
}

result = PyUnicode_Join($empty_unicode, value_tuple);
result = PyUnicode_Join(EMPTY(unicode), value_tuple);

bad:
Py_DECREF(value_tuple);
Expand Down

0 comments on commit e968415

Please sign in to comment.