@@ -286,3 +286,47 @@ class DummyConfig(ConfigBase):
286286 assert StubPluginConfigB in updated_union .__args__
287287 assert ConfigBase in updated_union .__args__
288288 assert DummyConfig in updated_union .__args__
289+
290+
291+ # =============================================================================
292+ # Circular Import Prevention Tests
293+ # =============================================================================
294+
295+
296+ def test_plugin_importing_from_base_does_not_cause_circular_import () -> None :
297+ """Test that a plugin importing from base.py doesn't cause circular imports during discovery."""
298+ import subprocess
299+ import sys
300+
301+ # Run a fresh Python process to test the import chain
302+ # This is necessary because Python caches modules, so we need a clean slate
303+ test_code = """
304+ import sys
305+
306+ # Track which modules trigger plugin discovery
307+ original_modules = set(sys.modules.keys())
308+
309+ # Import base.py - this should NOT cause column_types.py to be imported
310+ from data_designer.engine.column_generators.generators.base import ColumnGenerator
311+
312+ # Check if column_types was imported (which would trigger plugin discovery)
313+ if 'data_designer.config.column_types' in sys.modules:
314+ print("FAIL: column_types was imported when importing base.py")
315+ sys.exit(1)
316+ else:
317+ print("PASS: base.py does not import column_types at module level")
318+ sys.exit(0)
319+ """
320+
321+ result = subprocess .run (
322+ [sys .executable , "-c" , test_code ],
323+ capture_output = True ,
324+ text = True ,
325+ )
326+
327+ assert result .returncode == 0 , (
328+ f"Importing base.py triggered column_types.py import, which causes circular imports "
329+ f"for plugins that import from base.py.\n "
330+ f"stdout: { result .stdout } \n "
331+ f"stderr: { result .stderr } "
332+ )
0 commit comments