]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
Don't format output twice in writer
authorMike Waites <mikey.waites@gmail.com>
Fri, 31 Aug 2018 19:42:27 +0000 (19:42 +0000)
committerMike Waites <mikey.waites@gmail.com>
Wed, 19 Sep 2018 20:35:10 +0000 (21:35 +0100)
Fixed an issue where revision descriptions were essentially
being formatted twice. Any revision description that contained
characters like %, writing output to stdout will fail because
the call to config.print_stdout attempted to format any
additional args passed to the function.
This fix now only applies string formatting if any args are provided
along with the output text.

Fixes: #497
Change-Id: I64b2f00e8f67b95652bd7cbbe8510f8c5f645af1
Pull-request: https://github.com/zzzeek/alembic/pull/45

alembic/config.py
alembic/testing/env.py
docs/build/unreleased/497.rst [new file with mode: 0644]
tests/test_config.py

index 0e8d9e436e7e2618258c9572d0f30c9cf97b3a5b..308f26632cc319abe54fa5fab8cd14d349c4f2f9 100644 (file)
@@ -153,11 +153,27 @@ class Config(object):
         return {}
 
     def print_stdout(self, text, *arg):
-        """Render a message to standard out."""
+        """Render a message to standard out.
+
+        When :meth:`.Config.print_stdout` is called with additional args
+        those arguments will formatted against the provided text,
+        otherwise we simply output the provided text verbatim.
+
+        e.g.::
+
+            >>> config.print_stdout('Some text %s', 'arg')
+            Some Text arg
+
+        """
+
+        if arg:
+            output = (compat.text_type(text) % arg)
+        else:
+            output = compat.text_type(text)
 
         util.write_outstream(
             self.stdout,
-            (compat.text_type(text) % arg),
+            output,
             "\n"
         )
 
index 792db227fff073011b7cbaa876f39628104e8839..0318703f518d9926f1bfeb243220b2ee340c3faa 100644 (file)
@@ -283,9 +283,9 @@ def downgrade():
 
     script.generate_revision(b, "revision b", refresh=True)
     write_script(script, b, u("""# coding: utf-8
-"Rev B, méil"
-revision = '%s'
-down_revision = '%s'
+"Rev B, méil, %3"
+revision = '{}'
+down_revision = '{}'
 
 from alembic import op
 
@@ -297,7 +297,7 @@ def upgrade():
 def downgrade():
     op.execute("DROP STEP 2")
 
-""") % (b, a), encoding="utf-8")
+""").format(b, a), encoding="utf-8")
 
     script.generate_revision(c, "revision c", refresh=True)
     write_script(script, c, """\
diff --git a/docs/build/unreleased/497.rst b/docs/build/unreleased/497.rst
new file mode 100644 (file)
index 0000000..938beaf
--- /dev/null
@@ -0,0 +1,11 @@
+.. change::
+    :tags: bug, commands
+    :tickets: 497
+
+    Fixed an issue where revision descriptions were essentially
+    being formatted twice. Any revision description that contained
+    characters like %, writing output to stdout will fail because
+    the call to config.print_stdout attempted to format any
+    additional args passed to the function.
+    This fix now only applies string formatting if any args are provided
+    along with the output text.
\ No newline at end of file
index d9f998cb65b5bf33fa36a1cd02821d405401debc..50e1b05e35ee3a273f461d28c701eaa749e83431 100644 (file)
@@ -137,6 +137,15 @@ class StdoutOutputEncodingTest(TestBase):
             [call.write('m?il x y'), call.write('\n')]
         )
 
+    def test_only_formats_output_with_args(self):
+        stdout = Mock(encoding=None)
+        cfg = config.Config(stdout=stdout)
+        cfg.print_stdout(compat.u("test 3%"))
+        eq_(
+            stdout.mock_calls,
+            [call.write('test 3%'), call.write('\n')]
+        )
+
 
 class TemplateOutputEncodingTest(TestBase):
     def setUp(self):