Skip to content

Commit 7d7aa7b

Browse files
committed
libdrgn/python: remove Type == operator
The == operator on drgn.Type is only intended for testing. It's expensive and slow and not what people usually want. It's going to get even more awkward to define once types can refer to objects (for template parameters and static members and such). Let's replace == with a new identical() function only available in unit tests. Then, remove the operator from the Python bindings as well as the underlying libdrgn drgn_type_eq() and drgn_qualified_type_eq() functions. Signed-off-by: Omar Sandoval <osandov@osandov.com>
1 parent 523fd26 commit 7d7aa7b

File tree

9 files changed

+525
-1442
lines changed

9 files changed

+525
-1442
lines changed

_drgn.pyi

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,14 +1466,6 @@ class Type:
14661466
14671467
This class cannot be constructed directly. Instead, use one of the
14681468
:ref:`api-type-constructors`.
1469-
1470-
.. note::
1471-
1472-
``Type`` objects can be compared with ``==``. However, this is mostly
1473-
intended for testing and should not be used for type checking, as it
1474-
does a deep comparison that checks that the type definitions are
1475-
exactly the same, which is potentially time-consuming and
1476-
memory-intensive.
14771469
"""
14781470

14791471
prog: Program

libdrgn/drgn.h.in

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -908,35 +908,6 @@ static inline struct drgn_error *drgn_type_has_member(struct drgn_type *type,
908908
ret);
909909
}
910910

911-
/**
912-
* Compare two @ref drgn_type%s for equality.
913-
*
914-
* Two types are equal if all of their fields are equal, recursively.
915-
*
916-
* @param[in] a First type.
917-
* @param[in] b First type.
918-
* @param[out] ret @c true if the types are equal, @c false if they are not.
919-
* @return @c NULL on success, non-@c NULL on error.
920-
*/
921-
struct drgn_error *drgn_type_eq(struct drgn_type *a, struct drgn_type *b,
922-
bool *ret);
923-
924-
/**
925-
* Compare two @ref drgn_qualified_type%s for equality.
926-
*
927-
* Two qualified types are equal if their unqualified types are equal and their
928-
* qualifiers are equal.
929-
*
930-
* @param[in] a First qualified type.
931-
* @param[in] b First qualified type.
932-
* @param[out] ret @c true if the qualified types are equal, @c false if they
933-
* are not.
934-
* @return @c NULL on success, non-@c NULL on error.
935-
*/
936-
struct drgn_error *drgn_qualified_type_eq(struct drgn_qualified_type a,
937-
struct drgn_qualified_type b,
938-
bool *ret);
939-
940911
/**
941912
* Format the name of a type as a string.
942913
*

libdrgn/python/type.c

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -735,29 +735,6 @@ static PyObject *DrgnType_has_member(DrgnType *self, PyObject *args,
735735
Py_RETURN_FALSE;
736736
}
737737

738-
static PyObject *DrgnType_richcompare(DrgnType *self, PyObject *other, int op)
739-
{
740-
if (!PyObject_TypeCheck(other, &DrgnType_type) ||
741-
(op != Py_EQ && op != Py_NE))
742-
Py_RETURN_NOTIMPLEMENTED;
743-
744-
bool clear = set_drgn_in_python();
745-
bool ret;
746-
struct drgn_error *err = drgn_qualified_type_eq(DrgnType_unwrap(self),
747-
DrgnType_unwrap((DrgnType *)other),
748-
&ret);
749-
if (clear)
750-
clear_drgn_in_python();
751-
if (err)
752-
return set_drgn_error(err);
753-
if (op == Py_NE)
754-
ret = !ret;
755-
if (ret)
756-
Py_RETURN_TRUE;
757-
else
758-
Py_RETURN_FALSE;
759-
}
760-
761738
static PyMethodDef DrgnType_methods[] = {
762739
{"type_name", (PyCFunction)DrgnType_type_name, METH_NOARGS,
763740
drgn_Type_type_name_DOC},
@@ -785,7 +762,6 @@ PyTypeObject DrgnType_type = {
785762
.tp_doc = drgn_Type_DOC,
786763
.tp_traverse = (traverseproc)DrgnType_traverse,
787764
.tp_clear = (inquiry)DrgnType_clear,
788-
.tp_richcompare = (richcmpfunc)DrgnType_richcompare,
789765
.tp_methods = DrgnType_methods,
790766
.tp_getset = DrgnType_getset,
791767
};
@@ -1050,41 +1026,6 @@ static PyObject *TypeMember_repr(TypeMember *self)
10501026
}
10511027
}
10521028

1053-
static PyObject *TypeMember_richcompare(TypeMember *self, TypeMember *other,
1054-
int op)
1055-
{
1056-
DrgnType *self_type, *other_type;
1057-
PyObject *self_key, *other_key, *ret;
1058-
1059-
if ((op != Py_EQ && op != Py_NE) ||
1060-
!PyObject_TypeCheck((PyObject *)other, &TypeMember_type))
1061-
Py_RETURN_NOTIMPLEMENTED;
1062-
1063-
self_type = LazyType_get_borrowed((LazyType *)self);
1064-
if (!self_type)
1065-
return NULL;
1066-
other_type = LazyType_get_borrowed((LazyType *)other);
1067-
if (!other_type)
1068-
return NULL;
1069-
1070-
self_key = Py_BuildValue("OOOO", self_type, self->name,
1071-
self->bit_offset, self->bit_field_size);
1072-
if (!self_key)
1073-
return NULL;
1074-
1075-
other_key = Py_BuildValue("OOOO", other_type, other->name,
1076-
other->bit_offset, other->bit_field_size);
1077-
if (!other_key) {
1078-
Py_DECREF(self_key);
1079-
return NULL;
1080-
}
1081-
1082-
ret = PyObject_RichCompare(self_key, other_key, op);
1083-
Py_DECREF(other_key);
1084-
Py_DECREF(self_key);
1085-
return ret;
1086-
}
1087-
10881029
static PyMemberDef TypeMember_members[] = {
10891030
{"name", T_OBJECT, offsetof(TypeMember, name), READONLY,
10901031
drgn_TypeMember_name_DOC},
@@ -1110,7 +1051,6 @@ PyTypeObject TypeMember_type = {
11101051
.tp_repr = (reprfunc)TypeMember_repr,
11111052
.tp_flags = Py_TPFLAGS_DEFAULT,
11121053
.tp_doc = drgn_TypeMember_DOC,
1113-
.tp_richcompare = (richcmpfunc)TypeMember_richcompare,
11141054
.tp_members = TypeMember_members,
11151055
.tp_getset = TypeMember_getset,
11161056
.tp_new = (newfunc)TypeMember_new,
@@ -1171,39 +1111,6 @@ static PyObject *TypeParameter_repr(TypeParameter *self)
11711111
self->name);
11721112
}
11731113

1174-
static PyObject *TypeParameter_richcompare(TypeParameter *self, TypeParameter *other,
1175-
int op)
1176-
{
1177-
DrgnType *self_type, *other_type;
1178-
PyObject *self_key, *other_key, *ret;
1179-
1180-
if ((op != Py_EQ && op != Py_NE) ||
1181-
!PyObject_TypeCheck((PyObject *)other, &TypeParameter_type))
1182-
Py_RETURN_NOTIMPLEMENTED;
1183-
1184-
self_type = LazyType_get_borrowed((LazyType *)self);
1185-
if (!self_type)
1186-
return NULL;
1187-
other_type = LazyType_get_borrowed((LazyType *)other);
1188-
if (!other_type)
1189-
return NULL;
1190-
1191-
self_key = Py_BuildValue("OO", self_type, self->name);
1192-
if (!self_key)
1193-
return NULL;
1194-
1195-
other_key = Py_BuildValue("OO", other_type, other->name);
1196-
if (!other_key) {
1197-
Py_DECREF(self_key);
1198-
return NULL;
1199-
}
1200-
1201-
ret = PyObject_RichCompare(self_key, other_key, op);
1202-
Py_DECREF(other_key);
1203-
Py_DECREF(self_key);
1204-
return ret;
1205-
}
1206-
12071114
static PyMemberDef TypeParameter_members[] = {
12081115
{"name", T_OBJECT, offsetof(TypeParameter, name), READONLY,
12091116
drgn_TypeParameter_name_DOC},
@@ -1223,7 +1130,6 @@ PyTypeObject TypeParameter_type = {
12231130
.tp_repr = (reprfunc)TypeParameter_repr,
12241131
.tp_flags = Py_TPFLAGS_DEFAULT,
12251132
.tp_doc = drgn_TypeParameter_DOC,
1226-
.tp_richcompare = (richcmpfunc)TypeParameter_richcompare,
12271133
.tp_members = TypeParameter_members,
12281134
.tp_getset = TypeParameter_getset,
12291135
.tp_new = (newfunc)TypeParameter_new,

0 commit comments

Comments
 (0)