Source code for clize.converters

# clize -- A command-line argument parser for Python
# Copyright (C) 2011-2016 by Yann Kaiser and contributors. See AUTHORS and
# COPYING for details.

import sys
import io
import os
from functools import partial

from clize import parser, errors


@parser.value_converter(name='TIME')
[docs]def datetime(arg): """Parses a date into a `datetime` value Requires ``dateutil`` to be installed. """ from dateutil import parser as dparser return dparser.parse(arg)
class _FileOpener(object): def __init__(self, arg, kwargs, stdio, keep_stdio_open): self.arg = arg self.kwargs = kwargs self.stdio = stdio self.keep_stdio_open = keep_stdio_open self.validate_permissions() def validate_permissions(self): mode = self.kwargs.get('mode', 'r') if self.arg == self.stdio: return exists = os.access(self.arg, os.F_OK) if not exists: if 'r' in mode and '+' not in mode: raise errors.CliValueError( 'File does not exist: {0!r}'.format(self.arg)) else: dirname = os.path.dirname(self.arg) if not dirname or os.access(dirname, os.W_OK): return if not os.path.exists(dirname): raise errors.CliValueError( 'Directory does not exist: {0!r}'.format(self.arg)) elif os.access(self.arg, os.W_OK): return raise errors.CliValueError( 'Permission denied: {0!r}'.format(self.arg)) def __enter__(self): if self.arg == self.stdio: mode = self.kwargs.get('mode', 'r') self.f = sys.stdin if 'r' in mode else sys.stdout else: try: self.f = io.open(self.arg, **self.kwargs) except IOError as exc: raise _convert_ioerror(self.arg, exc) return self.f def __exit__(self, *exc_info): if self.arg != self.stdio or not self.keep_stdio_open: self.f.close()
[docs]def file(stdio='-', keep_stdio_open=False, **kwargs): """Takes a file argument and provides a Python object that opens a file :: def main(in_: file(), out: file(mode='w')): with in_ as infile, out as outfile: outfile.write(infile.read()) :param stdio: If this value is passed as argument, it will be interpreted as *stdin* or *stdout* depending on the ``mode`` parameter supplied. :param keep_stdio_open: If true, does not close the file if it is *stdin* or *stdout*. Other arguments will be relayed to `io.open`. """ return parser.value_converter( partial(_FileOpener, kwargs=kwargs, stdio=stdio, keep_stdio_open=keep_stdio_open), name='FILE')
def _convert_ioerror(arg, exc): nexc = errors.ArgumentError('{0.strerror}: {1!r}'.format(exc, arg)) nexc.__cause__ = exc return nexc