[Python-checkins] cpython: PEP 465: a dedicated infix operator for matrix multiplication (closes #21176)
benjamin.peterson
python-checkins at python.org
Thu Apr 10 05:56:07 CEST 2014
http://hg.python.org/cpython/rev/c553d8f72d65
changeset: 90206:c553d8f72d65
user: Benjamin Peterson <benjamin at python.org>
date: Wed Apr 09 23:55:56 2014 -0400
summary:
PEP 465: a dedicated infix operator for matrix multiplication (closes #21176)
files:
Doc/c-api/number.rst | 17 +
Doc/c-api/typeobj.rst | 3 +
Doc/library/dis.rst | 10 +
Doc/library/operator.rst | 18 +
Doc/library/token.rst | 1 +
Doc/reference/datamodel.rst | 60 +-
Doc/reference/expressions.rst | 17 +-
Doc/reference/simple_stmts.rst | 2 +-
Grammar/Grammar | 4 +-
Include/Python-ast.h | 6 +-
Include/abstract.h | 12 +
Include/object.h | 3 +
Include/opcode.h | 3 +
Include/token.h | 13 +-
Include/typeslots.h | 2 +
Lib/importlib/_bootstrap.py | 3 +-
Lib/opcode.py | 3 +
Lib/operator.py | 11 +
Lib/test/test_augassign.py | 15 +
Lib/test/test_capi.py | 17 +
Lib/test/test_descr.py | 1 +
Lib/test/test_grammar.py | 14 +
Lib/test/test_operator.py | 11 +
Lib/test/test_sys.py | 2 +-
Lib/test/test_tokenize.py | 5 +-
Lib/token.py | 11 +-
Lib/tokenize.py | 5 +-
Misc/NEWS | 2 +
Modules/_operator.c | 4 +
Modules/_testcapimodule.c | 107 +++++
Objects/abstract.c | 14 +
Objects/typeobject.c | 10 +
Objects/typeslots.inc | 2 +
Parser/Python.asdl | 2 +-
Parser/tokenizer.c | 8 +-
Python/Python-ast.c | 24 +-
Python/ast.c | 8 +-
Python/ceval.c | 24 +
Python/compile.c | 6 +
Python/graminit.c | 435 ++++++++++----------
Python/importlib.h | 320 +++++++-------
Python/opcode_targets.h | 4 +-
42 files changed, 800 insertions(+), 439 deletions(-)
diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst
--- a/Doc/c-api/number.rst
+++ b/Doc/c-api/number.rst
@@ -30,6 +30,14 @@
the equivalent of the Python expression ``o1 * o2``.
+.. c:function:: PyObject* PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2)
+
+ Returns the result of matrix multiplication on *o1* and *o2*, or *NULL* on
+ failure. This is the equivalent of the Python expression ``o1 @ o2``.
+
+ .. versionadded:: 3.5
+
+
.. c:function:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2)
Return the floor of *o1* divided by *o2*, or *NULL* on failure. This is
@@ -146,6 +154,15 @@
the Python statement ``o1 *= o2``.
+.. c:function:: PyObject* PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2)
+
+ Returns the result of matrix multiplication on *o1* and *o2*, or *NULL* on
+ failure. The operation is done *in-place* when *o1* supports it. This is
+ the equivalent of the Python statement ``o1 @= o2``.
+
+ .. versionadded:: 3.5
+
+
.. c:function:: PyObject* PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2)
Returns the mathematical floor of dividing *o1* by *o2*, or *NULL* on failure.
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -1121,6 +1121,9 @@
binaryfunc nb_inplace_true_divide;
unaryfunc nb_index;
+
+ binaryfunc nb_matrix_multiply;
+ binaryfunc nb_inplace_matrix_multiply;
} PyNumberMethods;
.. note::
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -364,6 +364,11 @@
Implements ``TOS = TOS1 * TOS``.
+.. opcode:: BINARY_MATRIX_MULTIPLY
+
+ Implements ``TOS = TOS1 @ TOS``.
+
+
.. opcode:: BINARY_FLOOR_DIVIDE
Implements ``TOS = TOS1 // TOS``.
@@ -436,6 +441,11 @@
Implements in-place ``TOS = TOS1 * TOS``.
+.. opcode:: INPLACE_MATRIX_MULTIPLY
+
+ Implements in-place ``TOS = TOS1 @ TOS``.
+
+
.. opcode:: INPLACE_FLOOR_DIVIDE
Implements in-place ``TOS = TOS1 // TOS``.
diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst
--- a/Doc/library/operator.rst
+++ b/Doc/library/operator.rst
@@ -138,6 +138,14 @@
Return ``a * b``, for *a* and *b* numbers.
+.. function:: matmul(a, b)
+ __matmul__(a, b)
+
+ Return ``a @ b``.
+
+ .. versionadded:: 3.5
+
+
.. function:: neg(obj)
__neg__(obj)
@@ -400,6 +408,8 @@
+-----------------------+-------------------------+---------------------------------------+
| Multiplication | ``a * b`` | ``mul(a, b)`` |
+-----------------------+-------------------------+---------------------------------------+
+| Matrix Multiplication | ``a @ b`` | ``matmul(a, b)`` |
++-----------------------+-------------------------+---------------------------------------+
| Negation (Arithmetic) | ``- a`` | ``neg(a)`` |
+-----------------------+-------------------------+---------------------------------------+
| Negation (Logical) | ``not a`` | ``not_(a)`` |
@@ -508,6 +518,14 @@
``a = imul(a, b)`` is equivalent to ``a *= b``.
+.. function:: imatmul(a, b)
+ __imatmul__(a, b)
+
+ ``a = imatmul(a, b)`` is equivalent to ``a @= b``.
+
+ .. versionadded:: 3.5
+
+
.. function:: ior(a, b)
__ior__(a, b)
diff --git a/Doc/library/token.rst b/Doc/library/token.rst
--- a/Doc/library/token.rst
+++ b/Doc/library/token.rst
@@ -93,6 +93,7 @@
DOUBLESLASH
DOUBLESLASHEQUAL
AT
+ ATEQUAL
RARROW
ELLIPSIS
OP
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst
--- a/Doc/reference/datamodel.rst
+++ b/Doc/reference/datamodel.rst
@@ -1970,6 +1970,7 @@
.. method:: object.__add__(self, other)
object.__sub__(self, other)
object.__mul__(self, other)
+ object.__matmul__(self, other)
object.__truediv__(self, other)
object.__floordiv__(self, other)
object.__mod__(self, other)
@@ -1986,15 +1987,16 @@
builtin: pow
builtin: pow
- These methods are called to implement the binary arithmetic operations (``+``,
- ``-``, ``*``, ``/``, ``//``, ``%``, :func:`divmod`, :func:`pow`, ``**``, ``<<``,
- ``>>``, ``&``, ``^``, ``|``). For instance, to evaluate the expression
- ``x + y``, where *x* is an instance of a class that has an :meth:`__add__`
- method, ``x.__add__(y)`` is called. The :meth:`__divmod__` method should be the
- equivalent to using :meth:`__floordiv__` and :meth:`__mod__`; it should not be
- related to :meth:`__truediv__`. Note that :meth:`__pow__` should be defined
- to accept an optional third argument if the ternary version of the built-in
- :func:`pow` function is to be supported.
+ These methods are called to implement the binary arithmetic operations
+ (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`,
+ :func:`pow`, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For instance, to
+ evaluate the expression ``x + y``, where *x* is an instance of a class that
+ has an :meth:`__add__` method, ``x.__add__(y)`` is called. The
+ :meth:`__divmod__` method should be the equivalent to using
+ :meth:`__floordiv__` and :meth:`__mod__`; it should not be related to
+ :meth:`__truediv__`. Note that :meth:`__pow__` should be defined to accept
+ an optional third argument if the ternary version of the built-in :func:`pow`
+ function is to be supported.
If one of those methods does not support the operation with the supplied
arguments, it should return ``NotImplemented``.
@@ -2003,6 +2005,7 @@
.. method:: object.__radd__(self, other)
object.__rsub__(self, other)
object.__rmul__(self, other)
+ object.__rmatmul__(self, other)
object.__rtruediv__(self, other)
object.__rfloordiv__(self, other)
object.__rmod__(self, other)
@@ -2018,14 +2021,14 @@
builtin: divmod
builtin: pow
- These methods are called to implement the binary arithmetic operations (``+``,
- ``-``, ``*``, ``/``, ``//``, ``%``, :func:`divmod`, :func:`pow`, ``**``,
- ``<<``, ``>>``, ``&``, ``^``, ``|``) with reflected (swapped) operands.
- These functions are only called if the left operand does not support the
- corresponding operation and the operands are of different types. [#]_ For
- instance, to evaluate the expression ``x - y``, where *y* is an instance of
- a class that has an :meth:`__rsub__` method, ``y.__rsub__(x)`` is called if
- ``x.__sub__(y)`` returns *NotImplemented*.
+ These methods are called to implement the binary arithmetic operations
+ (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`,
+ :func:`pow`, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with reflected
+ (swapped) operands. These functions are only called if the left operand does
+ not support the corresponding operation and the operands are of different
+ types. [#]_ For instance, to evaluate the expression ``x - y``, where *y* is
+ an instance of a class that has an :meth:`__rsub__` method, ``y.__rsub__(x)``
+ is called if ``x.__sub__(y)`` returns *NotImplemented*.
.. index:: builtin: pow
@@ -2043,6 +2046,7 @@
.. method:: object.__iadd__(self, other)
object.__isub__(self, other)
object.__imul__(self, other)
+ object.__imatmul__(self, other)
object.__itruediv__(self, other)
object.__ifloordiv__(self, other)
object.__imod__(self, other)
@@ -2054,17 +2058,17 @@
object.__ior__(self, other)
These methods are called to implement the augmented arithmetic assignments
- (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``, ``**=``, ``<<=``, ``>>=``,
- ``&=``, ``^=``, ``|=``). These methods should attempt to do the operation
- in-place (modifying *self*) and return the result (which could be, but does
- not have to be, *self*). If a specific method is not defined, the augmented
- assignment falls back to the normal methods. For instance, if *x* is an
- instance of a class with an :meth:`__iadd__` method, ``x += y`` is equivalent
- to ``x = x.__iadd__(y)`` . Otherwise, ``x.__add__(y)`` and ``y.__radd__(x)``
- are considered, as with the evaluation of ``x + y``. In certain situations,
- augmented assignment can result in unexpected errors (see
- :ref:`faq-augmented-assignment-tuple-error`), but this behavior is in
- fact part of the data model.
+ (``+=``, ``-=``, ``*=``, ``@=``, ``/=``, ``//=``, ``%=``, ``**=``, ``<<=``,
+ ``>>=``, ``&=``, ``^=``, ``|=``). These methods should attempt to do the
+ operation in-place (modifying *self*) and return the result (which could be,
+ but does not have to be, *self*). If a specific method is not defined, the
+ augmented assignment falls back to the normal methods. For instance, if *x*
+ is an instance of a class with an :meth:`__iadd__` method, ``x += y`` is
+ equivalent to ``x = x.__iadd__(y)`` . Otherwise, ``x.__add__(y)`` and
+ ``y.__radd__(x)`` are considered, as with the evaluation of ``x + y``. In
+ certain situations, augmented assignment can result in unexpected errors (see
+ :ref:`faq-augmented-assignment-tuple-error`), but this behavior is in fact
+ part of the data model.
.. method:: object.__neg__(self)
diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -892,8 +892,9 @@
operators and one for additive operators:
.. productionlist::
- m_expr: `u_expr` | `m_expr` "*" `u_expr` | `m_expr` "//" `u_expr` | `m_expr` "/" `u_expr`
- : | `m_expr` "%" `u_expr`
+ m_expr: `u_expr` | `m_expr` "*" `u_expr` | `m_expr` "@" `m_expr` |
+ : `m_expr` "//" `u_expr`| `m_expr` "/" `u_expr` |
+ : `m_expr` "%" `u_expr`
a_expr: `m_expr` | `a_expr` "+" `m_expr` | `a_expr` "-" `m_expr`
.. index:: single: multiplication
@@ -904,6 +905,13 @@
common type and then multiplied together. In the latter case, sequence
repetition is performed; a negative repetition factor yields an empty sequence.
+.. index:: single: matrix multiplication
+
+The ``@`` (at) operator is intended to be used for matrix multiplication. No
+builtin Python types implement this operator.
+
+.. versionadded:: 3.5
+
.. index::
exception: ZeroDivisionError
single: division
@@ -1346,8 +1354,9 @@
+-----------------------------------------------+-------------------------------------+
| ``+``, ``-`` | Addition and subtraction |
+-----------------------------------------------+-------------------------------------+
-| ``*``, ``/``, ``//``, ``%`` | Multiplication, division, remainder |
-| | [#]_ |
+| ``*``, ``@``, ``/``, ``//``, ``%`` | Multiplication, matrix |
+| | multiplication division, |
+| | remainder [#]_ |
+-----------------------------------------------+-------------------------------------+
| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT |
+-----------------------------------------------+-------------------------------------+
diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst
--- a/Doc/reference/simple_stmts.rst
+++ b/Doc/reference/simple_stmts.rst
@@ -267,7 +267,7 @@
.. productionlist::
augmented_assignment_stmt: `augtarget` `augop` (`expression_list` | `yield_expression`)
augtarget: `identifier` | `attributeref` | `subscription` | `slicing`
- augop: "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="
+ augop: "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="
: | ">>=" | "<<=" | "&=" | "^=" | "|="
(See section :ref:`primaries` for the syntax definitions for the last three
diff --git a/Grammar/Grammar b/Grammar/Grammar
--- a/Grammar/Grammar
+++ b/Grammar/Grammar
@@ -40,7 +40,7 @@
expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
('=' (yield_expr|testlist_star_expr))*)
testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
-augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' |
+augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
'<<=' | '>>=' | '**=' | '//=')
# For normal assignments, additional restrictions enforced by the interpreter
del_stmt: 'del' exprlist
@@ -97,7 +97,7 @@
and_expr: shift_expr ('&' shift_expr)*
shift_expr: arith_expr (('<<'|'>>') arith_expr)*
arith_expr: term (('+'|'-') term)*
-term: factor (('*'|'/'|'%'|'//') factor)*
+term: factor (('*'|'@'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power
power: atom trailer* ['**' factor]
atom: ('(' [yield_expr|testlist_comp] ')' |
diff --git a/Include/Python-ast.h b/Include/Python-ast.h
--- a/Include/Python-ast.h
+++ b/Include/Python-ast.h
@@ -15,9 +15,9 @@
typedef enum _boolop { And=1, Or=2 } boolop_ty;
-typedef enum _operator { Add=1, Sub=2, Mult=3, Div=4, Mod=5, Pow=6, LShift=7,
- RShift=8, BitOr=9, BitXor=10, BitAnd=11, FloorDiv=12 }
- operator_ty;
+typedef enum _operator { Add=1, Sub=2, Mult=3, MatMult=4, Div=5, Mod=6, Pow=7,
+ LShift=8, RShift=9, BitOr=10, BitXor=11, BitAnd=12,
+ FloorDiv=13 } operator_ty;
typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty;
diff --git a/Include/abstract.h b/Include/abstract.h
--- a/Include/abstract.h
+++ b/Include/abstract.h
@@ -658,6 +658,12 @@
o1*o2.
*/
+ PyAPI_FUNC(PyObject *) PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2);
+
+ /*
+ This is the equivalent of the Python expression: o1 @ o2.
+ */
+
PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2);
/*
@@ -832,6 +838,12 @@
o1 *= o2.
*/
+ PyAPI_FUNC(PyObject *) PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2);
+
+ /*
+ This is the equivalent of the Python expression: o1 @= o2.
+ */
+
PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1,
PyObject *o2);
diff --git a/Include/object.h b/Include/object.h
--- a/Include/object.h
+++ b/Include/object.h
@@ -275,6 +275,9 @@
binaryfunc nb_inplace_true_divide;
unaryfunc nb_index;
+
+ binaryfunc nb_matrix_multiply;
+ binaryfunc nb_inplace_matrix_multiply;
} PyNumberMethods;
typedef struct {
diff --git a/Include/opcode.h b/Include/opcode.h
--- a/Include/opcode.h
+++ b/Include/opcode.h
@@ -20,6 +20,9 @@
#define UNARY_INVERT 15
+#define BINARY_MATRIX_MULTIPLY 16
+#define INPLACE_MATRIX_MULTIPLY 17
+
#define BINARY_POWER 19
#define BINARY_MULTIPLY 20
diff --git a/Include/token.h b/Include/token.h
--- a/Include/token.h
+++ b/Include/token.h
@@ -58,13 +58,14 @@
#define DOUBLESTAREQUAL 46
#define DOUBLESLASH 47
#define DOUBLESLASHEQUAL 48
-#define AT 49
-#define RARROW 50
-#define ELLIPSIS 51
+#define AT 49
+#define ATEQUAL 50
+#define RARROW 51
+#define ELLIPSIS 52
/* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */
-#define OP 52
-#define ERRORTOKEN 53
-#define N_TOKENS 54
+#define OP 53
+#define ERRORTOKEN 54
+#define N_TOKENS 55
/* Special definitions for cooperation with parser */
diff --git a/Include/typeslots.h b/Include/typeslots.h
--- a/Include/typeslots.h
+++ b/Include/typeslots.h
@@ -74,3 +74,5 @@
#define Py_tp_members 72
#define Py_tp_getset 73
#define Py_tp_free 74
+#define Py_nb_matrix_multiply 75
+#define Py_nb_inplace_matrix_multiply 76
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -419,12 +419,13 @@
# Python 3.4a4 3290 (changes to __qualname__ computation)
# Python 3.4a4 3300 (more changes to __qualname__ computation)
# Python 3.4rc2 3310 (alter __qualname__ computation)
+# Python 3.5a0 3320 (matrix multiplication operator)
#
# MAGIC must change whenever the bytecode emitted by the compiler may no
# longer be understood by older implementations of the eval loop (usually
# due to the addition of new opcodes).
-MAGIC_NUMBER = (3310).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3320).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
_PYCACHE = '__pycache__'
diff --git a/Lib/opcode.py b/Lib/opcode.py
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -70,6 +70,9 @@
def_op('UNARY_INVERT', 15)
+def_op('BINARY_MATRIX_MULTIPLY', 16)
+def_op('INPLACE_MATRIX_MULTIPLY', 17)
+
def_op('BINARY_POWER', 19)
def_op('BINARY_MULTIPLY', 20)
diff --git a/Lib/operator.py b/Lib/operator.py
--- a/Lib/operator.py
+++ b/Lib/operator.py
@@ -105,6 +105,10 @@
"Same as a * b."
return a * b
+def matmul(a, b):
+ "Same as a @ b."
+ return a @ b
+
def neg(a):
"Same as -a."
return -a
@@ -326,6 +330,11 @@
a *= b
return a
+def imatmul(a, b):
+ "Same as a @= b."
+ a @= b
+ return a
+
def ior(a, b):
"Same as a |= b."
a |= b
@@ -383,6 +392,7 @@
__lshift__ = lshift
__mod__ = mod
__mul__ = mul
+__matmul__ = matmul
__neg__ = neg
__or__ = or_
__pos__ = pos
@@ -403,6 +413,7 @@
__ilshift__ = ilshift
__imod__ = imod
__imul__ = imul
+__imatmul__ = imatmul
__ior__ = ior
__ipow__ = ipow
__irshift__ = irshift
diff --git a/Lib/test/test_augassign.py b/Lib/test/test_augassign.py
--- a/Lib/test/test_augassign.py
+++ b/Lib/test/test_augassign.py
@@ -136,6 +136,14 @@
output.append("__imul__ called")
return self
+ def __matmul__(self, val):
+ output.append("__matmul__ called")
+ def __rmatmul__(self, val):
+ output.append("__rmatmul__ called")
+ def __imatmul__(self, val):
+ output.append("__imatmul__ called")
+ return self
+
def __div__(self, val):
output.append("__div__ called")
def __rdiv__(self, val):
@@ -233,6 +241,10 @@
1 * x
x *= 1
+ x @ 1
+ 1 @ x
+ x @= 1
+
x / 1
1 / x
x /= 1
@@ -279,6 +291,9 @@
__mul__ called
__rmul__ called
__imul__ called
+__matmul__ called
+__rmatmul__ called
+__imatmul__ called
__truediv__ called
__rtruediv__ called
__itruediv__ called
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -150,6 +150,23 @@
self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
"($module, /, parameter)")
+ def test_c_type_with_matrix_multiplication(self):
+ M = _testcapi.matmulType
+ m1 = M()
+ m2 = M()
+ self.assertEqual(m1 @ m2, ("matmul", m1, m2))
+ self.assertEqual(m1 @ 42, ("matmul", m1, 42))
+ self.assertEqual(42 @ m1, ("matmul", 42, m1))
+ o = m1
+ o @= m2
+ self.assertEqual(o, ("imatmul", m1, m2))
+ o = m1
+ o @= 42
+ self.assertEqual(o, ("imatmul", m1, 42))
+ o = 42
+ o @= m1
+ self.assertEqual(o, ("matmul", 42, m1))
+
@unittest.skipUnless(threading, 'Threading required for this test.')
class TestPendingCalls(unittest.TestCase):
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -4160,6 +4160,7 @@
('__add__', 'x + y', 'x += y'),
('__sub__', 'x - y', 'x -= y'),
('__mul__', 'x * y', 'x *= y'),
+ ('__matmul__', 'x @ y', 'x @= y'),
('__truediv__', 'operator.truediv(x, y)', None),
('__floordiv__', 'operator.floordiv(x, y)', None),
('__div__', 'x / y', 'x /= y'),
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -985,6 +985,20 @@
self.assertFalse((False is 2) is 3)
self.assertFalse(False is 2 is 3)
+ def test_matrix_mul(self):
+ # This is not intended to be a comprehensive test, rather just to be few
+ # samples of the @ operator in test_grammar.py.
+ class M:
+ def __matmul__(self, o):
+ return 4
+ def __imatmul__(self, o):
+ self.other = o
+ return self
+ m = M()
+ self.assertEqual(m @ m, 4)
+ m @= 42
+ self.assertEqual(m.other, 42)
+
def test_main():
run_unittest(TokenTests, GrammarTests)
diff --git a/Lib/test/test_operator.py b/Lib/test/test_operator.py
--- a/Lib/test/test_operator.py
+++ b/Lib/test/test_operator.py
@@ -203,6 +203,15 @@
self.assertRaises(TypeError, operator.mul, None, None)
self.assertTrue(operator.mul(5, 2) == 10)
+ def test_matmul(self):
+ operator = self.module
+ self.assertRaises(TypeError, operator.matmul)
+ self.assertRaises(TypeError, operator.matmul, 42, 42)
+ class M:
+ def __matmul__(self, other):
+ return other - 1
+ self.assertEqual(M() @ 42, 41)
+
def test_neg(self):
operator = self.module
self.assertRaises(TypeError, operator.neg)
@@ -416,6 +425,7 @@
def __ilshift__ (self, other): return "ilshift"
def __imod__ (self, other): return "imod"
def __imul__ (self, other): return "imul"
+ def __imatmul__ (self, other): return "imatmul"
def __ior__ (self, other): return "ior"
def __ipow__ (self, other): return "ipow"
def __irshift__ (self, other): return "irshift"
@@ -430,6 +440,7 @@
self.assertEqual(operator.ilshift (c, 5), "ilshift")
self.assertEqual(operator.imod (c, 5), "imod")
self.assertEqual(operator.imul (c, 5), "imul")
+ self.assertEqual(operator.imatmul (c, 5), "imatmul")
self.assertEqual(operator.ior (c, 5), "ior")
self.assertEqual(operator.ipow (c, 5), "ipow")
self.assertEqual(operator.irshift (c, 5), "irshift")
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -952,7 +952,7 @@
check(int, s)
# (PyTypeObject + PyNumberMethods + PyMappingMethods +
# PySequenceMethods + PyBufferProcs + 4P)
- s = vsize('P2n15Pl4Pn9Pn11PIP') + struct.calcsize('34P 3P 10P 2P 4P')
+ s = vsize('P2n17Pl4Pn9Pn11PIP') + struct.calcsize('34P 3P 10P 2P 4P')
# Separate block for PyDictKeysObject with 4 entries
s += struct.calcsize("2nPn") + 4*struct.calcsize("n2P")
# class
diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py
--- a/Lib/test/test_tokenize.py
+++ b/Lib/test/test_tokenize.py
@@ -464,7 +464,7 @@
Multiplicative
- >>> dump_tokens("x = 1//1*1/5*12%0x12")
+ >>> dump_tokens("x = 1//1*1/5*12%0x12 at 42")
ENCODING 'utf-8' (0, 0) (0, 0)
NAME 'x' (1, 0) (1, 1)
OP '=' (1, 2) (1, 3)
@@ -479,6 +479,8 @@
NUMBER '12' (1, 13) (1, 15)
OP '%' (1, 15) (1, 16)
NUMBER '0x12' (1, 16) (1, 20)
+ OP '@' (1, 20) (1, 21)
+ NUMBER '42' (1, 21) (1, 23)
Unary
@@ -1154,6 +1156,7 @@
self.assertExactTypeEqual('//', token.DOUBLESLASH)
self.assertExactTypeEqual('//=', token.DOUBLESLASHEQUAL)
self.assertExactTypeEqual('@', token.AT)
+ self.assertExactTypeEqual('@=', token.ATEQUAL)
self.assertExactTypeEqual('a**2+b**2==c**2',
NAME, token.DOUBLESTAR, NUMBER,
diff --git a/Lib/token.py b/Lib/token.py
--- a/Lib/token.py
+++ b/Lib/token.py
@@ -60,11 +60,12 @@
DOUBLESLASH = 47
DOUBLESLASHEQUAL = 48
AT = 49
-RARROW = 50
-ELLIPSIS = 51
-OP = 52
-ERRORTOKEN = 53
-N_TOKENS = 54
+ATEQUAL = 50
+RARROW = 51
+ELLIPSIS = 52
+OP = 53
+ERRORTOKEN = 54
+N_TOKENS = 55
NT_OFFSET = 256
#--end constants--
diff --git a/Lib/tokenize.py b/Lib/tokenize.py
--- a/Lib/tokenize.py
+++ b/Lib/tokenize.py
@@ -91,7 +91,8 @@
'**=': DOUBLESTAREQUAL,
'//': DOUBLESLASH,
'//=': DOUBLESLASHEQUAL,
- '@': AT
+ '@': AT,
+ '@=': ATEQUAL,
}
class TokenInfo(collections.namedtuple('TokenInfo', 'type string start end line')):
@@ -150,7 +151,7 @@
# recognized as two instances of =).
Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"!=",
r"//=?", r"->",
- r"[+\-*/%&|^=<>]=?",
+ r"[+\-*/%&@|^=<>]=?",
r"~")
Bracket = '[][(){}]'
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@
Core and Builtins
-----------------
+- PEP 465 and Issue #21176: Add the '@' operator for matrix multiplication.
+
- Issue #21134: Fix segfault when str is called on an uninitialized
UnicodeEncodeError, UnicodeDecodeError, or UnicodeTranslateError object.
diff --git a/Modules/_operator.c b/Modules/_operator.c
--- a/Modules/_operator.c
+++ b/Modules/_operator.c
@@ -69,6 +69,7 @@
spam2(op_add , PyNumber_Add)
spam2(op_sub , PyNumber_Subtract)
spam2(op_mul , PyNumber_Multiply)
+spam2(op_matmul , PyNumber_MatrixMultiply)
spam2(op_floordiv , PyNumber_FloorDivide)
spam2(op_truediv , PyNumber_TrueDivide)
spam2(op_mod , PyNumber_Remainder)
@@ -86,6 +87,7 @@
spam2(op_iadd , PyNumber_InPlaceAdd)
spam2(op_isub , PyNumber_InPlaceSubtract)
spam2(op_imul , PyNumber_InPlaceMultiply)
+spam2(op_imatmul , PyNumber_InPlaceMatrixMultiply)
spam2(op_ifloordiv , PyNumber_InPlaceFloorDivide)
spam2(op_itruediv , PyNumber_InPlaceTrueDivide)
spam2(op_imod , PyNumber_InPlaceRemainder)
@@ -343,6 +345,7 @@
spam2(add, "add(a, b) -- Same as a + b.")
spam2(sub, "sub(a, b) -- Same as a - b.")
spam2(mul, "mul(a, b) -- Same as a * b.")
+spam2(matmul, "matmul(a, b) -- Same as a @ b.")
spam2(floordiv, "floordiv(a, b) -- Same as a // b.")
spam2(truediv, "truediv(a, b) -- Same as a / b.")
spam2(mod, "mod(a, b) -- Same as a % b.")
@@ -360,6 +363,7 @@
spam2(iadd, "a = iadd(a, b) -- Same as a += b.")
spam2(isub, "a = isub(a, b) -- Same as a -= b.")
spam2(imul, "a = imul(a, b) -- Same as a *= b.")
+spam2(imatmul, "a = imatmul(a, b) -- Same as a @= b.")
spam2(ifloordiv, "a = ifloordiv(a, b) -- Same as a //= b.")
spam2(itruediv, "a = itruediv(a, b) -- Same as a /= b")
spam2(imod, "a = imod(a, b) -- Same as a %= b.")
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -3298,6 +3298,109 @@
};
+typedef struct {
+ PyObject_HEAD
+} matmulObject;
+
+static PyObject *
+matmulType_matmul(PyObject *self, PyObject *other)
+{
+ return Py_BuildValue("(sOO)", "matmul", self, other);
+}
+
+static PyObject *
+matmulType_imatmul(PyObject *self, PyObject *other)
+{
+ return Py_BuildValue("(sOO)", "imatmul", self, other);
+}
+
+static void
+matmulType_dealloc(PyObject *self)
+{
+ return Py_TYPE(self)->tp_free(self);
+}
+
+static PyNumberMethods matmulType_as_number = {
+ 0, /* nb_add */
+ 0, /* nb_subtract */
+ 0, /* nb_multiply */
+ 0, /* nb_remainde r*/
+ 0, /* nb_divmod */
+ 0, /* nb_power */
+ 0, /* nb_negative */
+ 0, /* tp_positive */
+ 0, /* tp_absolute */
+ 0, /* tp_bool */
+ 0, /* nb_invert */
+ 0, /* nb_lshift */
+ 0, /* nb_rshift */
+ 0, /* nb_and */
+ 0, /* nb_xor */
+ 0, /* nb_or */
+ 0, /* nb_int */
+ 0, /* nb_reserved */
+ 0, /* nb_float */
+ 0, /* nb_inplace_add */
+ 0, /* nb_inplace_subtract */
+ 0, /* nb_inplace_multiply */
+ 0, /* nb_inplace_remainder */
+ 0, /* nb_inplace_power */
+ 0, /* nb_inplace_lshift */
+ 0, /* nb_inplace_rshift */
+ 0, /* nb_inplace_and */
+ 0, /* nb_inplace_xor */
+ 0, /* nb_inplace_or */
+ 0, /* nb_floor_divide */
+ 0, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
+ 0, /* nb_index */
+ matmulType_matmul, /* nb_matrix_multiply */
+ matmulType_imatmul /* nb_matrix_inplace_multiply */
+};
+
+static PyTypeObject matmulType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "matmulType",
+ sizeof(matmulObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ matmulType_dealloc, /* destructor tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ &matmulType_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ 0, /* tp_flags */
+ "C level type with matrix operations defined",
+ 0, /* traverseproc tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ PyType_GenericNew, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
static struct PyModuleDef _testcapimodule = {
PyModuleDef_HEAD_INIT,
@@ -3327,6 +3430,10 @@
/* don't use a name starting with "test", since we don't want
test_capi to automatically call this */
PyModule_AddObject(m, "_test_structmembersType", (PyObject *)&test_structmembersType);
+ if (PyType_Ready(&matmulType) < 0)
+ return NULL;
+ Py_INCREF(&matmulType);
+ PyModule_AddObject(m, "matmulType", (PyObject *)&matmulType);
PyModule_AddObject(m, "CHAR_MAX", PyLong_FromLong(CHAR_MAX));
PyModule_AddObject(m, "CHAR_MIN", PyLong_FromLong(CHAR_MIN));
diff --git a/Objects/abstract.c b/Objects/abstract.c
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -932,6 +932,12 @@
}
PyObject *
+PyNumber_MatrixMultiply(PyObject *v, PyObject *w)
+{
+ return binary_op(v, w, NB_SLOT(nb_matrix_multiply), "@");
+}
+
+PyObject *
PyNumber_FloorDivide(PyObject *v, PyObject *w)
{
return binary_op(v, w, NB_SLOT(nb_floor_divide), "//");
@@ -1012,6 +1018,7 @@
INPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=")
INPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=")
INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=")
+INPLACE_BINOP(PyNumber_InMatrixMultiply, nb_inplace_matrix_multiply, nb_matrix_multiply, "@=")
PyObject *
PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w)
@@ -1078,6 +1085,13 @@
}
PyObject *
+PyNumber_InPlaceMatrixMultiply(PyObject *v, PyObject *w)
+{
+ return binary_iop(v, w, NB_SLOT(nb_inplace_matrix_multiply),
+ NB_SLOT(nb_matrix_multiply), "@=");
+}
+
+PyObject *
PyNumber_InPlaceRemainder(PyObject *v, PyObject *w)
{
return binary_iop(v, w, NB_SLOT(nb_inplace_remainder),
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -4469,6 +4469,8 @@
COPYNUM(nb_inplace_true_divide);
COPYNUM(nb_inplace_floor_divide);
COPYNUM(nb_index);
+ COPYNUM(nb_matrix_multiply);
+ COPYNUM(nb_inplace_matrix_multiply);
}
if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) {
@@ -5605,6 +5607,7 @@
SLOT1BIN(slot_nb_add, nb_add, "__add__", "__radd__")
SLOT1BIN(slot_nb_subtract, nb_subtract, "__sub__", "__rsub__")
SLOT1BIN(slot_nb_multiply, nb_multiply, "__mul__", "__rmul__")
+SLOT1BIN(slot_nb_matrix_multiply, nb_matrix_multiply, "__matmul__", "__rmatmul__")
SLOT1BIN(slot_nb_remainder, nb_remainder, "__mod__", "__rmod__")
SLOT1BIN(slot_nb_divmod, nb_divmod, "__divmod__", "__rdivmod__")
@@ -5698,6 +5701,7 @@
SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *, "O")
SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *, "O")
SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *, "O")
+SLOT1(slot_nb_inplace_matrix_multiply, "__imatmul__", PyObject *, "O")
SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *, "O")
/* Can't use SLOT1 here, because nb_inplace_power is ternary */
static PyObject *
@@ -6278,6 +6282,12 @@
"__index__($self, /)\n--\n\n"
"Return self converted to an integer, if self is suitable"
"for use as an index into a list."),
+ BINSLOT("__matmul__", nb_matrix_multiply, slot_nb_matrix_multiply,
+ "@"),
+ RBINSLOT("__rmatmul__", nb_matrix_multiply, slot_nb_matrix_multiply,
+ "@"),
+ IBSLOT("__imatmul__", nb_inplace_matrix_multiply, slot_nb_inplace_matrix_multiply,
+ wrap_binaryfunc, "@="),
MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc,
"__len__($self, /)\n--\n\nReturn len(self)."),
MPSLOT("__getitem__", mp_subscript, slot_mp_subscript,
diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc
--- a/Objects/typeslots.inc
+++ b/Objects/typeslots.inc
@@ -73,3 +73,5 @@
offsetof(PyHeapTypeObject, ht_type.tp_members),
offsetof(PyHeapTypeObject, ht_type.tp_getset),
offsetof(PyHeapTypeObject, ht_type.tp_free),
+offsetof(PyHeapTypeObject, as_number.nb_matrix_multiply),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_matrix_multiply),
diff --git a/Parser/Python.asdl b/Parser/Python.asdl
--- a/Parser/Python.asdl
+++ b/Parser/Python.asdl
@@ -91,7 +91,7 @@
boolop = And | Or
- operator = Add | Sub | Mult | Div | Mod | Pow | LShift
+ operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift
| RShift | BitOr | BitXor | BitAnd | FloorDiv
unaryop = Invert | Not | UAdd | USub
diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c
--- a/Parser/tokenizer.c
+++ b/Parser/tokenizer.c
@@ -98,6 +98,7 @@
"DOUBLESLASH",
"DOUBLESLASHEQUAL",
"AT",
+ "ATEQUAL",
"RARROW",
"ELLIPSIS",
/* This table must match the #defines in token.h! */
@@ -1131,7 +1132,7 @@
case '}': return RBRACE;
case '^': return CIRCUMFLEX;
case '~': return TILDE;
- case '@': return AT;
+ case '@': return AT;
default: return OP;
}
}
@@ -1207,6 +1208,11 @@
case '=': return CIRCUMFLEXEQUAL;
}
break;
+ case '@':
+ switch (c2) {
+ case '=': return ATEQUAL;
+ }
+ break;
}
return OP;
}
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -349,13 +349,14 @@
static PyTypeObject *Or_type;
static PyTypeObject *operator_type;
static PyObject *Add_singleton, *Sub_singleton, *Mult_singleton,
-*Div_singleton, *Mod_singleton, *Pow_singleton, *LShift_singleton,
-*RShift_singleton, *BitOr_singleton, *BitXor_singleton, *BitAnd_singleton,
-*FloorDiv_singleton;
+*MatMult_singleton, *Div_singleton, *Mod_singleton, *Pow_singleton,
+*LShift_singleton, *RShift_singleton, *BitOr_singleton, *BitXor_singleton,
+*BitAnd_singleton, *FloorDiv_singleton;
static PyObject* ast2obj_operator(operator_ty);
static PyTypeObject *Add_type;
static PyTypeObject *Sub_type;
static PyTypeObject *Mult_type;
+static PyTypeObject *MatMult_type;
static PyTypeObject *Div_type;
static PyTypeObject *Mod_type;
static PyTypeObject *Pow_type;
@@ -970,6 +971,10 @@
if (!Mult_type) return 0;
Mult_singleton = PyType_GenericNew(Mult_type, NULL, NULL);
if (!Mult_singleton) return 0;
+ MatMult_type = make_type("MatMult", operator_type, NULL, 0);
+ if (!MatMult_type) return 0;
+ MatMult_singleton = PyType_GenericNew(MatMult_type, NULL, NULL);
+ if (!MatMult_singleton) return 0;
Div_type = make_type("Div", operator_type, NULL, 0);
if (!Div_type) return 0;
Div_singleton = PyType_GenericNew(Div_type, NULL, NULL);
@@ -3232,6 +3237,9 @@
case Mult:
Py_INCREF(Mult_singleton);
return Mult_singleton;
+ case MatMult:
+ Py_INCREF(MatMult_singleton);
+ return MatMult_singleton;
case Div:
Py_INCREF(Div_singleton);
return Div_singleton;
@@ -6175,6 +6183,14 @@
*out = Mult;
return 0;
}
+ isinstance = PyObject_IsInstance(obj, (PyObject *)MatMult_type);
+ if (isinstance == -1) {
+ return 1;
+ }
+ if (isinstance) {
+ *out = MatMult;
+ return 0;
+ }
isinstance = PyObject_IsInstance(obj, (PyObject *)Div_type);
if (isinstance == -1) {
return 1;
@@ -6956,6 +6972,8 @@
if (PyDict_SetItemString(d, "Add", (PyObject*)Add_type) < 0) return NULL;
if (PyDict_SetItemString(d, "Sub", (PyObject*)Sub_type) < 0) return NULL;
if (PyDict_SetItemString(d, "Mult", (PyObject*)Mult_type) < 0) return NULL;
+ if (PyDict_SetItemString(d, "MatMult", (PyObject*)MatMult_type) < 0) return
+ NULL;
if (PyDict_SetItemString(d, "Div", (PyObject*)Div_type) < 0) return NULL;
if (PyDict_SetItemString(d, "Mod", (PyObject*)Mod_type) < 0) return NULL;
if (PyDict_SetItemString(d, "Pow", (PyObject*)Pow_type) < 0) return NULL;
diff --git a/Python/ast.c b/Python/ast.c
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -825,6 +825,8 @@
return Sub;
case STAR:
return Mult;
+ case AT:
+ return MatMult;
case SLASH:
return Div;
case DOUBLESLASH:
@@ -1030,6 +1032,8 @@
return Pow;
else
return Mult;
+ case '@':
+ return MatMult;
default:
PyErr_Format(PyExc_SystemError, "invalid augassign: %s", STR(n));
return (operator_ty)0;
@@ -2266,7 +2270,7 @@
and_expr: shift_expr ('&' shift_expr)*
shift_expr: arith_expr (('<<'|'>>') arith_expr)*
arith_expr: term (('+'|'-') term)*
- term: factor (('*'|'/'|'%'|'//') factor)*
+ term: factor (('*'|'@'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power
power: atom trailer* ('**' factor)*
*/
@@ -2577,7 +2581,7 @@
/* expr_stmt: testlist_star_expr (augassign (yield_expr|testlist)
| ('=' (yield_expr|testlist))*)
testlist_star_expr: (test|star_expr) (',' test|star_expr)* [',']
- augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^='
+ augassign: '+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^='
| '<<=' | '>>=' | '**=' | '//='
test: ... here starts the operator precendence dance
*/
diff --git a/Python/ceval.c b/Python/ceval.c
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1495,6 +1495,18 @@
DISPATCH();
}
+ TARGET(BINARY_MATRIX_MULTIPLY) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_MatrixMultiply(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
TARGET(BINARY_TRUE_DIVIDE) {
PyObject *divisor = POP();
PyObject *dividend = TOP();
@@ -1685,6 +1697,18 @@
DISPATCH();
}
+ TARGET(INPLACE_MATRIX_MULTIPLY) {
+ PyObject *right = POP();
+ PyObject *left = TOP();
+ PyObject *res = PyNumber_InPlaceMatrixMultiply(left, right);
+ Py_DECREF(left);
+ Py_DECREF(right);
+ SET_TOP(res);
+ if (res == NULL)
+ goto error;
+ DISPATCH();
+ }
+
TARGET(INPLACE_TRUE_DIVIDE) {
PyObject *divisor = POP();
PyObject *dividend = TOP();
diff --git a/Python/compile.c b/Python/compile.c
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -881,6 +881,7 @@
case BINARY_POWER:
case BINARY_MULTIPLY:
+ case BINARY_MATRIX_MULTIPLY:
case BINARY_MODULO:
case BINARY_ADD:
case BINARY_SUBTRACT:
@@ -895,6 +896,7 @@
case INPLACE_ADD:
case INPLACE_SUBTRACT:
case INPLACE_MULTIPLY:
+ case INPLACE_MATRIX_MULTIPLY:
case INPLACE_MODULO:
return -1;
case STORE_SUBSCR:
@@ -2625,6 +2627,8 @@
return BINARY_SUBTRACT;
case Mult:
return BINARY_MULTIPLY;
+ case MatMult:
+ return BINARY_MATRIX_MULTIPLY;
case Div:
return BINARY_TRUE_DIVIDE;
case Mod:
@@ -2689,6 +2693,8 @@
return INPLACE_SUBTRACT;
case Mult:
return INPLACE_MULTIPLY;
+ case MatMult:
+ return INPLACE_MATRIX_MULTIPLY;
case Div:
return INPLACE_TRUE_DIVIDE;
case Mod:
diff --git a/Python/graminit.c b/Python/graminit.c
--- a/Python/graminit.c
+++ b/Python/graminit.c
@@ -476,7 +476,7 @@
{2, arcs_16_1},
{3, arcs_16_2},
};
-static arc arcs_17_0[12] = {
+static arc arcs_17_0[13] = {
{49, 1},
{50, 1},
{51, 1},
@@ -489,19 +489,20 @@
{58, 1},
{59, 1},
{60, 1},
+ {61, 1},
};
static arc arcs_17_1[1] = {
{0, 1},
};
static state states_17[2] = {
- {12, arcs_17_0},
+ {13, arcs_17_0},
{1, arcs_17_1},
};
static arc arcs_18_0[1] = {
- {61, 1},
+ {62, 1},
};
static arc arcs_18_1[1] = {
- {62, 2},
+ {63, 2},
};
static arc arcs_18_2[1] = {
{0, 2},
@@ -512,7 +513,7 @@
{1, arcs_18_2},
};
static arc arcs_19_0[1] = {
- {63, 1},
+ {64, 1},
};
static arc arcs_19_1[1] = {
{0, 1},
@@ -522,11 +523,11 @@
{1, arcs_19_1},
};
static arc arcs_20_0[5] = {
- {64, 1},
{65, 1},
{66, 1},
{67, 1},
{68, 1},
+ {69, 1},
};
static arc arcs_20_1[1] = {
{0, 1},
@@ -536,7 +537,7 @@
{1, arcs_20_1},
};
static arc arcs_21_0[1] = {
- {69, 1},
+ {70, 1},
};
static arc arcs_21_1[1] = {
{0, 1},
@@ -546,7 +547,7 @@
{1, arcs_21_1},
};
static arc arcs_22_0[1] = {
- {70, 1},
+ {71, 1},
};
static arc arcs_22_1[1] = {
{0, 1},
@@ -556,7 +557,7 @@
{1, arcs_22_1},
};
static arc arcs_23_0[1] = {
- {71, 1},
+ {72, 1},
};
static arc arcs_23_1[2] = {
{9, 2},
@@ -581,14 +582,14 @@
{1, arcs_24_1},
};
static arc arcs_25_0[1] = {
- {72, 1},
+ {73, 1},
};
static arc arcs_25_1[2] = {
{24, 2},
{0, 1},
};
static arc arcs_25_2[2] = {
- {73, 3},
+ {74, 3},
{0, 2},
};
static arc arcs_25_3[1] = {
@@ -605,8 +606,8 @@
{1, arcs_25_4},
};
static arc arcs_26_0[2] = {
- {74, 1},
{75, 1},
+ {76, 1},
};
static arc arcs_26_1[1] = {
{0, 1},
@@ -616,10 +617,10 @@
{1, arcs_26_1},
};
static arc arcs_27_0[1] = {
- {76, 1},
+ {77, 1},
};
static arc arcs_27_1[1] = {
- {77, 2},
+ {78, 2},
};
static arc arcs_27_2[1] = {
{0, 2},
@@ -630,32 +631,32 @@
{1, arcs_27_2},
};
static arc arcs_28_0[1] = {
- {73, 1},
+ {74, 1},
};
static arc arcs_28_1[3] = {
- {78, 2},
{79, 2},
+ {80, 2},
{12, 3},
};
static arc arcs_28_2[4] = {
- {78, 2},
{79, 2},
+ {80, 2},
{12, 3},
- {76, 4},
+ {77, 4},
};
static arc arcs_28_3[1] = {
- {76, 4},
+ {77, 4},
};
static arc arcs_28_4[3] = {
{31, 5},
{13, 6},
- {80, 5},
+ {81, 5},
};
static arc arcs_28_5[1] = {
{0, 5},
};
static arc arcs_28_6[1] = {
- {80, 7},
+ {81, 7},
};
static arc arcs_28_7[1] = {
{15, 5},
@@ -674,7 +675,7 @@
{21, 1},
};
static arc arcs_29_1[2] = {
- {82, 2},
+ {83, 2},
{0, 1},
};
static arc arcs_29_2[1] = {
@@ -693,7 +694,7 @@
{12, 1},
};
static arc arcs_30_1[2] = {
- {82, 2},
+ {83, 2},
{0, 1},
};
static arc arcs_30_2[1] = {
@@ -709,14 +710,14 @@
{1, arcs_30_3},
};
static arc arcs_31_0[1] = {
- {81, 1},
+ {82, 1},
};
static arc arcs_31_1[2] = {
{30, 2},
{0, 1},
};
static arc arcs_31_2[2] = {
- {81, 1},
+ {82, 1},
{0, 2},
};
static state states_31[3] = {
@@ -725,7 +726,7 @@
{2, arcs_31_2},
};
static arc arcs_32_0[1] = {
- {83, 1},
+ {84, 1},
};
static arc arcs_32_1[2] = {
{30, 0},
@@ -739,7 +740,7 @@
{21, 1},
};
static arc arcs_33_1[2] = {
- {78, 0},
+ {79, 0},
{0, 1},
};
static state states_33[2] = {
@@ -747,7 +748,7 @@
{2, arcs_33_1},
};
static arc arcs_34_0[1] = {
- {84, 1},
+ {85, 1},
};
static arc arcs_34_1[1] = {
{21, 2},
@@ -762,7 +763,7 @@
{2, arcs_34_2},
};
static arc arcs_35_0[1] = {
- {85, 1},
+ {86, 1},
};
static arc arcs_35_1[1] = {
{21, 2},
@@ -777,7 +778,7 @@
{2, arcs_35_2},
};
static arc arcs_36_0[1] = {
- {86, 1},
+ {87, 1},
};
static arc arcs_36_1[1] = {
{24, 2},
@@ -800,11 +801,11 @@
{1, arcs_36_4},
};
static arc arcs_37_0[8] = {
- {87, 1},
{88, 1},
{89, 1},
{90, 1},
{91, 1},
+ {92, 1},
{19, 1},
{18, 1},
{17, 1},
@@ -817,7 +818,7 @@
{1, arcs_37_1},
};
static arc arcs_38_0[1] = {
- {92, 1},
+ {93, 1},
};
static arc arcs_38_1[1] = {
{24, 2},
@@ -829,8 +830,8 @@
{26, 4},
};
static arc arcs_38_4[3] = {
- {93, 1},
- {94, 5},
+ {94, 1},
+ {95, 5},
{0, 4},
};
static arc arcs_38_5[1] = {
@@ -853,7 +854,7 @@
{1, arcs_38_7},
};
static arc arcs_39_0[1] = {
- {95, 1},
+ {96, 1},
};
static arc arcs_39_1[1] = {
{24, 2},
@@ -865,7 +866,7 @@
{26, 4},
};
static arc arcs_39_4[2] = {
- {94, 5},
+ {95, 5},
{0, 4},
};
static arc arcs_39_5[1] = {
@@ -888,13 +889,13 @@
{1, arcs_39_7},
};
static arc arcs_40_0[1] = {
- {96, 1},
+ {97, 1},
};
static arc arcs_40_1[1] = {
- {62, 2},
+ {63, 2},
};
static arc arcs_40_2[1] = {
- {97, 3},
+ {98, 3},
};
static arc arcs_40_3[1] = {
{9, 4},
@@ -906,7 +907,7 @@
{26, 6},
};
static arc arcs_40_6[2] = {
- {94, 7},
+ {95, 7},
{0, 6},
};
static arc arcs_40_7[1] = {
@@ -931,7 +932,7 @@
{1, arcs_40_9},
};
static arc arcs_41_0[1] = {
- {98, 1},
+ {99, 1},
};
static arc arcs_41_1[1] = {
{25, 2},
@@ -940,8 +941,8 @@
{26, 3},
};
static arc arcs_41_3[2] = {
- {99, 4},
- {100, 5},
+ {100, 4},
+ {101, 5},
};
static arc arcs_41_4[1] = {
{25, 6},
@@ -956,9 +957,9 @@
{26, 9},
};
static arc arcs_41_8[4] = {
- {99, 4},
- {94, 10},
- {100, 5},
+ {100, 4},
+ {95, 10},
+ {101, 5},
{0, 8},
};
static arc arcs_41_9[1] = {
@@ -971,7 +972,7 @@
{26, 12},
};
static arc arcs_41_12[2] = {
- {100, 5},
+ {101, 5},
{0, 12},
};
static state states_41[13] = {
@@ -990,10 +991,10 @@
{2, arcs_41_12},
};
static arc arcs_42_0[1] = {
- {101, 1},
+ {102, 1},
};
static arc arcs_42_1[1] = {
- {102, 2},
+ {103, 2},
};
static arc arcs_42_2[2] = {
{30, 1},
@@ -1016,11 +1017,11 @@
{24, 1},
};
static arc arcs_43_1[2] = {
- {82, 2},
+ {83, 2},
{0, 1},
};
static arc arcs_43_2[1] = {
- {103, 3},
+ {104, 3},
};
static arc arcs_43_3[1] = {
{0, 3},
@@ -1032,14 +1033,14 @@
{1, arcs_43_3},
};
static arc arcs_44_0[1] = {
- {104, 1},
+ {105, 1},
};
static arc arcs_44_1[2] = {
{24, 2},
{0, 1},
};
static arc arcs_44_2[2] = {
- {82, 3},
+ {83, 3},
{0, 2},
};
static arc arcs_44_3[1] = {
@@ -1063,14 +1064,14 @@
{0, 1},
};
static arc arcs_45_2[1] = {
- {105, 3},
+ {106, 3},
};
static arc arcs_45_3[1] = {
{6, 4},
};
static arc arcs_45_4[2] = {
{6, 4},
- {106, 1},
+ {107, 1},
};
static state states_45[5] = {
{2, arcs_45_0},
@@ -1080,21 +1081,21 @@
{2, arcs_45_4},
};
static arc arcs_46_0[2] = {
- {107, 1},
- {108, 2},
+ {108, 1},
+ {109, 2},
};
static arc arcs_46_1[2] = {
- {92, 3},
+ {93, 3},
{0, 1},
};
static arc arcs_46_2[1] = {
{0, 2},
};
static arc arcs_46_3[1] = {
- {107, 4},
+ {108, 4},
};
static arc arcs_46_4[1] = {
- {94, 5},
+ {95, 5},
};
static arc arcs_46_5[1] = {
{24, 2},
@@ -1108,8 +1109,8 @@
{1, arcs_46_5},
};
static arc arcs_47_0[2] = {
- {107, 1},
- {110, 1},
+ {108, 1},
+ {111, 1},
};
static arc arcs_47_1[1] = {
{0, 1},
@@ -1119,7 +1120,7 @@
{1, arcs_47_1},
};
static arc arcs_48_0[1] = {
- {111, 1},
+ {112, 1},
};
static arc arcs_48_1[2] = {
{33, 2},
@@ -1142,7 +1143,7 @@
{1, arcs_48_4},
};
static arc arcs_49_0[1] = {
- {111, 1},
+ {112, 1},
};
static arc arcs_49_1[2] = {
{33, 2},
@@ -1152,7 +1153,7 @@
{25, 3},
};
static arc arcs_49_3[1] = {
- {109, 4},
+ {110, 4},
};
static arc arcs_49_4[1] = {
{0, 4},
@@ -1165,10 +1166,10 @@
{1, arcs_49_4},
};
static arc arcs_50_0[1] = {
- {112, 1},
+ {113, 1},
};
static arc arcs_50_1[2] = {
- {113, 0},
+ {114, 0},
{0, 1},
};
static state states_50[2] = {
@@ -1176,10 +1177,10 @@
{2, arcs_50_1},
};
static arc arcs_51_0[1] = {
- {114, 1},
+ {115, 1},
};
static arc arcs_51_1[2] = {
- {115, 0},
+ {116, 0},
{0, 1},
};
static state states_51[2] = {
@@ -1187,11 +1188,11 @@
{2, arcs_51_1},
};
static arc arcs_52_0[2] = {
- {116, 1},
- {117, 2},
+ {117, 1},
+ {118, 2},
};
static arc arcs_52_1[1] = {
- {114, 2},
+ {115, 2},
};
static arc arcs_52_2[1] = {
{0, 2},
@@ -1202,10 +1203,10 @@
{1, arcs_52_2},
};
static arc arcs_53_0[1] = {
- {103, 1},
+ {104, 1},
};
static arc arcs_53_1[2] = {
- {118, 0},
+ {119, 0},
{0, 1},
};
static state states_53[2] = {
@@ -1213,25 +1214,25 @@
{2, arcs_53_1},
};
static arc arcs_54_0[10] = {
- {119, 1},
{120, 1},
{121, 1},
{122, 1},
{123, 1},
{124, 1},
{125, 1},
- {97, 1},
- {116, 2},
- {126, 3},
+ {126, 1},
+ {98, 1},
+ {117, 2},
+ {127, 3},
};
static arc arcs_54_1[1] = {
{0, 1},
};
static arc arcs_54_2[1] = {
- {97, 1},
+ {98, 1},
};
static arc arcs_54_3[2] = {
- {116, 1},
+ {117, 1},
{0, 3},
};
static state states_54[4] = {
@@ -1244,7 +1245,7 @@
{31, 1},
};
static arc arcs_55_1[1] = {
- {103, 2},
+ {104, 2},
};
static arc arcs_55_2[1] = {
{0, 2},
@@ -1255,10 +1256,10 @@
{1, arcs_55_2},
};
static arc arcs_56_0[1] = {
- {127, 1},
+ {128, 1},
};
static arc arcs_56_1[2] = {
- {128, 0},
+ {129, 0},
{0, 1},
};
static state states_56[2] = {
@@ -1266,10 +1267,10 @@
{2, arcs_56_1},
};
static arc arcs_57_0[1] = {
- {129, 1},
+ {130, 1},
};
static arc arcs_57_1[2] = {
- {130, 0},
+ {131, 0},
{0, 1},
};
static state states_57[2] = {
@@ -1277,10 +1278,10 @@
{2, arcs_57_1},
};
static arc arcs_58_0[1] = {
- {131, 1},
+ {132, 1},
};
static arc arcs_58_1[2] = {
- {132, 0},
+ {133, 0},
{0, 1},
};
static state states_58[2] = {
@@ -1288,11 +1289,11 @@
{2, arcs_58_1},
};
static arc arcs_59_0[1] = {
- {133, 1},
+ {134, 1},
};
static arc arcs_59_1[3] = {
- {134, 0},
{135, 0},
+ {136, 0},
{0, 1},
};
static state states_59[2] = {
@@ -1300,11 +1301,11 @@
{3, arcs_59_1},
};
static arc arcs_60_0[1] = {
- {136, 1},
+ {137, 1},
};
static arc arcs_60_1[3] = {
- {137, 0},
{138, 0},
+ {139, 0},
{0, 1},
};
static state states_60[2] = {
@@ -1312,27 +1313,28 @@
{3, arcs_60_1},
};
static arc arcs_61_0[1] = {
- {139, 1},
+ {140, 1},
};
-static arc arcs_61_1[5] = {
+static arc arcs_61_1[6] = {
{31, 0},
- {140, 0},
+ {11, 0},
{141, 0},
{142, 0},
+ {143, 0},
{0, 1},
};
static state states_61[2] = {
{1, arcs_61_0},
- {5, arcs_61_1},
+ {6, arcs_61_1},
};
static arc arcs_62_0[4] = {
- {137, 1},
{138, 1},
- {143, 1},
- {144, 2},
+ {139, 1},
+ {144, 1},
+ {145, 2},
};
static arc arcs_62_1[1] = {
- {139, 2},
+ {140, 2},
};
static arc arcs_62_2[1] = {
{0, 2},
@@ -1343,15 +1345,15 @@
{1, arcs_62_2},
};
static arc arcs_63_0[1] = {
- {145, 1},
+ {146, 1},
};
static arc arcs_63_1[3] = {
- {146, 1},
+ {147, 1},
{32, 2},
{0, 1},
};
static arc arcs_63_2[1] = {
- {139, 3},
+ {140, 3},
};
static arc arcs_63_3[1] = {
{0, 3},
@@ -1364,44 +1366,44 @@
};
static arc arcs_64_0[10] = {
{13, 1},
- {148, 2},
- {150, 3},
+ {149, 2},
+ {151, 3},
{21, 4},
- {153, 4},
- {154, 5},
- {79, 4},
- {155, 4},
+ {154, 4},
+ {155, 5},
+ {80, 4},
{156, 4},
{157, 4},
+ {158, 4},
};
static arc arcs_64_1[3] = {
{47, 6},
- {147, 6},
+ {148, 6},
{15, 4},
};
static arc arcs_64_2[2] = {
- {147, 7},
- {149, 4},
+ {148, 7},
+ {150, 4},
};
static arc arcs_64_3[2] = {
- {151, 8},
- {152, 4},
+ {152, 8},
+ {153, 4},
};
static arc arcs_64_4[1] = {
{0, 4},
};
static arc arcs_64_5[2] = {
- {154, 5},
+ {155, 5},
{0, 5},
};
static arc arcs_64_6[1] = {
{15, 4},
};
static arc arcs_64_7[1] = {
- {149, 4},
+ {150, 4},
};
static arc arcs_64_8[1] = {
- {152, 4},
+ {153, 4},
};
static state states_64[9] = {
{10, arcs_64_0},
@@ -1419,7 +1421,7 @@
{48, 1},
};
static arc arcs_65_1[3] = {
- {158, 2},
+ {159, 2},
{30, 3},
{0, 1},
};
@@ -1444,15 +1446,15 @@
};
static arc arcs_66_0[3] = {
{13, 1},
- {148, 2},
- {78, 3},
+ {149, 2},
+ {79, 3},
};
static arc arcs_66_1[2] = {
{14, 4},
{15, 5},
};
static arc arcs_66_2[1] = {
- {159, 6},
+ {160, 6},
};
static arc arcs_66_3[1] = {
{21, 5},
@@ -1464,7 +1466,7 @@
{0, 5},
};
static arc arcs_66_6[1] = {
- {149, 5},
+ {150, 5},
};
static state states_66[7] = {
{3, arcs_66_0},
@@ -1476,14 +1478,14 @@
{1, arcs_66_6},
};
static arc arcs_67_0[1] = {
- {160, 1},
+ {161, 1},
};
static arc arcs_67_1[2] = {
{30, 2},
{0, 1},
};
static arc arcs_67_2[2] = {
- {160, 1},
+ {161, 1},
{0, 2},
};
static state states_67[3] = {
@@ -1501,11 +1503,11 @@
};
static arc arcs_68_2[3] = {
{24, 3},
- {161, 4},
+ {162, 4},
{0, 2},
};
static arc arcs_68_3[2] = {
- {161, 4},
+ {162, 4},
{0, 3},
};
static arc arcs_68_4[1] = {
@@ -1534,7 +1536,7 @@
{1, arcs_69_2},
};
static arc arcs_70_0[2] = {
- {103, 1},
+ {104, 1},
{48, 1},
};
static arc arcs_70_1[2] = {
@@ -1542,7 +1544,7 @@
{0, 1},
};
static arc arcs_70_2[3] = {
- {103, 1},
+ {104, 1},
{48, 1},
{0, 2},
};
@@ -1572,7 +1574,7 @@
};
static arc arcs_72_1[4] = {
{25, 2},
- {158, 3},
+ {159, 3},
{30, 4},
{0, 1},
};
@@ -1587,7 +1589,7 @@
{0, 4},
};
static arc arcs_72_5[3] = {
- {158, 3},
+ {159, 3},
{30, 7},
{0, 5},
};
@@ -1623,7 +1625,7 @@
{2, arcs_72_10},
};
static arc arcs_73_0[1] = {
- {162, 1},
+ {163, 1},
};
static arc arcs_73_1[1] = {
{21, 2},
@@ -1659,7 +1661,7 @@
{1, arcs_73_7},
};
static arc arcs_74_0[3] = {
- {163, 1},
+ {164, 1},
{31, 2},
{32, 3},
};
@@ -1674,7 +1676,7 @@
{24, 6},
};
static arc arcs_74_4[4] = {
- {163, 1},
+ {164, 1},
{31, 2},
{32, 3},
{0, 4},
@@ -1687,7 +1689,7 @@
{0, 6},
};
static arc arcs_74_7[2] = {
- {163, 5},
+ {164, 5},
{32, 3},
};
static state states_74[8] = {
@@ -1704,7 +1706,7 @@
{24, 1},
};
static arc arcs_75_1[3] = {
- {158, 2},
+ {159, 2},
{29, 3},
{0, 1},
};
@@ -1721,8 +1723,8 @@
{1, arcs_75_3},
};
static arc arcs_76_0[2] = {
- {158, 1},
- {165, 1},
+ {159, 1},
+ {166, 1},
};
static arc arcs_76_1[1] = {
{0, 1},
@@ -1732,19 +1734,19 @@
{1, arcs_76_1},
};
static arc arcs_77_0[1] = {
- {96, 1},
+ {97, 1},
};
static arc arcs_77_1[1] = {
- {62, 2},
+ {63, 2},
};
static arc arcs_77_2[1] = {
- {97, 3},
+ {98, 3},
};
static arc arcs_77_3[1] = {
- {107, 4},
+ {108, 4},
};
static arc arcs_77_4[2] = {
- {164, 5},
+ {165, 5},
{0, 4},
};
static arc arcs_77_5[1] = {
@@ -1759,13 +1761,13 @@
{1, arcs_77_5},
};
static arc arcs_78_0[1] = {
- {92, 1},
+ {93, 1},
};
static arc arcs_78_1[1] = {
- {109, 2},
+ {110, 2},
};
static arc arcs_78_2[2] = {
- {164, 3},
+ {165, 3},
{0, 2},
};
static arc arcs_78_3[1] = {
@@ -1788,10 +1790,10 @@
{1, arcs_79_1},
};
static arc arcs_80_0[1] = {
- {167, 1},
+ {168, 1},
};
static arc arcs_80_1[2] = {
- {168, 2},
+ {169, 2},
{0, 1},
};
static arc arcs_80_2[1] = {
@@ -1803,7 +1805,7 @@
{1, arcs_80_2},
};
static arc arcs_81_0[2] = {
- {73, 1},
+ {74, 1},
{9, 2},
};
static arc arcs_81_1[1] = {
@@ -1819,11 +1821,11 @@
};
static dfa dfas[82] = {
{256, "single_input", 0, 3, states_0,
- "004円050円060円200円000円000円000円240円340円223円160円220円045円200円020円000円000円206円120円076円204円000円"},
+ "004円050円060円200円000円000円000円100円301円047円341円040円113円000円041円000円000円014円241円174円010円001円"},
{257, "file_input", 0, 2, states_1,
- "204円050円060円200円000円000円000円240円340円223円160円220円045円200円020円000円000円206円120円076円204円000円"},
+ "204円050円060円200円000円000円000円100円301円047円341円040円113円000円041円000円000円014円241円174円010円001円"},
{258, "eval_input", 0, 3, states_2,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{259, "decorator", 0, 7, states_3,
"000円010円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
{260, "decorators", 0, 2, states_4,
@@ -1843,39 +1845,39 @@
{267, "vfpdef", 0, 2, states_11,
"000円000円040円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
{268, "stmt", 0, 2, states_12,
- "000円050円060円200円000円000円000円240円340円223円160円220円045円200円020円000円000円206円120円076円204円000円"},
+ "000円050円060円200円000円000円000円100円301円047円341円040円113円000円041円000円000円014円241円174円010円001円"},
{269, "simple_stmt", 0, 4, states_13,
- "000円040円040円200円000円000円000円240円340円223円160円000円000円200円020円000円000円206円120円076円200円000円"},
+ "000円040円040円200円000円000円000円100円301円047円341円000円000円000円041円000円000円014円241円174円000円001円"},
{270, "small_stmt", 0, 2, states_14,
- "000円040円040円200円000円000円000円240円340円223円160円000円000円200円020円000円000円206円120円076円200円000円"},
+ "000円040円040円200円000円000円000円100円301円047円341円000円000円000円041円000円000円014円241円174円000円001円"},
{271, "expr_stmt", 0, 6, states_15,
- "000円040円040円200円000円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円200円000円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{272, "testlist_star_expr", 0, 3, states_16,
- "000円040円040円200円000円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円200円000円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{273, "augassign", 0, 2, states_17,
- "000円000円000円000円000円000円376円037円000円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円376円077円000円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
{274, "del_stmt", 0, 3, states_18,
- "000円000円000円000円000円000円000円040円000円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円100円000円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
{275, "pass_stmt", 0, 2, states_19,
- "000円000円000円000円000円000円000円200円000円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円001円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
{276, "flow_stmt", 0, 2, states_20,
- "000円000円000円000円000円000円000円000円340円001円000円000円000円000円000円000円000円000円000円000円200円000円"},
+ "000円000円000円000円000円000円000円000円300円003円000円000円000円000円000円000円000円000円000円000円000円001円"},
{277, "break_stmt", 0, 2, states_21,
- "000円000円000円000円000円000円000円000円040円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円100円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
{278, "continue_stmt", 0, 2, states_22,
- "000円000円000円000円000円000円000円000円100円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円200円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
{279, "return_stmt", 0, 3, states_23,
- "000円000円000円000円000円000円000円000円200円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円001円000円000円000円000円000円000円000円000円000円000円000円000円"},
{280, "yield_stmt", 0, 2, states_24,
- "000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円200円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円001円"},
{281, "raise_stmt", 0, 5, states_25,
- "000円000円000円000円000円000円000円000円000円001円000円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円002円000円000円000円000円000円000円000円000円000円000円000円000円"},
{282, "import_stmt", 0, 2, states_26,
- "000円000円000円000円000円000円000円000円000円022円000円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円044円000円000円000円000円000円000円000円000円000円000円000円000円"},
{283, "import_name", 0, 3, states_27,
- "000円000円000円000円000円000円000円000円000円020円000円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円040円000円000円000円000円000円000円000円000円000円000円000円000円"},
{284, "import_from", 0, 8, states_28,
- "000円000円000円000円000円000円000円000円000円002円000円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円004円000円000円000円000円000円000円000円000円000円000円000円000円"},
{285, "import_as_name", 0, 4, states_29,
"000円000円040円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
{286, "dotted_as_name", 0, 4, states_30,
@@ -1887,103 +1889,103 @@
{289, "dotted_name", 0, 2, states_33,
"000円000円040円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
{290, "global_stmt", 0, 3, states_34,
- "000円000円000円000円000円000円000円000円000円000円020円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円040円000円000円000円000円000円000円000円000円000円000円000円"},
{291, "nonlocal_stmt", 0, 3, states_35,
- "000円000円000円000円000円000円000円000円000円000円040円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円100円000円000円000円000円000円000円000円000円000円000円000円"},
{292, "assert_stmt", 0, 5, states_36,
- "000円000円000円000円000円000円000円000円000円000円100円000円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円200円000円000円000円000円000円000円000円000円000円000円000円"},
{293, "compound_stmt", 0, 2, states_37,
- "000円010円020円000円000円000円000円000円000円000円000円220円045円000円000円000円000円000円000円000円004円000円"},
+ "000円010円020円000円000円000円000円000円000円000円000円040円113円000円000円000円000円000円000円000円010円000円"},
{294, "if_stmt", 0, 8, states_38,
- "000円000円000円000円000円000円000円000円000円000円000円020円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円040円000円000円000円000円000円000円000円000円000円000円"},
{295, "while_stmt", 0, 8, states_39,
- "000円000円000円000円000円000円000円000円000円000円000円200円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円000円001円000円000円000円000円000円000円000円000円000円"},
{296, "for_stmt", 0, 10, states_40,
- "000円000円000円000円000円000円000円000円000円000円000円000円001円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円000円002円000円000円000円000円000円000円000円000円000円"},
{297, "try_stmt", 0, 13, states_41,
- "000円000円000円000円000円000円000円000円000円000円000円000円004円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円000円010円000円000円000円000円000円000円000円000円000円"},
{298, "with_stmt", 0, 5, states_42,
- "000円000円000円000円000円000円000円000円000円000円000円000円040円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円000円100円000円000円000円000円000円000円000円000円000円"},
{299, "with_item", 0, 4, states_43,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{300, "except_clause", 0, 5, states_44,
- "000円000円000円000円000円000円000円000円000円000円000円000円000円001円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円000円000円002円000円000円000円000円000円000円000円000円"},
{301, "suite", 0, 5, states_45,
- "004円040円040円200円000円000円000円240円340円223円160円000円000円200円020円000円000円206円120円076円200円000円"},
+ "004円040円040円200円000円000円000円100円301円047円341円000円000円000円041円000円000円014円241円174円000円001円"},
{302, "test", 0, 6, states_46,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{303, "test_nocond", 0, 2, states_47,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{304, "lambdef", 0, 5, states_48,
- "000円000円000円000円000円000円000円000円000円000円000円000円000円200円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円000円000円000円001円000円000円000円000円000円000円000円"},
{305, "lambdef_nocond", 0, 5, states_49,
- "000円000円000円000円000円000円000円000円000円000円000円000円000円200円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円000円000円000円001円000円000円000円000円000円000円000円"},
{306, "or_test", 0, 2, states_50,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円020円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円040円000円000円014円241円174円000円000円"},
{307, "and_test", 0, 2, states_51,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円020円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円040円000円000円014円241円174円000円000円"},
{308, "not_test", 0, 3, states_52,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円020円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円040円000円000円014円241円174円000円000円"},
{309, "comparison", 0, 2, states_53,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円000円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円000円000円000円014円241円174円000円000円"},
{310, "comp_op", 0, 4, states_54,
- "000円000円000円000円000円000円000円000円000円000円000円000円002円000円220円177円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円000円004円000円040円377円000円000円000円000円000円000円"},
{311, "star_expr", 0, 3, states_55,
"000円000円000円200円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
{312, "expr", 0, 2, states_56,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円000円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円000円000円000円014円241円174円000円000円"},
{313, "xor_expr", 0, 2, states_57,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円000円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円000円000円000円014円241円174円000円000円"},
{314, "and_expr", 0, 2, states_58,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円000円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円000円000円000円014円241円174円000円000円"},
{315, "shift_expr", 0, 2, states_59,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円000円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円000円000円000円014円241円174円000円000円"},
{316, "arith_expr", 0, 2, states_60,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円000円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円000円000円000円014円241円174円000円000円"},
{317, "term", 0, 2, states_61,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円000円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円000円000円000円014円241円174円000円000円"},
{318, "factor", 0, 3, states_62,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円000円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円000円000円000円014円241円174円000円000円"},
{319, "power", 0, 4, states_63,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円000円000円000円000円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円000円000円000円000円240円174円000円000円"},
{320, "atom", 0, 9, states_64,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円000円000円000円000円000円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円000円000円000円000円240円174円000円000円"},
{321, "testlist_comp", 0, 5, states_65,
- "000円040円040円200円000円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円200円000円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{322, "trailer", 0, 7, states_66,
- "000円040円000円000円000円000円000円000円000円100円000円000円000円000円000円000円000円000円020円000円000円000円"},
+ "000円040円000円000円000円000円000円000円000円200円000円000円000円000円000円000円000円000円040円000円000円000円"},
{323, "subscriptlist", 0, 3, states_67,
- "000円040円040円002円000円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円002円000円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{324, "subscript", 0, 5, states_68,
- "000円040円040円002円000円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円002円000円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{325, "sliceop", 0, 3, states_69,
"000円000円000円002円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
{326, "exprlist", 0, 3, states_70,
- "000円040円040円200円000円000円000円000円000円200円000円000円000円000円000円000円000円206円120円076円000円000円"},
+ "000円040円040円200円000円000円000円000円000円000円001円000円000円000円000円000円000円014円241円174円000円000円"},
{327, "testlist", 0, 3, states_71,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{328, "dictorsetmaker", 0, 11, states_72,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{329, "classdef", 0, 8, states_73,
- "000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円004円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円010円000円"},
{330, "arglist", 0, 8, states_74,
- "000円040円040円200円001円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円200円001円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{331, "argument", 0, 4, states_75,
- "000円040円040円000円000円000円000円000円000円200円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円000円001円000円000円000円041円000円000円014円241円174円000円000円"},
{332, "comp_iter", 0, 2, states_76,
- "000円000円000円000円000円000円000円000円000円000円000円020円001円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円040円002円000円000円000円000円000円000円000円000円000円"},
{333, "comp_for", 0, 6, states_77,
- "000円000円000円000円000円000円000円000円000円000円000円000円001円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円000円002円000円000円000円000円000円000円000円000円000円"},
{334, "comp_if", 0, 4, states_78,
- "000円000円000円000円000円000円000円000円000円000円000円020円000円000円000円000円000円000円000円000円000円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円040円000円000円000円000円000円000円000円000円000円000円"},
{335, "encoding_decl", 0, 2, states_79,
"000円000円040円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円"},
{336, "yield_expr", 0, 3, states_80,
- "000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円200円000円"},
+ "000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円000円001円"},
{337, "yield_arg", 0, 3, states_81,
- "000円040円040円000円000円000円000円000円000円202円000円000円000円200円020円000円000円206円120円076円000円000円"},
+ "000円040円040円000円000円000円000円000円000円004円001円000円000円000円041円000円000円014円241円174円000円000円"},
};
-static label labels[169] = {
+static label labels[170] = {
{0, "EMPTY"},
{256, 0},
{4, 0},
@@ -2007,7 +2009,7 @@
{1, "def"},
{1, 0},
{263, 0},
- {50, 0},
+ {51, 0},
{302, 0},
{11, 0},
{301, 0},
@@ -2036,6 +2038,7 @@
{36, 0},
{37, 0},
{38, 0},
+ {50, 0},
{39, 0},
{40, 0},
{41, 0},
@@ -2063,7 +2066,7 @@
{1, "import"},
{288, 0},
{23, 0},
- {51, 0},
+ {52, 0},
{287, 0},
{285, 0},
{1, "as"},
@@ -2157,6 +2160,6 @@
grammar _PyParser_Grammar = {
82,
dfas,
- {169, labels},
+ {170, labels},
256
};
diff --git a/Python/importlib.h b/Python/importlib.h
--- a/Python/importlib.h
+++ b/Python/importlib.h
[stripped]
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -15,8 +15,8 @@
&&_unknown_opcode,
&&_unknown_opcode,
&&TARGET_UNARY_INVERT,
- &&_unknown_opcode,
- &&_unknown_opcode,
+ &&TARGET_BINARY_MATRIX_MULTIPLY,
+ &&TARGET_INPLACE_MATRIX_MULTIPLY,
&&_unknown_opcode,
&&TARGET_BINARY_POWER,
&&TARGET_BINARY_MULTIPLY,
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list