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)