1import contextlib 2import os.path 3 4 5def resolve(source, filename): 6 if _looks_like_filename(source): 7 return _resolve_filename(source, filename) 8 9 if isinstance(source, str): 10 source = source.splitlines() 11 12 # At this point "source" is not a str. 13 if not filename: 14 filename = None 15 elif not isinstance(filename, str): 16 raise TypeError(f'filename should be str (or None), got {filename!r}') 17 else: 18 filename, _ = _resolve_filename(filename) 19 return source, filename 20 21 22@contextlib.contextmanager 23def good_file(filename, alt=None): 24 if not _looks_like_filename(filename): 25 raise ValueError(f'expected a filename, got {filename}') 26 filename, _ = _resolve_filename(filename, alt) 27 try: 28 yield filename 29 except Exception: 30 if not os.path.exists(filename): 31 raise FileNotFoundError(f'file not found: {filename}') 32 raise # re-raise 33 34 35def _looks_like_filename(value): 36 if not isinstance(value, str): 37 return False 38 return value.endswith(('.c', '.h')) 39 40 41def _resolve_filename(filename, alt=None): 42 if os.path.isabs(filename): 43 ... 44# raise NotImplementedError 45 else: 46 filename = os.path.join('.', filename) 47 48 if not alt: 49 alt = filename 50 elif os.path.abspath(filename) == os.path.abspath(alt): 51 alt = filename 52 else: 53 raise ValueError(f'mismatch: {filename} != {alt}') 54 return filename, alt 55 56 57@contextlib.contextmanager 58def opened(source, filename=None): 59 source, filename = resolve(source, filename) 60 if isinstance(source, str): 61 with open(source) as srcfile: 62 yield srcfile, filename 63 else: 64 yield source, filename 65