diff options
-rw-r--r-- | .zuul.yaml | 4 | ||||
-rw-r--r-- | MANIFEST.in | 6 | ||||
-rw-r--r-- | Makefile | 21 | ||||
-rw-r--r-- | README.rst | 2 | ||||
-rw-r--r-- | cliff/_argparse.py | 80 | ||||
-rw-r--r-- | cliff/command.py | 1 | ||||
-rw-r--r-- | cliff/formatters/json_format.py | 1 | ||||
-rw-r--r-- | cliff/tests/test_command.py | 30 | ||||
-rw-r--r-- | doc/Makefile | 153 | ||||
-rw-r--r-- | doc/source/install/index.rst | 2 | ||||
-rw-r--r-- | setup.cfg | 5 | ||||
-rw-r--r-- | tox.ini | 4 |
12 files changed, 115 insertions, 194 deletions
@@ -26,9 +26,7 @@ - lib-forward-testing-python3 - openstack-lower-constraints-jobs - openstack-python-jobs - - openstack-python35-jobs - - openstack-python36-jobs - - openstack-python37-jobs + - openstack-python3-train-jobs - publish-openstack-docs-pti check: jobs: diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index bb56f02..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,6 +0,0 @@ -include setup.py -recursive-include docs *.rst *.py *.html *.css *.js *.png *.txt -recursive-include demoapp *.py -recursive-include tests *.py -include tox.ini - diff --git a/Makefile b/Makefile deleted file mode 100644 index 73adad1..0000000 --- a/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -help: - @echo "release - package and upload a release" - @echo "sdist - package" - @echo "docs - generate HTML documentation" - @echo "clean - remove build artifacts" - -release: docs - rm -rf dist build - python setup.py sdist upload - -sdist: docs - python setup.py sdist - ls -l dist - -clean: - rm -rf dist build *.egg-info - (cd doc && make clean) - -.PHONY: docs -docs: - (cd doc && make clean html) @@ -19,5 +19,5 @@ other extensions. * Free software: Apache license * Documentation: https://docs.openstack.org/cliff/latest/ -* Source: https://git.openstack.org/cgit/openstack/cliff +* Source: https://opendev.org/openstack/cliff * Bugs: https://bugs.launchpad.net/python-cliff diff --git a/cliff/_argparse.py b/cliff/_argparse.py index e48dc79..5358e72 100644 --- a/cliff/_argparse.py +++ b/cliff/_argparse.py @@ -14,11 +14,14 @@ from __future__ import absolute_import from argparse import * # noqa +import argparse import sys +import warnings -if sys.version_info < (3, 5): - class ArgumentParser(ArgumentParser): # noqa +class ArgumentParser(argparse.ArgumentParser): + + if sys.version_info < (3, 5): def __init__(self, *args, **kwargs): self.allow_abbrev = kwargs.pop("allow_abbrev", True) super(ArgumentParser, self).__init__(*args, **kwargs) @@ -28,3 +31,76 @@ if sys.version_info < (3, 5): return super(ArgumentParser, self)._get_option_tuples( option_string) return () + + # NOTE(dhellmann): We have to override the methods for creating + # groups to return our objects that know how to deal with the + # special conflict handler. + + def add_argument_group(self, *args, **kwargs): + group = _ArgumentGroup(self, *args, **kwargs) + self._action_groups.append(group) + return group + + def add_mutually_exclusive_group(self, **kwargs): + group = _MutuallyExclusiveGroup(self, **kwargs) + self._mutually_exclusive_groups.append(group) + return group + + def _handle_conflict_ignore(self, action, conflicting_actions): + _handle_conflict_ignore( + self, + self._option_string_actions, + action, + conflicting_actions, + ) + + +def _handle_conflict_ignore(container, option_string_actions, + new_action, conflicting_actions): + + # Remember the option strings the new action starts with so we can + # restore them as part of error reporting if we need to. + original_option_strings = new_action.option_strings + + # Remove all of the conflicting option strings from the new action + # and report an error if none are left at the end. + for option_string, action in conflicting_actions: + + # remove the conflicting option from the new action + new_action.option_strings.remove(option_string) + warnings.warn( + ('Ignoring option string {} for new action ' + 'because it conflicts with an existing option.').format( + option_string)) + + # if the option now has no option string, remove it from the + # container holding it + if not new_action.option_strings: + new_action.option_strings = original_option_strings + raise argparse.ArgumentError( + new_action, + ('Cannot resolve conflicting option string, ' + 'all names conflict.'), + ) + + +class _ArgumentGroup(argparse._ArgumentGroup): + + def _handle_conflict_ignore(self, action, conflicting_actions): + _handle_conflict_ignore( + self, + self._option_string_actions, + action, + conflicting_actions, + ) + + +class _MutuallyExclusiveGroup(argparse._MutuallyExclusiveGroup): + + def _handle_conflict_ignore(self, action, conflicting_actions): + _handle_conflict_ignore( + self, + self._option_string_actions, + action, + conflicting_actions, + ) diff --git a/cliff/command.py b/cliff/command.py index 13b872d..760832b 100644 --- a/cliff/command.py +++ b/cliff/command.py @@ -156,6 +156,7 @@ class Command(object): epilog=self.get_epilog(), prog=prog_name, formatter_class=_SmartHelpFormatter, + conflict_handler='ignore', ) for hook in self._hooks: hook.obj.get_parser(parser) diff --git a/cliff/formatters/json_format.py b/cliff/formatters/json_format.py index 4483e91..0480432 100644 --- a/cliff/formatters/json_format.py +++ b/cliff/formatters/json_format.py @@ -52,3 +52,4 @@ class JSONFormatter(base.ListFormatter, base.SingleFormatter): } indent = None if parsed_args.noindent else 2 json.dump(one, stdout, indent=indent) + stdout.write('\n') diff --git a/cliff/tests/test_command.py b/cliff/tests/test_command.py index 6aecff3..29c8c33 100644 --- a/cliff/tests/test_command.py +++ b/cliff/tests/test_command.py @@ -45,7 +45,9 @@ class TestCommand(command.Command): ) parser.add_argument( '-z', - help='used in TestArgumentParser', + dest='zippy', + default='zippy-default', + help='defined in TestCommand and used in TestArgumentParser', ) return parser @@ -141,10 +143,32 @@ class TestArgumentParser(base.TestBase): cmd = TestCommand(None, None) parser = cmd.get_parser('NAME') # We should have an exception registering an option with a - # name that already exists because we do not want commands to - # override global options. + # name that already exists because we configure the argument + # parser to ignore conflicts but this option has no other name + # to be used. self.assertRaises( argparse.ArgumentError, parser.add_argument, '-z', ) + + def test_option_name_collision_with_alias(self): + cmd = TestCommand(None, None) + parser = cmd.get_parser('NAME') + # We not should have an exception registering an option with a + # name that already exists because we configure the argument + # parser to ignore conflicts and this option can be added as + # --zero even if the -z is ignored. + parser.add_argument('-z', '--zero') + + def test_resolve_option_with_name_collision(self): + cmd = TestCommand(None, None) + parser = cmd.get_parser('NAME') + parser.add_argument( + '-z', '--zero', + dest='zero', + default='zero-default', + ) + args = parser.parse_args(['-z', 'foo', 'a', 'b']) + self.assertEqual(args.zippy, 'foo') + self.assertEqual(args.zero, 'zero-default') diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 0127250..0000000 --- a/doc/Makefile +++ /dev/null @@ -1,153 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make <target>' where <target> is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/cliff.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/cliff.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/cliff" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/cliff" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/doc/source/install/index.rst b/doc/source/install/index.rst index 51e0250..406bea0 100644 --- a/doc/source/install/index.rst +++ b/doc/source/install/index.rst @@ -33,7 +33,7 @@ or:: Source Code =========== -The source is hosted on github: https://git.openstack.org/cgit/openstack/cliff +The source is hosted on OpenDev: https://opendev.org/openstack/cliff Reporting Bugs ============== @@ -2,7 +2,7 @@ name = cliff description-file = README.rst author = OpenStack -author-email = openstack-dev@lists.openstack.org +author-email = openstack-discuss@lists.openstack.org summary = Command Line Interface Formulation Framework home-page = https://docs.openstack.org/cliff/latest/ classifier = @@ -12,7 +12,8 @@ classifier = Programming Language :: Python :: 2 Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 - Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 Intended Audience :: Developers Environment :: Console @@ -1,6 +1,6 @@ [tox] minversion = 2.0 -envlist = py35,py27,pep8 +envlist = py27,py37,pep8 [testenv] setenv = @@ -16,7 +16,7 @@ commands = python setup.py test --coverage --coverage-package-name=cliff --slowest --testr-args='{posargs}' coverage report --show-missing deps = - -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} + -c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/upper-constraints.txt} -r{toxinidir}/test-requirements.txt -r{toxinidir}/requirements.txt |