pyside-live 0.1.0__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.
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.5
2
+ Name: pyside-live
3
+ Version: 0.1.0
4
+ Summary: Un reloaded/watcher ultra ligero y eficiente para desarrollo rápido con PySide/Qt en Python.
5
+ Project-URL: Homepage, https://github.com/tu-usuario/pyside-live
6
+ Author: Mauricio Ruiz
7
+ License: MIT
8
+ Keywords: gui,hot-reload,live-reload,pyside,qt,watcher
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: >=3.8
20
+ Requires-Dist: watchdog>=3.0.0
21
+ Description-Content-Type: text/markdown
22
+
23
+ # PySide Live
24
+
25
+ Herramienta de línea de comandos ligera y eficiente para **Hot Reload / Live Reload** en desarrollo de aplicaciones de escritorio con PySide / Qt en Python.
26
+
27
+ ## Instalación
28
+
29
+ ```bash
30
+ pip install pyside-live
@@ -0,0 +1,8 @@
1
+ # PySide Live
2
+
3
+ Herramienta de línea de comandos ligera y eficiente para **Hot Reload / Live Reload** en desarrollo de aplicaciones de escritorio con PySide / Qt en Python.
4
+
5
+ ## Instalación
6
+
7
+ ```bash
8
+ pip install pyside-live
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "pyside-live"
7
+ version = "0.1.0"
8
+ description = "Un reloaded/watcher ultra ligero y eficiente para desarrollo rápido con PySide/Qt en Python."
9
+ readme = "README.md"
10
+ authors = [
11
+ { name = "Mauricio Ruiz" }
12
+ ]
13
+ license = { text = "MIT" }
14
+ keywords = ["pyside", "qt", "hot-reload", "live-reload", "gui", "watcher"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.8",
21
+ "Programming Language :: Python :: 3.9",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Topic :: Software Development :: Libraries :: Python Modules",
26
+ ]
27
+ requires-python = ">=3.8"
28
+ dependencies = [
29
+ "watchdog>=3.0.0",
30
+ ]
31
+
32
+ [project.scripts]
33
+ pyside-live = "pyside_live.cli:main"
34
+
35
+ [project.urls]
36
+ Homepage = "https://github.com/tu-usuario/pyside-live"
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
@@ -0,0 +1,108 @@
1
+ import sys
2
+ import time
3
+ import argparse
4
+ import subprocess
5
+ from pathlib import Path
6
+ from watchdog.observers import Observer
7
+ from watchdog.events import FileSystemEventHandler
8
+
9
+ EXCLUDE_DIRS = {
10
+ '.venv', 'venv', 'env', '__pycache__', '.git',
11
+ 'build', 'dist', '.idea', '.vscode', '.pytest_cache'
12
+ }
13
+
14
+ def get_python_interpreter(script_path: Path) -> str:
15
+ """Busca un entorno virtual local o usa python3 del sistema."""
16
+ # Buscar .venv o venv en la ruta del script o sus padres
17
+ current = script_path.parent
18
+ for parent in [current, *current.parents]:
19
+ for venv_name in ('.venv', 'venv', 'env'):
20
+ venv_path = parent / venv_name
21
+ if venv_path.is_dir():
22
+ # Detectar estructura de binarios según el SO
23
+ if sys.platform == "win32":
24
+ python_bin = venv_path / "Scripts" / "python.exe"
25
+ else:
26
+ python_bin = venv_path / "bin" / "python"
27
+
28
+ if python_bin.exists():
29
+ return str(python_bin)
30
+
31
+ # Fallback al python del sistema
32
+ return "python3"
33
+
34
+ class PySideReloadHandler(FileSystemEventHandler):
35
+ def __init__(self, script_path, debounce_interval=0.4):
36
+ self.script_path = Path(script_path).resolve()
37
+ self.debounce_interval = debounce_interval
38
+ self.python_interpreter = get_python_interpreter(self.script_path)
39
+ self.process = None
40
+ self.last_restart = 0
41
+ self.start_process()
42
+
43
+ def start_process(self):
44
+ if self.process:
45
+ print("\n🔄 [pyside-live] Cambios detectados. Reiniciando ventana...")
46
+ self.process.terminate()
47
+ try:
48
+ self.process.wait(timeout=1.5)
49
+ except subprocess.TimeoutExpired:
50
+ self.process.kill()
51
+
52
+ self.process = subprocess.Popen([self.python_interpreter, str(self.script_path)])
53
+
54
+ def on_modified(self, event):
55
+ if event.is_directory:
56
+ return
57
+
58
+ file_path = Path(event.src_path)
59
+
60
+ if any(excluded in file_path.parts for excluded in EXCLUDE_DIRS):
61
+ return
62
+
63
+ if file_path.suffix in ('.py', '.ui', '.qml'):
64
+ current_time = time.time()
65
+ if (current_time - self.last_restart) > self.debounce_interval:
66
+ self.last_restart = current_time
67
+ self.start_process()
68
+
69
+ def main():
70
+ parser = argparse.ArgumentParser(
71
+ description="pyside-live: Recarga en caliente ligera para aplicaciones PySide/Qt."
72
+ )
73
+ parser.add_argument(
74
+ "target",
75
+ help="Ruta al archivo .py principal de tu aplicación PySide."
76
+ )
77
+ args = parser.parse_args()
78
+
79
+ target_path = Path(args.target).resolve()
80
+ if not target_path.exists():
81
+ print(f"❌ Error: El archivo '{args.target}' no existe.")
82
+ sys.exit(1)
83
+
84
+ watch_dir = target_path.parent
85
+ event_handler = PySideReloadHandler(target_path)
86
+
87
+ print(f"🐍 Usando intérprete Python: {event_handler.python_interpreter}")
88
+
89
+ observer = Observer()
90
+ observer.schedule(event_handler, path=str(watch_dir), recursive=True)
91
+ observer.start()
92
+
93
+ print(f"🚀 [pyside-live] Vigilando cambios para: {target_path.name}")
94
+ print(f"📁 Directorio base: {watch_dir}")
95
+ print("💡 Presiona Ctrl+C para detener el proceso.\n")
96
+
97
+ try:
98
+ while True:
99
+ time.sleep(0.5)
100
+ except KeyboardInterrupt:
101
+ print("\n🛑 [pyside-live] Deteniendo vigilante...")
102
+ observer.stop()
103
+ if event_handler.process:
104
+ event_handler.process.terminate()
105
+ observer.join()
106
+
107
+ if __name__ == "__main__":
108
+ main()