moops 0.13.2__tar.gz → 0.13.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {moops-0.13.2 → moops-0.13.3}/PKG-INFO +1 -1
- {moops-0.13.2 → moops-0.13.3}/pyproject.toml +1 -1
- {moops-0.13.2 → moops-0.13.3}/src/moops/_options.py +28 -2
- {moops-0.13.2 → moops-0.13.3}/src/moops/_text_wrap.py +4 -2
- {moops-0.13.2 → moops-0.13.3}/src/moops/interface.py +35 -8
- {moops-0.13.2 → moops-0.13.3}/README.md +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/__init__.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_choice_options.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_control_mirroring.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_custom_element.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_embed.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_input_map.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_interface_utils.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_list_controls.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_list_options.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_marimo_controls.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_markdown.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_naming.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_parse.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_preset_state.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_presets_ui.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_query_params.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_run.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_run_button.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_subgroup_registry.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_terminal_graphics.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_ui_workarounds.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_value_resolution.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/_variant.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/group.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/presets.py +0 -0
- {moops-0.13.2 → moops-0.13.3}/src/moops/workarounds.py +0 -0
|
@@ -425,6 +425,24 @@ def _missing_path_error(value: str) -> ParseError | None:
|
|
|
425
425
|
return None
|
|
426
426
|
|
|
427
427
|
|
|
428
|
+
def _file_browser_paths(value: typing.Any) -> list[str]:
|
|
429
|
+
if not value:
|
|
430
|
+
return []
|
|
431
|
+
if isinstance(value, str):
|
|
432
|
+
return [value]
|
|
433
|
+
if isinstance(value, pathlib.Path):
|
|
434
|
+
return [str(value)]
|
|
435
|
+
if isinstance(value, typing.Sequence):
|
|
436
|
+
items = typing.cast(typing.Sequence[object], value)
|
|
437
|
+
return [
|
|
438
|
+
str(item.path)
|
|
439
|
+
if isinstance(item, _ui_workarounds.FileBrowserFileInfo)
|
|
440
|
+
else str(item)
|
|
441
|
+
for item in items
|
|
442
|
+
]
|
|
443
|
+
return [str(value)]
|
|
444
|
+
|
|
445
|
+
|
|
428
446
|
@dataclasses.dataclass
|
|
429
447
|
class FileControl(TextControl):
|
|
430
448
|
def create_marimo_element(
|
|
@@ -474,6 +492,14 @@ class FileControl(TextControl):
|
|
|
474
492
|
continue
|
|
475
493
|
return result
|
|
476
494
|
|
|
495
|
+
def format_value(self, value: typing.Any) -> list[str]:
|
|
496
|
+
paths = _file_browser_paths(value)
|
|
497
|
+
return super().format_value(paths[0] if paths else "")
|
|
498
|
+
|
|
499
|
+
def format_query_value(self, value: typing.Any) -> str | None:
|
|
500
|
+
paths = _file_browser_paths(value)
|
|
501
|
+
return super().format_query_value(paths[0] if paths else "")
|
|
502
|
+
|
|
477
503
|
|
|
478
504
|
@dataclasses.dataclass
|
|
479
505
|
class MultiFileControl(ValueControl):
|
|
@@ -554,13 +580,13 @@ class MultiFileControl(ValueControl):
|
|
|
554
580
|
return [line]
|
|
555
581
|
|
|
556
582
|
def format_value(self, value: typing.Any) -> list[str]:
|
|
557
|
-
values =
|
|
583
|
+
values = _file_browser_paths(value)
|
|
558
584
|
if values == self.default:
|
|
559
585
|
return []
|
|
560
586
|
return [option_value_token(self.option, v) for v in values]
|
|
561
587
|
|
|
562
588
|
def format_query_value(self, value: typing.Any) -> str | None:
|
|
563
|
-
values =
|
|
589
|
+
values = _file_browser_paths(value)
|
|
564
590
|
return None if values == self.default else json.dumps(values)
|
|
565
591
|
|
|
566
592
|
def prompt_interactive(self, effective_default: typing.Any = _UNSET) -> list[str]:
|
|
@@ -44,14 +44,16 @@ def wrap_help_line(line: str, width: int = 88) -> list[str]:
|
|
|
44
44
|
return result
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
def wrap_command(
|
|
47
|
+
def wrap_command(
|
|
48
|
+
name: str, groups: list[str], width: int = 72, *, quote_name: bool = True
|
|
49
|
+
) -> str:
|
|
48
50
|
"""Render a script command, wrapping long lines with shell continuations.
|
|
49
51
|
|
|
50
52
|
Short commands stay on one line. When the single-line form exceeds ``width``,
|
|
51
53
|
each option group goes on its own line joined by `` \\`` continuations, which
|
|
52
54
|
remains valid copy-pasteable shell.
|
|
53
55
|
"""
|
|
54
|
-
quoted_name = shlex.quote(name)
|
|
56
|
+
quoted_name = shlex.quote(name) if quote_name else name
|
|
55
57
|
single_line = " ".join([quoted_name, *groups])
|
|
56
58
|
if not groups or len(single_line) <= width:
|
|
57
59
|
return single_line
|
|
@@ -436,19 +436,22 @@ class Interface:
|
|
|
436
436
|
if not self.notebook_name:
|
|
437
437
|
return mo.md("Input bundle with no notebook name")
|
|
438
438
|
notebook_name = html.escape(self.notebook_name)
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
439
|
+
label = f"An embedded instance of `{notebook_name}`"
|
|
440
|
+
if _running_in_edit_mode():
|
|
441
|
+
href = html.escape(self._standalone_url(), quote=True)
|
|
442
|
+
heading: mo.Html = mo.md(
|
|
443
|
+
f'<a href="{href}" target="_blank" rel="noopener">{label}</a>'
|
|
444
|
+
)
|
|
445
|
+
else:
|
|
446
|
+
heading = mo.md(label)
|
|
444
447
|
if self.embedded_extra_overrides != frozenset():
|
|
445
448
|
# None: embedded outside moops.embed, so overrides are unknown.
|
|
446
449
|
# Non-empty: the parent injected defs beyond args, so no CLI
|
|
447
450
|
# command can reproduce this setup.
|
|
448
|
-
return
|
|
451
|
+
return heading
|
|
449
452
|
command = _wrap_command(self.notebook_file, self._standalone_arg_groups())
|
|
450
453
|
return mo.vstack(
|
|
451
|
-
[
|
|
454
|
+
[heading, mo.md(f"To run as a standalone script:\n```\n{command}\n```")]
|
|
452
455
|
)
|
|
453
456
|
|
|
454
457
|
def _standalone_url(self) -> str:
|
|
@@ -633,7 +636,9 @@ def attached_interface(ctrl: typing.Any) -> Interface | None:
|
|
|
633
636
|
|
|
634
637
|
def _wrap_command(command: str, groups: list[str]) -> str:
|
|
635
638
|
if _should_use_uv_run(command):
|
|
636
|
-
return _text_wrap.wrap_command(
|
|
639
|
+
return _text_wrap.wrap_command(
|
|
640
|
+
f"uv run {shlex.quote(command)}", groups, quote_name=False
|
|
641
|
+
)
|
|
637
642
|
return _text_wrap.wrap_command(command, groups)
|
|
638
643
|
|
|
639
644
|
|
|
@@ -716,3 +721,25 @@ def _collect_usage_placeholders(
|
|
|
716
721
|
for ctrl in iface.controls:
|
|
717
722
|
if sub_iface := attached_interface(ctrl):
|
|
718
723
|
_collect_usage_placeholders(sub_iface, result)
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
def _running_in_edit_mode() -> bool:
|
|
727
|
+
"""Return True only when running inside a marimo *edit* session.
|
|
728
|
+
|
|
729
|
+
``mo.running_in_notebook()`` is True for both ``marimo edit`` and
|
|
730
|
+
``marimo run``, but links to ``/?file=...`` only work in edit sessions.
|
|
731
|
+
"""
|
|
732
|
+
if not mo.running_in_notebook():
|
|
733
|
+
return False
|
|
734
|
+
try:
|
|
735
|
+
from marimo._runtime.context import get_context
|
|
736
|
+
from marimo._runtime.context.kernel_context import KernelRuntimeContext
|
|
737
|
+
from marimo._session.model import SessionMode
|
|
738
|
+
|
|
739
|
+
ctx = get_context()
|
|
740
|
+
return (
|
|
741
|
+
isinstance(ctx, KernelRuntimeContext)
|
|
742
|
+
and ctx.session_mode == SessionMode.EDIT
|
|
743
|
+
)
|
|
744
|
+
except Exception:
|
|
745
|
+
return False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|