diff --git a/bson/son.py b/bson/son.py index 8fd4f95cd2..ccb6bdb273 100644 --- a/bson/son.py +++ b/bson/son.py @@ -22,6 +22,7 @@ import copy import re +import warnings from collections.abc import Mapping as _Mapping from typing import ( Any, @@ -99,13 +100,28 @@ def __iter__(self) -> Iterator[_Key]: yield from self.__keys def has_key(self, key: _Key) -> bool: + warnings.warn( + "SON.has_key() is deprecated, use the in operator instead", + DeprecationWarning, + stacklevel=2, + ) return key in self.__keys def iterkeys(self) -> Iterator[_Key]: + warnings.warn( + "SON.iterkeys() is deprecated, use the keys() method instead", + DeprecationWarning, + stacklevel=2, + ) return self.__iter__() # fourth level uses definitions from lower levels def itervalues(self) -> Iterator[_Value]: + warnings.warn( + "SON.itervalues() is deprecated, use the values() method instead", + DeprecationWarning, + stacklevel=2, + ) for _, v in self.items(): yield v diff --git a/doc/changelog.rst b/doc/changelog.rst index f38709203c..23d5b2fc9e 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -6,6 +6,11 @@ Changes in Version 4.17.0 (2026/XX/XX) PyMongo 4.17 brings a number of changes including: +- ``has_key``, ``iterkeys`` and ``itervalues`` in :class:`bson.son.SON` have + been deprecated and will be removed in PyMongo 5.0. These methods were + deprecated in favor of the standard dictionary containment operator ``in`` + and the ``keys()`` and ``values()`` methods, respectively. + - Added the :meth:`~pymongo.asynchronous.client_session.AsyncClientSession.bind` and :meth:`~pymongo.client_session.ClientSession.bind` methods that allow users to bind a session to all database operations within the scope of a context manager instead of having to explicitly pass the session to each individual operation. See for examples and more information. diff --git a/test/test_son.py b/test/test_son.py index 36a6834889..3d2069a4c2 100644 --- a/test/test_son.py +++ b/test/test_son.py @@ -145,13 +145,11 @@ def test_iteration(self): self.assertEqual(ele * 100, test_son[ele]) def test_contains_has(self): - """has_key and __contains__""" + """Test key membership via 'in' and __contains__.""" test_son = SON([(1, 100), (2, 200), (3, 300)]) self.assertIn(1, test_son) self.assertIn(2, test_son, "in failed") self.assertNotIn(22, test_son, "in succeeded when it shouldn't") - self.assertTrue(test_son.has_key(2), "has_key failed") - self.assertFalse(test_son.has_key(22), "has_key succeeded when it shouldn't") def test_clears(self): """Test clear()"""