RustPython/RustPython · error · ValueError
argument "-" with mode %r
Error message
argument "-" with mode %r
What it means
FileType maps the special filename '-' to a standard stream: stdin when the mode contains 'r', stdout when it contains 'w', 'a', or 'x'. If the mode contains none of these characters, no stream can be selected, and __call__ raises this ValueError when '-' is passed on the command line for that argument.
Source
Thrown at Lib/argparse.py:1376
"FileType is deprecated. Simply open files after parsing arguments.",
category=PendingDeprecationWarning,
stacklevel=2
)
self._mode = mode
self._bufsize = bufsize
self._encoding = encoding
self._errors = errors
def __call__(self, string):
# the special argument "-" means sys.std{in,out}
if string == '-':
if 'r' in self._mode:
return _sys.stdin.buffer if 'b' in self._mode else _sys.stdin
elif any(c in self._mode for c in 'wax'):
return _sys.stdout.buffer if 'b' in self._mode else _sys.stdout
else:
msg = _('argument "-" with mode %r') % self._mode
raise ValueError(msg)
# all other arguments are used as file names
try:
return open(string, self._mode, self._bufsize, self._encoding,
self._errors)
except OSError as e:
args = {'filename': string, 'error': e}
message = _("can't open '%(filename)s': %(error)s")
raise ArgumentTypeError(message % args)
def __repr__(self):
args = self._mode, self._bufsize
kwargs = [('encoding', self._encoding), ('errors', self._errors)]
args_str = ', '.join([repr(arg) for arg in args if arg != -1] +
['%s=%r' % (kw, arg) for kw, arg in kwargs
if arg is not None])
return '%s(%s)' % (type(self).__name__, args_str)
View on GitHub (pinned to aaeab4f754)
Solutions
- Fix the mode to include a direction character, e.g. 'rb', 'wb', or 'ab'.
- If the standard-stream shortcut is not wanted for this argument, reject '-' explicitly with a custom type function instead of FileType.
Example fix
# before
parser.add_argument('--log', type=argparse.FileType('b'))
# after
parser.add_argument('--log', type=argparse.FileType('ab')) Defensive patterns
Strategy: validation
Validate before calling
def make_file_type(mode, bufsize=-1, encoding=None, errors=None):
if 'r' not in mode and not any(c in mode for c in 'wax'):
raise ValueError('mode cannot map dash to a standard stream: ' + repr(mode))
return argparse.FileType(mode, bufsize, encoding, errors) Type guard
def supports_dash(mode: str) -> bool:
return 'r' in mode or any(c in mode for c in 'wax') Prevention
- Define mode strings as named constants ('rb', 'wb') instead of building them dynamically.
- Add a unit test that parses '-' for every FileType argument in the CLI.
When it happens
Trigger: argparse.FileType(mode) where the mode has no r/w/a/x — e.g. type=argparse.FileType('b') or an empty mode — combined with the user passing '-'.
Common situations: Mode strings assembled from flags or configuration where the direction letter got dropped; passing a file extension or bare binary flag where a mode string is expected.
Related errors
- File or stream is not writable.
- invalid nargs value
- invalid option name {option_string!r} for BooleanOptionalAct
- nargs for store actions must be != 0; if you have nothing to
- nargs must be %r to supply const
AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17).
Data as JSON: /api/errors/02a1bc8e524851ec.
Report an issue: GitHub.