return_type=str_rprimitive, c_function_name='CPyStr_GetItem', error_kind=ERR_MAGIC) # str.split(...) str_split_types = [str_rprimitive, str_rprimitive, int_rprimitive] # type: List[RType] str_split_emits = [simple_emit('{dest} = PyUnicode_Split({args[0]}, NULL, -1);'), simple_emit('{dest} = PyUnicode_Split({args[0]}, {args[1]}, -1);'), call_emit('CPyStr_Split')] \ # type: List[EmitCallback] for i in range(len(str_split_types)): method_op(name='split', arg_types=str_split_types[0:i + 1], result_type=list_rprimitive, error_kind=ERR_MAGIC, emit=str_split_emits[i]) # str1 += str2 # # PyUnicodeAppend makes an effort to reuse the LHS when the refcount # is 1. This is super dodgy but oh well, the interpreter does it. c_binary_op(name='+=', arg_types=[str_rprimitive, str_rprimitive], return_type=str_rprimitive, c_function_name='CPyStr_Append', error_kind=ERR_MAGIC, steals=[True, False])
name_ref_op, method_op, binary_op, func_op, custom_op, simple_emit, negative_int_emit, call_emit, call_negative_bool_emit, ) # Get the 'dict' type object. name_ref_op('builtins.dict', result_type=object_rprimitive, error_kind=ERR_NEVER, emit=simple_emit('{dest} = (PyObject *)&PyDict_Type;'), is_borrowed=True) # dict[key] dict_get_item_op = method_op( name='__getitem__', arg_types=[dict_rprimitive, object_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('CPyDict_GetItem')) # dict[key] = value dict_set_item_op = method_op( name='__setitem__', arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=call_negative_bool_emit('CPyDict_SetItem')) # key in dict binary_op(op='in', arg_types=[object_rprimitive, dict_rprimitive], result_type=bool_rprimitive,
new_list_op = custom_op(arg_types=[c_pyssize_t_rprimitive], return_type=list_rprimitive, c_function_name='PyList_New', error_kind=ERR_MAGIC) list_build_op = custom_op(arg_types=[c_pyssize_t_rprimitive], return_type=list_rprimitive, c_function_name='CPyList_Build', error_kind=ERR_MAGIC, var_arg_type=object_rprimitive, steals=True) # list[index] (for an integer index) list_get_item_op = method_op(name='__getitem__', arg_types=[list_rprimitive, int_rprimitive], return_type=object_rprimitive, c_function_name='CPyList_GetItem', error_kind=ERR_MAGIC) # list[index] version with no int bounds check for when it is known to be short method_op(name='__getitem__', arg_types=[list_rprimitive, short_int_rprimitive], return_type=object_rprimitive, c_function_name='CPyList_GetItemShort', error_kind=ERR_MAGIC, priority=2) # list[index] that produces a borrowed result method_op(name='__getitem__', arg_types=[list_rprimitive, int_rprimitive], return_type=object_rprimitive,
result_type=int_rprimitive, error_kind=ERR_NEVER, emit=emit_len, ) binary_op( op='in', arg_types=[object_rprimitive, set_rprimitive], result_type=bool_rprimitive, error_kind=ERR_MAGIC, format_str='{dest} = {args[0]} in {args[1]} :: set', emit=negative_int_emit('{dest} = PySet_Contains({args[1]}, {args[0]});')) method_op(name='remove', arg_types=[set_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=call_emit('CPySet_Remove')) method_op(name='discard', arg_types=[set_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=call_negative_bool_emit('PySet_Discard')) set_add_op = method_op(name='add', arg_types=[set_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=call_negative_bool_emit('PySet_Add'))
arg_types=[set_rprimitive, object_rprimitive], return_type=bool_rprimitive, c_function_name='CPySet_Remove', error_kind=ERR_FALSE) # set.discard(obj) c_method_op(name='discard', arg_types=[set_rprimitive, object_rprimitive], return_type=c_int_rprimitive, c_function_name='PySet_Discard', error_kind=ERR_NEG_INT) # set.add(obj) set_add_op = method_op(name='add', arg_types=[set_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=call_negative_bool_emit('PySet_Add')) # set.update(obj) # # This is not a public API but looks like it should be fine. set_update_op = method_op(name='update', arg_types=[set_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=call_negative_bool_emit('_PySet_Update')) # set.clear() method_op(name='clear', arg_types=[set_rprimitive],
binary_op(name='+=', arg_types=[str_rprimitive, str_rprimitive], return_type=str_rprimitive, c_function_name='CPyStr_Append', error_kind=ERR_MAGIC, steals=[True, False]) unicode_compare = custom_op(arg_types=[str_rprimitive, str_rprimitive], return_type=c_int_rprimitive, c_function_name='PyUnicode_Compare', error_kind=ERR_NEVER) # str[index] (for an int index) method_op(name='__getitem__', arg_types=[str_rprimitive, int_rprimitive], return_type=str_rprimitive, c_function_name='CPyStr_GetItem', error_kind=ERR_MAGIC) # str[begin:end] str_slice_op = custom_op( arg_types=[str_rprimitive, int_rprimitive, int_rprimitive], return_type=object_rprimitive, c_function_name='CPyStr_GetSlice', error_kind=ERR_MAGIC) # str.join(obj) method_op(name='join', arg_types=[str_rprimitive, object_rprimitive], return_type=str_rprimitive, c_function_name='PyUnicode_Join',
These are for varying-length tuples represented as Python tuple objects (RPrimitive, not RTuple). """ from typing import List from mypyc.ir.ops import ( EmitterInterface, ERR_NEVER, ERR_MAGIC ) from mypyc.ir.rtypes import tuple_rprimitive, int_rprimitive, list_rprimitive, object_rprimitive from mypyc.primitives.registry import func_op, method_op, custom_op, call_emit, simple_emit tuple_get_item_op = method_op( name='__getitem__', arg_types=[tuple_rprimitive, int_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('CPySequenceTuple_GetItem')) new_tuple_op = custom_op( arg_types=[object_rprimitive], result_type=tuple_rprimitive, is_var_arg=True, error_kind=ERR_MAGIC, steals=False, format_str='{dest} = ({comma_args}) :: tuple', emit=simple_emit('{dest} = PyTuple_Pack({num_args}{pre_comma_args});')) def emit_len(emitter: EmitterInterface, args: List[str], dest: str) -> None:
# bytes(obj) function_op( name='builtins.bytes', arg_types=[RUnion([list_rprimitive, dict_rprimitive, str_rprimitive])], return_type=bytes_rprimitive, c_function_name='PyBytes_FromObject', error_kind=ERR_MAGIC) # bytearray(obj) function_op(name='builtins.bytearray', arg_types=[object_rprimitive], return_type=bytes_rprimitive, c_function_name='PyByteArray_FromObject', error_kind=ERR_MAGIC) # bytes + bytes # bytearray + bytearray binary_op(name='+', arg_types=[bytes_rprimitive, bytes_rprimitive], return_type=bytes_rprimitive, c_function_name='CPyBytes_Concat', error_kind=ERR_MAGIC, steals=[True, False]) # bytes.join(obj) method_op(name='join', arg_types=[bytes_rprimitive, object_rprimitive], return_type=bytes_rprimitive, c_function_name='CPyBytes_Join', error_kind=ERR_MAGIC)
c_function_name='PyFrozenSet_New', error_kind=ERR_MAGIC) # item in set binary_op(name='in', arg_types=[object_rprimitive, set_rprimitive], return_type=c_int_rprimitive, c_function_name='PySet_Contains', error_kind=ERR_NEG_INT, truncated_type=bool_rprimitive, ordering=[1, 0]) # set.remove(obj) method_op(name='remove', arg_types=[set_rprimitive, object_rprimitive], return_type=bit_rprimitive, c_function_name='CPySet_Remove', error_kind=ERR_FALSE) # set.discard(obj) method_op(name='discard', arg_types=[set_rprimitive, object_rprimitive], return_type=c_int_rprimitive, c_function_name='PySet_Discard', error_kind=ERR_NEG_INT) # set.add(obj) set_add_op = method_op(name='add', arg_types=[set_rprimitive, object_rprimitive], return_type=c_int_rprimitive, c_function_name='PySet_Add',
emit=call_emit(funcname), priority=0) unary_op(op='not', arg_type=object_rprimitive, result_type=bool_rprimitive, error_kind=ERR_MAGIC, format_str='{dest} = not {args[0]}', emit=call_negative_magic_emit('PyObject_Not'), priority=0) # obj1[obj2] method_op('__getitem__', arg_types=[object_rprimitive, object_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('PyObject_GetItem'), priority=0) # obj1[obj2] = obj3 method_op('__setitem__', arg_types=[object_rprimitive, object_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=call_negative_bool_emit('PyObject_SetItem'), priority=0) # del obj1[obj2] method_op('__delitem__', arg_types=[object_rprimitive, object_rprimitive], result_type=bool_rprimitive,
arg_types=[object_rprimitive], return_type=list_rprimitive, c_function_name='PySequence_List', error_kind=ERR_MAGIC, ) new_list_op = custom_op( arg_types=[c_pyssize_t_rprimitive], return_type=list_rprimitive, c_function_name='PyList_New', error_kind=ERR_MAGIC) # list[index] (for an integer index) list_get_item_op = method_op( name='__getitem__', arg_types=[list_rprimitive, int_rprimitive], return_type=object_rprimitive, c_function_name='CPyList_GetItem', error_kind=ERR_MAGIC) # Version with no int bounds check for when it is known to be short method_op( name='__getitem__', arg_types=[list_rprimitive, short_int_rprimitive], return_type=object_rprimitive, c_function_name='CPyList_GetItemShort', error_kind=ERR_MAGIC, priority=2) # This is unsafe because it assumes that the index is a non-negative short integer # that is in-bounds for the list. list_get_item_unsafe_op = custom_op(
return_type=c_int_rprimitive, c_function_name='CPyDict_UpdateFromAny', error_kind=ERR_NEG_INT) # dict.get(key, default) c_method_op( name='get', arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive], return_type=object_rprimitive, c_function_name='CPyDict_Get', error_kind=ERR_MAGIC) # dict.get(key) method_op( name='get', arg_types=[dict_rprimitive, object_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = CPyDict_Get({args[0]}, {args[1]}, Py_None);')) # Construct an empty dictionary. dict_new_op = c_custom_op( arg_types=[], return_type=dict_rprimitive, c_function_name='PyDict_New', error_kind=ERR_MAGIC) # Construct a dictionary from keys and values. # Positional argument is the number of key-value pairs # Variable arguments are (key1, value1, ..., keyN, valueN). dict_build_op = c_custom_op( arg_types=[c_pyssize_t_rprimitive],
emitter.emit_line('}') # Construct a list from values: [item1, item2, ....] new_list_op = custom_op(arg_types=[object_rprimitive], result_type=list_rprimitive, is_var_arg=True, error_kind=ERR_MAGIC, steals=True, format_str='{dest} = [{comma_args}]', emit=emit_new) # list[index] (for an integer index) list_get_item_op = method_op(name='__getitem__', arg_types=[list_rprimitive, int_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('CPyList_GetItem')) # Version with no int bounds check for when it is known to be short method_op(name='__getitem__', arg_types=[list_rprimitive, short_int_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('CPyList_GetItemShort'), priority=2) # This is unsafe because it assumes that the index is a non-negative short integer # that is in-bounds for the list. list_get_item_unsafe_op = custom_op( name='__getitem__',
c_function_name=funcname, error_kind=ERR_MAGIC, priority=0) c_unary_op(name='not', arg_type=object_rprimitive, return_type=c_int_rprimitive, c_function_name='PyObject_Not', error_kind=ERR_NEG_INT, truncated_type=bool_rprimitive, priority=0) # obj1[obj2] method_op(name='__getitem__', arg_types=[object_rprimitive, object_rprimitive], return_type=object_rprimitive, c_function_name='PyObject_GetItem', error_kind=ERR_MAGIC, priority=0) # obj1[obj2] = obj3 method_op(name='__setitem__', arg_types=[object_rprimitive, object_rprimitive, object_rprimitive], return_type=c_int_rprimitive, c_function_name='PyObject_SetItem', error_kind=ERR_NEG_INT, priority=0) # del obj1[obj2] method_op(name='__delitem__', arg_types=[object_rprimitive, object_rprimitive], return_type=c_int_rprimitive,
dict_next_rtuple_single, dict_next_rtuple_pair, c_pyssize_t_rprimitive, c_int_rprimitive, bit_rprimitive) from mypyc.primitives.registry import (custom_op, method_op, function_op, binary_op, load_address_op, ERR_NEG_INT) # Get the 'dict' type object. load_address_op(name='builtins.dict', type=object_rprimitive, src='PyDict_Type') # dict[key] dict_get_item_op = method_op(name='__getitem__', arg_types=[dict_rprimitive, object_rprimitive], return_type=object_rprimitive, c_function_name='CPyDict_GetItem', error_kind=ERR_MAGIC) # dict[key] = value dict_set_item_op = method_op( name='__setitem__', arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive], return_type=c_int_rprimitive, c_function_name='CPyDict_SetItem', error_kind=ERR_NEG_INT) # key in dict binary_op(name='in', arg_types=[object_rprimitive, dict_rprimitive], return_type=c_int_rprimitive,
func_op(name='builtins.str', arg_types=[object_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyObject_Str({args[0]});')) binary_op(op='+', arg_types=[str_rprimitive, str_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyUnicode_Concat({args[0]}, {args[1]});')) method_op(name='join', arg_types=[str_rprimitive, object_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=simple_emit('{dest} = PyUnicode_Join({args[0]}, {args[1]});')) str_split_types = [str_rprimitive, str_rprimitive, int_rprimitive] # type: List[RType] str_split_emits = [simple_emit('{dest} = PyUnicode_Split({args[0]}, NULL, -1);'), simple_emit('{dest} = PyUnicode_Split({args[0]}, {args[1]}, -1);'), simple_emit('{dest} = CPyStr_Split({args[0]}, {args[1]}, {args[2]});')] \ # type: List[EmitCallback] for i in range(len(str_split_types)): method_op(name='split', arg_types=str_split_types[0:i + 1], result_type=list_rprimitive, error_kind=ERR_MAGIC,
"""Primitive tuple ops for *variable-length* tuples. Note: Varying-length tuples are represented as boxed Python tuple objects, i.e. tuple_rprimitive (RPrimitive), not RTuple. """ from mypyc.ir.ops import ERR_MAGIC from mypyc.ir.rtypes import (tuple_rprimitive, int_rprimitive, list_rprimitive, object_rprimitive, c_pyssize_t_rprimitive) from mypyc.primitives.registry import method_op, function_op, custom_op # tuple[index] (for an int index) tuple_get_item_op = method_op(name='__getitem__', arg_types=[tuple_rprimitive, int_rprimitive], return_type=object_rprimitive, c_function_name='CPySequenceTuple_GetItem', error_kind=ERR_MAGIC) # Construct a boxed tuple from items: (item1, item2, ...) new_tuple_op = custom_op(arg_types=[c_pyssize_t_rprimitive], return_type=tuple_rprimitive, c_function_name='PyTuple_Pack', error_kind=ERR_MAGIC, var_arg_type=object_rprimitive) # Construct tuple from a list. list_tuple_op = function_op(name='builtins.tuple', arg_types=[list_rprimitive], return_type=tuple_rprimitive, c_function_name='PyList_AsTuple', error_kind=ERR_MAGIC,
arg_types=[str_rprimitive, str_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('PyUnicode_Concat')) # str.join(obj) c_method_op(name='join', arg_types=[str_rprimitive, object_rprimitive], return_type=str_rprimitive, c_function_name='PyUnicode_Join', error_kind=ERR_MAGIC) # str[index] (for an int index) method_op(name='__getitem__', arg_types=[str_rprimitive, int_rprimitive], result_type=str_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('CPyStr_GetItem')) # str.split(...) str_split_types = [str_rprimitive, str_rprimitive, int_rprimitive] # type: List[RType] str_split_emits = [simple_emit('{dest} = PyUnicode_Split({args[0]}, NULL, -1);'), simple_emit('{dest} = PyUnicode_Split({args[0]}, {args[1]}, -1);'), call_emit('CPyStr_Split')] \ # type: List[EmitCallback] for i in range(len(str_split_types)): method_op(name='split', arg_types=str_split_types[0:i + 1], result_type=list_rprimitive,
return_type=dict_rprimitive, c_function_name='PyDict_Copy', error_kind=ERR_MAGIC, priority=2) # Generic one-argument dict constructor: dict(obj) function_op(name='builtins.dict', arg_types=[object_rprimitive], return_type=dict_rprimitive, c_function_name='CPyDict_FromAny', error_kind=ERR_MAGIC) # dict[key] dict_get_item_op = method_op(name='__getitem__', arg_types=[dict_rprimitive, object_rprimitive], return_type=object_rprimitive, c_function_name='CPyDict_GetItem', error_kind=ERR_MAGIC) # dict[key] = value dict_set_item_op = method_op( name='__setitem__', arg_types=[dict_rprimitive, object_rprimitive, object_rprimitive], return_type=c_int_rprimitive, c_function_name='CPyDict_SetItem', error_kind=ERR_NEG_INT) # key in dict binary_op(name='in', arg_types=[object_rprimitive, dict_rprimitive], return_type=c_int_rprimitive,
format_str='{dest} = {args[0]}[{args[1]}] :: unsafe list', emit=call_emit('CPyList_GetItemUnsafe')) # list[index] = obj list_set_item_op = c_method_op( name='__setitem__', arg_types=[list_rprimitive, int_rprimitive, object_rprimitive], return_type=bool_rprimitive, c_function_name='CPyList_SetItem', error_kind=ERR_FALSE, steals=[False, False, True]) # list.append(obj) list_append_op = method_op(name='append', arg_types=[list_rprimitive, object_rprimitive], result_type=bool_rprimitive, error_kind=ERR_FALSE, emit=call_negative_bool_emit('PyList_Append')) # list.extend(obj) list_extend_op = method_op(name='extend', arg_types=[list_rprimitive, object_rprimitive], result_type=object_rprimitive, error_kind=ERR_MAGIC, emit=call_emit('CPyList_Extend')) # list.pop() list_pop_last = c_method_op(name='pop', arg_types=[list_rprimitive], return_type=object_rprimitive, c_function_name='CPyList_PopLast',