@@ -526,54 +526,17 @@ def object_pairs_hook(
526
526
527
527
528
528
def object_hook (dct : Mapping [str , Any ], json_options : JSONOptions = DEFAULT_JSON_OPTIONS ) -> Any :
529
- if "$oid" in dct :
530
- return _parse_canonical_oid (dct )
531
- if (
532
- isinstance (dct .get ("$ref" ), str )
533
- and "$id" in dct
534
- and isinstance (dct .get ("$db" ), (str , type (None )))
535
- ):
536
- return _parse_canonical_dbref (dct )
537
- if "$date" in dct :
538
- return _parse_canonical_datetime (dct , json_options )
539
- if "$regex" in dct :
540
- return _parse_legacy_regex (dct )
541
- if "$minKey" in dct :
542
- return _parse_canonical_minkey (dct )
543
- if "$maxKey" in dct :
544
- return _parse_canonical_maxkey (dct )
545
- if "$binary" in dct :
546
- if "$type" in dct :
547
- return _parse_legacy_binary (dct , json_options )
548
- else :
549
- return _parse_canonical_binary (dct , json_options )
550
- if "$code" in dct :
551
- return _parse_canonical_code (dct )
552
- if "$uuid" in dct :
553
- return _parse_legacy_uuid (dct , json_options )
554
- if "$undefined" in dct :
555
- return None
556
- if "$numberLong" in dct :
557
- return _parse_canonical_int64 (dct )
558
- if "$timestamp" in dct :
559
- tsp = dct ["$timestamp" ]
560
- return Timestamp (tsp ["t" ], tsp ["i" ])
561
- if "$numberDecimal" in dct :
562
- return _parse_canonical_decimal128 (dct )
563
- if "$dbPointer" in dct :
564
- return _parse_canonical_dbpointer (dct )
565
- if "$regularExpression" in dct :
566
- return _parse_canonical_regex (dct )
567
- if "$symbol" in dct :
568
- return _parse_canonical_symbol (dct )
569
- if "$numberInt" in dct :
570
- return _parse_canonical_int32 (dct )
571
- if "$numberDouble" in dct :
572
- return _parse_canonical_double (dct )
529
+ match = None
530
+ for k in dct :
531
+ if k in _PARSERS_SET :
532
+ match = k
533
+ break
534
+ if match :
535
+ return _PARSERS [match ](dct , json_options )
573
536
return dct
574
537
575
538
576
- def _parse_legacy_regex (doc : Any ) -> Any :
539
+ def _parse_legacy_regex (doc : Any , dummy0 : Any ) -> Any :
577
540
pattern = doc ["$regex" ]
578
541
# Check if this is the $regex query operator.
579
542
if not isinstance (pattern , (str , bytes )):
@@ -709,30 +672,30 @@ def _parse_canonical_datetime(
709
672
return _millis_to_datetime (int (dtm ), cast ("CodecOptions[Any]" , json_options ))
710
673
711
674
712
- def _parse_canonical_oid (doc : Any ) -> ObjectId :
675
+ def _parse_canonical_oid (doc : Any , dummy0 : Any ) -> ObjectId :
713
676
"""Decode a JSON ObjectId to bson.objectid.ObjectId."""
714
677
if len (doc ) != 1 :
715
678
raise TypeError (f"Bad $oid, extra field(s): { doc } " )
716
679
return ObjectId (doc ["$oid" ])
717
680
718
681
719
- def _parse_canonical_symbol (doc : Any ) -> str :
682
+ def _parse_canonical_symbol (doc : Any , dummy0 : Any ) -> str :
720
683
"""Decode a JSON symbol to Python string."""
721
684
symbol = doc ["$symbol" ]
722
685
if len (doc ) != 1 :
723
686
raise TypeError (f"Bad $symbol, extra field(s): { doc } " )
724
687
return str (symbol )
725
688
726
689
727
- def _parse_canonical_code (doc : Any ) -> Code :
690
+ def _parse_canonical_code (doc : Any , dummy0 : Any ) -> Code :
728
691
"""Decode a JSON code to bson.code.Code."""
729
692
for key in doc :
730
693
if key not in ("$code" , "$scope" ):
731
694
raise TypeError (f"Bad $code, extra field(s): { doc } " )
732
695
return Code (doc ["$code" ], scope = doc .get ("$scope" ))
733
696
734
697
735
- def _parse_canonical_regex (doc : Any ) -> Regex [str ]:
698
+ def _parse_canonical_regex (doc : Any , dummy0 : Any ) -> Regex [str ]:
736
699
"""Decode a JSON regex to bson.regex.Regex."""
737
700
regex = doc ["$regularExpression" ]
738
701
if len (doc ) != 1 :
@@ -749,12 +712,18 @@ def _parse_canonical_regex(doc: Any) -> Regex[str]:
749
712
return Regex (regex ["pattern" ], opts )
750
713
751
714
752
- def _parse_canonical_dbref (doc : Any ) -> DBRef :
715
+ def _parse_canonical_dbref (doc : Any , dummy0 : Any ) -> Any :
753
716
"""Decode a JSON DBRef to bson.dbref.DBRef."""
754
- return DBRef (doc .pop ("$ref" ), doc .pop ("$id" ), database = doc .pop ("$db" , None ), ** doc )
717
+ if (
718
+ isinstance (doc .get ("$ref" ), str )
719
+ and "$id" in doc
720
+ and isinstance (doc .get ("$db" ), (str , type (None )))
721
+ ):
722
+ return DBRef (doc .pop ("$ref" ), doc .pop ("$id" ), database = doc .pop ("$db" , None ), ** doc )
723
+ return doc
755
724
756
725
757
- def _parse_canonical_dbpointer (doc : Any ) -> Any :
726
+ def _parse_canonical_dbpointer (doc : Any , dummy0 : Any ) -> Any :
758
727
"""Decode a JSON (deprecated) DBPointer to bson.dbref.DBRef."""
759
728
dbref = doc ["$dbPointer" ]
760
729
if len (doc ) != 1 :
@@ -773,7 +742,7 @@ def _parse_canonical_dbpointer(doc: Any) -> Any:
773
742
raise TypeError (f"Bad $dbPointer, expected a DBRef: { doc } " )
774
743
775
744
776
- def _parse_canonical_int32 (doc : Any ) -> int :
745
+ def _parse_canonical_int32 (doc : Any , dummy0 : Any ) -> int :
777
746
"""Decode a JSON int32 to python int."""
778
747
i_str = doc ["$numberInt" ]
779
748
if len (doc ) != 1 :
@@ -783,15 +752,15 @@ def _parse_canonical_int32(doc: Any) -> int:
783
752
return int (i_str )
784
753
785
754
786
- def _parse_canonical_int64 (doc : Any ) -> Int64 :
755
+ def _parse_canonical_int64 (doc : Any , dummy0 : Any ) -> Int64 :
787
756
"""Decode a JSON int64 to bson.int64.Int64."""
788
757
l_str = doc ["$numberLong" ]
789
758
if len (doc ) != 1 :
790
759
raise TypeError (f"Bad $numberLong, extra field(s): { doc } " )
791
760
return Int64 (l_str )
792
761
793
762
794
- def _parse_canonical_double (doc : Any ) -> float :
763
+ def _parse_canonical_double (doc : Any , dummy0 : Any ) -> float :
795
764
"""Decode a JSON double to python float."""
796
765
d_str = doc ["$numberDouble" ]
797
766
if len (doc ) != 1 :
@@ -801,7 +770,7 @@ def _parse_canonical_double(doc: Any) -> float:
801
770
return float (d_str )
802
771
803
772
804
- def _parse_canonical_decimal128 (doc : Any ) -> Decimal128 :
773
+ def _parse_canonical_decimal128 (doc : Any , dummy0 : Any ) -> Decimal128 :
805
774
"""Decode a JSON decimal128 to bson.decimal128.Decimal128."""
806
775
d_str = doc ["$numberDecimal" ]
807
776
if len (doc ) != 1 :
@@ -811,7 +780,7 @@ def _parse_canonical_decimal128(doc: Any) -> Decimal128:
811
780
return Decimal128 (d_str )
812
781
813
782
814
- def _parse_canonical_minkey (doc : Any ) -> MinKey :
783
+ def _parse_canonical_minkey (doc : Any , dummy0 : Any ) -> MinKey :
815
784
"""Decode a JSON MinKey to bson.min_key.MinKey."""
816
785
if type (doc ["$minKey" ]) is not int or doc ["$minKey" ] != 1 : # noqa: E721
817
786
raise TypeError (f"$minKey value must be 1: { doc } " )
@@ -820,7 +789,7 @@ def _parse_canonical_minkey(doc: Any) -> MinKey:
820
789
return MinKey ()
821
790
822
791
823
- def _parse_canonical_maxkey (doc : Any ) -> MaxKey :
792
+ def _parse_canonical_maxkey (doc : Any , dummy0 : Any ) -> MaxKey :
824
793
"""Decode a JSON MaxKey to bson.max_key.MaxKey."""
825
794
if type (doc ["$maxKey" ]) is not int or doc ["$maxKey" ] != 1 : # noqa: E721
826
795
raise TypeError ("$maxKey value must be 1: %s" , (doc ,))
@@ -829,6 +798,41 @@ def _parse_canonical_maxkey(doc: Any) -> MaxKey:
829
798
return MaxKey ()
830
799
831
800
801
+ def _parse_binary (doc : Any , json_options : JSONOptions ) -> Union [Binary , uuid .UUID ]:
802
+ if "$type" in doc :
803
+ return _parse_legacy_binary (doc , json_options )
804
+ else :
805
+ return _parse_canonical_binary (doc , json_options )
806
+
807
+
808
+ def _parse_timestamp (doc : Any , dummy0 : Any ) -> Timestamp :
809
+ tsp = doc ["$timestamp" ]
810
+ return Timestamp (tsp ["t" ], tsp ["i" ])
811
+
812
+
813
+ _PARSERS : dict [str , Callable [[Any , JSONOptions ], Any ]] = {
814
+ "$oid" : _parse_canonical_oid ,
815
+ "$ref" : _parse_canonical_dbref ,
816
+ "$date" : _parse_canonical_datetime ,
817
+ "$regex" : _parse_legacy_regex ,
818
+ "$minKey" : _parse_canonical_minkey ,
819
+ "$maxKey" : _parse_canonical_maxkey ,
820
+ "$binary" : _parse_binary ,
821
+ "$code" : _parse_canonical_code ,
822
+ "$uuid" : _parse_legacy_uuid ,
823
+ "$undefined" : lambda _ , _1 : None ,
824
+ "$numberLong" : _parse_canonical_int64 ,
825
+ "$timestamp" : _parse_timestamp ,
826
+ "$numberDecimal" : _parse_canonical_decimal128 ,
827
+ "$dbPointer" : _parse_canonical_dbpointer ,
828
+ "$regularExpression" : _parse_canonical_regex ,
829
+ "$symbol" : _parse_canonical_symbol ,
830
+ "$numberInt" : _parse_canonical_int32 ,
831
+ "$numberDouble" : _parse_canonical_double ,
832
+ }
833
+ _PARSERS_SET = set (_PARSERS )
834
+
835
+
832
836
def _encode_binary (data : bytes , subtype : int , json_options : JSONOptions ) -> Any :
833
837
if json_options .json_mode == JSONMode .LEGACY :
834
838
return {"$binary" : base64 .b64encode (data ).decode (), "$type" : "%02x" % subtype }
0 commit comments