From: Mike Waites Date: Fri, 31 Aug 2018 19:42:27 +0000 (+0000) Subject: Don't format output twice in writer X-Git-Tag: rel_1_0_1~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a614443a3cc3107c7552607ce81942a15e81dd4c;p=thirdparty%2Fsqlalchemy%2Falembic.git Don't format output twice in writer 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 --- diff --git a/alembic/config.py b/alembic/config.py index 0e8d9e43..308f2663 100644 --- a/alembic/config.py +++ b/alembic/config.py @@ -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" ) diff --git a/alembic/testing/env.py b/alembic/testing/env.py index 792db227..0318703f 100644 --- a/alembic/testing/env.py +++ b/alembic/testing/env.py @@ -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 index 00000000..938beafb --- /dev/null +++ b/docs/build/unreleased/497.rst @@ -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 diff --git a/tests/test_config.py b/tests/test_config.py index d9f998cb..50e1b05e 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -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):