-
-
Notifications
You must be signed in to change notification settings - Fork 87
Remove crashtest #382
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove crashtest #382
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Removed `crashtest` dependency and vendored part of it into `cleo` |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| from __future__ import annotations | ||
|
|
||
| import operator | ||
|
|
||
| from functools import reduce | ||
| from pathlib import Path | ||
| from typing import TYPE_CHECKING | ||
| from typing import ClassVar | ||
|
|
||
|
|
||
| if TYPE_CHECKING: | ||
| import inspect | ||
|
|
||
| from types import FrameType | ||
|
|
||
|
|
||
| class Frame: | ||
| _content_cache: ClassVar[dict[str, str]] = {} | ||
|
|
||
| def __init__(self, frame_info: inspect.FrameInfo) -> None: | ||
| self._frame = frame_info.frame | ||
| self._frame_info = frame_info | ||
| self._lineno = frame_info.lineno | ||
| self._filename = frame_info.filename | ||
| self._function = frame_info.function | ||
| self._lines = None | ||
| self._file_content: str | None = None | ||
|
|
||
| @property | ||
| def frame(self) -> FrameType: | ||
| return self._frame | ||
|
|
||
| @property | ||
| def lineno(self) -> int: | ||
| return self._lineno | ||
|
|
||
| @property | ||
| def filename(self) -> str: | ||
| return self._filename | ||
|
|
||
| @property | ||
| def function(self) -> str: | ||
| return self._function | ||
|
|
||
| @property | ||
| def line(self) -> str: | ||
| if not self._frame_info.code_context: | ||
| return "" | ||
|
|
||
| return self._frame_info.code_context[0] | ||
|
|
||
| @property | ||
| def _key(self) -> tuple[str, str, int]: | ||
| return self._filename, self._function, self._lineno | ||
|
|
||
| @property | ||
| def file_content(self) -> str: | ||
| if self._file_content is not None: | ||
| return self._file_content | ||
| if not self._filename: | ||
| self._file_content = "" | ||
| return "" | ||
| if self._filename not in type(self)._content_cache: | ||
| try: | ||
| file_content = Path(self._filename).read_text() | ||
| except OSError: | ||
| file_content = "" | ||
| type(self)._content_cache[self._filename] = file_content | ||
| self._file_content = type(self)._content_cache[self._filename] | ||
| return self._file_content | ||
|
|
||
| def __hash__(self) -> int: | ||
| return reduce(operator.xor, map(hash, self._key)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. simply this in general is a better hash eg |
||
|
|
||
| def __eq__(self, other: object) -> bool: | ||
| if not isinstance(other, Frame): | ||
| return NotImplemented | ||
| return self._key == other._key | ||
|
|
||
| def __repr__(self) -> str: | ||
| return f"<Frame {self._filename}, {self._function}, {self._lineno}>" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from typing import List | ||
|
|
||
| from cleo.ui.exception_trace.frame import Frame | ||
|
|
||
|
|
||
| class FrameCollection(List[Frame]): | ||
| def __init__(self, frames: list[Frame] | None = None, count: int = 0) -> None: | ||
| if frames is None: | ||
| frames = [] | ||
|
|
||
| super().__init__(frames) | ||
|
|
||
| self._count = count | ||
|
|
||
| @property | ||
| def repetitions(self) -> int: | ||
| return self._count - 1 | ||
|
|
||
| @property | ||
| def is_repeated(self) -> bool: | ||
| return self._count > 1 | ||
|
|
||
| def increment_count(self, increment: int = 1) -> FrameCollection: | ||
| self._count += increment | ||
|
|
||
| return self | ||
|
|
||
| def compact(self) -> list[FrameCollection]: | ||
| """ | ||
| Compacts the frames to deduplicate recursive calls. | ||
| """ | ||
| collections = [] | ||
| current_collection = FrameCollection() | ||
|
|
||
| i = 0 | ||
| while i < len(self) - 1: | ||
| frame = self[i] | ||
| if frame in self[i + 1 :]: | ||
| duplicate_indices = [] | ||
| for sub_index, sub_frame in enumerate(self[i + 1 :]): | ||
| if frame == sub_frame: | ||
| duplicate_indices.append(sub_index + i + 1) | ||
|
|
||
| found_duplicate = False | ||
| for duplicate_index in duplicate_indices: | ||
| collection = FrameCollection(self[i:duplicate_index]) | ||
| if collection == current_collection: | ||
| current_collection.increment_count() | ||
| i = duplicate_index | ||
| found_duplicate = True | ||
| break | ||
|
|
||
| if found_duplicate: | ||
| continue | ||
|
|
||
| collections.append(current_collection) | ||
| current_collection = FrameCollection(self[i : duplicate_indices[0]]) | ||
|
|
||
| i = duplicate_indices[0] | ||
|
|
||
| continue | ||
|
|
||
| if current_collection.is_repeated: | ||
| collections.append(current_collection) | ||
| current_collection = FrameCollection() | ||
|
|
||
| current_collection.append(frame) | ||
| i += 1 | ||
|
|
||
| collections.append(current_collection) | ||
|
|
||
| return collections |
Uh oh!
There was an error while loading. Please reload this page.