From 3417068618594ecb1782759b5282d0238959bb29 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Wed, 9 Mar 2022 17:37:46 +0100 Subject: [PATCH 01/20] Re-add database user and password as settings, and rename from MYSQL_* to SQL_* --- terracotta/config.py | 12 ++++++------ terracotta/drivers/relational_meta_store.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/terracotta/config.py b/terracotta/config.py index ee44f563..9f4a6f4d 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -67,11 +67,11 @@ class TerracottaSettings(NamedTuple): #: CORS allowed origins for tiles endpoints ALLOWED_ORIGINS_TILES: List[str] = [r'http[s]?://(localhost|127\.0\.0\.1):*'] - #: MySQL database username (if not given in driver path) - MYSQL_USER: Optional[str] = None + #: SQL database username (if not given in driver path) + SQL_USER: Optional[str] = None - #: MySQL database password (if not given in driver path) - MYSQL_PASSWORD: Optional[str] = None + #: SQL database password (if not given in driver path) + SQL_PASSWORD: Optional[str] = None #: Use a process pool for band retrieval in parallel USE_MULTIPROCESSING: bool = True @@ -123,8 +123,8 @@ class SettingSchema(Schema): ALLOWED_ORIGINS_METADATA = fields.List(fields.String()) ALLOWED_ORIGINS_TILES = fields.List(fields.String()) - MYSQL_USER = fields.String() - MYSQL_PASSWORD = fields.String() + SQL_USER = fields.String() + SQL_PASSWORD = fields.String() USE_MULTIPROCESSING = fields.Boolean() diff --git a/terracotta/drivers/relational_meta_store.py b/terracotta/drivers/relational_meta_store.py index 2ccdf45f..bb772f1e 100644 --- a/terracotta/drivers/relational_meta_store.py +++ b/terracotta/drivers/relational_meta_store.py @@ -115,8 +115,8 @@ def _parse_path(cls, connection_string: str) -> URL: url = URL.create( drivername=f'{cls.SQL_DIALECT}+{cls.SQL_DRIVER}', - username=con_params.username, - password=con_params.password, + username=con_params.username or terracotta.get_settings().SQL_USER, + password=con_params.password or terracotta.get_settings().SQL_PASSWORD, host=con_params.hostname, port=con_params.port, database=con_params.path[1:], # remove leading '/' from urlparse From 8aa22816d38d0c095b06402b4b9b0f18f34d1e12 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Tue, 29 Mar 2022 13:40:14 +0200 Subject: [PATCH 02/20] Implement config settings deprecation system --- terracotta/config.py | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/terracotta/config.py b/terracotta/config.py index 9f4a6f4d..c7c950cd 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -7,12 +7,13 @@ import os import json import tempfile +import warnings from marshmallow import Schema, fields, validate, pre_load, post_load, ValidationError class TerracottaSettings(NamedTuple): - """Contains all settings for the current Terracotta instance.""" + """Contains all non-deprecated settings for the current Terracotta instance.""" #: Path to database DRIVER_PATH: str = '' @@ -77,7 +78,21 @@ class TerracottaSettings(NamedTuple): USE_MULTIPROCESSING: bool = True -AVAILABLE_SETTINGS: Tuple[str, ...] = tuple(TerracottaSettings._fields) +class DeprecatedTerracottaSettings(NamedTuple): + """Contains all deprecated, but still existing, settings.""" + #: MySQL database username (if not given in driver path) + MYSQL_USER: Optional[str] = None + + #: MySQL database password (if not given in driver path) + MYSQL_PASSWORD: Optional[str] = None + + +DEPRECATION_MAP: Dict[str, str] = { + 'MYSQL_USER': 'SQL_USER', + # 'MYSQL_PASSWORD': 'SQL_PASSWORD', +} + +AVAILABLE_SETTINGS: Tuple[str, ...] = (*TerracottaSettings._fields, *DeprecatedTerracottaSettings._fields) def _is_writable(path: str) -> bool: @@ -160,6 +175,22 @@ def parse_config(config: Mapping[str, Any] = None) -> TerracottaSettings: for setting in AVAILABLE_SETTINGS: env_setting = f'TC_{setting}' + + if setting in DeprecatedTerracottaSettings._fields: + if setting in DEPRECATION_MAP: + warnings.warn( + f'Setting TC_{setting} is being deprecated. ' + f'Please use TC_{DEPRECATION_MAP[setting]} instead.', + PendingDeprecationWarning + ) + setting = DEPRECATION_MAP[setting] + else: + warnings.warn( + f'Setting TC_{setting} is deprecated and no longer has any effect.', + DeprecationWarning + ) + continue + if setting not in config_dict and env_setting in os.environ: config_dict[setting] = os.environ[env_setting] From 12d5043deda59259a91071603db4e117b1c98f36 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Tue, 29 Mar 2022 13:43:37 +0200 Subject: [PATCH 03/20] Include the accidentally excluded MYSQL_PASSWORD in the deprecation map --- terracotta/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terracotta/config.py b/terracotta/config.py index c7c950cd..0226593f 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -89,7 +89,7 @@ class DeprecatedTerracottaSettings(NamedTuple): DEPRECATION_MAP: Dict[str, str] = { 'MYSQL_USER': 'SQL_USER', - # 'MYSQL_PASSWORD': 'SQL_PASSWORD', + 'MYSQL_PASSWORD': 'SQL_PASSWORD', } AVAILABLE_SETTINGS: Tuple[str, ...] = (*TerracottaSettings._fields, *DeprecatedTerracottaSettings._fields) From c6f6b3b67f6a5b8209cea7a6fd86b600df52876c Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Tue, 29 Mar 2022 13:50:12 +0200 Subject: [PATCH 04/20] Merge main branch into fix-db-connection-settings --- terracotta/config.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/terracotta/config.py b/terracotta/config.py index f88f4281..1880f102 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -138,15 +138,8 @@ class SettingSchema(Schema): ALLOWED_ORIGINS_METADATA = fields.List(fields.String()) ALLOWED_ORIGINS_TILES = fields.List(fields.String()) -<<<<<<< HEAD SQL_USER = fields.String() SQL_PASSWORD = fields.String() -======= - MYSQL_USER = fields.String() - MYSQL_PASSWORD = fields.String() - POSTGRESQL_USER = fields.String() - POSTGRESQL_PASSWORD = fields.String() ->>>>>>> main USE_MULTIPROCESSING = fields.Boolean() From 5b91dd03ddca7157f448a2e8208922355390e1ba Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Tue, 29 Mar 2022 13:52:00 +0200 Subject: [PATCH 05/20] Include postgres user/password settings as deprecated --- terracotta/config.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/terracotta/config.py b/terracotta/config.py index 1880f102..a433bfa8 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -86,10 +86,18 @@ class DeprecatedTerracottaSettings(NamedTuple): #: MySQL database password (if not given in driver path) MYSQL_PASSWORD: Optional[str] = None + #: PostgreSQL database username (if not given in driver path) + POSTGRESQL_USER: Optional[str] = None + + #: PostgreSQL database password (if not given in driver path) + POSTGRESQL_PASSWORD: Optional[str] = None + DEPRECATION_MAP: Dict[str, str] = { 'MYSQL_USER': 'SQL_USER', 'MYSQL_PASSWORD': 'SQL_PASSWORD', + 'POSTGRESQL_USER': 'SQL_USER', + 'POSTGRESQL_PASSWORD': 'SQL_PASSWORD', } AVAILABLE_SETTINGS: Tuple[str, ...] = (*TerracottaSettings._fields, *DeprecatedTerracottaSettings._fields) From 80006c6ed2c54a83b36035577c614dfd085ba578 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Tue, 29 Mar 2022 14:26:40 +0200 Subject: [PATCH 06/20] Please flake8 --- terracotta/config.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/terracotta/config.py b/terracotta/config.py index a433bfa8..311feeaf 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -100,7 +100,10 @@ class DeprecatedTerracottaSettings(NamedTuple): 'POSTGRESQL_PASSWORD': 'SQL_PASSWORD', } -AVAILABLE_SETTINGS: Tuple[str, ...] = (*TerracottaSettings._fields, *DeprecatedTerracottaSettings._fields) +AVAILABLE_SETTINGS: Tuple[str, ...] = ( + *TerracottaSettings._fields, + *DeprecatedTerracottaSettings._fields +) def _is_writable(path: str) -> bool: From 49ede5f3313d9119b5cce3d1b98b5c11b08ed06b Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Tue, 5 Apr 2022 13:25:49 +0200 Subject: [PATCH 07/20] Add DeprecationWarning exception --- terracotta/exceptions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/terracotta/exceptions.py b/terracotta/exceptions.py index b6d904b2..747fd751 100644 --- a/terracotta/exceptions.py +++ b/terracotta/exceptions.py @@ -26,3 +26,6 @@ class InvalidDatabaseError(Exception): class PerformanceWarning(UserWarning): pass + +class DeprecationWarning(UserWarning): + pass From b9f39743df21ad0587b7aad19f3ddd45d82e4568 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Tue, 5 Apr 2022 13:26:46 +0200 Subject: [PATCH 08/20] Handle deprecated settings in schema preload, and provide better warnings --- terracotta/config.py | 71 ++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/terracotta/config.py b/terracotta/config.py index 311feeaf..b74dcc83 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -11,6 +11,8 @@ from marshmallow import Schema, fields, validate, pre_load, post_load, ValidationError +from terracotta import exceptions + class TerracottaSettings(NamedTuple): """Contains all non-deprecated settings for the current Terracotta instance.""" @@ -74,24 +76,23 @@ class TerracottaSettings(NamedTuple): #: SQL database password (if not given in driver path) SQL_PASSWORD: Optional[str] = None - #: Use a process pool for band retrieval in parallel - USE_MULTIPROCESSING: bool = True - - -class DeprecatedTerracottaSettings(NamedTuple): - """Contains all deprecated, but still existing, settings.""" - #: MySQL database username (if not given in driver path) + #: Deprecated, use SQL_USER. MySQL database username (if not given in driver path) MYSQL_USER: Optional[str] = None - #: MySQL database password (if not given in driver path) + #: Deprecated, use SQL_PASSWORD. MySQL database password (if not given in driver path) MYSQL_PASSWORD: Optional[str] = None - #: PostgreSQL database username (if not given in driver path) + #: Deprecated, use SQL_USER. PostgreSQL database username (if not given in driver path) POSTGRESQL_USER: Optional[str] = None - #: PostgreSQL database password (if not given in driver path) + #: Deprecated, use SQL_PASSWORD. PostgreSQL database password (if not given in driver path) POSTGRESQL_PASSWORD: Optional[str] = None + #: Use a process pool for band retrieval in parallel + USE_MULTIPROCESSING: bool = True + + +AVAILABLE_SETTINGS: Tuple[str, ...] = TerracottaSettings._fields DEPRECATION_MAP: Dict[str, str] = { 'MYSQL_USER': 'SQL_USER', @@ -100,11 +101,6 @@ class DeprecatedTerracottaSettings(NamedTuple): 'POSTGRESQL_PASSWORD': 'SQL_PASSWORD', } -AVAILABLE_SETTINGS: Tuple[str, ...] = ( - *TerracottaSettings._fields, - *DeprecatedTerracottaSettings._fields -) - def _is_writable(path: str) -> bool: return os.access(os.path.dirname(path) or os.getcwd(), os.W_OK) @@ -149,8 +145,13 @@ class SettingSchema(Schema): ALLOWED_ORIGINS_METADATA = fields.List(fields.String()) ALLOWED_ORIGINS_TILES = fields.List(fields.String()) - SQL_USER = fields.String() - SQL_PASSWORD = fields.String() + SQL_USER = fields.String(allow_none=True) + SQL_PASSWORD = fields.String(allow_none=True) + + MYSQL_USER = fields.String(allow_none=True) + MYSQL_PASSWORD = fields.String(allow_none=True) + POSTGRESQL_USER = fields.String(allow_none=True) + POSTGRESQL_PASSWORD = fields.String(allow_none=True) USE_MULTIPROCESSING = fields.Boolean() @@ -167,6 +168,26 @@ def decode_lists(self, data: Dict[str, Any], **kwargs: Any) -> Dict[str, Any]: f'Could not parse value for key {var} as JSON: "{val}"' ) from exc return data + + @pre_load + def handle_deprecated_fields(self, data: Dict[str, Any], **kwargs: Any) -> Dict[str, Any]: + for deprecated_field, new_field in DEPRECATION_MAP.items(): + if data.get(deprecated_field): + if not data.get(new_field): + warnings.warn( + f'Setting TC_{deprecated_field} is being deprecated. ' + f'Please use TC_{new_field} instead.', + exceptions.DeprecationWarning + ) + data[new_field] = data[deprecated_field] + else: + warnings.warn( + f'Both the deprecated TC_{deprecated_field} setting ' + f'and its replacement TC_{new_field} is set: ' + 'This may result in unexpected behaviour.', + exceptions.DeprecationWarning + ) + return data @post_load def make_settings(self, data: Dict[str, Any], **kwargs: Any) -> TerracottaSettings: @@ -186,22 +207,6 @@ def parse_config(config: Mapping[str, Any] = None) -> TerracottaSettings: for setting in AVAILABLE_SETTINGS: env_setting = f'TC_{setting}' - - if setting in DeprecatedTerracottaSettings._fields: - if setting in DEPRECATION_MAP: - warnings.warn( - f'Setting TC_{setting} is being deprecated. ' - f'Please use TC_{DEPRECATION_MAP[setting]} instead.', - PendingDeprecationWarning - ) - setting = DEPRECATION_MAP[setting] - else: - warnings.warn( - f'Setting TC_{setting} is deprecated and no longer has any effect.', - DeprecationWarning - ) - continue - if setting not in config_dict and env_setting in os.environ: config_dict[setting] = os.environ[env_setting] From 24d08a0cfd9a0b9bc595c3ff3d340158e13964dc Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Tue, 5 Apr 2022 13:28:39 +0200 Subject: [PATCH 09/20] Adhere flake8 style guide --- terracotta/config.py | 2 +- terracotta/exceptions.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/terracotta/config.py b/terracotta/config.py index b74dcc83..71fde853 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -168,7 +168,7 @@ def decode_lists(self, data: Dict[str, Any], **kwargs: Any) -> Dict[str, Any]: f'Could not parse value for key {var} as JSON: "{val}"' ) from exc return data - + @pre_load def handle_deprecated_fields(self, data: Dict[str, Any], **kwargs: Any) -> Dict[str, Any]: for deprecated_field, new_field in DEPRECATION_MAP.items(): diff --git a/terracotta/exceptions.py b/terracotta/exceptions.py index 747fd751..3ba3eeab 100644 --- a/terracotta/exceptions.py +++ b/terracotta/exceptions.py @@ -27,5 +27,6 @@ class InvalidDatabaseError(Exception): class PerformanceWarning(UserWarning): pass + class DeprecationWarning(UserWarning): pass From 285e4b10990d93b5aca3cdb01541e8a1882b6664 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Tue, 5 Apr 2022 14:35:20 +0200 Subject: [PATCH 10/20] Test usage of TC_SQL_* env var credentials --- tests/drivers/test_drivers.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/drivers/test_drivers.py b/tests/drivers/test_drivers.py index a584833f..c1c8e5fe 100644 --- a/tests/drivers/test_drivers.py +++ b/tests/drivers/test_drivers.py @@ -261,3 +261,23 @@ def test_invalid_key_types(driver_path, provider): with pytest.raises(exceptions.InvalidKeyError) as exc: db.get_datasets({'not-a-key': 'val'}) assert 'unrecognized keys' in str(exc) + + +@pytest.mark.parametrize('provider', TESTABLE_DRIVERS) +def test_use_credentials_from_settings(driver_path, provider, monkeypatch): + with monkeypatch.context() as m: + m.setenv('TC_SQL_USER', 'foo') + m.setenv('TC_SQL_PASSWORD', 'bar') + + from terracotta import drivers, update_settings + update_settings() + + if 'sqlite' not in provider: + meta_store_class = drivers.load_driver(provider) + assert meta_store_class._parse_path('').username == 'foo' + assert meta_store_class._parse_path('').password == 'bar' + + driver_path_without_credentials = driver_path[driver_path.find('@')+1:] + db = drivers.get_driver(driver_path_without_credentials, provider) + assert db.meta_store.url.username == 'foo' + assert db.meta_store.url.password == 'bar' From 3931a35396e54118f0d32a130f0dc1954fa01e3e Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Tue, 5 Apr 2022 14:47:47 +0200 Subject: [PATCH 11/20] Test behaviour of handling of deprecated config settings --- tests/test_config.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_config.py b/tests/test_config.py index 4d2af340..090becad 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -76,3 +76,26 @@ def test_update_config(): update_settings(DEFAULT_TILE_SIZE=[50, 50]) new_settings = get_settings() assert new_settings.DRIVER_PATH == 'test' and new_settings.DEFAULT_TILE_SIZE == (50, 50) + + +def test_deprecation_behaviour(monkeypatch): + from terracotta import config, exceptions, get_settings, update_settings + for deprecated_field, new_field in config.DEPRECATION_MAP.items(): + with monkeypatch.context() as m: + m.setenv(f'TC_{deprecated_field}', 'foo') + + with pytest.warns(exceptions.DeprecationWarning) as warning: + update_settings() + assert f'TC_{deprecated_field} is being deprecated' in str(warning[0]) + + assert getattr(get_settings(), deprecated_field) == 'foo' + assert getattr(get_settings(), new_field) == 'foo' + + m.setenv(f'TC_{new_field}', 'bar') + + with pytest.warns(exceptions.DeprecationWarning) as warning: + update_settings() + assert f'and its replacement TC_{new_field} is set' in str(warning[0]) + + assert getattr(get_settings(), deprecated_field) == 'foo' + assert getattr(get_settings(), new_field) == 'bar' From 2b2555f78aff01bcb1632be64fcdbe08883f13c5 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Tue, 5 Apr 2022 14:52:10 +0200 Subject: [PATCH 12/20] Adhere to flake8 style guide --- tests/drivers/test_drivers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/drivers/test_drivers.py b/tests/drivers/test_drivers.py index c1c8e5fe..ea8f1ccf 100644 --- a/tests/drivers/test_drivers.py +++ b/tests/drivers/test_drivers.py @@ -277,7 +277,7 @@ def test_use_credentials_from_settings(driver_path, provider, monkeypatch): assert meta_store_class._parse_path('').username == 'foo' assert meta_store_class._parse_path('').password == 'bar' - driver_path_without_credentials = driver_path[driver_path.find('@')+1:] + driver_path_without_credentials = driver_path[driver_path.find('@') + 1:] db = drivers.get_driver(driver_path_without_credentials, provider) assert db.meta_store.url.username == 'foo' assert db.meta_store.url.password == 'bar' From e486b8bf897e727fcf802fcc84154b0477108c58 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Tue, 5 Apr 2022 14:58:15 +0200 Subject: [PATCH 13/20] Fix docstring --- terracotta/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terracotta/config.py b/terracotta/config.py index 71fde853..6395cd9b 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -15,7 +15,7 @@ class TerracottaSettings(NamedTuple): - """Contains all non-deprecated settings for the current Terracotta instance.""" + """Contains all settings for the current Terracotta instance.""" #: Path to database DRIVER_PATH: str = '' From de85eeca46bbfdf572a8e5738d966bdc1b3fa403 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Wed, 27 Apr 2022 11:20:38 +0200 Subject: [PATCH 14/20] Add comment about when settings shall be removed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dion Häfner --- terracotta/config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/terracotta/config.py b/terracotta/config.py index 6395cd9b..4e58d51a 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -95,6 +95,7 @@ class TerracottaSettings(NamedTuple): AVAILABLE_SETTINGS: Tuple[str, ...] = TerracottaSettings._fields DEPRECATION_MAP: Dict[str, str] = { + # TODO: Remove in v0.8.0 'MYSQL_USER': 'SQL_USER', 'MYSQL_PASSWORD': 'SQL_PASSWORD', 'POSTGRESQL_USER': 'SQL_USER', From 05f1917905e91acd7016da2e9f751f6a6ed991e0 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Wed, 27 Apr 2022 11:21:05 +0200 Subject: [PATCH 15/20] Improve deprecated setting warning message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dion Häfner --- terracotta/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terracotta/config.py b/terracotta/config.py index 4e58d51a..ffcc1aea 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -176,7 +176,7 @@ def handle_deprecated_fields(self, data: Dict[str, Any], **kwargs: Any) -> Dict[ if data.get(deprecated_field): if not data.get(new_field): warnings.warn( - f'Setting TC_{deprecated_field} is being deprecated. ' + f'Setting TC_{deprecated_field} is deprecated and will be removed in the next major release. ' f'Please use TC_{new_field} instead.', exceptions.DeprecationWarning ) From 8acb4486cdef1a0a6a0ab1e5054bbb6e989de2c7 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Wed, 27 Apr 2022 11:22:41 +0200 Subject: [PATCH 16/20] Adhere to flake8 max line length --- terracotta/config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/terracotta/config.py b/terracotta/config.py index ffcc1aea..f3bbbf26 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -176,7 +176,8 @@ def handle_deprecated_fields(self, data: Dict[str, Any], **kwargs: Any) -> Dict[ if data.get(deprecated_field): if not data.get(new_field): warnings.warn( - f'Setting TC_{deprecated_field} is deprecated and will be removed in the next major release. ' + f'Setting TC_{deprecated_field} is deprecated ' + 'and will be removed in the next major release. ' f'Please use TC_{new_field} instead.', exceptions.DeprecationWarning ) From 3c562ca74492c7719d8d78e0ad19f39ac41ebf2d Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Wed, 27 Apr 2022 11:26:13 +0200 Subject: [PATCH 17/20] Simply warnings for usage of deprecated fields --- terracotta/config.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/terracotta/config.py b/terracotta/config.py index f3bbbf26..270e09ac 100644 --- a/terracotta/config.py +++ b/terracotta/config.py @@ -174,21 +174,17 @@ def decode_lists(self, data: Dict[str, Any], **kwargs: Any) -> Dict[str, Any]: def handle_deprecated_fields(self, data: Dict[str, Any], **kwargs: Any) -> Dict[str, Any]: for deprecated_field, new_field in DEPRECATION_MAP.items(): if data.get(deprecated_field): + warnings.warn( + f'Setting TC_{deprecated_field} is deprecated ' + 'and will be removed in the next major release. ' + f'Please use TC_{new_field} instead.', + exceptions.DeprecationWarning + ) + + # Only use the mapping if the new field has not been set if not data.get(new_field): - warnings.warn( - f'Setting TC_{deprecated_field} is deprecated ' - 'and will be removed in the next major release. ' - f'Please use TC_{new_field} instead.', - exceptions.DeprecationWarning - ) data[new_field] = data[deprecated_field] - else: - warnings.warn( - f'Both the deprecated TC_{deprecated_field} setting ' - f'and its replacement TC_{new_field} is set: ' - 'This may result in unexpected behaviour.', - exceptions.DeprecationWarning - ) + return data @post_load From 39766495b38bbccf79ad4aae3f068619125a1eb7 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Wed, 27 Apr 2022 11:27:33 +0200 Subject: [PATCH 18/20] Fetch settings once when creating URL instance --- terracotta/drivers/relational_meta_store.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/terracotta/drivers/relational_meta_store.py b/terracotta/drivers/relational_meta_store.py index 60312c64..62179b7c 100644 --- a/terracotta/drivers/relational_meta_store.py +++ b/terracotta/drivers/relational_meta_store.py @@ -113,10 +113,11 @@ def _parse_path(cls, connection_string: str) -> URL: if con_params.scheme != cls.SQL_DIALECT: raise ValueError(f'unsupported URL scheme "{con_params.scheme}"') + settings = terracotta.get_settings() url = URL.create( drivername=f'{cls.SQL_DIALECT}+{cls.SQL_DRIVER}', - username=con_params.username or terracotta.get_settings().SQL_USER, - password=con_params.password or terracotta.get_settings().SQL_PASSWORD, + username=con_params.username or settings.SQL_USER, + password=con_params.password or settings.SQL_PASSWORD, host=con_params.hostname, port=con_params.port, database=con_params.path[1:], # remove leading '/' from urlparse From 4bee8499487dc6ca5fb05240c0cf81021ffbbb07 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Wed, 27 Apr 2022 11:29:40 +0200 Subject: [PATCH 19/20] Update test for setting deprecated settings; for the simpler warnings --- tests/test_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_config.py b/tests/test_config.py index 090becad..761a4da9 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -95,7 +95,7 @@ def test_deprecation_behaviour(monkeypatch): with pytest.warns(exceptions.DeprecationWarning) as warning: update_settings() - assert f'and its replacement TC_{new_field} is set' in str(warning[0]) + assert f'TC_{deprecated_field} is being deprecated' in str(warning[0]) assert getattr(get_settings(), deprecated_field) == 'foo' assert getattr(get_settings(), new_field) == 'bar' From a82d805e908d6e8be7a69e0c4aa8e45cf292fda0 Mon Sep 17 00:00:00 2001 From: Nicklas Boserup Date: Wed, 27 Apr 2022 11:59:32 +0200 Subject: [PATCH 20/20] Update test to correspond to the new warning messages --- tests/test_config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index 761a4da9..da3f944f 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -86,7 +86,7 @@ def test_deprecation_behaviour(monkeypatch): with pytest.warns(exceptions.DeprecationWarning) as warning: update_settings() - assert f'TC_{deprecated_field} is being deprecated' in str(warning[0]) + assert f'TC_{deprecated_field} is deprecated' in str(warning[0]) assert getattr(get_settings(), deprecated_field) == 'foo' assert getattr(get_settings(), new_field) == 'foo' @@ -95,7 +95,7 @@ def test_deprecation_behaviour(monkeypatch): with pytest.warns(exceptions.DeprecationWarning) as warning: update_settings() - assert f'TC_{deprecated_field} is being deprecated' in str(warning[0]) + assert f'TC_{deprecated_field} is deprecated' in str(warning[0]) assert getattr(get_settings(), deprecated_field) == 'foo' assert getattr(get_settings(), new_field) == 'bar'