File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -8,7 +8,18 @@ use rustpython_vm::import::import_code_obj;
88pub unsafe extern "C" fn PyImport_Import ( name : * mut PyObject ) -> * mut PyObject {
99 with_vm ( |vm| {
1010 let name = unsafe { ( & * name) . try_downcast_ref :: < PyStr > ( vm) ? } ;
11- vm. import ( name, 0 )
11+ vm. import ( name, 0 ) ?;
12+
13+ let sys_modules = vm
14+ . sys_module
15+ . get_attr ( rustpython_vm:: identifier!( vm, modules) , vm) ?;
16+ let sys_modules = sys_modules. try_downcast_ref :: < PyDict > ( vm) ?;
17+
18+ if let Some ( module) = sys_modules. get_item_opt ( name, vm) ? {
19+ Ok ( module)
20+ } else {
21+ vm. import ( name, 0 )
22+ }
1223 } )
1324}
1425
@@ -74,4 +85,12 @@ mod tests {
7485 let _module = py. import ( "types" ) . unwrap ( ) ;
7586 } )
7687 }
88+
89+ #[ test]
90+ fn import_sub_module ( ) {
91+ Python :: attach ( |py| {
92+ let module = py. import ( "collections.abc" ) . unwrap ( ) ;
93+ module. getattr ( "Sequence" ) . unwrap ( ) ;
94+ } )
95+ }
7796}
Original file line number Diff line number Diff line change @@ -53,6 +53,7 @@ pub(crate) fn build_method_def(
5353
5454 let flags = PyMethodFlags :: from_bits ( ml. ml_flags as u32 )
5555 . ok_or_else ( || vm. new_system_error ( "PyMethodDef contains unknown flags" ) ) ?;
56+ let has_self = has_self && !flags. contains ( PyMethodFlags :: STATIC ) ;
5657
5758 let method = ml. ml_meth ;
5859
@@ -359,4 +360,17 @@ mod tests {
359360 ) ;
360361 } )
361362 }
363+
364+ #[ test]
365+ fn test_wrap_static_no_args_function ( ) {
366+ #[ pyfunction( ) ]
367+ fn f ( ) { }
368+
369+ Python :: attach ( |py| {
370+ let module = PyModule :: new ( py, "test_wrap_pyfunction_forms" ) . unwrap ( ) ;
371+
372+ let func = wrap_pyfunction ! ( f, & module) . unwrap ( ) ;
373+ func. call0 ( ) . unwrap ( ) ;
374+ } ) ;
375+ }
362376}
Original file line number Diff line number Diff line change @@ -217,7 +217,7 @@ pub unsafe extern "C" fn PyObject_HasAttrWithError(
217217 with_vm ( |vm| {
218218 let obj = unsafe { & * obj } ;
219219 let name = unsafe { & * attr_name } . try_downcast_ref :: < PyStr > ( vm) ?;
220- obj. has_attr ( name , vm )
220+ Ok ( vm . get_attribute_opt ( obj. to_owned ( ) , name ) ? . is_some ( ) )
221221 } )
222222}
223223
@@ -272,7 +272,7 @@ pub unsafe extern "C" fn PyObject_HasAttrStringWithError(
272272 with_vm ( |vm| {
273273 let obj = unsafe { & * obj } ;
274274 let name = unsafe { attr_name. try_as_str ( vm) } ?;
275- obj. has_attr ( name , vm )
275+ Ok ( vm . get_attribute_opt ( obj. to_owned ( ) , name ) ? . is_some ( ) )
276276 } )
277277}
278278
@@ -591,4 +591,15 @@ mod tests {
591591 assert ! ( dict. get_item( "foo" ) . is_ok( ) ) ;
592592 } )
593593 }
594+
595+ #[ test]
596+ fn test_hasattr ( ) {
597+ Python :: attach ( |py| {
598+ let x = 5i32 . into_pyobject ( py) . unwrap ( ) ;
599+ assert ! ( x. is_instance_of:: <PyInt >( ) ) ;
600+
601+ assert ! ( x. hasattr( "to_bytes" ) . unwrap( ) ) ;
602+ assert ! ( !x. hasattr( "bbbbbbytes" ) . unwrap( ) ) ;
603+ } )
604+ }
594605}
Original file line number Diff line number Diff line change @@ -48,6 +48,11 @@ pub unsafe extern "C" fn PyCapsule_GetContext(capsule: *mut PyObject) -> *mut c_
4848 let capsule = unsafe { & * capsule }
4949 . downcast_ref_if_exact :: < PyCapsule > ( vm)
5050 . ok_or_else ( || vm. new_value_error ( "Invalid capsule" ) ) ?;
51+
52+ if capsule. pointer ( ) . is_null ( ) {
53+ return Err ( vm. new_value_error ( "Capsule has null pointer" ) ) ;
54+ }
55+
5156 Ok ( capsule. context ( ) )
5257 } )
5358}
@@ -143,6 +148,7 @@ fn checked_capsule<'a>(
143148
144149#[ cfg( test) ]
145150mod tests {
151+ use pyo3:: ffi;
146152 use pyo3:: prelude:: * ;
147153 use pyo3:: types:: PyCapsule ;
148154
@@ -156,4 +162,21 @@ mod tests {
156162 assert_eq ! ( unsafe { ptr. cast:: <String >( ) . as_ref( ) } , "Some data" ) ;
157163 } )
158164 }
165+
166+ #[ test]
167+ fn capsule_context_on_invalid_capsule ( ) {
168+ Python :: attach ( |py| {
169+ let cap = PyCapsule :: new_with_value ( py, 123u32 , c"name" ) . unwrap ( ) ;
170+
171+ // Invalidate the capsule
172+ // SAFETY: intentionally breaking the capsule for testing
173+ unsafe {
174+ ffi:: PyCapsule_SetPointer ( cap. as_ptr ( ) , core:: ptr:: null_mut ( ) ) ;
175+ }
176+
177+ // context() on invalid capsule should fail
178+ let result = cap. context ( ) ;
179+ assert ! ( result. is_err( ) ) ;
180+ } ) ;
181+ }
159182}
Original file line number Diff line number Diff line change @@ -76,7 +76,7 @@ impl Representable for PyCapsule {
7676
7777impl Destructor for PyCapsule {
7878 fn del ( zelf : & Py < Self > , _vm : & VirtualMachine ) -> PyResult < ( ) > {
79- if let Some ( destructor) = zelf. destructor ( ) {
79+ if !zelf . pointer ( ) . is_null ( ) && let Some ( destructor) = zelf. destructor ( ) {
8080 unsafe { destructor ( zelf. as_object ( ) . as_raw ( ) . cast_mut ( ) ) } ;
8181 }
8282 Ok ( ( ) )
You can’t perform that action at this time.
0 commit comments