Skip to content

Commit 22cf2e6

Browse files
authored
Merge pull request #98 from rhuygen/fix/discarded-square-bracket-output
Fixed square-bracket content being silently discarded from console output. Bump version to v0.25.2
2 parents d813088 + a988e04 commit 22cf2e6

9 files changed

Lines changed: 102 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66

77
## [Unreleased]
88

9+
## [0.25.2] - 2026-06-12
10+
11+
### Added
12+
13+
- Added `tests/tasks/specific/console/` task package with a "Console" tab containing `console_output` and `print_numpy_output` tasks for testing plain and rich console output rendering.
14+
- Registered the new `console` subpackage in `UI_TAB_ORDER` in `tests/tasks/specific/__init__.py`.
15+
16+
### Fixed
17+
18+
- Fixed square-bracket content being silently discarded from console output. Stream text from the Jupyter kernel is now wrapped in `Text.from_ansi()` before display, so literal `[text]` in `print()` output is preserved while ANSI styling from `rich.print()` continues to render correctly.
19+
920
## [0.25.1] - 2026-05-13
1021

1122
### Changed
@@ -79,7 +90,8 @@ Other changes are not blocking and can be implemented later when needed.
7990

8091

8192

82-
[Unreleased]: https://github.com/IvS-KULeuven/gui-executor/compare/v0.25.1...HEAD
93+
[Unreleased]: https://github.com/IvS-KULeuven/gui-executor/compare/v0.25.2...HEAD
94+
[0.25.2]: https://github.com/IvS-KULeuven/gui-executor/compare/v0.25.1...v0.25.2
8395
[0.25.1]: https://github.com/IvS-KULeuven/gui-executor/compare/v0.25.0...v0.25.1
8496
[0.25.0]: https://github.com/IvS-KULeuven/gui-executor/compare/v0.24.0...v0.25.0
8597
[0.24.0]: https://github.com/IvS-KULeuven/gui-executor/compare/v0.23.0...v0.24.0

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[project]
22
name = "gui-executor"
33
description = "Execute Python code in an automatically generated GUI App."
4-
version = "0.25.1"
4+
version = "0.25.2"
55
requires-python = ">=3.10"
66
license = {text = "MIT"}
77
readme = {"file" = "README.md", "content-type" = "text/markdown"}

src/gui_executor/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
The one and only place for the version number.
33
"""
44

5-
VERSION = (0, 25, 1)
5+
VERSION = (0, 25, 2)
66

77
__version__ = ".".join(map(str, VERSION))

src/gui_executor/view.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ def run(self):
429429
def flush_stream_buffer():
430430
if not stream_buffer:
431431
return
432-
self.signals.data.emit("\n".join(stream_buffer))
432+
self.signals.data.emit(Text.from_ansi("\n".join(stream_buffer)))
433433
stream_buffer.clear()
434434

435435
try:

tests/tasks/docs/advanced_type_hints.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
@exec_task()
88
def save_observation(
9-
coordinates: FixedList([float, float], name="lat, long"),
9+
coordinates: FixedList([float, float], name="lat, long"), # type: ignore
1010
time: str,
1111
bird_name: str,
1212
):
@@ -24,7 +24,7 @@ def save_observation(
2424

2525
@exec_task()
2626
def save_targets(
27-
targets: ListList([int, float, str], [1, 0.0, "target-A"], name="id, angle, label"),
27+
targets: ListList([int, float, str], [1, 0.0, "target-A"], name="id, angle, label"), # type: ignore
2828
):
2929
"""
3030
Save a dynamic number of target definitions.
@@ -42,7 +42,7 @@ def choose_filters(
4242
["none", "bias", "dark", "flat"],
4343
defaults=["bias", "dark"],
4444
name="Image filters",
45-
),
45+
), # type: ignore
4646
):
4747
"""
4848
Select one or more filters to apply.
@@ -70,16 +70,16 @@ def default_digit():
7070

7171

7272
@exec_task()
73-
def select_digit(digit: Callback(available_digits, name="digit", default=default_digit)):
73+
def select_digit(digit: Callback(available_digits, name="digit", default=default_digit)): # type: ignore
7474
"""Select a digit from values determined at runtime."""
7575
print(f"{digit = }")
7676

7777

7878
@exec_ui()
79-
def select_mode(mode: Callback(lambda: ["full", "fast"], name="mode")):
79+
def select_mode(mode: Callback(lambda: ["full", "fast"], name="mode")): # type: ignore
8080
print(f"{mode = }")
8181

8282

8383
@exec_ui()
84-
def use_calibration(enabled: Callback(lambda: True, name="calibration")):
84+
def use_calibration(enabled: Callback(lambda: True, name="calibration")): # type: ignore
8585
print(f"{enabled = }")

tests/tasks/specific/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
UI_TAB_ORDER = [
22
"virtual",
3+
"console",
34
"second_tab",
45
"sys_func",
56
"third_tab",
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
UI_TAB_DISPLAY_NAME = "Console"
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import logging
2+
import rich
3+
4+
from gui_executor.exec import exec_task
5+
6+
_LOGGER = logging.getLogger(__name__)
7+
8+
9+
@exec_task()
10+
def console_output(message: str) -> str:
11+
# This task is to test a problem with rendering a string that contains text between square brackets.
12+
#
13+
# If you remove the blank after the opening bracket, the GUI will crash!
14+
15+
msg = f"Console output: {message}"
16+
17+
print("-----")
18+
19+
print("Console output using plain print")
20+
print(msg)
21+
print(f"Console output with f-string: {msg}")
22+
23+
print("-----")
24+
25+
rich.print("Console output using rich print")
26+
rich.print(msg)
27+
rich.print(f"Console output with f-string: {msg}")
28+
29+
print("-----")
30+
31+
_LOGGER.info(msg)
32+
33+
return msg
34+
35+
36+
@exec_task()
37+
def print_numpy_output(rich_output: bool) -> str:
38+
import numpy as np
39+
40+
arr = np.array([[1, 2, 3], [4, 5, 6]])
41+
42+
if rich_output:
43+
print = rich.print
44+
else:
45+
import builtins
46+
47+
print = builtins.print
48+
49+
print(
50+
f"The numpy array is printed twice with '{'rich.print' if rich_output else 'builtins.print'}', "
51+
f"first with a comma and then with an f-string. The GUI should render both correctly without crashing."
52+
)
53+
54+
print("-----")
55+
56+
print("Numpy array:\n", arr)
57+
print(f"Numpy array:\n{arr}")
58+
59+
print("-----")
60+
61+
arr_str = "[0., 1., 2.]"
62+
63+
print("Numpy array as string:", arr_str)
64+
print(f"Numpy array as string: {arr_str}")
65+
66+
print("-----")
67+
68+
arr_str = "[np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(0.0), np.float64(-0.0), np.float64(0.0)]"
69+
70+
print("Numpy array as string:", arr_str)
71+
print(f"Numpy array as string: {arr_str}")
72+
73+
print("-----")
74+
75+
_LOGGER.info(f"Numpy array: {arr}")
76+
77+
return "Numpy array printed to console"

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)