Skip to content

Commit 445645b

Browse files
Chore: Add check for dot env to avoid python env conflicts (#4866)
1 parent a3302e4 commit 445645b

File tree

2 files changed

+64
-2
lines changed

2 files changed

+64
-2
lines changed

sqlmesh/core/config/loader.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ def load_configs(
3737
for p in (glob.glob(str(path)) or [str(path)])
3838
]
3939

40-
if dotenv_path:
40+
if dotenv_path and dotenv_path.exists() and dotenv_path.is_file():
4141
load_dotenv(dotenv_path=dotenv_path, override=True)
4242
else:
4343
for path in absolute_paths:
44-
load_dotenv(dotenv_path=path / ".env", override=True)
44+
env_file = path / ".env"
45+
if env_file.exists() and env_file.is_file():
46+
load_dotenv(dotenv_path=env_file, override=True)
4547

4648
if not isinstance(config, str):
4749
if type(config) != config_type:

tests/core/test_config.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,66 @@ def test_load_yaml_config_dot_env_vars(tmp_path_factory):
12381238
)
12391239

12401240

1241+
def test_load_config_dotenv_directory_not_loaded(tmp_path_factory):
1242+
main_dir = tmp_path_factory.mktemp("config_with_env_dir")
1243+
config_path = main_dir / "config.yaml"
1244+
with open(config_path, "w", encoding="utf-8") as fd:
1245+
fd.write(
1246+
"""gateways:
1247+
test_gateway:
1248+
connection:
1249+
type: duckdb
1250+
database: test.db
1251+
model_defaults:
1252+
dialect: duckdb
1253+
"""
1254+
)
1255+
1256+
# Create a .env directory instead of a file to simulate a Python virtual environment
1257+
env_dir = main_dir / ".env"
1258+
env_dir.mkdir()
1259+
(env_dir / "pyvenv.cfg").touch()
1260+
1261+
# Also create a regular .env file in another project directory
1262+
other_dir = tmp_path_factory.mktemp("config_with_env_file")
1263+
other_config_path = other_dir / "config.yaml"
1264+
with open(other_config_path, "w", encoding="utf-8") as fd:
1265+
fd.write(
1266+
"""gateways:
1267+
test_gateway:
1268+
connection:
1269+
type: duckdb
1270+
database: test.db
1271+
model_defaults:
1272+
dialect: duckdb
1273+
"""
1274+
)
1275+
1276+
env_file = other_dir / ".env"
1277+
with open(env_file, "w", encoding="utf-8") as fd:
1278+
fd.write('TEST_ENV_VAR="from_dotenv_file"')
1279+
1280+
# Test that the .env directory doesn't cause an error and is skipped
1281+
with mock.patch.dict(os.environ, {}, clear=True):
1282+
load_configs(
1283+
"config",
1284+
Config,
1285+
paths=[main_dir],
1286+
)
1287+
# Should succeed without loading any env vars from the directory
1288+
assert "TEST_ENV_VAR" not in os.environ
1289+
1290+
# Test that a real .env file is still loaded properly
1291+
with mock.patch.dict(os.environ, {}, clear=True):
1292+
load_configs(
1293+
"config",
1294+
Config,
1295+
paths=[other_dir],
1296+
)
1297+
# The env var should be loaded from the file
1298+
assert os.environ.get("TEST_ENV_VAR") == "from_dotenv_file"
1299+
1300+
12411301
def test_load_yaml_config_custom_dotenv_path(tmp_path_factory):
12421302
main_dir = tmp_path_factory.mktemp("yaml_config_2")
12431303
config_path = main_dir / "config.yaml"

0 commit comments

Comments
 (0)