Skip to content

Instantly share code, notes, and snippets.

@wecsam
Created December 3, 2018 01:29
Show Gist options
  • Save wecsam/7d60a4afe11a7cee8348834711fb619f to your computer and use it in GitHub Desktop.
Save wecsam/7d60a4afe11a7cee8348834711fb619f to your computer and use it in GitHub Desktop.
This class is like argparse.FileType, except that it supports all keyword arguments for open() and returns a function that opens a handle rather than returning the handle itself.
#!/usr/bin/env python3
import argparse, gettext, sys
class FileType(argparse.FileType):
'''
This class is just like argparse.FileType, except that it supports all
keyword arguments for open() and returns a function that opens a handle
rather than returning the handle itself. This means that the file is not
actually opened until that function is called. This also means that the
result can be used with a "with" block.
Example:
parser = argparse.ArgumentParser()
parser.add_argument(
"--out-file",
type=filetype.FileType("w", newline="", encoding="UTF-8")
)
arguments = parser.parse_args(["--out-file=test.txt"])
# The file test.txt is opened in the next function call below.
with arguments.out_file() as f:
f.write("Hello!\n")
# At the end of the block, the file is closed.
See: https://bugs.python.org/issue24739
'''
def __init__(self, mode="r", **kwargs):
self._mode = mode
self._open_kwargs = kwargs
def __call__(self, string):
if string == "-":
if "r" in self._mode:
return lambda: sys.stdin
if "w" in self._mode:
return lambda: sys.stdout
raise ValueError(
gettext.gettext('argument "-" with mode %r') % self._mode
)
return lambda: open(string, self._mode, **self._open_kwargs)
def __repr__(self):
return "%s(%s)" % (
type(self).__name__,
", ".join(
[self._mode] +
[
"%s=%r" % kwarg
for kwarg in self._open_kwargs.items()
]
)
)
@property
def _bufsize(self):
return self._open_kwargs.get("bufsize", -1)
@_bufsize.setter
def _bufsize_setter(self, value):
self._open_kwargs["bufsize"] = value
@property
def _encoding(self):
return self._open_kwargs.get("encoding")
@_encoding.setter
def _encoding_setter(self, value):
self._open_kwargs["encoding"] = value
@property
def _errors(self):
return self._open_kwargs.get("errors")
@_errors.setter
def _errors_setter(self, value):
self._open_kwargs["errors"] = value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment