Skip to content

Commit b6bb0c7

Browse files
committed
Implement == and != comparisons for code objects by value.
This makes test_codeop and test_marshal pass.
1 parent 8f78fe9 commit b6bb0c7

File tree

1 file changed

+55
-39
lines changed

1 file changed

+55
-39
lines changed

Objects/codeobject.c

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -294,44 +294,60 @@ code_repr(PyCodeObject *co)
294294
static PyObject *
295295
code_richcompare(PyObject *self, PyObject *other, int op)
296296
{
297-
/* Temporarily make this unsupported */
298-
_Py_Break();
299-
Py_INCREF(Py_NotImplemented);
300-
return Py_NotImplemented;
301-
302-
#if 0
303-
int cmp;
304-
cmp = PyObject_Compare(co->co_name, cp->co_name);
305-
if (cmp) return cmp;
306-
cmp = co->co_argcount - cp->co_argcount;
307-
if (cmp) goto normalize;
308-
cmp = co->co_nlocals - cp->co_nlocals;
309-
if (cmp) goto normalize;
310-
cmp = co->co_flags - cp->co_flags;
311-
if (cmp) goto normalize;
312-
cmp = co->co_firstlineno - cp->co_firstlineno;
313-
if (cmp) goto normalize;
314-
cmp = PyObject_Compare(co->co_code, cp->co_code);
315-
if (cmp) return cmp;
316-
cmp = PyObject_Compare(co->co_consts, cp->co_consts);
317-
if (cmp) return cmp;
318-
cmp = PyObject_Compare(co->co_names, cp->co_names);
319-
if (cmp) return cmp;
320-
cmp = PyObject_Compare(co->co_varnames, cp->co_varnames);
321-
if (cmp) return cmp;
322-
cmp = PyObject_Compare(co->co_freevars, cp->co_freevars);
323-
if (cmp) return cmp;
324-
cmp = PyObject_Compare(co->co_cellvars, cp->co_cellvars);
325-
return cmp;
326-
327-
normalize:
328-
if (cmp > 0)
329-
return 1;
330-
else if (cmp < 0)
331-
return -1;
297+
PyCodeObject *co, *cp;
298+
int eq;
299+
PyObject *res;
300+
301+
if ((op != Py_EQ && op != Py_NE) ||
302+
!PyCode_Check(self) ||
303+
!PyCode_Check(other)) {
304+
Py_INCREF(Py_NotImplemented);
305+
return Py_NotImplemented;
306+
}
307+
308+
co = (PyCodeObject *)self;
309+
cp = (PyCodeObject *)other;
310+
311+
eq = PyObject_RichCompare(co->co_name, cp->co_name, Py_EQ);
312+
if (eq <= 0) goto unequal;
313+
eq = co->co_argcount == cp->co_argcount;
314+
if (!eq) goto unequal;
315+
eq = co->co_nlocals == cp->co_nlocals;
316+
if (!eq) goto unequal;
317+
eq = co->co_flags == cp->co_flags;
318+
if (!eq) goto unequal;
319+
eq = co->co_firstlineno == cp->co_firstlineno;
320+
if (!eq) goto unequal;
321+
eq = PyObject_RichCompare(co->co_code, cp->co_code, Py_EQ);
322+
if (eq <= 0) goto unequal;
323+
eq = PyObject_RichCompare(co->co_consts, cp->co_consts, Py_EQ);
324+
if (eq <= 0) goto unequal;
325+
eq = PyObject_RichCompare(co->co_names, cp->co_names, Py_EQ);
326+
if (eq <= 0) goto unequal;
327+
eq = PyObject_RichCompare(co->co_varnames, cp->co_varnames, Py_EQ);
328+
if (eq <= 0) goto unequal;
329+
eq = PyObject_RichCompare(co->co_freevars, cp->co_freevars, Py_EQ);
330+
if (eq <= 0) goto unequal;
331+
eq = PyObject_RichCompare(co->co_cellvars, cp->co_cellvars, Py_EQ);
332+
if (eq <= 0) goto unequal;
333+
334+
if (op == Py_EQ)
335+
res = Py_True;
336+
else
337+
res = Py_False;
338+
goto done;
339+
340+
unequal:
341+
if (eq < 0)
342+
return NULL;
343+
if (op == Py_NE)
344+
res = Py_True;
332345
else
333-
return 0;
334-
#endif
346+
res = Py_False;
347+
348+
done:
349+
Py_INCREF(res);
350+
return res;
335351
}
336352

337353
static long
@@ -375,7 +391,7 @@ PyTypeObject PyCode_Type = {
375391
0, /* tp_as_number */
376392
0, /* tp_as_sequence */
377393
0, /* tp_as_mapping */
378-
0, /* tp_hash */
394+
(hashfunc)code_hash, /* tp_hash */
379395
0, /* tp_call */
380396
0, /* tp_str */
381397
PyObject_GenericGetAttr, /* tp_getattro */
@@ -385,7 +401,7 @@ PyTypeObject PyCode_Type = {
385401
code_doc, /* tp_doc */
386402
0, /* tp_traverse */
387403
0, /* tp_clear */
388-
0, /* tp_richcompare */
404+
code_richcompare, /* tp_richcompare */
389405
0, /* tp_weaklistoffset */
390406
0, /* tp_iter */
391407
0, /* tp_iternext */

0 commit comments

Comments
 (0)