]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-46721: Optimize set.issuperset() for non-set arguments (GH-31280)
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 6 Apr 2022 16:57:13 +0000 (19:57 +0300)
committerGitHub <noreply@github.com>
Wed, 6 Apr 2022 16:57:13 +0000 (19:57 +0300)
Misc/NEWS.d/next/Core and Builtins/2022-02-11-17-16-30.bpo-46721.JkHaLF.rst [new file with mode: 0644]
Objects/setobject.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-11-17-16-30.bpo-46721.JkHaLF.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-11-17-16-30.bpo-46721.JkHaLF.rst
new file mode 100644 (file)
index 0000000..5644f10
--- /dev/null
@@ -0,0 +1 @@
+Optimize :meth:`set.issuperset` for non-set argument.
index 18dc49be93d6dad10f1df51d9a3fdcc8dcdb70fc..ef2190de914b3d7c99d5a28596550860c57668de 100644 (file)
@@ -1382,14 +1382,7 @@ set_isdisjoint(PySetObject *so, PyObject *other)
         return NULL;
 
     while ((key = PyIter_Next(it)) != NULL) {
-        Py_hash_t hash = PyObject_Hash(key);
-
-        if (hash == -1) {
-            Py_DECREF(key);
-            Py_DECREF(it);
-            return NULL;
-        }
-        rv = set_contains_entry(so, key, hash);
+        rv = set_contains_key(so, key);
         Py_DECREF(key);
         if (rv < 0) {
             Py_DECREF(it);
@@ -1773,17 +1766,31 @@ PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
 static PyObject *
 set_issuperset(PySetObject *so, PyObject *other)
 {
-    PyObject *tmp, *result;
+    if (PyAnySet_Check(other)) {
+        return set_issubset((PySetObject *)other, (PyObject *)so);
+    }
 
-    if (!PyAnySet_Check(other)) {
-        tmp = make_new_set(&PySet_Type, other);
-        if (tmp == NULL)
+    PyObject *key, *it = PyObject_GetIter(other);
+    if (it == NULL) {
+        return NULL;
+    }
+    while ((key = PyIter_Next(it)) != NULL) {
+        int rv = set_contains_key(so, key);
+        Py_DECREF(key);
+        if (rv < 0) {
+            Py_DECREF(it);
             return NULL;
-        result = set_issuperset(so, tmp);
-        Py_DECREF(tmp);
-        return result;
+        }
+        if (!rv) {
+            Py_DECREF(it);
+            Py_RETURN_FALSE;
+        }
     }
-    return set_issubset((PySetObject *)other, (PyObject *)so);
+    Py_DECREF(it);
+    if (PyErr_Occurred()) {
+        return NULL;
+    }
+    Py_RETURN_TRUE;
 }
 
 PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");