Thanks to visit codestin.com
Credit goes to github.com

Skip to content

io.StringIO constructor info is misleading #95880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mark-summerfield opened this issue Aug 11, 2022 · 6 comments
Closed

io.StringIO constructor info is misleading #95880

mark-summerfield opened this issue Aug 11, 2022 · 6 comments
Assignees
Labels
docs Documentation in the Doc dir

Comments

@mark-summerfield
Copy link
Contributor

The io.StringIO constructor says:

The initial value of the buffer can be set by providing initial_value.

I suggest changing this to:

The initial value of the buffer can be set by providing initial_value.
Note that if the buffer is written to, the character(s) written will overwrite part or all of any initial_value.

I tried to do this change in the source but the source docs didn't seem to match up with the text shown on docs.python.org, hence this report.

@mark-summerfield mark-summerfield added the docs Documentation in the Doc dir label Aug 11, 2022
@ghost
Copy link

ghost commented Aug 11, 2022

I work on this issue^^

@iforapsy
Copy link

A more accurate way to phrase it would be to say that the StringIO position always starts from 0, even with an initial value string. One way to fix this is to seek the stream to the end manually.

import io

str_io = io.StringIO('foo bar')
str_io.seek(0, io.SEEK_END)  # seek to end

# Now writes to the stream append instead of overwrite existing characters
str_io.write(' baz')
assert str_io.getvalue() == 'foo bar baz'

@mark-summerfield
Copy link
Contributor Author

In that case I suggest changing the docs to:

The initial value of the buffer can be set by providing _initial_value_.
Writing to the buffer starts at position 0 (even if there's an _initial_value_), so to start with some content and add more do this:

    import io
    out = io.StringIO('Start text')
    out.seek(0, io.SEEK_END) # move from position 0 to the end
    out.write(' and end text')
    assert out.getvalue() == 'Start text and end text'

@rhettinger
Copy link
Contributor

rhettinger commented Aug 13, 2022

I'll submit a separate PR for this. The text already says, "The stream is positioned at the start of the buffer." The covers the essential technical fact about how it works.

The example is needs to remain as it now because it covers the common case. We could add a separate example, but I'm not sure we want to steer people down that path. In a code review, if I saw this:

f = io.StringIO('first line\n')
f.seek(0, io.SEEK_END)
f.write('second line\n')
print(f.getvalue())

I would suggest that it be simplified to:

f = io.StringIO()
f.write('first line\n')
f.write('second line\n')
print(f.getvalue())

AFAICT, the first way is almost always the wrong way to do it with the IO module. Also, the first way doesn't emulate how we would work with regular files (which is the overall goal of the module).

Mark's first suggestion, "Note that if the buffer is written to, the character(s) written will overwrite part or all of any initial_value", was a nice minimal edit. If added, that should go after the line, "The stream is positioned at the start of the buffer." Ideally, it should be reworded in a affirmative tone rather than a cautionary note:

The stream is positioned at the start of the buffer. This emulates opening an existing file in a w+ mode, making it ready for an immediate write from the beginning or for a write that would overwrite the initial value. To emulate opening a file in an a+ mode ready for appending, use f.seek(0, io.SEEK_END) to reposition the stream at the end of the buffer.

@ghost
Copy link

ghost commented Aug 13, 2022

@rhettinger Can I submit another PR? I provide better context.

@rhettinger
Copy link
Contributor

@najmiehsa I don't think that would be helpful. Let's just do a discussion here and I'll finish it off. I would like to hear what Mark thinks and whether he has further suggestions. The best way to help at this point is to think through the proposed wording and make suggestions. There isn't much of a value add to copying what we're saying here into a PR, that is the least interesting part of the process and it makes it a little more time consuming for the reviewer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir
Projects
None yet
Development

No branches or pull requests

3 participants