@@ -9,11 +9,8 @@ use crate::internal_tricks::get_ssize_index;
9
9
use crate :: py_result_ext:: PyResultExt ;
10
10
use crate :: sync:: PyOnceLock ;
11
11
use crate :: type_object:: PyTypeInfo ;
12
- use crate :: types:: { any:: PyAnyMethods , PyAny , PyList , PyString , PyTuple , PyType } ;
13
- use crate :: {
14
- ffi, Borrowed , BoundObject , FromPyObject , IntoPyObject , IntoPyObjectExt , Py , PyTypeCheck ,
15
- Python ,
16
- } ;
12
+ use crate :: types:: { any:: PyAnyMethods , PyAny , PyList , PyString , PyTuple , PyType , PyTypeMethods } ;
13
+ use crate :: { ffi, Borrowed , BoundObject , FromPyObject , IntoPyObject , IntoPyObjectExt , Py , Python } ;
17
14
18
15
/// Represents a reference to a Python object supporting the sequence protocol.
19
16
///
@@ -24,15 +21,36 @@ use crate::{
24
21
/// [`Bound<'py, PySequence>`][Bound].
25
22
#[ repr( transparent) ]
26
23
pub struct PySequence ( PyAny ) ;
27
- pyobject_native_type_named ! ( PySequence ) ;
24
+
25
+ pyobject_native_type_core ! (
26
+ PySequence ,
27
+ |py| {
28
+ static TYPE : PyOnceLock <Py <PyType >> = PyOnceLock :: new( ) ;
29
+ TYPE . import( py, "collections.abc" , "Sequence" )
30
+ . unwrap( )
31
+ . as_type_ptr( )
32
+ } ,
33
+ #module=Some ( "collections.abc" ) ,
34
+ #pyo3checkfunction=|object| {
35
+ // Using `is_instance` for `collections.abc.Sequence` is slow, so provide
36
+ // optimized cases for list and tuples as common well-known sequences
37
+ PyList :: is_type_of( object)
38
+ || PyTuple :: is_type_of( object)
39
+ || object. is_instance( & Self :: type_object( object. py( ) ) . into_any( ) )
40
+ . unwrap_or_else( |err| {
41
+ err. write_unraisable( object. py( ) , Some ( object) ) ;
42
+ false
43
+ } )
44
+ }
45
+ ) ;
28
46
29
47
impl PySequence {
30
48
/// Register a pyclass as a subclass of `collections.abc.Sequence` (from the Python standard
31
49
/// library). This is equivalent to `collections.abc.Sequence.register(T)` in Python.
32
50
/// This registration is required for a pyclass to be castable from `PyAny` to `PySequence`.
33
51
pub fn register < T : PyTypeInfo > ( py : Python < ' _ > ) -> PyResult < ( ) > {
34
52
let ty = T :: type_object ( py) ;
35
- get_sequence_abc ( py) ? . call_method1 ( "register" , ( ty, ) ) ?;
53
+ Self :: type_object ( py) . call_method1 ( "register" , ( ty, ) ) ?;
36
54
Ok ( ( ) )
37
55
}
38
56
}
@@ -372,32 +390,6 @@ where
372
390
Ok ( v)
373
391
}
374
392
375
- fn get_sequence_abc ( py : Python < ' _ > ) -> PyResult < & Bound < ' _ , PyType > > {
376
- static SEQUENCE_ABC : PyOnceLock < Py < PyType > > = PyOnceLock :: new ( ) ;
377
-
378
- SEQUENCE_ABC . import ( py, "collections.abc" , "Sequence" )
379
- }
380
-
381
- impl PyTypeCheck for PySequence {
382
- const NAME : & ' static str = "Sequence" ;
383
- #[ cfg( feature = "experimental-inspect" ) ]
384
- const PYTHON_TYPE : & ' static str = "collections.abc.Sequence" ;
385
-
386
- #[ inline]
387
- fn type_check ( object : & Bound < ' _ , PyAny > ) -> bool {
388
- // Using `is_instance` for `collections.abc.Sequence` is slow, so provide
389
- // optimized cases for list and tuples as common well-known sequences
390
- PyList :: is_type_of ( object)
391
- || PyTuple :: is_type_of ( object)
392
- || get_sequence_abc ( object. py ( ) )
393
- . and_then ( |abc| object. is_instance ( abc) )
394
- . unwrap_or_else ( |err| {
395
- err. write_unraisable ( object. py ( ) , Some ( object) ) ;
396
- false
397
- } )
398
- }
399
- }
400
-
401
393
#[ cfg( test) ]
402
394
mod tests {
403
395
use crate :: types:: { PyAnyMethods , PyList , PySequence , PySequenceMethods , PyTuple } ;
0 commit comments