@@ -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,44 @@ use crate::{
24
21
/// [`Bound<'py, PySequence>`][Bound].
25
22
#[ repr( transparent) ]
26
23
pub struct PySequence ( PyAny ) ;
24
+
27
25
pyobject_native_type_named ! ( PySequence ) ;
28
26
27
+ unsafe impl PyTypeInfo for PySequence {
28
+ const NAME : & ' static str = "Sequence" ;
29
+ const MODULE : Option < & ' static str > = Some ( "collections.abc" ) ;
30
+
31
+ #[ inline]
32
+ #[ allow( clippy:: redundant_closure_call) ]
33
+ fn type_object_raw ( py : Python < ' _ > ) -> * mut ffi:: PyTypeObject {
34
+ static TYPE : PyOnceLock < Py < PyType > > = PyOnceLock :: new ( ) ;
35
+ TYPE . import ( py, "collections.abc" , "Sequence" )
36
+ . unwrap ( )
37
+ . as_type_ptr ( )
38
+ }
39
+
40
+ #[ inline]
41
+ fn is_type_of ( object : & Bound < ' _ , PyAny > ) -> bool {
42
+ // Using `is_instance` for `collections.abc.Sequence` is slow, so provide
43
+ // optimized cases for list and tuples as common well-known sequences
44
+ PyList :: is_type_of ( object)
45
+ || PyTuple :: is_type_of ( object)
46
+ || object
47
+ . is_instance ( & Self :: type_object ( object. py ( ) ) . into_any ( ) )
48
+ . unwrap_or_else ( |err| {
49
+ err. write_unraisable ( object. py ( ) , Some ( object) ) ;
50
+ false
51
+ } )
52
+ }
53
+ }
54
+
29
55
impl PySequence {
30
56
/// Register a pyclass as a subclass of `collections.abc.Sequence` (from the Python standard
31
57
/// library). This is equivalent to `collections.abc.Sequence.register(T)` in Python.
32
58
/// This registration is required for a pyclass to be castable from `PyAny` to `PySequence`.
33
59
pub fn register < T : PyTypeInfo > ( py : Python < ' _ > ) -> PyResult < ( ) > {
34
60
let ty = T :: type_object ( py) ;
35
- get_sequence_abc ( py) ? . call_method1 ( "register" , ( ty, ) ) ?;
61
+ Self :: type_object ( py) . call_method1 ( "register" , ( ty, ) ) ?;
36
62
Ok ( ( ) )
37
63
}
38
64
}
@@ -372,32 +398,6 @@ where
372
398
Ok ( v)
373
399
}
374
400
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
401
#[ cfg( test) ]
402
402
mod tests {
403
403
use crate :: types:: { PyAnyMethods , PyList , PySequence , PySequenceMethods , PyTuple } ;
0 commit comments