2626from pymongo .errors import ConfigurationError , InvalidName
2727
2828
29+ try :
30+ from collections import OrderedDict
31+ ordered_types = (SON , OrderedDict )
32+ except ImportError :
33+ ordered_types = SON
34+
35+
2936def _gen_index_name (keys ):
3037 """Generate an index name from the set of fields it is over.
3138 """
@@ -1228,7 +1235,8 @@ def inline_map_reduce(self, map, reduce, full_response=False, **kwargs):
12281235 else :
12291236 return res .get ("results" )
12301237
1231- def find_and_modify (self , query = {}, update = None , upsert = False , ** kwargs ):
1238+ def find_and_modify (self , query = {}, update = None ,
1239+ upsert = False , sort = None , ** kwargs ):
12321240 """Update and return an object.
12331241
12341242 This is a thin wrapper around the findAndModify_ command. The
@@ -1243,13 +1251,15 @@ def find_and_modify(self, query={}, update=None, upsert=False, **kwargs):
12431251
12441252 :Parameters:
12451253 - `query`: filter for the update (default ``{}``)
1246- - `sort`: priority if multiple objects match (default ``{}``)
12471254 - `update`: see second argument to :meth:`update` (no default)
1255+ - `upsert`: insert if object doesn't exist (default ``False``)
1256+ - `sort`: a list of (key, direction) pairs specifying the sort
1257+ order for this query. See :meth:`~pymongo.cursor.Cursor.sort`
1258+ for details.
12481259 - `remove`: remove rather than updating (default ``False``)
12491260 - `new`: return updated rather than original object
12501261 (default ``False``)
12511262 - `fields`: see second argument to :meth:`find` (default all)
1252- - `upsert`: insert if object doesn't exist (default ``False``)
12531263 - `**kwargs`: any other options the findAndModify_ command
12541264 supports can be passed here.
12551265
@@ -1260,6 +1270,9 @@ def find_and_modify(self, query={}, update=None, upsert=False, **kwargs):
12601270
12611271 .. note:: Requires server version **>= 1.3.0**
12621272
1273+ .. versionchanged:: 2.3+
1274+ Deprecated the use of mapping types for the sort parameter
1275+
12631276 .. versionadded:: 1.10
12641277 """
12651278 if (not update and not kwargs .get ('remove' , None )):
@@ -1275,6 +1288,22 @@ def find_and_modify(self, query={}, update=None, upsert=False, **kwargs):
12751288 kwargs ['update' ] = update
12761289 if upsert :
12771290 kwargs ['upsert' ] = upsert
1291+ if sort :
1292+ # Accept a list of tuples to match Cursor's sort parameter.
1293+ if isinstance (sort , list ):
1294+ kwargs ['sort' ] = helpers ._index_document (sort )
1295+ # Accept OrderedDict, SON, and dict with len == 1 so we
1296+ # don't break existing code already using find_and_modify.
1297+ elif (isinstance (sort , ordered_types ) or
1298+ isinstance (sort , dict ) and len (sort ) == 1 ):
1299+ warnings .warn ("Passing mapping types for `sort` is deprecated,"
1300+ " use a list of (key, direction) pairs instead" ,
1301+ DeprecationWarning )
1302+ kwargs ['sort' ] = sort
1303+ else :
1304+ raise TypeError ("sort must be a list of (key, direction) "
1305+ "pairs, a dict of len 1, or an instance of "
1306+ "SON or OrderedDict" )
12781307
12791308 no_obj_error = "No matching object found"
12801309
0 commit comments