Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions mypyc/irbuild/ll_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
)
from mypyc.primitives.tuple_ops import (
list_tuple_op,
load_empty_tuple_constant_op,
new_tuple_op,
new_tuple_with_length_op,
sequence_tuple_op,
Expand Down Expand Up @@ -2359,8 +2360,11 @@ def builtin_len(self, val: Value, line: int, use_pyssize_t: bool = False) -> Val
return self.call_c(generic_len_op, [val], line)

def new_tuple(self, items: list[Value], line: int) -> Value:
size: Value = Integer(len(items), c_pyssize_t_rprimitive)
return self.call_c(new_tuple_op, [size] + items, line)
if items:
size: Value = Integer(len(items), c_pyssize_t_rprimitive)
return self.call_c(new_tuple_op, [size] + items, line)
else:
return self.call_c(load_empty_tuple_constant_op, [], line)

def new_tuple_with_length(self, length: Value, line: int) -> Value:
"""This function returns an uninitialized tuple.
Expand Down
8 changes: 8 additions & 0 deletions mypyc/lib-rt/CPy.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ typedef struct tuple_T4CIOO {
} tuple_T4CIOO;
#endif

// System-wide empty tuple constant
extern PyObject * __mypyc_empty_tuple__;

static inline PyObject *_CPyTuple_LoadEmptyTupleConstant() {
// do tests still pass if I comment this out? empty tuple singleton is not tracked by gc
// Py_INCREF(__mypyc_empty_tuple__);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe I can take out this Py_INCREF since the empty tuple singleton is not tracked by the GC but I want to wait for confirmation before I get rid of the comment

return __mypyc_empty_tuple__;
}

// Native object operations

Expand Down
13 changes: 13 additions & 0 deletions mypyc/lib-rt/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,23 @@
struct ExcDummyStruct _CPy_ExcDummyStruct = { PyObject_HEAD_INIT(NULL) };
PyObject *_CPy_ExcDummy = (PyObject *)&_CPy_ExcDummyStruct;

// System-wide empty tuple constant
PyObject * __mypyc_empty_tuple__ = NULL;

// Because its dynamic linker is more restricted than linux/OS X,
// Windows doesn't allow initializing globals with values from
// other dynamic libraries. This means we need to initialize
// things at load time.
void CPy_Init(void) {
_CPy_ExcDummyStruct.ob_base.ob_type = &PyBaseObject_Type;

// Initialize system-wide empty tuple constant
if (__mypyc_empty_tuple__ == NULL) {
__mypyc_empty_tuple__ = PyTuple_New(0);
if (!__mypyc_empty_tuple__) {
PyErr_SetString(PyExc_RuntimeError, "Failed to initialize __mypyc_empty_tuple__");
return;
}
Py_INCREF(__mypyc_empty_tuple__);
}
}
7 changes: 7 additions & 0 deletions mypyc/primitives/tuple_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@
error_kind=ERR_MAGIC,
)

load_empty_tuple_constant_op = custom_op(
arg_types=[],
return_type=tuple_rprimitive,
c_function_name="_CPyTuple_LoadEmptyTupleConstant",
error_kind=ERR_NEVER,
)

# PyTuple_SET_ITEM does no error checking,
# and should only be used to fill in brand new tuples.
new_tuple_set_item_op = custom_op(
Expand Down
2 changes: 1 addition & 1 deletion mypyc/test-data/irbuild-basic.test
Original file line number Diff line number Diff line change
Expand Up @@ -1755,7 +1755,7 @@ L0:
r7 = __main__.globals :: static
r8 = 'f'
r9 = CPyDict_GetItem(r7, r8)
r10 = PyTuple_Pack(0)
r10 = _CPyTuple_LoadEmptyTupleConstant()
r11 = PyDict_Copy(r6)
r12 = PyObject_Call(r9, r10, r11)
r13 = unbox(tuple[int, int, int], r12)
Expand Down
4 changes: 2 additions & 2 deletions mypyc/test-data/irbuild-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ L2:
r27 = CPyType_FromTemplate(r26, r24, r25)
r28 = C_trait_vtable_setup()
r29 = '__mypyc_attrs__'
r30 = PyTuple_Pack(0)
r30 = _CPyTuple_LoadEmptyTupleConstant()
r31 = PyObject_SetAttr(r27, r29, r30)
r32 = r31 >= 0 :: signed
__main__.C = r27 :: type
Expand All @@ -310,7 +310,7 @@ L2:
r39 = __main__.S_template :: type
r40 = CPyType_FromTemplate(r39, r37, r38)
r41 = '__mypyc_attrs__'
r42 = PyTuple_Pack(0)
r42 = _CPyTuple_LoadEmptyTupleConstant()
r43 = PyObject_SetAttr(r40, r41, r42)
r44 = r43 >= 0 :: signed
__main__.S = r40 :: type
Expand Down
Loading