Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Slot wrappers
A slot wrapper is installed in the dict of an extension type to access a special method implemented in C. For example, ``object.__init__`` or ``Integer.__lt__``. Note that slot wrappers are always unbound (there is a bound variant called method-wrapper).
EXAMPLES::
sage: int.__add__ <slot wrapper '__add__' of 'int' objects>
Pure Python classes have normal methods, not slot wrappers::
sage: class X(object): ....: def __add__(self, other): ....: return NotImplemented sage: X.__add__ <unbound method X.__add__> """
#***************************************************************************** # Copyright (C) 2017 Jeroen Demeyer <J.Demeyer@UGent.be> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
from .string import bytes_to_str
def wrapperdescr_call(slotwrapper, self, *args, **kwds): """ Call a slot wrapper without any type checks.
The main reason to use this is to call arithmetic slots like ``__mul__`` without having to worry about whether to call ``T.__mul__(a, b)`` or ``T.__rmul__(b, a)``.
INPUT:
- ``slotwrapper`` -- a slot wrapper (for example ``int.__add__``).
- ``self`` -- the first positional argument. Normally, this should be of the correct type (an ``int`` when calling ``int.__add__``). However, this check is skipped: you can pass an arbitrary object.
- ``*args``, ``**kwds`` -- further arguments.
.. WARNING::
Since this skips type checks, it can easily crash Python if used incorrectly.
EXAMPLES::
sage: from sage.cpython.wrapperdescr import wrapperdescr_call sage: wrapperdescr_call(Integer.__mul__, 6, 9) 54 sage: wrapperdescr_call(Integer.__mul__, 7/5, 9) 63/5 sage: from sage.structure.element import Element sage: wrapperdescr_call(Element.__mul__, 6, 9) 54 sage: wrapperdescr_call(Element.__mul__, 7/5, 9) 63/5 sage: from sage.numerical.mip import MixedIntegerLinearProgram sage: wrapperdescr_call(type.__call__, MixedIntegerLinearProgram, maximization=False) Mixed Integer Program (no objective, 0 variables, 0 constraints)
TESTS::
sage: wrapperdescr_call(Integer.__mul__, 1, 2, 3) Traceback (most recent call last): ... TypeError: expected 1 arguments, got 2 sage: wrapperdescr_call(Integer.__mul__, 6, other=9) Traceback (most recent call last): ... TypeError: wrapper __mul__ slotdef doesn't take keyword arguments """ return wrapperdescr_fastcall(slotwrapper, self, args, kwds)
cdef wrapperdescr_fastcall(wrapper_descriptor slotwrapper, self, args, kwds): # Cython implementation of wrapperdescr_call
cdef wrapperfunc_kwds wk wk = <wrapperfunc_kwds>(slotdef.wrapper) return wk(self, args, slotwrapper.d_wrapped, kwds)
raise TypeError(f"wrapper {bytes_to_str(slotdef.name)} slotdef " "doesn't take keyword arguments")
|