2828
2929
3030def test_config () -> None :
31- """To check if all the file lookups go well without any mocking """
31+ """Config() should be a pure empty container and perform no implicit IO. """
3232 assert Config ()
33+ assert Config ().config == {}
34+
35+
36+ def test_config_does_not_load_implicitly () -> None :
37+ with (
38+ mock .patch .object (Config , "_from_configuration_files" ) as from_files_mock ,
39+ mock .patch .object (Config , "_from_environment_variables" ) as from_env_mock ,
40+ ):
41+ Config ()
42+
43+ from_files_mock .assert_not_called ()
44+ from_env_mock .assert_not_called ()
3345
3446
3547@mock .patch .dict (os .environ , EXAMPLE_ENV )
3648def test_from_environment_variables () -> None :
37- assert Config ().get_catalog_config ("production" ) == {"uri" : "https://service.io/api" }
49+ assert Config . load ().get_catalog_config ("production" ) == {"uri" : "https://service.io/api" }
3850
3951
4052@mock .patch .dict (os .environ , EXAMPLE_ENV )
4153def test_from_environment_variables_uppercase () -> None :
42- assert Config ().get_catalog_config ("PRODUCTION" ) == {"uri" : "https://service.io/api" }
54+ assert Config . load ().get_catalog_config ("PRODUCTION" ) == {"uri" : "https://service.io/api" }
4355
4456
4557@mock .patch .dict (
@@ -50,7 +62,7 @@ def test_from_environment_variables_uppercase() -> None:
5062 },
5163)
5264def test_fix_nested_objects_from_environment_variables () -> None :
53- assert Config ().get_catalog_config ("PRODUCTION" ) == {
65+ assert Config . load ().get_catalog_config ("PRODUCTION" ) == {
5466 "s3.region" : "eu-north-1" ,
5567 "s3.access-key-id" : "username" ,
5668 }
@@ -59,7 +71,7 @@ def test_fix_nested_objects_from_environment_variables() -> None:
5971@mock .patch .dict (os .environ , EXAMPLE_ENV )
6072@mock .patch .dict (os .environ , {"PYICEBERG_CATALOG__DEVELOPMENT__URI" : "https://dev.service.io/api" })
6173def test_list_all_known_catalogs () -> None :
62- catalogs = Config ().get_known_catalogs ()
74+ catalogs = Config . load ().get_known_catalogs ()
6375 assert "production" in catalogs
6476 assert "development" in catalogs
6577
@@ -71,7 +83,7 @@ def test_from_configuration_files(tmp_path_factory: pytest.TempPathFactory) -> N
7183 file .write (yaml_str )
7284
7385 os .environ ["PYICEBERG_HOME" ] = config_path
74- assert Config ().get_catalog_config ("production" ) == {"uri" : "https://service.io/api" }
86+ assert Config . load ().get_catalog_config ("production" ) == {"uri" : "https://service.io/api" }
7587
7688
7789def test_lowercase_dictionary_keys () -> None :
@@ -95,13 +107,13 @@ def test_from_configuration_files_get_typed_value(tmp_path_factory: pytest.TempP
95107
96108 os .environ ["PYICEBERG_HOME" ] = config_path
97109 with pytest .raises (ValueError ):
98- Config ().get_bool ("max-workers" )
110+ Config . load ().get_bool ("max-workers" )
99111
100112 with pytest .raises (ValueError ):
101- Config ().get_int ("legacy-current-snapshot-id" )
113+ Config . load ().get_int ("legacy-current-snapshot-id" )
102114
103- assert Config ().get_bool ("legacy-current-snapshot-id" )
104- assert Config ().get_int ("max-workers" ) == 4
115+ assert Config . load ().get_bool ("legacy-current-snapshot-id" )
116+ assert Config . load ().get_int ("max-workers" ) == 4
105117
106118
107119@pytest .mark .parametrize (
@@ -183,3 +195,14 @@ def create_config_file(path: str, uri: str | None) -> None:
183195 assert (
184196 result ["catalog" ]["default" ]["uri" ] if result else None # type: ignore
185197 ) == expected_result , f"Unexpected configuration result. Expected: { expected_result } , Actual: { result } "
198+
199+
200+ def test_load_reads_file_and_environment_once (monkeypatch : pytest .MonkeyPatch ) -> None :
201+ monkeypatch .setenv ("PYICEBERG_CATALOG__PRODUCTION__URI" , "https://env.service.io/api" )
202+ with mock .patch .object (
203+ Config , "_from_configuration_files" , return_value = {"catalog" : {"production" : {"type" : "rest" }}}
204+ ) as files_mock :
205+ config = Config .load ()
206+
207+ files_mock .assert_called_once ()
208+ assert config .get_catalog_config ("production" ) == {"type" : "rest" , "uri" : "https://env.service.io/api" }
0 commit comments