Skip to content

Commit efb2c2a

Browse files
committed
PYTHON-789 Clarify valid ObjectId input.
1 parent 1cf2f16 commit efb2c2a

File tree

1 file changed

+40
-11
lines changed

1 file changed

+40
-11
lines changed

bson/objectid.py

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ def _machine_bytes():
5454
return machine_hash.digest()[0:3]
5555

5656

57+
def _raise_invalid_id(oid):
58+
raise InvalidId(
59+
"%r is not a valid ObjectId, it must be a 12-byte input"
60+
" of type %r or a 24-character hex string" % (
61+
oid, binary_type.__name__))
62+
63+
5764
class ObjectId(object):
5865
"""A MongoDB ObjectId.
5966
"""
@@ -70,19 +77,41 @@ class ObjectId(object):
7077
def __init__(self, oid=None):
7178
"""Initialize a new ObjectId.
7279
73-
If `oid` is ``None``, create a new (unique) ObjectId. If `oid`
74-
is an instance of (:class:`basestring` (:class:`str` or :class:`bytes`
75-
in python 3), :class:`ObjectId`) validate it and use that. Otherwise,
76-
a :class:`TypeError` is raised. If `oid` is invalid,
77-
:class:`~bson.errors.InvalidId` is raised.
80+
An ObjectId is a 12-byte unique identifier consisting of:
81+
82+
- a 4-byte value representing the seconds since the Unix epoch,
83+
- a 3-byte machine identifier,
84+
- a 2-byte process id, and
85+
- a 3-byte counter, starting with a random value.
86+
87+
By default, ``ObjectId()`` creates a new unique identifier. The
88+
optional parameter `oid` can be an :class:`ObjectId`, or any 12
89+
:class:`bytes` or, in Python 2, any 12-character :class:`str`.
90+
91+
For example, the 12 bytes b'foo-bar-quux' do not follow the ObjectId
92+
specification but they are acceptable input::
93+
94+
>>> ObjectId(b'foo-bar-quux')
95+
ObjectId('666f6f2d6261722d71757578')
96+
97+
`oid` can also be a :class:`unicode` or :class:`str` of 24 hex digits::
98+
99+
>>> ObjectId('0123456789ab0123456789ab')
100+
ObjectId('0123456789ab0123456789ab')
101+
>>>
102+
>>> # A u-prefixed unicode literal:
103+
>>> ObjectId(u'0123456789ab0123456789ab')
104+
ObjectId('0123456789ab0123456789ab')
105+
106+
Raises :class:`~bson.errors.InvalidId` if `oid` is not 12 bytes nor
107+
24 hex digits, or :class:`TypeError` if `oid` is not an accepted type.
78108
79109
:Parameters:
80-
- `oid` (optional): a valid ObjectId (12 byte binary or 24 character
81-
hex string)
110+
- `oid` (optional): a valid ObjectId.
82111
83112
.. versionadded:: 1.2.1
84113
The `oid` parameter can be a ``unicode`` instance (that contains
85-
only hexadecimal digits).
114+
24 hexadecimal digits).
86115
87116
.. mongodoc:: objectids
88117
"""
@@ -189,14 +218,14 @@ def __validate(self, oid):
189218
if isinstance(oid, binary_type):
190219
self.__id = oid
191220
else:
192-
raise InvalidId("%s is not a valid ObjectId" % oid)
221+
_raise_invalid_id(oid)
193222
elif len(oid) == 24:
194223
try:
195224
self.__id = bytes_from_hex(oid)
196225
except (TypeError, ValueError):
197-
raise InvalidId("%s is not a valid ObjectId" % oid)
226+
_raise_invalid_id(oid)
198227
else:
199-
raise InvalidId("%s is not a valid ObjectId" % oid)
228+
_raise_invalid_id(oid)
200229
else:
201230
raise TypeError("id must be an instance of (%s, %s, ObjectId), "
202231
"not %s" % (binary_type.__name__,

0 commit comments

Comments
 (0)