-
Notifications
You must be signed in to change notification settings - Fork 4
Merge util file into utils folder #92
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
Open
gselzer
wants to merge
6
commits into
pyapp-kit:main
Choose a base branch
from
gselzer:merge-utils
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
1ce5f1d
Mere scenex.util into scenex.utils
gselzer 2dad66f
Clean up some __init__s
gselzer 7230230
Update new module docstrings
gselzer 49ab80f
Remove unused debug code
gselzer 067891b
Fix tree_repr import
gselzer 0303c95
Also tree_dict import
gselzer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| """Utilities for working with scenex structures.""" | ||
|
|
||
| __all__ = [] | ||
| from ._app import native, run, set_cursor, show | ||
|
|
||
| __all__ = ["native", "run", "set_cursor", "show"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| """Utility functions for displaying and debugging scenex scenegraphs.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from collections.abc import Callable, Iterable | ||
| from contextlib import suppress | ||
| from typing import TYPE_CHECKING, Any, Protocol | ||
|
|
||
| if TYPE_CHECKING: | ||
| from typing import TypeAlias | ||
|
|
||
| Tree: TypeAlias = str | dict[str, list["Tree"]] | ||
|
|
||
| class SupportsChildren(Protocol): | ||
| """Protocol for node-like objects that have children.""" | ||
|
|
||
| @property | ||
| def children(self) -> Iterable[SupportsChildren]: | ||
| """Return the children of the node.""" | ||
| ... | ||
|
|
||
|
|
||
| def _cls_name_with_id(obj: Any) -> str: | ||
| return f"{obj.__class__.__name__}:{id(obj)}" | ||
|
|
||
|
|
||
| def tree_repr( | ||
| node: SupportsChildren, | ||
| *, | ||
| node_repr: Callable[[Any], str] = object.__repr__, | ||
| _prefix: str = "", | ||
| _is_last: bool = True, | ||
| ) -> str: | ||
| """ | ||
| Return an ASCII/Unicode tree representation of `node` and its descendants. | ||
|
|
||
| This assumes that `node` is a tree-like object with a `children` attribute that is | ||
| either a property or a callable that returns an iterable of child nodes. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| node : SupportsChildren | ||
| Any object that has a `children` attribute or method that returns an iterable | ||
| of child nodes. | ||
| node_repr : Callable[[Any], str], optional | ||
| Function to convert the node to a string. Defaults to `object.__repr__` (which | ||
| avoids complex repr functions on objects, but use `repr` if you want to see | ||
| the full representation). | ||
| _prefix : str, optional | ||
| Prefix to use for each line of the tree. Defaults to an empty string. | ||
| _is_last : bool, optional | ||
| Whether this node is the last child of its parent. Defaults to `True`. | ||
| This is used to determine the branch character to use in the tree | ||
| representation. | ||
| """ | ||
| if _prefix: | ||
| branch = "└── " if _is_last else "├── " | ||
| else: | ||
| branch = "" | ||
|
|
||
| lines: list[str] = [f"{_prefix}{branch}{node_repr(node)}"] | ||
| if children := list(_get_children(node)): | ||
| prefix_child = _prefix + (" " if _is_last else "│ ") | ||
| for idx, child in enumerate(children): | ||
| lines.append( | ||
| tree_repr( | ||
| child, | ||
| node_repr=node_repr, | ||
| _prefix=prefix_child, | ||
| _is_last=idx == len(children) - 1, | ||
| ) | ||
| ) | ||
| return "\n".join(lines) | ||
|
|
||
|
|
||
| def tree_dict( | ||
| node: SupportsChildren, | ||
| *, | ||
| obj_name: Callable[[Any], str] = _cls_name_with_id, | ||
| ) -> Tree: | ||
| """Build an intermediate representation of the tree rooted at `node`. | ||
|
|
||
| Leaves are represented as strings, and non-leaf nodes are represented as | ||
| dictionaries with the node name as the key and a list of child nodes as the value. | ||
| This is useful for debugging and visualization purposes. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| node : SupportsChildren | ||
| The root node of the tree to be represented. | ||
| obj_name : Callable[[Any], str], optional | ||
| A function to convert the node to a string. Defaults to a lambda function that | ||
| returns the class name and ID | ||
|
|
||
| Returns | ||
| ------- | ||
| str | dict[str, list[dict | str]] | ||
| A string, if the node is a leaf, or a dictionary representing the tree, | ||
| if the node has children, like `{"node_name": ["child1", "child2", ...]}`. | ||
| """ | ||
| node_name = obj_name(node) | ||
| if not (children := _get_children(node)): | ||
| return node_name | ||
|
|
||
| result: list[dict | str] = [] | ||
| for child in children: | ||
| result.append(tree_dict(child, obj_name=obj_name)) | ||
| return {obj_name(node): result} | ||
|
|
||
|
|
||
| def _get_children(obj: Any) -> Iterable[Any]: | ||
| if (children := getattr(obj, "children", None)) is None: | ||
| return () | ||
| return _ensure_iterable(children) | ||
|
|
||
|
|
||
| def _ensure_iterable(obj: object) -> Iterable[Any]: | ||
| if isinstance(obj, Iterable): | ||
| return obj | ||
| if callable(obj): | ||
| with suppress(TypeError): | ||
| return _ensure_iterable(obj()) | ||
| raise TypeError( | ||
| f"Expected an iterable or callable that returns an iterable, " | ||
| f"got {type(obj).__name__}" | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.