Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions Lib/test/test_memoryio.py
Original file line number Diff line number Diff line change
Expand Up @@ -1026,10 +1026,6 @@ def test_relative_seek(self):
def test_flags(self):
return super().test_flags()

@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: 'StringIO' object has no attribute 'detach'
def test_detach(self):
return super().test_detach()

@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: 'StringIO' object has no attribute 'newlines'. Did you mean: 'readlines'?
def test_newlines_property(self):
return super().test_newlines_property()
Expand Down
5 changes: 2 additions & 3 deletions Lib/test/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ def clear_typing_caches():

class TypesTests(unittest.TestCase):

@unittest.skipUnless(c_types, "TODO: RUSTPYTHON; requires _types module")
def test_names(self):
c_only_names = {'CapsuleType'}
ignored = {'new_class', 'resolve_bases', 'prepare_class',
Expand Down Expand Up @@ -636,7 +635,7 @@ def test_slot_wrapper_types(self):
self.assertIsInstance(object.__lt__, types.WrapperDescriptorType)
self.assertIsInstance(int.__lt__, types.WrapperDescriptorType)

@unittest.expectedFailure # TODO: RUSTPYTHON; No signature found in builtin method __get__ of 'method_descriptor' objects.
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: no signature found for builtin <method-wrapper '__get__' of wrapper_descriptor object
@unittest.skipIf(MISSING_C_DOCSTRINGS,
"Signature information for builtins requires docstrings")
def test_dunder_get_signature(self):
Expand All @@ -661,7 +660,7 @@ def test_method_descriptor_types(self):
self.assertIsInstance(int.from_bytes, types.BuiltinMethodType)
self.assertIsInstance(int.__new__, types.BuiltinMethodType)

@unittest.expectedFailure # TODO: RUSTPYTHON; ModuleNotFoundError: No module named '_queue'
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: descriptor 'read' needs a type, not 'StringIO', as arg 2
def test_method_descriptor_crash(self):
# gh-132747: The default __get__() implementation in C was unable
# to handle a second argument of None when called from Python
Expand Down
30 changes: 30 additions & 0 deletions crates/vm/src/stdlib/_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -789,11 +789,41 @@ mod _io {

#[pyclass(flags(BASETYPE, HAS_WEAKREF))]
impl _TextIOBase {
#[pymethod]
fn read(zelf: PyObjectRef, _size: OptionalArg, vm: &VirtualMachine) -> PyResult {
_unsupported(vm, &zelf, "read")
}

#[pymethod]
fn write(zelf: PyObjectRef, _b: PyObjectRef, vm: &VirtualMachine) -> PyResult {
_unsupported(vm, &zelf, "write")
}

#[pymethod]
fn truncate(zelf: PyObjectRef, _pos: OptionalArg, vm: &VirtualMachine) -> PyResult {
_unsupported(vm, &zelf, "truncate")
}

#[pymethod]
fn readline(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult {
_unsupported(vm, &zelf, "readline")
}
Comment on lines +807 to +810

@coderabbitai coderabbitai Bot Jun 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

_TextIOBase.readline is missing the optional size argument

At Line 808, this method currently accepts no size parameter, which changes Python-call behavior (readline(1) can fail with TypeError instead of UnsupportedOperation). Keep the signature compatible and ignore the arg in the stub.

Proposed fix
-        fn readline(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult {
+        fn readline(zelf: PyObjectRef, _size: OptionalArg, vm: &VirtualMachine) -> PyResult {
             _unsupported(vm, &zelf, "readline")
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/vm/src/stdlib/_io.rs` around lines 807 - 810, The readline method in
_TextIOBase is missing an optional size parameter in its signature. Update the
readline method to accept an optional size argument (which can be of type i32 or
similar numeric type with a default value) while keeping the implementation
unchanged. This ensures that calls like readline(1) will properly pass the
argument to the method rather than causing a TypeError, allowing the
_unsupported call to handle it with the correct UnsupportedOperation error.

@ShaharNaveh ShaharNaveh Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might not be intentional, I've asked at python/cpython#151596

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ShaharNaveh, interesting find! The CPython issue confirms this is an upstream inconsistency. That said, applying the fix proactively in RustPython is still worthwhile — it costs nothing (the arg is just ignored) and future-proofs the implementation against code that passes a size argument. If CPython eventually fixes #151596, RustPython will already be aligned.

(ᵔᴥᵔ)


✏️ Learnings added
Learnt from: ShaharNaveh
Repo: RustPython/RustPython PR: 8126
File: crates/vm/src/stdlib/_io.rs:807-810
Timestamp: 2026-06-17T10:32:36.012Z
Learning: In `crates/vm/src/stdlib/_io.rs`, `_TextIOBase.readline` in both CPython and RustPython is missing the optional `size` parameter. CPython tracks this as a bug in https://github.com/python/cpython/issues/151596. The fix is to add `_size: OptionalArg` to the stub signature while keeping the `_unsupported` implementation unchanged.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


#[pymethod]
fn detach(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult {
_unsupported(vm, &zelf, "detach")
}

#[pygetset]
fn encoding(_zelf: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
vm.ctx.none()
}

#[pygetset]
fn newlines(_zelf: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
vm.ctx.none()
}

#[pygetset]
fn errors(_zelf: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
vm.ctx.none()
Expand Down
Loading