@@ -1753,11 +1753,23 @@ mod _io {
17531753 }
17541754
17551755 #[ pyclass(
1756- with( Constructor , BufferedMixin , BufferedReadable ) ,
1756+ with( Constructor , BufferedMixin , BufferedReadable , Destructor ) ,
17571757 flags( BASETYPE , HAS_DICT )
17581758 ) ]
17591759 impl BufferedReader { }
17601760
1761+ impl Destructor for BufferedReader {
1762+ fn slot_del ( zelf : & PyObject , vm : & VirtualMachine ) -> PyResult < ( ) > {
1763+ let _ = vm. call_method ( zelf, "close" , ( ) ) ;
1764+ Ok ( ( ) )
1765+ }
1766+
1767+ #[ cold]
1768+ fn del ( _zelf : & Py < Self > , _vm : & VirtualMachine ) -> PyResult < ( ) > {
1769+ unreachable ! ( "slot_del is implemented" )
1770+ }
1771+ }
1772+
17611773 impl DefaultConstructor for BufferedReader { }
17621774
17631775 #[ pyclass]
@@ -1810,11 +1822,23 @@ mod _io {
18101822 }
18111823
18121824 #[ pyclass(
1813- with( Constructor , BufferedMixin , BufferedWritable ) ,
1825+ with( Constructor , BufferedMixin , BufferedWritable , Destructor ) ,
18141826 flags( BASETYPE , HAS_DICT )
18151827 ) ]
18161828 impl BufferedWriter { }
18171829
1830+ impl Destructor for BufferedWriter {
1831+ fn slot_del ( zelf : & PyObject , vm : & VirtualMachine ) -> PyResult < ( ) > {
1832+ let _ = vm. call_method ( zelf, "close" , ( ) ) ;
1833+ Ok ( ( ) )
1834+ }
1835+
1836+ #[ cold]
1837+ fn del ( _zelf : & Py < Self > , _vm : & VirtualMachine ) -> PyResult < ( ) > {
1838+ unreachable ! ( "slot_del is implemented" )
1839+ }
1840+ }
1841+
18181842 impl DefaultConstructor for BufferedWriter { }
18191843
18201844 #[ pyattr]
@@ -1852,11 +1876,29 @@ mod _io {
18521876 }
18531877
18541878 #[ pyclass(
1855- with( Constructor , BufferedMixin , BufferedReadable , BufferedWritable ) ,
1879+ with(
1880+ Constructor ,
1881+ BufferedMixin ,
1882+ BufferedReadable ,
1883+ BufferedWritable ,
1884+ Destructor
1885+ ) ,
18561886 flags( BASETYPE , HAS_DICT )
18571887 ) ]
18581888 impl BufferedRandom { }
18591889
1890+ impl Destructor for BufferedRandom {
1891+ fn slot_del ( zelf : & PyObject , vm : & VirtualMachine ) -> PyResult < ( ) > {
1892+ let _ = vm. call_method ( zelf, "close" , ( ) ) ;
1893+ Ok ( ( ) )
1894+ }
1895+
1896+ #[ cold]
1897+ fn del ( _zelf : & Py < Self > , _vm : & VirtualMachine ) -> PyResult < ( ) > {
1898+ unreachable ! ( "slot_del is implemented" )
1899+ }
1900+ }
1901+
18601902 impl DefaultConstructor for BufferedRandom { }
18611903
18621904 #[ pyattr]
@@ -1900,7 +1942,13 @@ mod _io {
19001942 }
19011943
19021944 #[ pyclass(
1903- with( Constructor , Initializer , BufferedReadable , BufferedWritable ) ,
1945+ with(
1946+ Constructor ,
1947+ Initializer ,
1948+ BufferedReadable ,
1949+ BufferedWritable ,
1950+ Destructor
1951+ ) ,
19041952 flags( BASETYPE , HAS_DICT )
19051953 ) ]
19061954 impl BufferedRWPair {
@@ -1942,6 +1990,18 @@ mod _io {
19421990 }
19431991 }
19441992
1993+ impl Destructor for BufferedRWPair {
1994+ fn slot_del ( zelf : & PyObject , vm : & VirtualMachine ) -> PyResult < ( ) > {
1995+ let _ = vm. call_method ( zelf, "close" , ( ) ) ;
1996+ Ok ( ( ) )
1997+ }
1998+
1999+ #[ cold]
2000+ fn del ( _zelf : & Py < Self > , _vm : & VirtualMachine ) -> PyResult < ( ) > {
2001+ unreachable ! ( "slot_del is implemented" )
2002+ }
2003+ }
2004+
19452005 #[ derive( FromArgs ) ]
19462006 struct TextIOWrapperArgs {
19472007 #[ pyarg( any, default ) ]
@@ -2413,7 +2473,10 @@ mod _io {
24132473 vm. call_method ( & textio. buffer , "flush" , ( ) )
24142474 }
24152475
2416- #[ pyclass( with( Constructor , Initializer ) , flags( BASETYPE ) ) ]
2476+ #[ pyclass(
2477+ with( Constructor , Initializer , Destructor , Iterable , IterNext ) ,
2478+ flags( BASETYPE )
2479+ ) ]
24172480 impl TextIOWrapper {
24182481 #[ pymethod]
24192482 fn reconfigure ( & self , args : TextIOWrapperArgs , vm : & VirtualMachine ) -> PyResult < ( ) > {
@@ -3276,6 +3339,57 @@ mod _io {
32763339 }
32773340 }
32783341
3342+ impl Destructor for TextIOWrapper {
3343+ fn slot_del ( zelf : & PyObject , vm : & VirtualMachine ) -> PyResult < ( ) > {
3344+ let _ = vm. call_method ( zelf, "close" , ( ) ) ;
3345+ Ok ( ( ) )
3346+ }
3347+
3348+ #[ cold]
3349+ fn del ( _zelf : & Py < Self > , _vm : & VirtualMachine ) -> PyResult < ( ) > {
3350+ unreachable ! ( "slot_del is implemented" )
3351+ }
3352+ }
3353+
3354+ impl Iterable for TextIOWrapper {
3355+ fn slot_iter ( zelf : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
3356+ check_closed ( & zelf, vm) ?;
3357+ Ok ( zelf)
3358+ }
3359+
3360+ fn iter ( _zelf : PyRef < Self > , _vm : & VirtualMachine ) -> PyResult {
3361+ unreachable ! ( "slot_iter is implemented" )
3362+ }
3363+ }
3364+
3365+ impl IterNext for TextIOWrapper {
3366+ fn slot_iternext ( zelf : & PyObject , vm : & VirtualMachine ) -> PyResult < PyIterReturn > {
3367+ // Set telling = false during iteration (matches CPython behavior)
3368+ let textio_ref: PyRef < TextIOWrapper > =
3369+ zelf. downcast_ref :: < TextIOWrapper > ( ) . unwrap ( ) . to_owned ( ) ;
3370+ {
3371+ let mut textio = textio_ref. lock ( vm) ?;
3372+ textio. telling = false ;
3373+ }
3374+
3375+ let line = vm. call_method ( zelf, "readline" , ( ) ) ?;
3376+
3377+ if !line. clone ( ) . try_to_bool ( vm) ? {
3378+ // Restore telling on StopIteration
3379+ let mut textio = textio_ref. lock ( vm) ?;
3380+ textio. snapshot = None ;
3381+ textio. telling = textio. seekable ;
3382+ Ok ( PyIterReturn :: StopIteration ( None ) )
3383+ } else {
3384+ Ok ( PyIterReturn :: Return ( line) )
3385+ }
3386+ }
3387+
3388+ fn next ( _zelf : & Py < Self > , _vm : & VirtualMachine ) -> PyResult < PyIterReturn > {
3389+ unreachable ! ( "slot_iternext is implemented" )
3390+ }
3391+ }
3392+
32793393 #[ pyattr]
32803394 #[ pyclass( name) ]
32813395 #[ derive( Debug , PyPayload , Default ) ]
@@ -4166,14 +4280,15 @@ mod _io {
41664280mod fileio {
41674281 use super :: { _io:: * , Offset } ;
41684282 use crate :: {
4169- AsObject , Py , PyObjectRef , PyPayload , PyRef , PyResult , TryFromObject , VirtualMachine ,
4283+ AsObject , Py , PyObject , PyObjectRef , PyPayload , PyRef , PyResult , TryFromObject ,
4284+ VirtualMachine ,
41704285 builtins:: { PyBaseExceptionRef , PyUtf8Str , PyUtf8StrRef } ,
41714286 common:: crt_fd,
41724287 convert:: { IntoPyException , ToPyException } ,
41734288 function:: { ArgBytesLike , ArgMemoryBuffer , OptionalArg , OptionalOption } ,
41744289 ospath:: { IOErrorBuilder , OsPath , OsPathOrFd } ,
41754290 stdlib:: os,
4176- types:: { Constructor , DefaultConstructor , Initializer , Representable } ,
4291+ types:: { Constructor , DefaultConstructor , Destructor , Initializer , Representable } ,
41774292 } ;
41784293 use crossbeam_utils:: atomic:: AtomicCell ;
41794294 use std:: io:: { Read , Write } ;
@@ -4433,7 +4548,7 @@ mod fileio {
44334548 }
44344549
44354550 #[ pyclass(
4436- with( Constructor , Initializer , Representable ) ,
4551+ with( Constructor , Initializer , Representable , Destructor ) ,
44374552 flags( BASETYPE , HAS_DICT )
44384553 ) ]
44394554 impl FileIO {
@@ -4649,4 +4764,16 @@ mod fileio {
46494764 Err ( vm. new_type_error ( format ! ( "cannot pickle '{}' object" , zelf. class( ) . name( ) ) ) )
46504765 }
46514766 }
4767+
4768+ impl Destructor for FileIO {
4769+ fn slot_del ( zelf : & PyObject , vm : & VirtualMachine ) -> PyResult < ( ) > {
4770+ let _ = vm. call_method ( zelf, "close" , ( ) ) ;
4771+ Ok ( ( ) )
4772+ }
4773+
4774+ #[ cold]
4775+ fn del ( _zelf : & Py < Self > , _vm : & VirtualMachine ) -> PyResult < ( ) > {
4776+ unreachable ! ( "slot_del is implemented" )
4777+ }
4778+ }
46524779}
0 commit comments