@@ -3,8 +3,10 @@ use crate::exceptions::PyStopAsyncIteration;
3
3
use crate :: gil:: LockGIL ;
4
4
use crate :: impl_:: panic:: PanicTrap ;
5
5
use crate :: internal_tricks:: extract_c_string;
6
+ use crate :: types:: { any:: PyAnyMethods , PyModule , PyType } ;
6
7
use crate :: {
7
- ffi, PyAny , PyCell , PyClass , PyErr , PyObject , PyResult , PyTraverseError , PyVisit , Python ,
8
+ ffi, Bound , Py , PyAny , PyCell , PyClass , PyErr , PyObject , PyResult , PyTraverseError , PyVisit ,
9
+ Python ,
8
10
} ;
9
11
use std:: borrow:: Cow ;
10
12
use std:: ffi:: CStr ;
@@ -466,3 +468,52 @@ pub trait AsyncIterResultOptionKind {
466
468
}
467
469
468
470
impl < Value , Error > AsyncIterResultOptionKind for Result < Option < Value > , Error > { }
471
+
472
+ /// Used in `#[classmethod]` to pass the class object to the method
473
+ /// and also in `#[pyfunction(pass_module)]`.
474
+ ///
475
+ /// This is a wrapper to avoid implementing `From<Bound>` for GIL Refs.
476
+ ///
477
+ /// Once the GIL Ref API is fully removed, it should be possible to simplify
478
+ /// this to just `&'a Bound<'py, T>` and `From` implementations.
479
+ pub struct BoundRef < ' a , ' py , T > ( pub & ' a Bound < ' py , T > ) ;
480
+
481
+ impl < ' a , ' py > BoundRef < ' a , ' py , PyAny > {
482
+ pub unsafe fn ref_from_ptr ( py : Python < ' py > , ptr : & ' a * mut ffi:: PyObject ) -> Self {
483
+ BoundRef ( Bound :: ref_from_ptr ( py, ptr) )
484
+ }
485
+
486
+ pub unsafe fn downcast_unchecked < T > ( self ) -> BoundRef < ' a , ' py , T > {
487
+ BoundRef ( self . 0 . downcast_unchecked :: < T > ( ) )
488
+ }
489
+ }
490
+
491
+ // GIL Ref implementations for &'a T ran into trouble with orphan rules,
492
+ // so explicit implementations are used instead for the two relevant types.
493
+ impl < ' a > From < BoundRef < ' a , ' a , PyType > > for & ' a PyType {
494
+ #[ inline]
495
+ fn from ( bound : BoundRef < ' a , ' a , PyType > ) -> Self {
496
+ bound. 0 . as_gil_ref ( )
497
+ }
498
+ }
499
+
500
+ impl < ' a > From < BoundRef < ' a , ' a , PyModule > > for & ' a PyModule {
501
+ #[ inline]
502
+ fn from ( bound : BoundRef < ' a , ' a , PyModule > ) -> Self {
503
+ bound. 0 . as_gil_ref ( )
504
+ }
505
+ }
506
+
507
+ impl < ' a , ' py , T > From < BoundRef < ' a , ' py , T > > for & ' a Bound < ' py , T > {
508
+ #[ inline]
509
+ fn from ( bound : BoundRef < ' a , ' py , T > ) -> Self {
510
+ bound. 0
511
+ }
512
+ }
513
+
514
+ impl < T > From < BoundRef < ' _ , ' _ , T > > for Py < T > {
515
+ #[ inline]
516
+ fn from ( bound : BoundRef < ' _ , ' _ , T > ) -> Self {
517
+ bound. 0 . clone ( ) . unbind ( )
518
+ }
519
+ }
0 commit comments