| 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 |