From: Luís Henrique Allebrandt Schunemann <44511825+luishenri@users.noreply.github.com> Date: Tue, 19 Aug 2025 12:59:24 +0000 (-0400) Subject: fix(config): Accept int on toml config X-Git-Tag: rel_1_16_5~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d45b7d1bf36db1ea8d7f725c2a48361cc3cddcae;p=thirdparty%2Fsqlalchemy%2Falembic.git fix(config): Accept int on toml config Fixed issue where new pyproject.toml config would fail to parse the integer value used for the ``truncate_slug_length`` parameter. Pull request courtesy Luís Henrique Allebrandt Schunemann. Fixes: #1709 Closes: #1710 Pull-request: https://github.com/sqlalchemy/alembic/pull/1710 Pull-request-sha: 87652ee288d2e0a4883394cd244f23b3e13c323e Change-Id: Ide0f00437740c94250815a5340b2d742e960d1ca --- diff --git a/alembic/config.py b/alembic/config.py index dcc64a4c..b8c60a48 100644 --- a/alembic/config.py +++ b/alembic/config.py @@ -426,7 +426,9 @@ class Config: def get_alembic_option( self, name: str, default: Optional[str] = None - ) -> Union[None, str, list[str], dict[str, str], list[dict[str, str]]]: + ) -> Union[ + None, str, list[str], dict[str, str], list[dict[str, str]], int + ]: """Return an option from the "[alembic]" or "[tool.alembic]" section of the configparser-parsed .ini file (e.g. ``alembic.ini``) or toml-parsed ``pyproject.toml`` file. @@ -470,9 +472,11 @@ class Config: def _get_toml_config_value( self, name: str, default: Optional[Any] = None - ) -> Union[None, str, list[str], dict[str, str], list[dict[str, str]]]: + ) -> Union[ + None, str, list[str], dict[str, str], list[dict[str, str]], int + ]: USE_DEFAULT = object() - value: Union[None, str, list[str], dict[str, str]] = ( + value: Union[None, str, list[str], dict[str, str], int] = ( self.toml_alembic_config.get(name, USE_DEFAULT) ) if value is USE_DEFAULT: @@ -495,6 +499,8 @@ class Config: "dict[str, str]", {k: v % (self.toml_args) for k, v in value.items()}, ) + elif isinstance(value, int): + return value else: raise util.CommandError( f"unsupported TOML value type for key: {name!r}" diff --git a/alembic/ddl/mysql.py b/alembic/ddl/mysql.py index 8f5f9252..3d7cf21a 100644 --- a/alembic/ddl/mysql.py +++ b/alembic/ddl/mysql.py @@ -507,7 +507,7 @@ def _mysql_drop_constraint( # note that SQLAlchemy as of 1.2 does not yet support # DROP CONSTRAINT for MySQL/MariaDB, so we implement fully # here. - if compiler.dialect.is_mariadb: # type: ignore[attr-defined] + if compiler.dialect.is_mariadb: return "ALTER TABLE %s DROP CONSTRAINT %s" % ( compiler.preparer.format_table(constraint.table), compiler.preparer.format_constraint(constraint), diff --git a/docs/build/unreleased/1709.rst b/docs/build/unreleased/1709.rst new file mode 100644 index 00000000..3d962d62 --- /dev/null +++ b/docs/build/unreleased/1709.rst @@ -0,0 +1,7 @@ +.. change:: + :tags: bug, config + :tickets: 1709 + + Fixed issue where new pyproject.toml config would fail to parse the integer + value used for the ``truncate_slug_length`` parameter. Pull request + courtesy Luís Henrique Allebrandt Schunemann. diff --git a/tests/test_config.py b/tests/test_config.py index 40a22f71..2a1960a4 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -586,6 +586,53 @@ script_location = "%(here)s/scripts" sd = ScriptDirectory.from_config(cfg) eq_(getattr(sd, paramname), bool(argtype.true)) + @testing.variation( + "arg_type", ["int", "string_int", "omit", "wrong_value"] + ) + def test_truncate_slug_length_types( + self, pyproject_only_env, arg_type: testing.Variation + ): + param_name = "truncate_slug_length" + cfg = pyproject_only_env + with cfg._toml_file_path.open("w") as file_: + if arg_type.int: + config_option = f"{param_name} = 42" + elif arg_type.string_int: + config_option = f"{param_name} = '42'" + elif arg_type.omit: + config_option = "" + elif arg_type.wrong_value: + config_option = f"{param_name} = 'wrong_value'" + else: + arg_type.fail() + + file_.write( + rf""" +[tool.alembic] +script_location = "%(here)s/scripts" + +{config_option} +""" + ) + if "toml_alembic_config" in cfg.__dict__: + cfg.__dict__.pop("toml_alembic_config") + + if arg_type.wrong_value: + with expect_raises_message( + ValueError, + "invalid literal for int() with base 10: 'wrong_value'", + text_exact=True, + ): + sd = ScriptDirectory.from_config(cfg) + elif arg_type.omit: + sd = ScriptDirectory.from_config(cfg) + + DEFAULT_TRUNCATE_SLUG_LENGTH = 40 + eq_(getattr(sd, param_name), DEFAULT_TRUNCATE_SLUG_LENGTH) + else: + sd = ScriptDirectory.from_config(cfg) + eq_(getattr(sd, param_name), 42) + class StdoutOutputEncodingTest(TestBase): def test_plain(self):