An immutable object holding a source code fragment. When using Source(...), the source lines are deindented.
| 15 | |
| 16 | |
| 17 | class Source: |
| 18 | """An immutable object holding a source code fragment. |
| 19 | |
| 20 | When using Source(...), the source lines are deindented. |
| 21 | """ |
| 22 | |
| 23 | def __init__(self, obj: object = None) -> None: |
| 24 | if not obj: |
| 25 | self.lines: List[str] = [] |
| 26 | elif isinstance(obj, Source): |
| 27 | self.lines = obj.lines |
| 28 | elif isinstance(obj, (tuple, list)): |
| 29 | self.lines = deindent(x.rstrip("\n") for x in obj) |
| 30 | elif isinstance(obj, str): |
| 31 | self.lines = deindent(obj.split("\n")) |
| 32 | else: |
| 33 | try: |
| 34 | rawcode = getrawcode(obj) |
| 35 | src = inspect.getsource(rawcode) |
| 36 | except TypeError: |
| 37 | src = inspect.getsource(obj) # type: ignore[arg-type] |
| 38 | self.lines = deindent(src.split("\n")) |
| 39 | |
| 40 | def __eq__(self, other: object) -> bool: |
| 41 | if not isinstance(other, Source): |
| 42 | return NotImplemented |
| 43 | return self.lines == other.lines |
| 44 | |
| 45 | # Ignore type because of https://github.com/python/mypy/issues/4266. |
| 46 | __hash__ = None # type: ignore |
| 47 | |
| 48 | @overload |
| 49 | def __getitem__(self, key: int) -> str: |
| 50 | ... |
| 51 | |
| 52 | @overload |
| 53 | def __getitem__(self, key: slice) -> "Source": |
| 54 | ... |
| 55 | |
| 56 | def __getitem__(self, key: Union[int, slice]) -> Union[str, "Source"]: |
| 57 | if isinstance(key, int): |
| 58 | return self.lines[key] |
| 59 | else: |
| 60 | if key.step not in (None, 1): |
| 61 | raise IndexError("cannot slice a Source with a step") |
| 62 | newsource = Source() |
| 63 | newsource.lines = self.lines[key.start : key.stop] |
| 64 | return newsource |
| 65 | |
| 66 | def __iter__(self) -> Iterator[str]: |
| 67 | return iter(self.lines) |
| 68 | |
| 69 | def __len__(self) -> int: |
| 70 | return len(self.lines) |
| 71 | |
| 72 | def strip(self) -> "Source": |
| 73 | """Return new Source object with trailing and leading blank lines removed.""" |
| 74 | start, end = 0, len(self) |
no outgoing calls