@@ -88,6 +88,50 @@ pg_scancodewrapper_subscript(pgScancodeWrapper *self, PyObject *item)
8888 return ret ;
8989}
9090
91+ static PyObject *
92+ pg_iter_raise (PyObject * self )
93+ {
94+ PyErr_SetString (PyExc_TypeError ,
95+ "Iterating over key states is not supported" );
96+ return NULL ;
97+ }
98+
99+ /**
100+ * There is an issue in PyPy that causes __iter__ to be called
101+ * on creation of a ScancodeWrapper. This stops this from
102+ * happening.
103+ */
104+ #ifdef PYPY_VERSION
105+ static PyObject *
106+ pg_scancodewrapper_new (PyTypeObject * subtype , PyObject * args , PyObject * kwds )
107+ {
108+ PyObject * tuple = NULL ;
109+ Py_ssize_t size = PyTuple_Size (args );
110+ if (size == 1 ) {
111+ tuple = PyTuple_GET_ITEM (args , 0 );
112+ if (PyTuple_Check (tuple )) {
113+ size = PyTuple_Size (tuple );
114+ }
115+ else {
116+ tuple = NULL ;
117+ }
118+ }
119+
120+ pgScancodeWrapper * obj =
121+ (pgScancodeWrapper * )(subtype -> tp_alloc (subtype , size ));
122+
123+ if (obj && tuple ) {
124+ for (Py_ssize_t i = 0 ; i < size ; ++ i ) {
125+ PyObject * item = PyTuple_GET_ITEM ((PyObject * )tuple , i );
126+ PyTuple_SET_ITEM ((PyObject * )obj , i , item );
127+ }
128+ Py_DECREF (tuple );
129+ }
130+
131+ return (PyObject * )obj ;
132+ }
133+ #endif /* PYPY_VERSION */
134+
91135static PyMappingMethods pg_scancodewrapper_mapping = {
92136 .mp_subscript = (binaryfunc )pg_scancodewrapper_subscript ,
93137};
@@ -106,6 +150,11 @@ static PyTypeObject pgScancodeWrapper_Type = {
106150 PyVarObject_HEAD_INIT (NULL , 0 ).tp_name = "pygame.key.ScancodeWrapper" ,
107151 .tp_repr = (reprfunc )pg_scancodewrapper_repr ,
108152 .tp_as_mapping = & pg_scancodewrapper_mapping ,
153+ .tp_iter = (getiterfunc )pg_iter_raise ,
154+ .tp_iternext = (iternextfunc )pg_iter_raise ,
155+ #ifdef PYPY_VERSION
156+ .tp_new = pg_scancodewrapper_new ,
157+ #endif
109158 .tp_flags =
110159 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_TUPLE_SUBCLASS | Py_TPFLAGS_BASETYPE ,
111160};
0 commit comments