GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — _pyio buffered classes raise AttributeError after detach() instead of ValueError · Issue #160472 · python/cpython

_pyio buffered classes raise AttributeError after detach() instead of ValueError #160472

New issue
Copy link
New issue
Copy link
Closed as duplicate
Closed as duplicate
_pyio buffered classes raise AttributeError after detach() instead of ValueError#160472
Copy link

Description

@scrieve
scrieve
opened on Oct 23, 2026
Issue body actions

Bug description

After detach(), the pure-Python buffered classes in _pyio raise AttributeError
from the None raw stream, where the C implementations raise ValueError. The two
implementations therefore disagree on the kind of error, not just the wording.

import io, _pyio

for mod in (io, _pyio):
    b = mod.BufferedReader(mod.BytesIO(b"abcdef"))
    b.detach()
    for op, args in [("read", (1,)), ("seek", (0,)), ("truncate", ()), ("flush", ())]:
        try:
            getattr(b, op)(*args)
            result = "no error"
        except Exception as exc:
            result = type(exc).__name__
        print(mod.__name__, op, "->", result)
io read -> ValueError
io seek -> ValueError
io truncate -> ValueError
io flush -> ValueError
_pyio read -> AttributeError
_pyio seek -> AttributeError
_pyio truncate -> AttributeError
_pyio flush -> AttributeError

Same shape for _pyio.BufferedWriter (write, flush, seek, tell),
_pyio.BufferedRandom and _pyio.TextIOWrapper.tell().

Cause

In Lib/_pyio.py, BufferedReader.detach() does

def detach(self):
    if self.raw is None:
        raise ValueError("raw stream already detached")
    self.flush()
    raw = self._raw
    self._raw = None
    return raw

so the class already knows the detached state, but only detach() itself checks
it. Every other method reaches self.raw and fails on the None, producing
AttributeError: 'NoneType' object has no attribute '...'.

Expected behaviour

ValueError, matching the C implementation and matching the documented state of
the object ("After the raw stream has been detached, the buffer is in an unusable
state"). The check C performs is the CHECK_ATTACHED macro in
Modules/_io/bufferedio.c.

Why it matters beyond error text

test_io runs the same test classes against both implementations (C and
Py variants in Lib/test/test_io/), so any test that asserts ValueError for a
detached operation cannot be shared today. A _checkDetached() helper next to the
existing _checkClosed() would let those tests be written once.

Scope

I have not opened a patch, following the guidance in #160467 that the expected
behaviour should be agreed on the issue first. If the ValueError above is the
direction a triager wants, I can prepare the fix plus a test in test_textio.py
and test_bufferedio.py that runs against both implementations.

Found by differential testing _io against _pyio over random operation
sequences.

CPython versions tested on

CPython main branch (3.16.0a1+)

Operating systems tested on

Linux

Activity

  1. cmaloney commented on Oct 23, 2026

    @cmaloney
    cmaloney
    on Oct 23, 2026
    Contributor
    More actions

    Please read through https://devguide.python.org/getting-started/ai-tools/ in particular the "Considerations for success" section.

    I'm going to close this as a duplicate of gh-160467. Both _pyio and _io should have matching behavior (so a fix in one should happen in both).

    In general _pyio is not at parity at the moment, I've actually requested permission to remove it python/steering-council#372.

  2. cmaloney
    closed this as a duplicateof hasattr(stream, "buffer") fails with ValueError if buffer is detached #160427 on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.