@@ -13,11 +13,11 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
13
13
#[ pymodule( name = "_typing" ) ]
14
14
pub ( crate ) mod decl {
15
15
use crate :: {
16
- AsObject , PyObjectRef , PyPayload , PyResult , VirtualMachine ,
16
+ AsObject , PyObject , PyObjectRef , PyPayload , PyResult , VirtualMachine ,
17
17
builtins:: { PyGenericAlias , PyTupleRef , PyTypeRef , pystr:: AsPyStr } ,
18
- function:: { FuncArgs , IntoFuncArgs } ,
18
+ function:: { FuncArgs , IntoFuncArgs , PyComparisonValue } ,
19
19
protocol:: PyNumberMethods ,
20
- types:: { AsNumber , Constructor , Representable } ,
20
+ types:: { AsNumber , Comparable , Constructor , PyComparisonOp , Representable } ,
21
21
} ;
22
22
23
23
pub ( crate ) fn _call_typing_func_object < ' a > (
@@ -751,7 +751,7 @@ pub(crate) mod decl {
751
751
pub ( crate ) struct ParamSpecArgs {
752
752
__origin__ : PyObjectRef ,
753
753
}
754
- #[ pyclass( flags ( BASETYPE ) , with( Constructor , Representable ) ) ]
754
+ #[ pyclass( with( Constructor , Representable , Comparable ) ) ]
755
755
impl ParamSpecArgs {
756
756
#[ pymethod( magic) ]
757
757
fn mro_entries ( & self , _bases : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
@@ -762,15 +762,6 @@ pub(crate) mod decl {
762
762
fn origin ( & self ) -> PyObjectRef {
763
763
self . __origin__ . clone ( )
764
764
}
765
-
766
- #[ pymethod( magic) ]
767
- fn eq ( & self , other : PyObjectRef , vm : & VirtualMachine ) -> PyResult < bool > {
768
- // Check if other has __origin__ attribute
769
- if let Ok ( other_origin) = other. get_attr ( "__origin__" , vm) {
770
- return Ok ( self . __origin__ . is ( & other_origin) ) ;
771
- }
772
- Ok ( false )
773
- }
774
765
}
775
766
776
767
impl Constructor for ParamSpecArgs {
@@ -794,14 +785,52 @@ pub(crate) mod decl {
794
785
}
795
786
}
796
787
788
+ impl Comparable for ParamSpecArgs {
789
+ fn cmp (
790
+ zelf : & crate :: Py < Self > ,
791
+ other : & PyObject ,
792
+ op : PyComparisonOp ,
793
+ vm : & VirtualMachine ,
794
+ ) -> PyResult < PyComparisonValue > {
795
+ fn eq (
796
+ zelf : & crate :: Py < ParamSpecArgs > ,
797
+ other : PyObjectRef ,
798
+ vm : & VirtualMachine ,
799
+ ) -> PyResult < bool > {
800
+ // Check if other has __origin__ attribute
801
+ if let Ok ( other_origin) = other. get_attr ( "__origin__" , vm) {
802
+ return Ok ( zelf. __origin__ . is ( & other_origin) ) ;
803
+ }
804
+ Ok ( false )
805
+ }
806
+ match op {
807
+ PyComparisonOp :: Eq => {
808
+ if let Ok ( result) = eq ( zelf, other. to_owned ( ) , vm) {
809
+ Ok ( result. into ( ) )
810
+ } else {
811
+ Ok ( PyComparisonValue :: NotImplemented )
812
+ }
813
+ }
814
+ PyComparisonOp :: Ne => {
815
+ if let Ok ( result) = eq ( zelf, other. to_owned ( ) , vm) {
816
+ Ok ( ( !result) . into ( ) )
817
+ } else {
818
+ Ok ( PyComparisonValue :: NotImplemented )
819
+ }
820
+ }
821
+ _ => Ok ( PyComparisonValue :: NotImplemented ) ,
822
+ }
823
+ }
824
+ }
825
+
797
826
#[ pyattr]
798
827
#[ pyclass( name = "ParamSpecKwargs" , module = "typing" ) ]
799
828
#[ derive( Debug , PyPayload ) ]
800
829
#[ allow( dead_code) ]
801
830
pub ( crate ) struct ParamSpecKwargs {
802
831
__origin__ : PyObjectRef ,
803
832
}
804
- #[ pyclass( flags ( BASETYPE ) , with( Constructor , Representable ) ) ]
833
+ #[ pyclass( with( Constructor , Representable , Comparable ) ) ]
805
834
impl ParamSpecKwargs {
806
835
#[ pymethod( magic) ]
807
836
fn mro_entries ( & self , _bases : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
@@ -812,15 +841,6 @@ pub(crate) mod decl {
812
841
fn origin ( & self ) -> PyObjectRef {
813
842
self . __origin__ . clone ( )
814
843
}
815
-
816
- #[ pymethod( magic) ]
817
- fn eq ( & self , other : PyObjectRef , vm : & VirtualMachine ) -> PyResult < bool > {
818
- // Check if other has __origin__ attribute
819
- if let Ok ( other_origin) = other. get_attr ( "__origin__" , vm) {
820
- return Ok ( self . __origin__ . is ( & other_origin) ) ;
821
- }
822
- Ok ( false )
823
- }
824
844
}
825
845
826
846
impl Constructor for ParamSpecKwargs {
@@ -844,6 +864,44 @@ pub(crate) mod decl {
844
864
}
845
865
}
846
866
867
+ impl Comparable for ParamSpecKwargs {
868
+ fn cmp (
869
+ zelf : & crate :: Py < Self > ,
870
+ other : & PyObject ,
871
+ op : PyComparisonOp ,
872
+ vm : & VirtualMachine ,
873
+ ) -> PyResult < PyComparisonValue > {
874
+ fn eq (
875
+ zelf : & crate :: Py < ParamSpecKwargs > ,
876
+ other : PyObjectRef ,
877
+ vm : & VirtualMachine ,
878
+ ) -> PyResult < bool > {
879
+ // Check if other has __origin__ attribute
880
+ if let Ok ( other_origin) = other. get_attr ( "__origin__" , vm) {
881
+ return Ok ( zelf. __origin__ . is ( & other_origin) ) ;
882
+ }
883
+ Ok ( false )
884
+ }
885
+ match op {
886
+ PyComparisonOp :: Eq => {
887
+ if let Ok ( result) = eq ( zelf, other. to_owned ( ) , vm) {
888
+ Ok ( result. into ( ) )
889
+ } else {
890
+ Ok ( PyComparisonValue :: NotImplemented )
891
+ }
892
+ }
893
+ PyComparisonOp :: Ne => {
894
+ if let Ok ( result) = eq ( zelf, other. to_owned ( ) , vm) {
895
+ Ok ( ( !result) . into ( ) )
896
+ } else {
897
+ Ok ( PyComparisonValue :: NotImplemented )
898
+ }
899
+ }
900
+ _ => Ok ( PyComparisonValue :: NotImplemented ) ,
901
+ }
902
+ }
903
+ }
904
+
847
905
#[ pyattr]
848
906
#[ pyclass( name) ]
849
907
#[ derive( Debug , PyPayload ) ]
@@ -922,13 +980,17 @@ pub(crate) mod decl {
922
980
if let Ok ( name_str) = module_name. str ( vm) {
923
981
let name = name_str. as_str ( ) ;
924
982
// CPython sets __module__ to None for builtins and <...> modules
983
+ // Also set to None for exec contexts (no __name__ in globals means exec)
925
984
if name == "builtins" || name. starts_with ( '<' ) {
926
985
// Don't set __module__ attribute at all (CPython behavior)
927
986
// This allows the typing module to handle it
928
987
return Ok ( ( ) ) ;
929
988
}
930
989
}
931
990
obj. set_attr ( "__module__" , module_name, vm) ?;
991
+ } else {
992
+ // If no module name is found (e.g., in exec context), set __module__ to None
993
+ obj. set_attr ( "__module__" , vm. ctx . none ( ) , vm) ?;
932
994
}
933
995
Ok ( ( ) )
934
996
}
0 commit comments