gtn/.venv/Lib/site-packages/mypyc/primitives/generic_ops.py
Tipragot 628be439b8 Ajout d'un environement de développement.
Cela permet de ne pas avoir de problèmes de compatibilité
car python est dans le git.
2023-10-26 15:33:03 +02:00

385 lines
10 KiB
Python

"""Fallback primitive operations that operate on 'object' operands.
These just call the relevant Python C API function or a thin wrapper
around an API function. Most of these also have faster, specialized
ops that operate on some more specific types.
Many of these ops are given a low priority (0) so that specialized ops
will take precedence. If your specialized op doesn't seem to be used,
check that the priorities are configured properly.
"""
from __future__ import annotations
from mypyc.ir.ops import ERR_MAGIC, ERR_NEVER
from mypyc.ir.rtypes import (
bool_rprimitive,
c_int_rprimitive,
c_pyssize_t_rprimitive,
c_size_t_rprimitive,
int_rprimitive,
object_pointer_rprimitive,
object_rprimitive,
pointer_rprimitive,
)
from mypyc.primitives.registry import (
ERR_NEG_INT,
binary_op,
custom_op,
function_op,
method_op,
unary_op,
)
# Binary operations
for op, opid in [
("==", 2), # PY_EQ
("!=", 3), # PY_NE
("<", 0), # PY_LT
("<=", 1), # PY_LE
(">", 4), # PY_GT
(">=", 5),
]: # PY_GE
# The result type is 'object' since that's what PyObject_RichCompare returns.
binary_op(
name=op,
arg_types=[object_rprimitive, object_rprimitive],
return_type=object_rprimitive,
c_function_name="PyObject_RichCompare",
error_kind=ERR_MAGIC,
extra_int_constants=[(opid, c_int_rprimitive)],
priority=0,
)
for op, funcname in [
("+", "PyNumber_Add"),
("-", "PyNumber_Subtract"),
("*", "PyNumber_Multiply"),
("//", "PyNumber_FloorDivide"),
("/", "PyNumber_TrueDivide"),
("%", "PyNumber_Remainder"),
("<<", "PyNumber_Lshift"),
(">>", "PyNumber_Rshift"),
("&", "PyNumber_And"),
("^", "PyNumber_Xor"),
("|", "PyNumber_Or"),
("@", "PyNumber_MatrixMultiply"),
]:
binary_op(
name=op,
arg_types=[object_rprimitive, object_rprimitive],
return_type=object_rprimitive,
c_function_name=funcname,
error_kind=ERR_MAGIC,
priority=0,
)
function_op(
name="builtins.divmod",
arg_types=[object_rprimitive, object_rprimitive],
return_type=object_rprimitive,
c_function_name="PyNumber_Divmod",
error_kind=ERR_MAGIC,
priority=0,
)
for op, funcname in [
("+=", "PyNumber_InPlaceAdd"),
("-=", "PyNumber_InPlaceSubtract"),
("*=", "PyNumber_InPlaceMultiply"),
("@=", "PyNumber_InPlaceMatrixMultiply"),
("//=", "PyNumber_InPlaceFloorDivide"),
("/=", "PyNumber_InPlaceTrueDivide"),
("%=", "PyNumber_InPlaceRemainder"),
("<<=", "PyNumber_InPlaceLshift"),
(">>=", "PyNumber_InPlaceRshift"),
("&=", "PyNumber_InPlaceAnd"),
("^=", "PyNumber_InPlaceXor"),
("|=", "PyNumber_InPlaceOr"),
]:
binary_op(
name=op,
arg_types=[object_rprimitive, object_rprimitive],
return_type=object_rprimitive,
c_function_name=funcname,
error_kind=ERR_MAGIC,
priority=0,
)
for op, c_function in (("**", "CPyNumber_Power"), ("**=", "CPyNumber_InPlacePower")):
binary_op(
name=op,
arg_types=[object_rprimitive, object_rprimitive],
return_type=object_rprimitive,
error_kind=ERR_MAGIC,
c_function_name=c_function,
priority=0,
)
for arg_count, c_function in ((2, "CPyNumber_Power"), (3, "PyNumber_Power")):
function_op(
name="builtins.pow",
arg_types=[object_rprimitive] * arg_count,
return_type=object_rprimitive,
error_kind=ERR_MAGIC,
c_function_name=c_function,
priority=0,
)
binary_op(
name="in",
arg_types=[object_rprimitive, object_rprimitive],
return_type=c_int_rprimitive,
c_function_name="PySequence_Contains",
error_kind=ERR_NEG_INT,
truncated_type=bool_rprimitive,
ordering=[1, 0],
priority=0,
)
# Unary operations
for op, funcname in [
("-", "PyNumber_Negative"),
("+", "PyNumber_Positive"),
("~", "PyNumber_Invert"),
]:
unary_op(
name=op,
arg_type=object_rprimitive,
return_type=object_rprimitive,
c_function_name=funcname,
error_kind=ERR_MAGIC,
priority=0,
)
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,
)
# abs(obj)
function_op(
name="builtins.abs",
arg_types=[object_rprimitive],
return_type=object_rprimitive,
c_function_name="PyNumber_Absolute",
error_kind=ERR_MAGIC,
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,
c_function_name="PyObject_DelItem",
error_kind=ERR_NEG_INT,
priority=0,
)
# hash(obj)
function_op(
name="builtins.hash",
arg_types=[object_rprimitive],
return_type=int_rprimitive,
c_function_name="CPyObject_Hash",
error_kind=ERR_MAGIC,
)
# getattr(obj, attr)
py_getattr_op = function_op(
name="builtins.getattr",
arg_types=[object_rprimitive, object_rprimitive],
return_type=object_rprimitive,
c_function_name="CPyObject_GetAttr",
error_kind=ERR_MAGIC,
)
# getattr(obj, attr, default)
function_op(
name="builtins.getattr",
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
return_type=object_rprimitive,
c_function_name="CPyObject_GetAttr3",
error_kind=ERR_MAGIC,
)
# setattr(obj, attr, value)
py_setattr_op = function_op(
name="builtins.setattr",
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
return_type=c_int_rprimitive,
c_function_name="PyObject_SetAttr",
error_kind=ERR_NEG_INT,
)
# hasattr(obj, attr)
py_hasattr_op = function_op(
name="builtins.hasattr",
arg_types=[object_rprimitive, object_rprimitive],
return_type=bool_rprimitive,
c_function_name="PyObject_HasAttr",
error_kind=ERR_NEVER,
)
# del obj.attr
py_delattr_op = function_op(
name="builtins.delattr",
arg_types=[object_rprimitive, object_rprimitive],
return_type=c_int_rprimitive,
c_function_name="PyObject_DelAttr",
error_kind=ERR_NEG_INT,
)
# Call callable object with N positional arguments: func(arg1, ..., argN)
# Arguments are (func, arg1, ..., argN).
py_call_op = custom_op(
arg_types=[],
return_type=object_rprimitive,
c_function_name="PyObject_CallFunctionObjArgs",
error_kind=ERR_MAGIC,
var_arg_type=object_rprimitive,
extra_int_constants=[(0, pointer_rprimitive)],
)
# Call callable object using positional and/or keyword arguments (Python 3.8+)
py_vectorcall_op = custom_op(
arg_types=[
object_rprimitive, # Callable
object_pointer_rprimitive, # Args (PyObject **)
c_size_t_rprimitive, # Number of positional args
object_rprimitive,
], # Keyword arg names tuple (or NULL)
return_type=object_rprimitive,
c_function_name="_PyObject_Vectorcall",
error_kind=ERR_MAGIC,
)
# Call method using positional and/or keyword arguments (Python 3.9+)
py_vectorcall_method_op = custom_op(
arg_types=[
object_rprimitive, # Method name
object_pointer_rprimitive, # Args, including self (PyObject **)
c_size_t_rprimitive, # Number of positional args, including self
object_rprimitive,
], # Keyword arg names tuple (or NULL)
return_type=object_rprimitive,
c_function_name="PyObject_VectorcallMethod",
error_kind=ERR_MAGIC,
)
# Call callable object with positional + keyword args: func(*args, **kwargs)
# Arguments are (func, *args tuple, **kwargs dict).
py_call_with_kwargs_op = custom_op(
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
return_type=object_rprimitive,
c_function_name="PyObject_Call",
error_kind=ERR_MAGIC,
)
# Call method with positional arguments: obj.method(arg1, ...)
# Arguments are (object, attribute name, arg1, ...).
py_method_call_op = custom_op(
arg_types=[],
return_type=object_rprimitive,
c_function_name="CPyObject_CallMethodObjArgs",
error_kind=ERR_MAGIC,
var_arg_type=object_rprimitive,
extra_int_constants=[(0, pointer_rprimitive)],
)
# len(obj)
generic_len_op = custom_op(
arg_types=[object_rprimitive],
return_type=int_rprimitive,
c_function_name="CPyObject_Size",
error_kind=ERR_MAGIC,
)
# len(obj)
# same as generic_len_op, however return py_ssize_t
generic_ssize_t_len_op = custom_op(
arg_types=[object_rprimitive],
return_type=c_pyssize_t_rprimitive,
c_function_name="PyObject_Size",
error_kind=ERR_NEG_INT,
)
# iter(obj)
iter_op = function_op(
name="builtins.iter",
arg_types=[object_rprimitive],
return_type=object_rprimitive,
c_function_name="PyObject_GetIter",
error_kind=ERR_MAGIC,
)
# next(iterator)
#
# Although the error_kind is set to be ERR_NEVER, this can actually
# return NULL, and thus it must be checked using Branch.IS_ERROR.
next_op = custom_op(
arg_types=[object_rprimitive],
return_type=object_rprimitive,
c_function_name="PyIter_Next",
error_kind=ERR_NEVER,
)
# next(iterator)
#
# Do a next, don't swallow StopIteration, but also don't propagate an
# error. (N.B: This can still return NULL without an error to
# represent an implicit StopIteration, but if StopIteration is
# *explicitly* raised this will not swallow it.)
# Can return NULL: see next_op.
next_raw_op = custom_op(
arg_types=[object_rprimitive],
return_type=object_rprimitive,
c_function_name="CPyIter_Next",
error_kind=ERR_NEVER,
)
# this would be aiter(obj) if it existed
aiter_op = custom_op(
arg_types=[object_rprimitive],
return_type=object_rprimitive,
c_function_name="CPy_GetAIter",
error_kind=ERR_MAGIC,
)
# this would be anext(obj) if it existed
anext_op = custom_op(
arg_types=[object_rprimitive],
return_type=object_rprimitive,
c_function_name="CPy_GetANext",
error_kind=ERR_MAGIC,
)