diff --git a/reflex/app.py b/reflex/app.py index 74ed31fe5..93b5d4d80 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -466,22 +466,29 @@ class App(Base): # Compile the pages. custom_components = set() thread_pool = ThreadPool() + compile_results = [] for route, component in self.pages.items(): component.add_style(self.style) - thread_pool.apply_async( - compiler.compile_page, - args=( - route, - component, - self.state, - self.connect_error_component, - ), + compile_results.append( + thread_pool.apply_async( + compiler.compile_page, + args=( + route, + component, + self.state, + self.connect_error_component, + ), + ) ) # Add the custom components from the page to the set. custom_components |= component.get_custom_components() thread_pool.close() thread_pool.join() + # check the results of all the threads in case an exception was raised. + for r in compile_results: + r.get() + # Compile the custom components. compiler.compile_components(custom_components) diff --git a/reflex/compiler/compiler.py b/reflex/compiler/compiler.py index 364291efa..bd3c23444 100644 --- a/reflex/compiler/compiler.py +++ b/reflex/compiler/compiler.py @@ -78,11 +78,13 @@ def _compile_page( state: The app state. connect_error_component: The component to render on sever connection error. + Returns: The compiled component. """ # Merge the default imports with the app-specific imports. imports = utils.merge_imports(DEFAULT_IMPORTS, component.get_imports()) + utils.validate_imports(imports) imports = utils.compile_imports(imports) # Compile the code to render the component. diff --git a/reflex/compiler/utils.py b/reflex/compiler/utils.py index 639b0d412..0edba6f78 100644 --- a/reflex/compiler/utils.py +++ b/reflex/compiler/utils.py @@ -51,6 +51,28 @@ def compile_import_statement(fields: Set[ImportVar]) -> Tuple[str, Set[str]]: return default, rest +def validate_imports(imports: imports.ImportDict): + """Verify that the same Tag is not used in multiple import. + + Args: + imports: The dict of imports to validate + + Raises: + ValueError: if a conflict on "tag/alias" is detected for an import. + """ + used_tags = {} + for lib, _imports in imports.items(): + for _import in _imports: + import_name = ( + f"{_import.tag}/{_import.alias}" if _import.alias else _import.tag + ) + if import_name in used_tags: + raise ValueError( + f"Can not compile, the tag {import_name} is used multiple time from {lib} and {used_tags[import_name]}" + ) + used_tags[import_name] = lib + + def compile_imports(imports: imports.ImportDict) -> List[dict]: """Compile an import dict. diff --git a/reflex/components/datadisplay/code.py b/reflex/components/datadisplay/code.py index 4453f75c7..ce736adbe 100644 --- a/reflex/components/datadisplay/code.py +++ b/reflex/components/datadisplay/code.py @@ -44,6 +44,8 @@ class CodeBlock(Component): # Props passed down to the code tag. code_tag_props: Var[Dict[str, str]] + is_default = True + def _get_imports(self) -> imports.ImportDict: merged_imports = super()._get_imports() if self.theme is not None: