summaryrefslogtreecommitdiff
path: root/tests/run/matrix_multiplier.pyx
blob: b54e5d78f850f5fe9273e22ca7614432a84fdcea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

import sys

if sys.version_info >= (3, 5):
    __doc__ = """\
Note: support for providing Python special methods despite missing the C-level slot
is currently not supported.

>>> a, b = ExtMatMult(1), ExtMatMult(2)
>>> print(test_matmul(a, b))
ExtMatMult(1) @ ExtMatMult(2)
>>> print(test_matmul(a, 22))
ExtMatMult(1) @ 22
>>> print(test_matmul(11, b))
11 @ ExtMatMult(2)
>>> print(test_imatmul(a, b))
ExtMatMult('ExtMatMult(1) @ ExtMatMult(2)')
>>> print(test_imatmul(a, b))
ExtMatMult("ExtMatMult('ExtMatMult(1) @ ExtMatMult(2)') @ ExtMatMult(2)")

>>> x = y = 1
>>> x @ y
Traceback (most recent call last):
TypeError: unsupported operand type(s) for @: 'int' and 'int'

PyPy exception message has '@' rather than '@='
>>> x @= y  # doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: unsupported operand type(s) for @...: 'int' and 'int'

>>> y = MatMult(22)
>>> x @= y
>>> print(x)
1 @ MatMult(22)

>>> x = MatMult(22)
>>> print(x @ 1)
MatMult(22) @ 1
>>> print(1 @ x)
1 @ MatMult(22)
>>> x @= 1
>>> print(x)
MatMult('MatMult(22) @ 1')
"""


class MatMult(object):
    def __init__(self, myself):
        self.myself = myself

    def __matmul__(self, other):
        return '%r @ %r' % (self, other)

    def __rmatmul__(self, other):
        return '%r @ %r' % (other, self)

    def __imatmul__(self, other):
        self.myself = '%r @ %r' % (self, other)
        return self

    def __repr__(self):
        return 'MatMult(%r)' % self.myself


cdef class ExtMatMult:
    """
    Note: support for providing Python special methods despite missing the C-level slot
    is currently not supported.
    """
    cdef object myself
    def __init__(self, myself):
        self.myself = myself

    def __matmul__(self, other):
        return '%r @ %r' % (self, other)

    def __rmatmul__(self, other):
        return '%r @ %r' % (other, self)

    def __imatmul__(self, other):
        self.myself = '%r @ %r' % (self, other)
        return self

    def __repr__(self):
        return 'ExtMatMult(%r)' % self.myself


def test_matmul(a, b):
    """
    >>> print(test_matmul(MatMult(1), MatMult(2)))
    MatMult(1) @ MatMult(2)
    >>> print(test_matmul(MatMult(1), 22))
    MatMult(1) @ 22
    >>> print(test_matmul(11, MatMult(2)))
    11 @ MatMult(2)
    >>> print(test_matmul(MatMult('abc'), MatMult('def')))
    MatMult('abc') @ MatMult('def')

    >>> test_matmul(1, 2)
    Traceback (most recent call last):
    TypeError: unsupported operand type(s) for @: 'int' and 'int'
    """
    return a @ b


def test_imatmul(a, b):
    """
    >>> print(test_imatmul(MatMult(1), MatMult(2)))
    MatMult('MatMult(1) @ MatMult(2)')
    >>> print(test_imatmul(MatMult('abc'), MatMult('def')))
    MatMult("MatMult('abc') @ MatMult('def')")
    >>> print(test_imatmul(11, MatMult('def')))
    11 @ MatMult('def')
    >>> print(test_imatmul(MatMult('abc'), 11))
    MatMult("MatMult('abc') @ 11")

    >>> test_imatmul(1, 2)  # doctest: +ELLIPSIS
    Traceback (most recent call last):
    TypeError: unsupported operand type(s) for @...: 'int' and 'int'
    """
    a @= b
    return a