• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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