65 lines
1.7 KiB
Python
65 lines
1.7 KiB
Python
import contextlib
|
|
import os.path
|
|
|
|
|
|
def resolve(source, filename):
|
|
if _looks_like_filename(source):
|
|
return _resolve_filename(source, filename)
|
|
|
|
if isinstance(source, str):
|
|
source = source.splitlines()
|
|
|
|
# At this point "source" is not a str.
|
|
if not filename:
|
|
filename = None
|
|
elif not isinstance(filename, str):
|
|
raise TypeError(f'filename should be str (or None), got {filename!r}')
|
|
else:
|
|
filename, _ = _resolve_filename(filename)
|
|
return source, filename
|
|
|
|
|
|
@contextlib.contextmanager
|
|
def good_file(filename, alt=None):
|
|
if not _looks_like_filename(filename):
|
|
raise ValueError(f'expected a filename, got {filename}')
|
|
filename, _ = _resolve_filename(filename, alt)
|
|
try:
|
|
yield filename
|
|
except Exception:
|
|
if not os.path.exists(filename):
|
|
raise FileNotFoundError(f'file not found: {filename}')
|
|
raise # re-raise
|
|
|
|
|
|
def _looks_like_filename(value):
|
|
if not isinstance(value, str):
|
|
return False
|
|
return value.endswith(('.c', '.h'))
|
|
|
|
|
|
def _resolve_filename(filename, alt=None):
|
|
if os.path.isabs(filename):
|
|
...
|
|
# raise NotImplementedError
|
|
else:
|
|
filename = os.path.join('.', filename)
|
|
|
|
if not alt:
|
|
alt = filename
|
|
elif os.path.abspath(filename) == os.path.abspath(alt):
|
|
alt = filename
|
|
else:
|
|
raise ValueError(f'mismatch: {filename} != {alt}')
|
|
return filename, alt
|
|
|
|
|
|
@contextlib.contextmanager
|
|
def opened(source, filename=None):
|
|
source, filename = resolve(source, filename)
|
|
if isinstance(source, str):
|
|
with open(source) as srcfile:
|
|
yield srcfile, filename
|
|
else:
|
|
yield source, filename
|