Ver código fonte

do not fallback to key name and print tracebacks properly in compile (#5003)

Khaleel Al-Adhami 2 meses atrás
pai
commit
d3cebe8f43
3 arquivos alterados com 80 adições e 5 exclusões
  1. 1 1
      reflex/base.py
  2. 8 4
      reflex/reflex.py
  3. 71 0
      reflex/utils/prerequisites.py

+ 1 - 1
reflex/base.py

@@ -128,5 +128,5 @@ class Base(BaseModel):
         if isinstance(key, str):
             # Seems like this function signature was wrong all along?
             # If the user wants a field that we know of, get it and pass it off to _get_value
-            return getattr(self, key, key)
+            return getattr(self, key)
         return key

+ 8 - 4
reflex/reflex.py

@@ -205,18 +205,22 @@ def _run(
     prerequisites.check_latest_package_version(constants.Reflex.MODULE_NAME)
 
     # Get the app module.
-    app_task = prerequisites.compile_app if frontend else prerequisites.validate_app
+    app_task = prerequisites.compile_or_validate_app
+    args = (frontend,)
 
     # Granian fails if the app is already imported.
     if should_use_granian():
         import concurrent.futures
 
         compile_future = concurrent.futures.ProcessPoolExecutor(max_workers=1).submit(
-            app_task
+            app_task,
+            *args,
         )
-        compile_future.result()
+        validation_result = compile_future.result()
     else:
-        app_task()
+        validation_result = app_task(*args)
+    if not validation_result:
+        raise typer.Exit(1)
 
     # Warn if schema is not up to date.
     prerequisites.check_schema_up_to_date()

+ 71 - 0
reflex/utils/prerequisites.py

@@ -8,6 +8,7 @@ import functools
 import importlib
 import importlib.metadata
 import importlib.util
+import io
 import json
 import os
 import platform
@@ -449,6 +450,76 @@ def compile_app(reload: bool = False, export: bool = False) -> None:
     get_compiled_app(reload=reload, export=export)
 
 
+def _can_colorize() -> bool:
+    """Check if the output can be colorized.
+
+    Copied from _colorize.can_colorize.
+
+    https://raw.githubusercontent.com/python/cpython/refs/heads/main/Lib/_colorize.py
+
+    Returns:
+        If the output can be colorized
+    """
+    file = sys.stdout
+
+    if not sys.flags.ignore_environment:
+        if os.environ.get("PYTHON_COLORS") == "0":
+            return False
+        if os.environ.get("PYTHON_COLORS") == "1":
+            return True
+    if os.environ.get("NO_COLOR"):
+        return False
+    if os.environ.get("FORCE_COLOR"):
+        return True
+    if os.environ.get("TERM") == "dumb":
+        return False
+
+    if not hasattr(file, "fileno"):
+        return False
+
+    if sys.platform == "win32":
+        try:
+            import nt
+
+            if not nt._supports_virtual_terminal():
+                return False
+        except (ImportError, AttributeError):
+            return False
+
+    try:
+        return os.isatty(file.fileno())
+    except io.UnsupportedOperation:
+        return file.isatty()
+
+
+def compile_or_validate_app(compile: bool = False) -> bool:
+    """Compile or validate the app module based on the default config.
+
+    Args:
+        compile: Whether to compile the app.
+
+    Returns:
+        If the app is compiled successfully.
+    """
+    try:
+        if compile:
+            compile_app()
+        else:
+            validate_app()
+    except Exception as e:
+        import traceback
+
+        sys_exception = sys.exception()
+
+        try:
+            colorize = _can_colorize()
+            traceback.print_exception(e, colorize=colorize)  # pyright: ignore[reportCallIssue]
+        except Exception:
+            traceback.print_exception(sys_exception)
+        return False
+    return True
+
+
 def get_redis() -> Redis | None:
     """Get the asynchronous redis client.