]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
fix(config): Accept int on toml config
authorLuís Henrique Allebrandt Schunemann <44511825+luishenri@users.noreply.github.com>
Tue, 19 Aug 2025 12:59:24 +0000 (08:59 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 27 Aug 2025 17:03:37 +0000 (13:03 -0400)
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

alembic/config.py
alembic/ddl/mysql.py
docs/build/unreleased/1709.rst [new file with mode: 0644]
tests/test_config.py

index dcc64a4cfd9f0543d55a13b985ca16e1b1b132ba..b8c60a48971abf915549f4ac8b2a47757e9ef985 100644 (file)
@@ -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}"
index 8f5f9252663d967bfb29b5764dc63634f3f97a7e..3d7cf21a49a3b724ccf3eb2335c37b90556d70d1 100644 (file)
@@ -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 (file)
index 0000000..3d962d6
--- /dev/null
@@ -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.
index 40a22f7179334c904c5f6e992b1f9f717f52b967..2a1960a4eb439bbce69760d6167c902b1f697e28 100644 (file)
@@ -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):