@@ -9,11 +9,8 @@ use crate::internal_tricks::get_ssize_index;
99use crate :: py_result_ext:: PyResultExt ;
1010use crate :: sync:: PyOnceLock ;
1111use 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 } ;
1714
1815/// Represents a reference to a Python object supporting the sequence protocol.
1916///
@@ -24,15 +21,44 @@ use crate::{
2421/// [`Bound<'py, PySequence>`][Bound].
2522#[ repr( transparent) ]
2623pub struct PySequence ( PyAny ) ;
24+
2725pyobject_native_type_named ! ( PySequence ) ;
2826
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+
2955impl PySequence {
3056 /// Register a pyclass as a subclass of `collections.abc.Sequence` (from the Python standard
3157 /// library). This is equivalent to `collections.abc.Sequence.register(T)` in Python.
3258 /// This registration is required for a pyclass to be castable from `PyAny` to `PySequence`.
3359 pub fn register < T : PyTypeInfo > ( py : Python < ' _ > ) -> PyResult < ( ) > {
3460 let ty = T :: type_object ( py) ;
35- get_sequence_abc ( py) ? . call_method1 ( "register" , ( ty, ) ) ?;
61+ Self :: type_object ( py) . call_method1 ( "register" , ( ty, ) ) ?;
3662 Ok ( ( ) )
3763 }
3864}
@@ -372,32 +398,6 @@ where
372398 Ok ( v)
373399}
374400
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-
401401#[ cfg( test) ]
402402mod tests {
403403 use crate :: types:: { PyAnyMethods , PyList , PySequence , PySequenceMethods , PyTuple } ;
0 commit comments