Skip to content

Commit da1ae4e

Browse files
SNOW-902097 adding default_connection_name and default value to ConfigOption (#1718)
1 parent 8f2dcbf commit da1ae4e

File tree

3 files changed

+78
-2
lines changed

3 files changed

+78
-2
lines changed

DESCRIPTION.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Source code is also available at: https://github.com/snowflakedb/snowflake-conne
1111
- v3.1.2(TBD)
1212

1313
- Made the ``parser`` -> ``manager`` renaming more consistent in ``snowflake.connector.config_manager`` module.
14+
- Added support for default values for ConfigOptions
15+
- Added default_connection_name to config.toml file
1416

1517
- v3.1.1(August 28,2023)
1618

src/snowflake/connector/config_manager.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ class ConfigOption:
6262
supplied, we'll construct this. False disables reading from
6363
environmental variables, None uses the auto generated variable name
6464
and explicitly provided string overwrites the default one.
65+
default: The value we should resolve to when the option is not defined
66+
in any of the sources. When it's None we treat that as there's no
67+
default value.
6568
_root_manager: Reference to the root manager. Used to efficiently
6669
refer to cached config file. Is supplied by the parent
6770
ConfigManager.
@@ -78,6 +81,7 @@ def __init__(
7881
parse_str: Callable[[str], _T] | None = None,
7982
choices: Iterable[Any] | None = None,
8083
env_name: str | None | Literal[False] = None,
84+
default: Any | None = None,
8185
_root_manager: ConfigManager | None = None,
8286
_nest_path: list[str] | None,
8387
) -> None:
@@ -91,6 +95,8 @@ def __init__(
9195
Providing a string will use that environment variable, False disables
9296
reading value from environmental variables and the default None generates
9397
an environmental variable name for it using the _nest_path and name.
98+
default: Default value for the option. Used in case the value is
99+
is not defined in any of the sources.
94100
_root_manager: Reference to the root manager. Should be supplied by
95101
the parent ConfigManager.
96102
_nest_path: The names of the ConfigManagers that this option is
@@ -106,6 +112,7 @@ def __init__(
106112
self._nest_path = _nest_path + [name]
107113
self._root_manager: ConfigManager = _root_manager
108114
self.env_name = env_name
115+
self.default = default
109116

110117
def value(self) -> Any:
111118
"""Retrieve a value of option.
@@ -115,8 +122,15 @@ def value(self) -> Any:
115122
source = "environment variable"
116123
loaded_env, value = self._get_env()
117124
if not loaded_env:
118-
source = "configuration file"
119-
value = self._get_config()
125+
try:
126+
value = self._get_config()
127+
source = "configuration file"
128+
except MissingConfigOptionError:
129+
if self.default:
130+
source = "default_value"
131+
value = self.default
132+
else:
133+
raise
120134
if self.choices and value not in self.choices:
121135
raise ConfigSourceError(
122136
f"The value of {self.option_name} read from "
@@ -436,6 +450,10 @@ def __getitem__(self, name: str) -> ConfigOption | ConfigManager:
436450
name="connections",
437451
parse_str=tomlkit.parse,
438452
)
453+
CONFIG_MANAGER.add_option(
454+
name="default_connection_name",
455+
default="default",
456+
)
439457

440458

441459
def __getattr__(name):

test/unit/test_configmanager.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import re
99
import shutil
1010
import stat
11+
import string
1112
import warnings
1213
from pathlib import Path
1314
from test.randomize import random_string
@@ -22,6 +23,7 @@
2223

2324
try:
2425
from snowflake.connector.config_manager import (
26+
CONFIG_MANAGER,
2527
ConfigManager,
2628
ConfigOption,
2729
ConfigSlice,
@@ -653,3 +655,57 @@ def test_deprecationwarning_config_parser():
653655
== "CONFIG_PARSER has been deprecated, use CONFIG_MANAGER instead"
654656
)
655657
assert config_manager.CONFIG_MANAGER is config_manager.CONFIG_PARSER
658+
659+
660+
def test_configoption_default_value(tmp_path, monkeypatch):
661+
env_name = random_string(
662+
5,
663+
"SF_TEST_OPTION_",
664+
choices=string.ascii_uppercase,
665+
)
666+
conf_val = random_string(5)
667+
cm = ConfigManager(
668+
name="test_manager",
669+
file_path=tmp_path / "config.toml",
670+
)
671+
cm.add_option(
672+
name="test_option",
673+
env_name=env_name,
674+
default=conf_val,
675+
)
676+
assert cm["test_option"] == conf_val
677+
env_value = random_string(5)
678+
with monkeypatch.context() as c:
679+
c.setenv(env_name, env_value)
680+
assert cm["test_option"] == env_value
681+
682+
683+
def test_defaultconnectionname(tmp_path, monkeypatch):
684+
c_file = tmp_path / "config.toml"
685+
old_path = CONFIG_MANAGER.file_path
686+
CONFIG_MANAGER.file_path = c_file
687+
CONFIG_MANAGER.conf_file_cache = None
688+
try:
689+
with monkeypatch.context() as m:
690+
m.delenv("SNOWFLAKE_DEFAULT_CONNECTION_NAME", raising=False)
691+
assert CONFIG_MANAGER["default_connection_name"] == "default"
692+
env_val = random_string(5, "DEF_CONN_")
693+
with monkeypatch.context() as m:
694+
m.setenv("SNOWFLAKE_DEFAULT_CONNECTION_NAME", env_val)
695+
assert CONFIG_MANAGER["default_connection_name"] == env_val
696+
assert CONFIG_MANAGER.file_path is not None
697+
con_name = random_string(5, "conn_")
698+
c_file.write_text(
699+
dedent(
700+
f"""\
701+
default_connection_name = "{con_name}"
702+
"""
703+
)
704+
)
705+
# re-cache config file from disk
706+
CONFIG_MANAGER.file_path = c_file
707+
CONFIG_MANAGER.conf_file_cache = None
708+
assert CONFIG_MANAGER["default_connection_name"] == con_name
709+
finally:
710+
CONFIG_MANAGER.file_path = old_path
711+
CONFIG_MANAGER.conf_file_cache = None

0 commit comments

Comments
 (0)