[stdlib-sig] argparse PathType class -- validate file/directory paths without opening them
Dan Lenski
dlenski at gmail.com
Sat Jul 25 00:12:31 CEST 2015
Dan Lenski <dlenski at gmail.com> writes:
> To support this case, I wrote the following PathType class, which
> will validate the suitability of a path for the specified usage
> (e.g. directory that exists, file that doesn't exist, etc.) before
> returning it unchanged.
>
> Would this be useful for inclusion in the standard library? Any
comments
> on style, parameter-naming, etc?
I received a couple suggestions in terms of normalizing the path with
os.path.normpath (I've made it automatic) and changing it to an absolute
path (optional).
Thanks,
Dan Lenski
# patharg.py
class PathType(object):
def __init__(self, exists=True, type='file', dash_ok=True,
abs=False):
'''exists:
True: a path that does exist
False: a path that does not exist, in a valid parent
directory
None: don't care, in a valid parent directory
type: file, dir, symlink, None, or a function returning True
for valid paths
None: don't care
dash_ok: whether to allow - as stdin/stdout
abs: if True, path will be coerced to an absolute path'''
assert exists in (True, False, None)
assert type in ('file','dir','symlink',None) or
hasattr(type,'__call__')
self._exists = exists
self._type = type
self._dash_ok = dash_ok
def __call__(self, string):
if string=='-':
# the special argument "-" means sys.std{in,out}
if self._type == 'dir':
raise ArgumentTypeError('standard input/output (-) not
allowed as directory path')
elif self._type == 'symlink':
raise ArgumentTypeError('standard input/output (-) not
allowed as symlink path')
elif not self._dash_ok:
raise ArgumentTypeError('standard input/output (-) not
allowed')
else:
np = os.path.abspath(string) if abs else
os.path.normpath(string)
e = os.path.exists(np)
if self._exists==True:
if not e:
raise ArgumentTypeError("path does not exist: '%s'"
% np)
if self._type is None:
pass
elif self._type=='file':
if not os.path.isfile(np):
raise ArgumentTypeError("path is not a file:
'%s'" % np)
elif self._type=='symlink':
if not os.path.symlink(np):
raise ArgumentTypeError("path is not a symlink:
'%s'" % np)
elif self._type=='dir':
if not os.path.isdir(np):
raise ArgumentTypeError("path is not a
directory: '%s'" % np)
elif not self._type(np):
raise ArgumentTypeError("path not valid: '%s'" % np)
else:
if self._exists==False and e:
raise ArgumentTypeError("path exists: '%s'" % np)
p = os.path.dirname(os.path.normpath(np)) or '.'
if not os.path.isdir(p):
raise ArgumentTypeError("parent path is not a
directory: '%s'" % p)
elif not os.path.exists(p):
raise ArgumentTypeError("parent directory does not
exist: '%s'" % p)
return np
More information about the stdlib-sig
mailing list