Circular import: importing data_designer.engine.models.errors (or .registry) first raises ImportError
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 72/100
Línea de trabajo
Start with engine/models/errors.py, engine/models/clients/__init__.py, and engine/models/clients/factory.py to trace the import cycle; then read tests/test_lazy_imports.py and its _run_python_snippet helper. Reproduce the failure with a fresh-process import of data_designer.engine.models.errors and check whether registry is covered too. Done means the relevant first-import cases succeed and regression tests pass.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Priority Level
Medium (Annoying but has workaround)
Describe the bug
In a fresh interpreter, import data_designer.engine.models.errors fails with:
ImportError: cannot import name 'FormattedLLMErrorMessage' from partially initialized module 'data_designer.engine.models.errors' (most likely due to a circular import)
import data_designer.engine.models.registry fails the same way, because it imports errors first. Importing almost any other Data Designer module first (data_designer.interface, data_designer.engine.models, ...models.facade, ...models.factory, ...models.clients) loads the modules in an order that avoids the cycle. So whether the import works depends on what the process happened to import earlier.
data_designer.engine.models.errors defines the model exception classes (ModelRateLimitError, ModelAuthenticationError, ModelContextWindowExceededError, and so on), and they aren't re-exported anywhere else. Code that catches them, such as a plugin, a script or a test module, crashes on import when this is its first Data Designer import. In test suites that shows up as failures that depend on collection order.
Steps/Code to reproduce bug
python -c "import data_designer.engine.models.errors"
Traceback (most recent call last):
File "<string>", line 1, in <module>
import data_designer.engine.models.errors
File ".../data_designer/engine/models/errors.py", line 14, in <module>
from data_designer.engine.models.clients.errors import ProviderError, ProviderErrorKind, SyncClientUnavailableError
File ".../data_designer/engine/models/clients/__init__.py", line 14, in <module>
from data_designer.engine.models.clients.factory import create_model_client
File ".../data_designer/engine/models/clients/factory.py", line 15, in <module>
from data_designer.engine.models.errors import FormattedLLMErrorMessage
ImportError: cannot import name 'FormattedLLMErrorMessage' from partially initialized module 'data_designer.engine.models.errors' (most likely due to a circular import) (.../data_designer/engine/models/errors.py)
python -c "import data_designer.engine.models.registry" fails with the same traceback. Importing another module first works around it:
python -c "import data_designer.engine.models.factory; import data_designer.engine.models.errors"
Reproduced on data-designer 0.9.3 and on main at f9aff6e (built from source).
Expected behavior
Every module imports successfully regardless of which Data Designer module the process imports first.
Agent Diagnostic / Prior Investigation
The cycle (at f9aff6e):
engine/models/errors.pyL14 importsengine.models.clients.errors, which first executes theclientspackage__init__.engine/models/clients/__init__.pyL14 eagerly importscreate_model_clientfromclients.factory.engine/models/clients/factory.pyL15 importsFormattedLLMErrorMessagefromengine.models.errors, which is still on its line 14, so the class (defined at L155) doesn't exist yet.factory.pyuses it in one place (L100).
registry.py imports errors at L11, so it enters the same cycle.
#781 fixed a regression caused by this same cycle. Its first revision made create_model_client a lazy export in clients/__init__.py, which broke the cycle. The merged version instead removed the health-check script's direct import of engine.models.errors and reverted the lazy export. The cycle itself is still present, so the error returns whenever errors or registry is the first module imported. The fresh-process test in tests/test_lazy_imports.py covers the health-check script's entry point, not this import order.
Additional context
Possible fixes, not mutually exclusive:
- Smallest: in
clients/factory.py, importFormattedLLMErrorMessageinside the function that uses it, with a short comment explaining why the import is deferred. - Remove the edge: move
FormattedLLMErrorMessageinto a module that doesn't importclients(for example next toGenerationTruncationReasoninengine/models/utils.py), and re-export it fromerrors.pyfor compatibility. - Public import path: if
engine.*is meant to stay internal, re-export the model exception classes from a public module (such asdata_designer.interface), so downstream code never has to importengine.models.errorsto catch them. That would fit the boundary direction taken in #781.
Regression coverage: a parametrized fresh-process test (the _run_python_snippet helper in tests/test_lazy_imports.py already does this) that imports each module under data_designer.engine.models as the very first import.
Happy to contribute a PR for whichever direction is preferred.
Checklist
- I reproduced this issue or provided a minimal example
- I searched the docs/issues myself, or had my agent do so
- If I used an agent, I included its diagnostics above
- Lenguaje dominante
- Python
- Estrellas
- 2.3k
- Forks
- 219
- Merge medio
- 1 d 21 h
- PR fusionados (30 d)
- 38
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de NVIDIA-NeMo/DataDesigner
-
docs: required_columns description is incomplete for LLM and multimodal columnsPosiblemente ocupada @nightcityblade la tomó hoy. Abiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
NVIDIA-NeMo/DataDesigner#1002 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
NVIDIA-NeMo/DataDesigner#995 ·
Los mantenedores suelen responder en 1 día
-
enforce \from future import annotations` via ruff FA102 rule`Posiblemente ocupada @chethanuk la tomó hace 28 días. Abiertotask
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
NVIDIA-NeMo/DataDesigner#760 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 63/100
NVIDIA-NeMo/DataDesigner#1001 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 4/5 3-5 días Aptitud para principiantes 53/100
NVIDIA-NeMo/DataDesigner#996 ·
Los mantenedores suelen responder en 1 día
Todos los issues de NVIDIA-NeMo/DataDesigner
Issues similares
-
Broken link in index.rstAbiertodocumentation
Dificultad 1/5 Menos de una hora Aptitud para principiantes 65/100
ansys/pydpf-core#3547 ·
Los mantenedores suelen responder en 1 día
-
core
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
vectorize-io/hindsight#5457 ·
Los mantenedores suelen responder en 1 día
-
[Bug]: LangChain drops OpenAI Responses text blocks from session recordingPosiblemente ocupada @ktz03 la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
volcengine/OpenViking#5806 ·
Los mantenedores suelen responder en 1 día
-
HTML: <template> content is extracted as document textPosiblemente ocupada @ryanmeowy la tomó hoy. Abiertobug html
Dificultad 1/5 Menos de una hora Aptitud para principiantes 82/100
docling-project/docling#4714 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
APIv2 event data accepts a non-string reply and a NaN upper_boundPosiblemente ocupada @awss1i la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
freedomofpress/securedrop#7946 · 1 comentario ·
Los mantenedores suelen responder en 2 días