RustPython/RustPython · error · ValueError
binary mode doesn't take a newline argument
Error message
binary mode doesn't take a newline argument
What it means
ValueError raised when newline is passed together with a binary mode. newline controls line-ending translation ('\n' vs os.linesep), which is a text-layer concept; binary streams must see bytes exactly as they are. Notably the common csv recipe open(path, 'w', newline='') is text-mode and legal - the error only appears when 'b' is combined with a non-None newline.
Source
Thrown at Lib/_pyio.py:227
creating = "x" in modes
reading = "r" in modes
writing = "w" in modes
appending = "a" in modes
updating = "+" in modes
text = "t" in modes
binary = "b" in modes
if text and binary:
raise ValueError("can't have text and binary mode at once")
if creating + reading + writing + appending > 1:
raise ValueError("can't have read/write/append mode at once")
if not (creating or reading or writing or appending):
raise ValueError("must have exactly one of read/write/append mode")
if binary and encoding is not None:
raise ValueError("binary mode doesn't take an encoding argument")
if binary and errors is not None:
raise ValueError("binary mode doesn't take an errors argument")
if binary and newline is not None:
raise ValueError("binary mode doesn't take a newline argument")
if binary and buffering == 1:
import warnings
warnings.warn("line buffering (buffering=1) isn't supported in binary "
"mode, the default buffer size will be used",
RuntimeWarning, 2)
raw = FileIO(file,
(creating and "x" or "") +
(reading and "r" or "") +
(writing and "w" or "") +
(appending and "a" or "") +
(updating and "+" or ""),
closefd, opener=opener)
result = raw
try:
line_buffering = False
if buffering == 1 or buffering < 0 and raw._isatty_open_only():
buffering = -1
line_buffering = TrueView on GitHub (pinned to aaeab4f754)
Solutions
- Remove newline from binary opens
- Keep newline='' only with text modes: open(path, 'w', newline='', encoding='utf-8')
- Strip text-only keys from shared kwargs when 'b' in mode
Example fix
# before
with open(path, 'wb', newline='') as f:
writer = csv.writer(f) # binary + newline -> ValueError
# after
with open(path, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f) Defensive patterns
Strategy: validation
Validate before calling
def open_any(path, mode='r', newline=None):
kwargs = {} if 'b' in mode else ({'newline': newline} if newline is not None else {})
return open(path, mode, **kwargs) Type guard
def takes_text_kwargs(mode) -> bool:
return 'b' not in mode Prevention
- newline='' belongs to text-mode csv usage only
- When flipping 'w' to 'wb', remove newline from the same call
- Keep per-call-site kwargs instead of one global open-kwargs dict
When it happens
Trigger: open(path, 'wb', newline='') copied from the csv.writer recipe after switching to binary; wrappers that always pass newline='' to avoid universal-newline surprises; a commit that flipped 'w' to 'wb' while leaving newline in place.
Common situations: CSV/text exporters migrated to binary formats; a shared open-kwargs dict reused across text and binary paths; documentation examples adapted incompletely.
Related errors
- binary mode doesn't take an encoding argument
- binary mode doesn't take an errors argument
- can't have text and binary mode at once
- can't have read/write/append mode at once
- must have exactly one of read/write/append mode
AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17).
Data as JSON: /api/errors/e299119551b731f7.
Report an issue: GitHub.