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
Optimize vterm
: adopt data types and add annotations. Fix tests
#547
Optimize vterm
: adopt data types and add annotations. Fix tests
#547
Conversation
urwid/tests/test_vterm.py
Outdated
@@ -238,6 +243,58 @@ def test_erase_display(self): | |||
self.write(r'98765\e[8D\e[1Jx') | |||
self.expect(' x5a98765') | |||
|
|||
def test_scrolling_region_simple_incremental(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this extra verbose tests maybe removed or replace "short" versions.
@wardi which approach is better?
@@ -74,7 +74,7 @@ def detect_encoding() -> str: | |||
else: | |||
assert 0, "It worked!" | |||
|
|||
_target_encoding = None | |||
_target_encoding = 'ascii' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's set implicit, make explicit
|
||
KEY_TRANSLATIONS = { | ||
'enter': chr(13), | ||
'enter': "\r", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
more human-readable with the same internals
@@ -98,7 +101,19 @@ | |||
'f5': f"{ESC}[15~", | |||
} | |||
|
|||
CSI_COMMANDS = { | |||
|
|||
class CSIAlias(typing.NamedTuple): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
named tuples less complex to deal with
self.utf8_eat_bytes = None | ||
self.utf8_buffer = b'' | ||
self.utf8_eat_bytes: int | None = None | ||
self.utf8_buffer = bytearray() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bytearray
changed in-place
bytes
is immutable and new object on any change
if self.term_modes.lfnl and key == "\x0d": | ||
key += "\x0a" | ||
|
||
key = key.encode(self.encoding, 'ignore') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do not change type of variable just for 1 line, make in-place during call
vterm
: adopt data types and add annotations. Fix testsvterm
: adopt data types and add annotations. Fix tests
b980cec
to
f40c05e
Compare
urwid/tests/test_vterm.py
Outdated
@@ -140,7 +145,7 @@ def expect( | |||
else: | |||
desc += '\n' | |||
desc += f'Expected:\n{what!r}\nGot:\n{got!r}' | |||
self.assertEqual(got, what, desc) | |||
self.assertEqual(what, got, desc) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most unittest parsers expect, that expected value is first
@@ -1690,16 +1755,14 @@ def keypress(self, size: tuple[int, int], key: str) -> str | None: | |||
key = chr(ord(key[-1]) - ord('A') + 1) | |||
else: | |||
if self.term_modes.keys_decckm and key in KEY_TRANSLATIONS_DECCKM: | |||
key = KEY_TRANSLATIONS_DECCKM.get(key) | |||
key = KEY_TRANSLATIONS_DECCKM[key] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already know that it in KEY_TRANSLATIONS_DECCKM
urwid/tests/test_vterm.py
Outdated
@@ -60,6 +63,7 @@ def read(self, size: int) -> bytes: | |||
|
|||
def write(self, data: bytes) -> None: | |||
os.write(self.writer, data) | |||
sleep(0.025) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not fond of this. Never really fixes flaky tests — merely shifts flake probability.
Did you try os.fdopen(self.writer).flush()
instead ?
Or better yet, disabling buffering completely with `unbuffered_pipe = os.fdopen(self.writer, 'wb', 0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can try unbuffered pipe, but stdout
will be still buffered
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
os.fdopen
fails in 10 from 10 runs with Bad file descriptor
os.fsync
also disagree to deal with pipe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That can be disabled too.
In a unit test though, why is there a dependency onto sys.stdout
at all? Can't it allocate a private PTY ?
... Even that seems redundant, as .read()
passes the output of Terminal.render()
to asserts directly:
urwid/urwid/tests/test_vterm.py
Lines 118 to 129 in bac20db
def read(self, raw: bool = False, focus: bool = False) -> bytes | list[list[bytes, typing.Any, typing.Any]]: | |
self.term.wait_and_feed() | |
rendered = self.term.render(self.termsize, focus=focus) | |
if raw: | |
is_empty = lambda c: c == (None, None, b' ') | |
content = list(rendered.content()) | |
lines = (tuple(dropwhile(is_empty, reversed(line))) for line in content) | |
return [list(reversed(line)) for line in lines if line] | |
else: | |
content = rendered.text | |
lines = (line.rstrip() for line in content) | |
return b'\n'.join(lines).rstrip() |
I don't see any need to use sys.stdout
at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Render spawn process, which execute pty.fork()
.
Data read from fork stdout and rendered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming of added tests is incomprehensible.
test_scrolling_region_simple_incremental
test_cursor_scrolling_region_incremental
test_scrolling_region_simple_with_focus_incremental
test_cursor_scrolling_region_with_focus_incremental
When seen side-by-side — one can sort-of-make-out-maybe-guesstimate how they differ.
When seen pages apart — no chance 😕
Tests was added only for debug purposes and now it's possible to decide: keep or drop |
Without huge mocking, `Terminal.spawn` call `pty.fork`, which accept 0
arguments.
Op ma 1 mei 2023 20:14 schreef Maxim Ivanov ***@***.***>:
… ***@***.**** commented on this pull request.
------------------------------
In urwid/tests/test_vterm.py
<#547 (comment)>:
> @@ -60,6 +63,7 @@ def read(self, size: int) -> bytes:
def write(self, data: bytes) -> None:
os.write(self.writer, data)
+ sleep(0.025)
That can be disabled too.
In a unit test though, why is there a dependency onto sys.stdout at all?
Can't it allocate a private PTY ?
... Even that seems redundant, as .read() passes the output of
Terminal.render() to asserts directly:
https://github.com/urwid/urwid/blob/bac20db87eaeb0b7a0026807d7e6dbe391b08580/urwid/tests/test_vterm.py#L118-L129
I don't see any need to use sys.stdout at all.
—
Reply to this email directly, view it on GitHub
<#547 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AD2KMM2HHK25XI3XWHNVPHDXD74QLANCNFSM6AAAAAAXRBQW2M>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Yes, that's the What I'm talking about is |
|
* `TermModes` - make `dataclass` as it's used * `TermScroller` - deprecate and use `deque` instead (faster both side access, automatic size limit control) * `utf8_buffer` - use `bytearray` as mutual storage for bytes (no re-allocation if no crazy size changes) * `CSI_COMMANDS` - use `namedtuple` types for better type management * use native string escape sequences instead of hex encoded one (easier to read and understand, internally the same) * not `elif` after `return` (follow actual static checkers rules) * `_target_encoding = 'ascii'` as default (no re-cast)
f40c05e
to
f00e7ba
Compare
Removed test changes: at this time I have lack time for refactoring it |
TermModes
- makedataclass
as it's usedTermScroller
- deprecate and usedeque
instead(faster both side access, automatic size limit control)
utf8_buffer
- usebytearray
as mutual storage for bytes(no re-allocation if no crazy size changes)
CSI_COMMANDS
- usenamedtuple
types for better type managementuse native string escape sequences instead of hex encoded one
(easier to read and understand, internally the same)
not
elif
afterreturn
(follow actual static checkers rules)_target_encoding = 'ascii'
as default (no re-cast)add extra verbose version of tests for scrolling region
Fix #544
Checklist
master
orpython-dual-support
branchtox
successfully in local environment