From: Thomas Bechtold Date: Tue, 24 Sep 2019 14:27:03 +0000 (-0400) Subject: Revert alembic.stamp "revisions" to "revision" X-Git-Tag: rel_1_2_1~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=310017f4acafaab750d8fdfbf3eec0007962dfc1;p=thirdparty%2Fsqlalchemy%2Falembic.git Revert alembic.stamp "revisions" to "revision" Reverted the name change of the "revisions" argument to :func:`.command.stamp` to "revision" as apparently applications are calling upon this argument as a keyword name. Pull request courtesy Thomas Bechtold. Special translations are also added to the command line interface so that it is still known as "revisions" in the CLI. Co-authored-by: Mike Bayer Fixes: #601 Closes: #602 Pull-request: https://github.com/sqlalchemy/alembic/pull/602 Pull-request-sha: 4126635e272f82ec53d630bb77c00cb6ff42cec9 Change-Id: I4312954bedc42bb4b76656a70c95b2b7280efae7 --- diff --git a/alembic/command.py b/alembic/command.py index d4acfdbf..7d19e3c6 100644 --- a/alembic/command.py +++ b/alembic/command.py @@ -515,13 +515,20 @@ def current(config, verbose=False, head_only=False): script.run_env() -def stamp(config, revisions, sql=False, tag=None, purge=False): +def stamp(config, revision, sql=False, tag=None, purge=False): """'stamp' the revision table with the given revision; don't run any migrations. :param config: a :class:`.Config` instance. - :param revision: target revision. + :param revision: target revision or list of revisions. May be a list + to indicate stamping of multiple branch heads. + + .. note:: this parameter is called "revisions" in the command line + interface. + + .. versionchanged:: 1.2 The revision may be a single revision or + list of revisions when stamping multiple branch heads. :param sql: use ``--sql`` mode @@ -540,9 +547,9 @@ def stamp(config, revisions, sql=False, tag=None, purge=False): if sql: destination_revs = [] starting_rev = None - for revision in util.to_list(revisions): - if ":" in revision: - srev, revision = revision.split(":", 2) + for _revision in util.to_list(revision): + if ":" in _revision: + srev, _revision = _revision.split(":", 2) if starting_rev != srev: if starting_rev is None: @@ -552,9 +559,9 @@ def stamp(config, revisions, sql=False, tag=None, purge=False): "Stamp operation with --sql only supports a " "single starting revision at a time" ) - destination_revs.append(revision) + destination_revs.append(_revision) else: - destination_revs = util.to_list(revisions) + destination_revs = util.to_list(revision) def do_stamp(rev, context): return script._stamp_revs(util.to_tuple(destination_revs), rev) diff --git a/alembic/config.py b/alembic/config.py index 22320961..b0700d56 100644 --- a/alembic/config.py +++ b/alembic/config.py @@ -296,7 +296,7 @@ class CommandLine(object): self._generate_args(prog) def _generate_args(self, prog): - def add_options(parser, positional, kwargs): + def add_options(fn, parser, positional, kwargs): kwargs_opts = { "template": ( "-t", @@ -454,9 +454,15 @@ class CommandLine(object): parser.add_argument(*args, **kw) for arg in positional: - if arg == "revisions": + if ( + arg == "revisions" + or fn in positional_translations + and positional_translations[fn][arg] == "revisions" + ): subparser.add_argument( - arg, nargs="+", help=positional_help.get(arg) + "revisions", + nargs="+", + help=positional_help.get("revisions"), ) else: subparser.add_argument(arg, help=positional_help.get(arg)) @@ -490,6 +496,8 @@ class CommandLine(object): ) subparsers = parser.add_subparsers() + positional_translations = {command.stamp: {"revision": "revisions"}} + for fn in [getattr(command, n) for n in dir(command)]: if ( inspect.isfunction(fn) @@ -505,6 +513,12 @@ class CommandLine(object): positional = spec[0][1:] kwarg = [] + if fn in positional_translations: + positional = [ + positional_translations[fn].get(name, name) + for name in positional + ] + # parse first line(s) of helptext without a line break help_ = fn.__doc__ if help_: @@ -519,7 +533,7 @@ class CommandLine(object): subparser = subparsers.add_parser( fn.__name__, help=" ".join(help_text) ) - add_options(subparser, positional, kwarg) + add_options(fn, subparser, positional, kwarg) subparser.set_defaults(cmd=(fn, positional, kwarg)) self.parser = parser diff --git a/docs/build/unreleased/601.rst b/docs/build/unreleased/601.rst new file mode 100644 index 00000000..5e89f394 --- /dev/null +++ b/docs/build/unreleased/601.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, command + :tickets: 601 + + Reverted the name change of the "revisions" argument to + :func:`.command.stamp` to "revision" as apparently applications are + calling upon this argument as a keyword name. Pull request courtesy + Thomas Bechtold. Special translations are also added to the command + line interface so that it is still known as "revisions" in the CLI. diff --git a/tests/test_command.py b/tests/test_command.py index e0934792..2aeb28c8 100644 --- a/tests/test_command.py +++ b/tests/test_command.py @@ -765,6 +765,41 @@ class UpgradeDowngradeStampTest(TestBase): "WHERE alembic_version.version_num = '%s';" % (self.c, self.a) ) in buf.getvalue() + def test_sql_stamp_revision_as_kw(self): + with capture_context_buffer() as buf: + command.stamp(self.cfg, revision="head", sql=True) + assert ( + "INSERT INTO alembic_version (version_num) VALUES ('%s')" % self.c + in buf.getvalue() + ) + + def test_stamp_argparser_single_rev(self): + cmd = config.CommandLine() + options = cmd.parser.parse_args(["stamp", self.c, "--sql"]) + with capture_context_buffer() as buf: + cmd.run_cmd(self.cfg, options) + assert ( + "INSERT INTO alembic_version (version_num) VALUES ('%s')" % self.c + in buf.getvalue() + ) + + def test_stamp_argparser_multiple_rev(self): + cmd = config.CommandLine() + options = cmd.parser.parse_args(["stamp", self.b, self.c, "--sql"]) + with capture_context_buffer() as buf: + cmd.run_cmd(self.cfg, options) + # TODO: this is still wrong, as this stamp command is putting + # conflicting heads into the table. The test here is only to test + # that the revisions are passed as a list. + assert ( + "INSERT INTO alembic_version (version_num) VALUES ('%s')" % self.b + in buf.getvalue() + ) + assert ( + "INSERT INTO alembic_version (version_num) VALUES ('%s')" % self.c + in buf.getvalue() + ) + class LiveStampTest(TestBase): __only_on__ = "sqlite"