Spaces:
Running on Zero
Running on Zero
feat(copy): tooltip strings dict — one source of truth for param descriptions
Browse filesAlso fix conftest.py to pre-load torch/gradio/pydantic before swapping
sys.modules["copy"] with the project module, preventing stdlib shadow
breakage in tests that import those packages.
- copy.py +26 -0
- tests/conftest.py +30 -1
- tests/test_copy.py +19 -0
copy.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""User-facing copy — tooltips and similar short strings.
|
| 2 |
+
|
| 3 |
+
Kept separate from ``ui.py`` so copy edits don't touch component wiring. Every
|
| 4 |
+
key here MUST be referenced from a labeled component in ``ui.py`` (and vice versa).
|
| 5 |
+
"""
|
| 6 |
+
from __future__ import annotations
|
| 7 |
+
|
| 8 |
+
TOOLTIPS: dict[str, str] = {
|
| 9 |
+
"prompt": "What to generate. Be specific: subject, style, lighting, camera angle.",
|
| 10 |
+
"negative_prompt": "What to avoid (Base only). e.g. 'blurry, low quality, distorted'.",
|
| 11 |
+
"model": "Base = 25 steps, higher quality. Turbo = 8 steps, fast.",
|
| 12 |
+
"lora": "Optional .safetensors LoRA file. Trained on Z-Image base or turbo.",
|
| 13 |
+
"lora_strength": "LoRA influence. 0.6–1.0 typical. Higher = more LoRA, less base model.",
|
| 14 |
+
"steps": "Denoising steps. Turbo: 6–10. Base: 20–30. More = better detail, slower.",
|
| 15 |
+
"cfg": "Classifier-free guidance. Turbo: locked at 1.0. Base: 3–5 typical.",
|
| 16 |
+
"width": "Output width in pixels. Multiples of 64. Higher = more memory.",
|
| 17 |
+
"height": "Output height in pixels. Multiples of 64.",
|
| 18 |
+
"seed": "0 = random each run. Pin a number to reproduce an image exactly.",
|
| 19 |
+
"controlnet_image": "Control image — the structural reference for the output.",
|
| 20 |
+
"controlnet_preprocessor": "Canny = edges, Depth = depth map, Pose = body pose, Pre-processed = use image as-is.",
|
| 21 |
+
"controlnet_scale": "How strongly the control image guides the output. 0.6–1.2 typical.",
|
| 22 |
+
"upscale_image": "Input image to upscale 2x.",
|
| 23 |
+
"refine_steps": "Steps for the Z-Image-Turbo refinement pass after RealESRGAN. 3–8 typical.",
|
| 24 |
+
"refine_denoise": "How much the refinement alters pixels. 0.2–0.4 typical. Higher = more detail change.",
|
| 25 |
+
"output": "Generated image. Right-click to download full resolution.",
|
| 26 |
+
}
|
tests/conftest.py
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
|
|
| 1 |
import sys
|
| 2 |
from pathlib import Path
|
| 3 |
|
|
|
|
|
|
|
| 4 |
# Make top-level modules importable in tests
|
| 5 |
-
sys.path.insert(0, str(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import importlib.util
|
| 2 |
import sys
|
| 3 |
from pathlib import Path
|
| 4 |
|
| 5 |
+
_PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
| 6 |
+
|
| 7 |
# Make top-level modules importable in tests
|
| 8 |
+
sys.path.insert(0, str(_PROJECT_ROOT))
|
| 9 |
+
|
| 10 |
+
# ── copy.py shadow fix ────────────────────────────────────────────────────────
|
| 11 |
+
# The project ships a file named ``copy.py`` which shadows the stdlib module.
|
| 12 |
+
# Third-party packages (pydantic, gradio) use ``from copy import deepcopy``;
|
| 13 |
+
# they must see the stdlib module. test_copy.py uses ``import copy as zis_copy``
|
| 14 |
+
# and must see the project module.
|
| 15 |
+
#
|
| 16 |
+
# Fix: eagerly import all third-party packages that use stdlib copy so their
|
| 17 |
+
# module-level ``from copy import ...`` calls are resolved against stdlib NOW,
|
| 18 |
+
# before we swap sys.modules["copy"]. After the swap only new ``import copy``
|
| 19 |
+
# statements are affected — and test_copy.py is the only file that issues one.
|
| 20 |
+
try:
|
| 21 |
+
import torch # noqa: F401 — torch._tensor uses `from copy import deepcopy`
|
| 22 |
+
import pydantic # noqa: F401 — resolves `from copy import deepcopy` in pydantic.main
|
| 23 |
+
import fastapi # noqa: F401 — depends on pydantic
|
| 24 |
+
import gradio # noqa: F401 — depends on fastapi/pydantic
|
| 25 |
+
except ImportError:
|
| 26 |
+
pass # optional deps; if absent the swap is harmless
|
| 27 |
+
|
| 28 |
+
# Now replace sys.modules["copy"] with our project module so that any
|
| 29 |
+
# subsequent ``import copy`` (i.e., in test_copy.py) gets TOOLTIPS.
|
| 30 |
+
_project_copy_path = _PROJECT_ROOT / "copy.py"
|
| 31 |
+
_spec = importlib.util.spec_from_file_location("copy", _project_copy_path)
|
| 32 |
+
_project_copy_module = importlib.util.module_from_spec(_spec)
|
| 33 |
+
_spec.loader.exec_module(_project_copy_module)
|
| 34 |
+
sys.modules["copy"] = _project_copy_module
|
tests/test_copy.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy as zis_copy # name shadows the stdlib `copy` but the module is unrelated
|
| 2 |
+
|
| 3 |
+
REQUIRED_KEYS = {
|
| 4 |
+
"prompt", "negative_prompt", "model", "lora", "lora_strength",
|
| 5 |
+
"steps", "cfg", "width", "height", "seed",
|
| 6 |
+
"controlnet_image", "controlnet_preprocessor", "controlnet_scale",
|
| 7 |
+
"upscale_image", "refine_steps", "refine_denoise", "output",
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
def test_tooltips_has_all_required_keys():
|
| 11 |
+
assert REQUIRED_KEYS <= set(zis_copy.TOOLTIPS)
|
| 12 |
+
|
| 13 |
+
def test_tooltips_values_are_non_empty_strings():
|
| 14 |
+
for key, val in zis_copy.TOOLTIPS.items():
|
| 15 |
+
assert isinstance(val, str) and val.strip(), f"{key} is empty or non-string"
|
| 16 |
+
|
| 17 |
+
def test_tooltips_values_are_short_enough_for_a_tooltip():
|
| 18 |
+
for key, val in zis_copy.TOOLTIPS.items():
|
| 19 |
+
assert len(val) <= 200, f"{key} is too long for a tooltip ({len(val)} chars)"
|