diff --git a/bson/objectid.py b/bson/objectid.py index 970c4e52e8..68d0ba7d95 100644 --- a/bson/objectid.py +++ b/bson/objectid.py @@ -98,11 +98,27 @@ def __init__(self, oid: Optional[Union[str, ObjectId, bytes]] = None) -> None: objectid.rst>`_. """ if oid is None: - self.__generate() + # Generate a new value for this ObjectId. + with ObjectId._inc_lock: + inc = ObjectId._inc + ObjectId._inc = (inc + 1) % (_MAX_COUNTER_VALUE + 1) + + # 4 bytes current time, 5 bytes random, 3 bytes inc. + self.__id = _PACK_INT_RANDOM(int(time.time()), ObjectId._random()) + _PACK_INT(inc)[1:4] elif isinstance(oid, bytes) and len(oid) == 12: self.__id = oid + elif isinstance(oid, str): + if len(oid) == 24: + try: + self.__id = bytes.fromhex(oid) + except (TypeError, ValueError): + _raise_invalid_id(oid) + else: + _raise_invalid_id(oid) + elif isinstance(oid, ObjectId): + self.__id = oid.binary else: - self.__validate(oid) + raise TypeError(f"id must be an instance of (bytes, str, ObjectId), not {type(oid)}") @classmethod def from_datetime(cls: Type[ObjectId], generation_time: datetime.datetime) -> ObjectId: @@ -163,37 +179,6 @@ def _random(cls) -> bytes: cls.__random = _random_bytes() return cls.__random - def __generate(self) -> None: - """Generate a new value for this ObjectId.""" - with ObjectId._inc_lock: - inc = ObjectId._inc - ObjectId._inc = (inc + 1) % (_MAX_COUNTER_VALUE + 1) - - # 4 bytes current time, 5 bytes random, 3 bytes inc. - self.__id = _PACK_INT_RANDOM(int(time.time()), ObjectId._random()) + _PACK_INT(inc)[1:4] - - def __validate(self, oid: Any) -> None: - """Validate and use the given id for this ObjectId. - - Raises TypeError if id is not an instance of :class:`str`, - :class:`bytes`, or ObjectId. Raises InvalidId if it is not a - valid ObjectId. - - :param oid: a valid ObjectId - """ - if isinstance(oid, ObjectId): - self.__id = oid.binary - elif isinstance(oid, str): - if len(oid) == 24: - try: - self.__id = bytes.fromhex(oid) - except (TypeError, ValueError): - _raise_invalid_id(oid) - else: - _raise_invalid_id(oid) - else: - raise TypeError(f"id must be an instance of (bytes, str, ObjectId), not {type(oid)}") - @property def binary(self) -> bytes: """12-byte binary representation of this ObjectId."""