From 252f7b994d62f0cb2ff85654368d99cfacba5d7b Mon Sep 17 00:00:00 2001 From: "Pavel V. Pristupa" Date: Tue, 30 Jul 2024 01:45:20 -0400 Subject: [PATCH] Enhance version_path_separator behaviour by adding a newline option ### Description version_path_separator now consists a new option "newline" which allows you to specify multiple version locations across multiple lines like this: ``` version_locations = /foo/versions /bar/versions /baz/versions version_path_separator = newline ``` ### Checklist This pull request is: - [ ] A documentation / typographical error fix - Good to go, no issue or tests are needed - [ ] A short code fix - please include the issue number, and create an issue if none exists, which must include a complete example of the issue. one line code fixes without an issue and demonstration will not be accepted. - Please include: `Fixes: #` in the commit message - please include tests. one line code fixes without tests will not be accepted. - [x] A new feature implementation - please include the issue number, and create an issue if none exists, which must include a complete example of how the feature would look. - Please include: `Fixes: #` in the commit message - please include tests. **Have a nice day!** Closes: #1510 Pull-request: https://github.com/sqlalchemy/alembic/pull/1510 Pull-request-sha: 6155da71472fa2727beabd0aeaec1bdc07378b1b Change-Id: I364906906a9c7164e8f7fa5f51f3097ab118cc65 --- alembic/script/base.py | 8 ++++++-- alembic/templates/async/alembic.ini.mako | 1 + alembic/templates/generic/alembic.ini.mako | 1 + alembic/templates/multidb/alembic.ini.mako | 1 + alembic/testing/assertions.py | 17 +++++++++++++---- docs/build/tutorial.rst | 1 + docs/build/unreleased/1509.rst | 5 +++++ tests/test_config.py | 11 +++++++++-- 8 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 docs/build/unreleased/1509.rst diff --git a/alembic/script/base.py b/alembic/script/base.py index 9a955b6b..30df6ddb 100644 --- a/alembic/script/base.py +++ b/alembic/script/base.py @@ -187,6 +187,7 @@ def from_config(cls, config: Config) -> ScriptDirectory: split_on_path = { None: None, "space": " ", + "newline": "\n", "os": os.pathsep, ":": ":", ";": ";", @@ -200,7 +201,8 @@ def from_config(cls, config: Config) -> ScriptDirectory: raise ValueError( "'%s' is not a valid value for " "version_path_separator; " - "expected 'space', 'os', ':', ';'" % version_path_separator + "expected 'space', 'newline', 'os', ':', ';'" + % version_path_separator ) from ke else: if split_char is None: @@ -210,7 +212,9 @@ def from_config(cls, config: Config) -> ScriptDirectory: ) else: version_locations = [ - x for x in version_locations_str.split(split_char) if x + x.strip() + for x in version_locations_str.split(split_char) + if x ] else: version_locations = None diff --git a/alembic/templates/async/alembic.ini.mako b/alembic/templates/async/alembic.ini.mako index 3558295e..46a0904e 100644 --- a/alembic/templates/async/alembic.ini.mako +++ b/alembic/templates/async/alembic.ini.mako @@ -47,6 +47,7 @@ prepend_sys_path = . # version_path_separator = : # version_path_separator = ; # version_path_separator = space +# version_path_separator = newline version_path_separator = os # Use os.pathsep. Default configuration used for new projects. # set to 'true' to search source files recursively diff --git a/alembic/templates/generic/alembic.ini.mako b/alembic/templates/generic/alembic.ini.mako index b3fe0535..dd4ea588 100644 --- a/alembic/templates/generic/alembic.ini.mako +++ b/alembic/templates/generic/alembic.ini.mako @@ -49,6 +49,7 @@ prepend_sys_path = . # version_path_separator = : # version_path_separator = ; # version_path_separator = space +# version_path_separator = newline version_path_separator = os # Use os.pathsep. Default configuration used for new projects. # set to 'true' to search source files recursively diff --git a/alembic/templates/multidb/alembic.ini.mako b/alembic/templates/multidb/alembic.ini.mako index 6e901999..d5cc86f1 100644 --- a/alembic/templates/multidb/alembic.ini.mako +++ b/alembic/templates/multidb/alembic.ini.mako @@ -49,6 +49,7 @@ prepend_sys_path = . # version_path_separator = : # version_path_separator = ; # version_path_separator = space +# version_path_separator = newline version_path_separator = os # Use os.pathsep. Default configuration used for new projects. # set to 'true' to search source files recursively diff --git a/alembic/testing/assertions.py b/alembic/testing/assertions.py index ec9593b7..e071697c 100644 --- a/alembic/testing/assertions.py +++ b/alembic/testing/assertions.py @@ -74,7 +74,9 @@ class _ErrorContainer: @contextlib.contextmanager -def _expect_raises(except_cls, msg=None, check_context=False): +def _expect_raises( + except_cls, msg=None, check_context=False, text_exact=False +): ec = _ErrorContainer() if check_context: are_we_already_in_a_traceback = sys.exc_info()[0] @@ -85,7 +87,10 @@ def _expect_raises(except_cls, msg=None, check_context=False): ec.error = err success = True if msg is not None: - assert re.search(msg, str(err), re.UNICODE), f"{msg} !~ {err}" + if text_exact: + assert str(err) == msg, f"{msg} != {err}" + else: + assert re.search(msg, str(err), re.UNICODE), f"{msg} !~ {err}" if check_context and not are_we_already_in_a_traceback: _assert_proper_exception_context(err) print(str(err).encode("utf-8")) @@ -98,8 +103,12 @@ def expect_raises(except_cls, check_context=True): return _expect_raises(except_cls, check_context=check_context) -def expect_raises_message(except_cls, msg, check_context=True): - return _expect_raises(except_cls, msg=msg, check_context=check_context) +def expect_raises_message( + except_cls, msg, check_context=True, text_exact=False +): + return _expect_raises( + except_cls, msg=msg, check_context=check_context, text_exact=text_exact + ) def eq_ignore_whitespace(a, b, msg=None): diff --git a/docs/build/tutorial.rst b/docs/build/tutorial.rst index f1cd4916..6cc16697 100644 --- a/docs/build/tutorial.rst +++ b/docs/build/tutorial.rst @@ -174,6 +174,7 @@ The file generated with the "generic" configuration looks like:: # version_path_separator = : # version_path_separator = ; # version_path_separator = space + # version_path_separator = newline version_path_separator = os # Use os.pathsep. Default configuration used for new projects. # set to 'true' to search source files recursively diff --git a/docs/build/unreleased/1509.rst b/docs/build/unreleased/1509.rst new file mode 100644 index 00000000..df3bf97d --- /dev/null +++ b/docs/build/unreleased/1509.rst @@ -0,0 +1,5 @@ +.. change:: + :tags: feature, environment + :tickets: 1509 + + Enhance ``version_locations`` parsing to handle paths containing newlines. diff --git a/tests/test_config.py b/tests/test_config.py index 73ce2aa9..a98994c4 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -134,6 +134,12 @@ def test_attributes_constructor(self): "/foo /bar", ["/foo", "/bar"], ), + ( + "multiline string 1", + "newline", + " /foo \n/bar ", + ["/foo", "/bar"], + ), ( "Linux pathsep 1", ":", @@ -171,7 +177,7 @@ def test_attributes_constructor(self): "/foo|/bar", ValueError( "'|' is not a valid value for version_path_separator; " - "expected 'space', 'os', ':', ';'" + "expected 'space', 'newline', 'os', ':', ';'" ), ), id_="iaaa", @@ -188,7 +194,8 @@ def test_version_locations(self, separator, string_value, expected_result): cfg.set_main_option("version_locations", string_value) if isinstance(expected_result, ValueError): - with expect_raises_message(ValueError, expected_result.args[0]): + message = str(expected_result) + with expect_raises_message(ValueError, message, text_exact=True): ScriptDirectory.from_config(cfg) else: s = ScriptDirectory.from_config(cfg)