From 710227237a399371ab1f9d50df28fe69b6172def Mon Sep 17 00:00:00 2001 From: "A. Jesse Jiryu Davis" Date: Tue, 18 Nov 2014 19:17:24 -0500 Subject: [PATCH] PYTHON-789 Clarify valid ObjectId input (3.0-dev). --- bson/objectid.py | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/bson/objectid.py b/bson/objectid.py index 0f40f75bc..dbcd2e5f9 100644 --- a/bson/objectid.py +++ b/bson/objectid.py @@ -46,6 +46,12 @@ def _machine_bytes(): return machine_hash.digest()[0:3] +def _raise_invalid_id(oid): + raise InvalidId( + "%r is not a valid ObjectId, it must be a 12-byte input" + " or a 24-character hex string" % oid) + + class ObjectId(object): """A MongoDB ObjectId. """ @@ -62,15 +68,37 @@ class ObjectId(object): def __init__(self, oid=None): """Initialize a new ObjectId. - If `oid` is ``None``, create a new (unique) ObjectId. If `oid` - is an instance of (:class:`basestring` (:class:`str` or :class:`bytes` - in python 3), :class:`ObjectId`) validate it and use that. Otherwise, - a :class:`TypeError` is raised. If `oid` is invalid, - :class:`~bson.errors.InvalidId` is raised. + An ObjectId is a 12-byte unique identifier consisting of: + + - a 4-byte value representing the seconds since the Unix epoch, + - a 3-byte machine identifier, + - a 2-byte process id, and + - a 3-byte counter, starting with a random value. + + By default, ``ObjectId()`` creates a new unique identifier. The + optional parameter `oid` can be an :class:`ObjectId`, or any 12 + :class:`bytes` or, in Python 2, any 12-character :class:`str`. + + For example, the 12 bytes b'foo-bar-quux' do not follow the ObjectId + specification but they are acceptable input:: + + >>> ObjectId(b'foo-bar-quux') + ObjectId('666f6f2d6261722d71757578') + + `oid` can also be a :class:`unicode` or :class:`str` of 24 hex digits:: + + >>> ObjectId('0123456789ab0123456789ab') + ObjectId('0123456789ab0123456789ab') + >>> + >>> # A u-prefixed unicode literal: + >>> ObjectId(u'0123456789ab0123456789ab') + ObjectId('0123456789ab0123456789ab') + + Raises :class:`~bson.errors.InvalidId` if `oid` is not 12 bytes nor + 24 hex digits, or :class:`TypeError` if `oid` is not an accepted type. :Parameters: - - `oid` (optional): a valid ObjectId (12 byte binary or 24 character - hex string) + - `oid` (optional): a valid ObjectId. .. mongodoc:: objectids """ @@ -173,9 +201,9 @@ class ObjectId(object): try: self.__id = bytes_from_hex(oid) except (TypeError, ValueError): - raise InvalidId("%s is not a valid ObjectId" % oid) + _raise_invalid_id(oid) else: - raise InvalidId("%s is not a valid ObjectId" % oid) + _raise_invalid_id(oid) else: raise TypeError("id must be an instance of (bytes, %s, ObjectId), " "not %s" % (text_type.__name__, type(oid)))