will print ``Yes`` if the handle is currently valid (has not been closed or
detached).
-The object also support comparison semantics, so handle objects will compare
-true if they both reference the same underlying Windows handle value.
+The object also support equality comparison semantics, so handle objects will
+compare equal if they both reference the same underlying Windows handle value.
+Closed handle objects (those with a handle value of zero) always compare equal.
Handle objects can be converted to an integer (e.g., using the built-in
:func:`int` function), in which case the underlying Windows handle value is
will automatically close *key* when control leaves the :keyword:`with` block.
+.. versionchanged:: next
+ Handle objects are now compared by their underlying Windows handle value
+ instead of object identity for equality comparisons.
access=KEY_ALL_ACCESS) as okey:
self.assertTrue(okey.handle != 0)
+ def test_hkey_comparison(self):
+ """Test HKEY comparison by handle value rather than object identity."""
+ key1 = OpenKey(HKEY_CURRENT_USER, None)
+ key2 = OpenKey(HKEY_CURRENT_USER, None)
+ key3 = OpenKey(HKEY_LOCAL_MACHINE, None)
+
+ self.addCleanup(CloseKey, key1)
+ self.addCleanup(CloseKey, key2)
+ self.addCleanup(CloseKey, key3)
+
+ self.assertEqual(key1.handle, key2.handle)
+ self.assertTrue(key1 == key2)
+ self.assertFalse(key1 != key2)
+
+ self.assertTrue(key1 != key3)
+ self.assertFalse(key1 == key3)
+
+ # Closed keys should be equal (all have handle=0)
+ CloseKey(key1)
+ CloseKey(key2)
+ CloseKey(key3)
+
+ self.assertEqual(key1.handle, 0)
+ self.assertEqual(key2.handle, 0)
+ self.assertEqual(key3.handle, 0)
+ self.assertEqual(key2, key3)
+
class LocalWinregTests(BaseWinregTests):
--- /dev/null
+Now :class:`!winreg.HKEYType` objects are compared by their underlying Windows
+registry handle value instead of their object identity.
return PyUnicode_FromFormat("<PyHKEY:%p>", pyhkey->hkey);
}
-static int
-PyHKEY_compareFunc(PyObject *ob1, PyObject *ob2)
+static PyObject *
+PyHKEY_richcompare(PyObject *ob1, PyObject *ob2, int op)
{
+ /* Both objects must be PyHKEY objects from the same module */
+ if (Py_TYPE(ob1) != Py_TYPE(ob2)) {
+ Py_RETURN_NOTIMPLEMENTED;
+ }
+
PyHKEYObject *pyhkey1 = (PyHKEYObject *)ob1;
PyHKEYObject *pyhkey2 = (PyHKEYObject *)ob2;
- return pyhkey1 == pyhkey2 ? 0 :
- (pyhkey1 < pyhkey2 ? -1 : 1);
+ HKEY hkey1 = pyhkey1->hkey;
+ HKEY hkey2 = pyhkey2->hkey;
+ int result;
+
+ switch (op) {
+ case Py_EQ:
+ result = (hkey1 == hkey2);
+ break;
+ case Py_NE:
+ result = (hkey1 != hkey2);
+ break;
+ default:
+ /* Only support equality comparisons, not ordering */
+ Py_RETURN_NOTIMPLEMENTED;
+ }
+
+ if (result) {
+ Py_RETURN_TRUE;
+ }
+ else {
+ Py_RETURN_FALSE;
+ }
}
static Py_hash_t
{Py_tp_traverse, _PyObject_VisitType},
{Py_tp_hash, PyHKEY_hashFunc},
{Py_tp_str, PyHKEY_strFunc},
+ {Py_tp_richcompare, PyHKEY_richcompare},
// Number protocol
{Py_nb_add, PyHKEY_binaryFailureFunc},