Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-sphinx-argparse for 
openSUSE:Factory checked in at 2022-02-18 23:02:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-sphinx-argparse (Old)
 and      /work/SRC/openSUSE:Factory/.python-sphinx-argparse.new.1958 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-sphinx-argparse"

Fri Feb 18 23:02:50 2022 rev:3 rq:955732 version:0.3.1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-sphinx-argparse/python-sphinx-argparse.changes
    2020-06-12 21:45:40.312527257 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-sphinx-argparse.new.1958/python-sphinx-argparse.changes
  2022-02-18 23:03:11.433411682 +0100
@@ -1,0 +2,17 @@
+Thu Feb 17 15:48:53 UTC 2022 - pgaj...@suse.com
+
+- version update to 0.3.1
+  0.3.1
+  Include tests in sdist
+  0.3.0
+  First release from ashb/sphinx-argparse
+  Declare that parallel builds are supported (issue #131).
+- deleted sources
+  - LICENSE-sphinx-argparse (in tarball)
+- added patches
+  fix 
https://github.com/ashb/sphinx-argparse/commit/fdb7e448b2776986415cb724d9bb3eed424e23b2
+  + python-sphinx-argparse-python310.patch
+- remove patches which were included upstream
+  - prog-in-description.patch
+
+-------------------------------------------------------------------

Old:
----
  LICENSE-sphinx-argparse
  prog-in-description.patch
  sphinx-argparse-0.2.5.tar.gz

New:
----
  python-sphinx-argparse-python310.patch
  sphinx-argparse-0.3.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-sphinx-argparse.spec ++++++
--- /var/tmp/diff_new_pack.jjFH0O/_old  2022-02-18 23:03:12.125411628 +0100
+++ /var/tmp/diff_new_pack.jjFH0O/_new  2022-02-18 23:03:12.133411628 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-sphinx-argparse
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,17 +19,15 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-sphinx-argparse
-Version:        0.2.5
+Version:        0.3.1
 Release:        0
 Summary:        Sphinx extension to document argparse commands and options
 License:        MIT
 Group:          Development/Languages/Python
-URL:            https://github.com/ribozz/sphinx-argparse
+URL:            https://github.com/ashb/sphinx-argparse
 Source0:        
https://files.pythonhosted.org/packages/source/s/sphinx-argparse/sphinx-argparse-%{version}.tar.gz
-Source1:        
https://raw.githubusercontent.com/alex-rudakov/sphinx-argparse/%{version}/LICENSE#/LICENSE-sphinx-argparse
-# PATCH-FIX-UPSTREAM prog-in-description.patch 
gh#alex-rudakov/sphinx-argparse#113 mc...@suse.com
-# Substitute %(prog)s in description and epilog
-Patch0:         prog-in-description.patch
+# 
https://github.com/ashb/sphinx-argparse/commit/fdb7e448b2776986415cb724d9bb3eed424e23b2
+Patch0:         python-sphinx-argparse-python310.patch
 BuildRequires:  %{python_module CommonMark}
 BuildRequires:  %{python_module Sphinx >= 1.2.0}
 BuildRequires:  %{python_module pytest}
@@ -43,10 +41,7 @@
 Sphinx extension that automatically documents argparse commands and options.
 
 %prep
-%setup -q -n sphinx-argparse-%{version}
-%autopatch -p1
-
-install -m0644 %{SOURCE1} LICENSE
+%autosetup -p1 -n sphinx-argparse-%{version}
 
 %build
 %python_build
@@ -56,14 +51,10 @@
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %check
-# can't use %%pytest until gh#alex-rudakov/sphinx-argparse#121 is solved
-%{python_expand export PYTHONPATH=%{buildroot}%{$python_sitelib} 
PYTEST_NAME="py.test-%{$python_bin_suffix}"
-$PYTEST_NAME --ignore=_build.python2 --ignore=_build.python3 
--ignore=_build.pypy3 -vv
-}
+%pytest
 
 %files %{python_files}
 %license LICENSE
-%doc README.md
 %{python_sitelib}/*
 
 %changelog

++++++ python-sphinx-argparse-python310.patch ++++++
diff --git a/sphinxarg/parser.py b/sphinxarg/parser.py
index 9a6f76a..89583c6 100644
--- a/sphinxarg/parser.py
+++ b/sphinxarg/parser.py
@@ -154,7 +154,9 @@ def parse_parser(parser, data=None, **kwargs):
             continue
 
         # Upper case "Positional Arguments" and "Optional Arguments" titles
-        if action_group.title == 'optional arguments':
+        # Since python-3.10 'optional arguments' changed to 'options'
+        # more info: https://github.com/python/cpython/pull/23858
+        if action_group.title == 'optional arguments' or action_group.title == 
'options':
             action_group.title = 'Named Arguments'
         if action_group.title == 'positional arguments':
             action_group.title = 'Positional Arguments'

++++++ sphinx-argparse-0.2.5.tar.gz -> sphinx-argparse-0.3.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-argparse-0.2.5/LICENSE 
new/sphinx-argparse-0.3.1/LICENSE
--- old/sphinx-argparse-0.2.5/LICENSE   1970-01-01 01:00:00.000000000 +0100
+++ new/sphinx-argparse-0.3.1/LICENSE   2021-04-14 15:39:06.817999800 +0200
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 Alex Rudakov
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-argparse-0.2.5/PKG-INFO 
new/sphinx-argparse-0.3.1/PKG-INFO
--- old/sphinx-argparse-0.2.5/PKG-INFO  2018-11-14 15:03:25.000000000 +0100
+++ new/sphinx-argparse-0.3.1/PKG-INFO  2021-09-06 22:00:56.387063500 +0200
@@ -1,23 +1,20 @@
 Metadata-Version: 2.1
 Name: sphinx-argparse
-Version: 0.2.5
+Version: 0.3.1
 Summary: A sphinx extension that automatically documents argparse commands and 
options
-Home-page: https://github.com/ribozz/sphinx-argparse
-Author: Aleksandr Rudakov and Devon Ryan
-Author-email: rib...@gmail.com
 License: MIT
-Description: A sphinx extension that automatically documents argparse commands 
and options.
-        
-        For installation and usage details, see the `documentation 
<http://sphinx-argparse.readthedocs.org/en/latest/>`_.
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
+Author: Ash Berlin-Taylor
+Author-email: ash_git...@firemirror.com
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
 Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
-Classifier: Topic :: Documentation :: Sphinx
-Classifier: Topic :: Software Development :: Documentation
-Provides-Extra: dev
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
 Provides-Extra: markdown
+Requires-Dist: CommonMark (>=0.5.6); extra == "markdown"
+Requires-Dist: sphinx (>=1.2.0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-argparse-0.2.5/README.md 
new/sphinx-argparse-0.3.1/README.md
--- old/sphinx-argparse-0.2.5/README.md 2018-03-12 09:09:14.000000000 +0100
+++ new/sphinx-argparse-0.3.1/README.md 1970-01-01 01:00:00.000000000 +0100
@@ -1,12 +0,0 @@
-[![Build 
Status](https://travis-ci.org/ribozz/sphinx-argparse.svg?branch=master)](https://travis-ci.org/ribozz/sphinx-argparse)
-[![Documentation 
Status](https://readthedocs.org/projects/sphinx-argparse/badge/?version=stable)](http://sphinx-argparse.readthedocs.org/)
-[![PyPI 
version](https://badge.fury.io/py/sphinx-argparse.svg)](https://badge.fury.io/py/sphinx-argparse)
-[![Install with 
conda](https://anaconda.org/conda-forge/sphinx-argparse/badges/installer/conda.svg)](https://github.com/conda-forge/sphinx-argparse-feedstock)
-![Conda 
downloads](https://anaconda.org/conda-forge/sphinx-argparse/badges/downloads.svg)
-
-sphinx-argparse
-===============
-
-A sphinx extension that automatically documents argparse commands and options.
-
-For installation and usage details see the 
[documentation](http://sphinx-argparse.readthedocs.org/en/latest/). The 
changelog is also [found 
there](http://sphinx-argparse.readthedocs.org/en/latest/changelog.html).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-argparse-0.2.5/pyproject.toml 
new/sphinx-argparse-0.3.1/pyproject.toml
--- old/sphinx-argparse-0.2.5/pyproject.toml    1970-01-01 01:00:00.000000000 
+0100
+++ new/sphinx-argparse-0.3.1/pyproject.toml    2021-09-06 22:00:16.496185300 
+0200
@@ -0,0 +1,34 @@
+[tool.poetry]
+name = "sphinx-argparse"
+version = "0.3.1"
+description = "A sphinx extension that automatically documents argparse 
commands and options"
+authors = ["Ash Berlin-Taylor <ash_git...@firemirror.com>"]
+license = "MIT"
+packages = [
+  { include = "sphinxarg" },
+  { include = "test", format = "sdist" },
+]
+
+[tool.poetry.dependencies]
+python = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*"
+sphinx = ">=1.2.0"
+CommonMark = { version = ">=0.5.6", optional = true }
+
+[tool.poetry.extras]
+markdown = ["CommonMark"]
+
+[tool.poetry.dev-dependencies]
+six = "*"
+flake8 = "*"
+pytest = "*"
+pytest-deadfixtures = "*"
+flake8-colors = "^0.1.9"
+black = {version = "^20.8b1", allow-prereleases = true, python = ">=3.6h"}
+isort = {version = "^5.8.0", python = "^3.6"}
+
+[build-system]
+requires = ["poetry-core>=1.0.0"]
+build-backend = "poetry.core.masonry.api"
+
+[tool.black]
+skip-string-normalization = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-argparse-0.2.5/setup.cfg 
new/sphinx-argparse-0.3.1/setup.cfg
--- old/sphinx-argparse-0.2.5/setup.cfg 2018-11-14 15:03:25.000000000 +0100
+++ new/sphinx-argparse-0.3.1/setup.cfg 1970-01-01 01:00:00.000000000 +0100
@@ -1,4 +0,0 @@
-[egg_info]
-tag_build = 
-tag_date = 0
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-argparse-0.2.5/setup.py 
new/sphinx-argparse-0.3.1/setup.py
--- old/sphinx-argparse-0.2.5/setup.py  2018-11-14 09:59:17.000000000 +0100
+++ new/sphinx-argparse-0.3.1/setup.py  2021-09-06 22:00:56.386750200 +0200
@@ -1,44 +1,34 @@
+# -*- coding: utf-8 -*-
 from setuptools import setup
 
+packages = \
+['sphinxarg', 'test']
 
-def getVersion():
-    f = open("sphinxarg/__init__.py")
-    _ = f.read()
-    ver = _.split("'")[1]
-    f.close()
-    return ver
-
-
-setup(
-    name='sphinx-argparse',
-    version=getVersion(),
-    packages=[
-        'sphinxarg',
-    ],
-    url='https://github.com/ribozz/sphinx-argparse',
-    license='MIT',
-    author='Aleksandr Rudakov and Devon Ryan',
-    author_email='rib...@gmail.com',
-    description='A sphinx extension that automatically documents argparse 
commands and options',
-    long_description="""A sphinx extension that automatically documents 
argparse commands and options.
-
-For installation and usage details, see the `documentation 
<http://sphinx-argparse.readthedocs.org/en/latest/>`_.""",
-    classifiers=[
-        'Development Status :: 5 - Production/Stable',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: MIT License',
-        'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3.5',
-        'Programming Language :: Python :: 3.6',
-        'Programming Language :: Python :: 3.7',
-        'Topic :: Documentation :: Sphinx',
-        'Topic :: Software Development :: Documentation'
-    ],
-    install_requires=[
-        'sphinx>=1.2.0'
-    ],
-    extras_require={
-        'dev': ['pytest', 'sphinx_rtd_theme'],
-        'markdown': ['CommonMark>=0.5.6']
-    }
-)
+package_data = \
+{'': ['*']}
+
+install_requires = \
+['sphinx>=1.2.0']
+
+extras_require = \
+{'markdown': ['CommonMark>=0.5.6']}
+
+setup_kwargs = {
+    'name': 'sphinx-argparse',
+    'version': '0.3.1',
+    'description': 'A sphinx extension that automatically documents argparse 
commands and options',
+    'long_description': None,
+    'author': 'Ash Berlin-Taylor',
+    'author_email': 'ash_git...@firemirror.com',
+    'maintainer': None,
+    'maintainer_email': None,
+    'url': None,
+    'packages': packages,
+    'package_data': package_data,
+    'install_requires': install_requires,
+    'extras_require': extras_require,
+    'python_requires': '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
+}
+
+
+setup(**setup_kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-argparse-0.2.5/sphinx_argparse.egg-info/PKG-INFO 
new/sphinx-argparse-0.3.1/sphinx_argparse.egg-info/PKG-INFO
--- old/sphinx-argparse-0.2.5/sphinx_argparse.egg-info/PKG-INFO 2018-11-14 
15:03:25.000000000 +0100
+++ new/sphinx-argparse-0.3.1/sphinx_argparse.egg-info/PKG-INFO 1970-01-01 
01:00:00.000000000 +0100
@@ -1,23 +0,0 @@
-Metadata-Version: 2.1
-Name: sphinx-argparse
-Version: 0.2.5
-Summary: A sphinx extension that automatically documents argparse commands and 
options
-Home-page: https://github.com/ribozz/sphinx-argparse
-Author: Aleksandr Rudakov and Devon Ryan
-Author-email: rib...@gmail.com
-License: MIT
-Description: A sphinx extension that automatically documents argparse commands 
and options.
-        
-        For installation and usage details, see the `documentation 
<http://sphinx-argparse.readthedocs.org/en/latest/>`_.
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Topic :: Documentation :: Sphinx
-Classifier: Topic :: Software Development :: Documentation
-Provides-Extra: dev
-Provides-Extra: markdown
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-argparse-0.2.5/sphinx_argparse.egg-info/SOURCES.txt 
new/sphinx-argparse-0.3.1/sphinx_argparse.egg-info/SOURCES.txt
--- old/sphinx-argparse-0.2.5/sphinx_argparse.egg-info/SOURCES.txt      
2018-11-14 15:03:25.000000000 +0100
+++ new/sphinx-argparse-0.3.1/sphinx_argparse.egg-info/SOURCES.txt      
1970-01-01 01:00:00.000000000 +0100
@@ -1,12 +0,0 @@
-README.md
-setup.py
-sphinx_argparse.egg-info/PKG-INFO
-sphinx_argparse.egg-info/SOURCES.txt
-sphinx_argparse.egg-info/dependency_links.txt
-sphinx_argparse.egg-info/requires.txt
-sphinx_argparse.egg-info/top_level.txt
-sphinxarg/__init__.py
-sphinxarg/ext.py
-sphinxarg/markdown.py
-sphinxarg/parser.py
-test/test_parser.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-argparse-0.2.5/sphinx_argparse.egg-info/dependency_links.txt 
new/sphinx-argparse-0.3.1/sphinx_argparse.egg-info/dependency_links.txt
--- old/sphinx-argparse-0.2.5/sphinx_argparse.egg-info/dependency_links.txt     
2018-11-14 15:03:25.000000000 +0100
+++ new/sphinx-argparse-0.3.1/sphinx_argparse.egg-info/dependency_links.txt     
1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-argparse-0.2.5/sphinx_argparse.egg-info/requires.txt 
new/sphinx-argparse-0.3.1/sphinx_argparse.egg-info/requires.txt
--- old/sphinx-argparse-0.2.5/sphinx_argparse.egg-info/requires.txt     
2018-11-14 15:03:25.000000000 +0100
+++ new/sphinx-argparse-0.3.1/sphinx_argparse.egg-info/requires.txt     
1970-01-01 01:00:00.000000000 +0100
@@ -1,8 +0,0 @@
-sphinx>=1.2.0
-
-[dev]
-pytest
-sphinx_rtd_theme
-
-[markdown]
-CommonMark>=0.5.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sphinx-argparse-0.2.5/sphinx_argparse.egg-info/top_level.txt 
new/sphinx-argparse-0.3.1/sphinx_argparse.egg-info/top_level.txt
--- old/sphinx-argparse-0.2.5/sphinx_argparse.egg-info/top_level.txt    
2018-11-14 15:03:25.000000000 +0100
+++ new/sphinx-argparse-0.3.1/sphinx_argparse.egg-info/top_level.txt    
1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-sphinxarg
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-argparse-0.2.5/sphinxarg/ext.py 
new/sphinx-argparse-0.3.1/sphinxarg/ext.py
--- old/sphinx-argparse-0.2.5/sphinxarg/ext.py  2018-11-14 15:02:19.000000000 
+0100
+++ new/sphinx-argparse-0.3.1/sphinxarg/ext.py  2021-09-06 21:59:31.252555800 
+0200
@@ -1,17 +1,19 @@
+import os
 import sys
 from argparse import ArgumentParser
-import os
 
 from docutils import nodes
-from docutils.statemachine import StringList
+from docutils.frontend import OptionParser
+from docutils.parsers.rst import Directive, Parser
 from docutils.parsers.rst.directives import flag, unchanged
-from docutils.parsers.rst import Parser, Directive
+from docutils.statemachine import StringList
 from docutils.utils import new_document
-from docutils.frontend import OptionParser
 from sphinx.util.nodes import nested_parse_with_titles
 
 from sphinxarg.parser import parse_parser, parser_navigate
 
+from . import __version__
+
 
 def map_nested_definitions(nested_content):
     if nested_content is None:
@@ -33,7 +35,11 @@
                 if len(ci.children) > 0:
                     classifier = ci.children[0].astext()
             if classifier is not None and classifier not in (
-                    '@replace', '@before', '@after', '@skip'):
+                '@replace',
+                '@before',
+                '@after',
+                '@skip',
+            ):
                 raise Exception('Unknown classifier: %s' % classifier)
             idx = subitem.first_child_matching_class(nodes.term)
             if idx is not None:
@@ -59,6 +65,7 @@
         return []
     if markDownHelp:
         from sphinxarg.markdown import parseMarkDownBlock
+
         return parseMarkDownBlock('\n\n'.join(l) + '\n')
     else:
         all_children = []
@@ -119,20 +126,25 @@
             items = []
             # Iterate over action group members
             for entry in action_group['options']:
-                """
-                Members will include:
-                    default    The default value. This may be ==SUPPRESS==
-                    name       A list of option names (e.g., ['-h', '--help']
-                    help       The help message string
-                There may also be a 'choices' member.
-                """
+                # Members will include:
+                #    default   The default value. This may be ==SUPPRESS==
+                #    name      A list of option names (e.g., ['-h', '--help']
+                #    help      The help message string
+                # There may also be a 'choices' member.
                 # Build the help text
                 arg = []
                 if 'choices' in entry:
-                    arg.append('Possible choices: {}\n'.format(", 
".join([str(c) for c in entry['choices']])))
+                    arg.append(
+                        'Possible choices: {}\n'.format(
+                            ", ".join([str(c) for c in entry['choices']])
+                        )
+                    )
                 if 'help' in entry:
                     arg.append(entry['help'])
-                if entry['default'] is not None and entry['default'] not in 
['"==SUPPRESS=="', '==SUPPRESS==']:
+                if entry['default'] is not None and entry['default'] not in [
+                    '"==SUPPRESS=="',
+                    '==SUPPRESS==',
+                ]:
                     if entry['default'] == '':
                         arg.append('Default: ""')
                     else:
@@ -151,9 +163,11 @@
                         desc.insert(0, s)
                 term = ', '.join(entry['name'])
 
-                n = nodes.option_list_item('',
-                                           nodes.option_group('', 
nodes.option_string(text=term)),
-                                           nodes.description('', 
*renderList(desc, markDownHelp, settings)))
+                n = nodes.option_list_item(
+                    '',
+                    nodes.option_group('', nodes.option_string(text=term)),
+                    nodes.description('', *renderList(desc, markDownHelp, 
settings)),
+                )
                 items.append(n)
 
             section += nodes.option_list('', *items)
@@ -203,12 +217,14 @@
             for element in renderList(desc, markDownHelp):
                 sec += element
             sec += nodes.literal_block(text=child['bare_usage'])
-            for x in print_action_groups(child, nested_content + subContent, 
markDownHelp,
-                                         settings=settings):
+            for x in print_action_groups(
+                child, nested_content + subContent, markDownHelp, 
settings=settings
+            ):
                 sec += x
 
-            for x in print_subcommands(child, nested_content + subContent, 
markDownHelp,
-                                       settings=settings):
+            for x in print_subcommands(
+                child, nested_content + subContent, markDownHelp, 
settings=settings
+            ):
                 sec += x
 
             if 'epilog' in child and child['epilog']:
@@ -248,12 +264,23 @@
 
 class ArgParseDirective(Directive):
     has_content = True
-    option_spec = dict(module=unchanged, func=unchanged, ref=unchanged,
-                       prog=unchanged, path=unchanged, nodefault=flag,
-                       nodefaultconst=flag, filename=unchanged,
-                       manpage=unchanged, nosubcommands=unchanged, 
passparser=flag,
-                       noepilog=unchanged, nodescription=unchanged,
-                       markdown=flag, markdownhelp=flag)
+    option_spec = dict(
+        module=unchanged,
+        func=unchanged,
+        ref=unchanged,
+        prog=unchanged,
+        path=unchanged,
+        nodefault=flag,
+        nodefaultconst=flag,
+        filename=unchanged,
+        manpage=unchanged,
+        nosubcommands=unchanged,
+        passparser=flag,
+        noepilog=unchanged,
+        nodescription=unchanged,
+        markdown=flag,
+        markdownhelp=flag,
+    )
 
     def _construct_manpage_specific_structure(self, parser_info):
         """
@@ -272,19 +299,23 @@
             '',
             nodes.title(text='Synopsis'),
             nodes.literal_block(text=parser_info["bare_usage"]),
-            ids=['synopsis-section'])
+            ids=['synopsis-section'],
+        )
         items.append(synopsis_section)
         # DESCRIPTION section
         if 'nodescription' not in self.options:
             description_section = nodes.section(
                 '',
                 nodes.title(text='Description'),
-                nodes.paragraph(text=parser_info.get(
-                    'description', parser_info.get(
-                        'help', "undocumented").capitalize())),
-                ids=['description-section'])
-            nested_parse_with_titles(
-                self.state, self.content, description_section)
+                nodes.paragraph(
+                    text=parser_info.get(
+                        'description',
+                        parser_info.get('help', "undocumented").capitalize(),
+                    )
+                ),
+                ids=['description-section'],
+            )
+            nested_parse_with_titles(self.state, self.content, 
description_section)
             items.append(description_section)
         if parser_info.get('epilog') and 'noepilog' not in self.options:
             # TODO: do whatever sphinx does to understand ReST inside
@@ -292,17 +323,14 @@
             # parse method invoked above seem to be able to do this but
             # I haven't found a way to do it for arbitrary text
             if description_section:
-                description_section += nodes.paragraph(
-                    text=parser_info['epilog'])
+                description_section += 
nodes.paragraph(text=parser_info['epilog'])
             else:
-                description_section = nodes.paragraph(
-                    text=parser_info['epilog'])
+                description_section = 
nodes.paragraph(text=parser_info['epilog'])
                 items.append(description_section)
         # OPTIONS section
         options_section = nodes.section(
-            '',
-            nodes.title(text='Options'),
-            ids=['options-section'])
+            '', nodes.title(text='Options'), ids=['options-section']
+        )
         if 'args' in parser_info:
             options_section += nodes.paragraph()
             options_section += nodes.subtitle(text='Positional arguments:')
@@ -324,21 +352,22 @@
         if 'nosubcommands' not in self.options:
             # SUBCOMMANDS section (non-standard)
             subcommands_section = nodes.section(
-                '',
-                nodes.title(text='Sub-Commands'),
-                ids=['subcommands-section'])
+                '', nodes.title(text='Sub-Commands'), 
ids=['subcommands-section']
+            )
             if 'children' in parser_info:
                 subcommands_section += self._format_subcommands(parser_info)
             if len(subcommands_section) > 1:
                 items.append(subcommands_section)
         if os.getenv("INCLUDE_DEBUG_SECTION"):
             import json
+
             # DEBUG section (non-standard)
             debug_section = nodes.section(
                 '',
                 nodes.title(text="Argparse + Sphinx Debugging"),
                 nodes.literal_block(text=json.dumps(parser_info, indent='  ')),
-                ids=['debug-section'])
+                ids=['debug-section'],
+            )
             items.append(debug_section)
         return items
 
@@ -354,16 +383,18 @@
             if 'choices' in arg:
                 arg_items.append(
                     nodes.paragraph(
-                        text='Possible choices: ' + ', '.join(arg['choices'])))
+                        text='Possible choices: ' + ', '.join(arg['choices'])
+                    )
+                )
             items.append(
                 nodes.option_list_item(
                     '',
                     nodes.option_group(
-                        '', nodes.option(
-                            '', nodes.option_string(text=arg['metavar'])
-                        )
+                        '', nodes.option('', 
nodes.option_string(text=arg['metavar']))
                     ),
-                    nodes.description('', *arg_items)))
+                    nodes.description('', *arg_items),
+                )
+            )
         return nodes.option_list('', *items)
 
     def _format_optional_arguments(self, parser_info):
@@ -374,10 +405,13 @@
             opt_items = []
             for name in opt['name']:
                 option_declaration = [nodes.option_string(text=name)]
-                if opt['default'] is not None \
-                        and opt['default'] not in ['"==SUPPRESS=="', 
'==SUPPRESS==']:
+                if opt['default'] is not None and opt['default'] not in [
+                    '"==SUPPRESS=="',
+                    '==SUPPRESS==',
+                ]:
                     option_declaration += nodes.option_argument(
-                        '', text='=' + str(opt['default']))
+                        '', text='=' + str(opt['default'])
+                    )
                 names.append(nodes.option('', *option_declaration))
             if opt['help']:
                 opt_items.append(nodes.paragraph(text=opt['help']))
@@ -386,11 +420,16 @@
             if 'choices' in opt:
                 opt_items.append(
                     nodes.paragraph(
-                        text='Possible choices: ' + ', '.join(opt['choices'])))
+                        text='Possible choices: ' + ', '.join(opt['choices'])
+                    )
+                )
             items.append(
                 nodes.option_list_item(
-                    '', nodes.option_group('', *names),
-                    nodes.description('', *opt_items)))
+                    '',
+                    nodes.option_group('', *names),
+                    nodes.description('', *opt_items),
+                )
+            )
         return nodes.option_list('', *items)
 
     def _format_subcommands(self, parser_info):
@@ -405,9 +444,10 @@
             items.append(
                 nodes.definition_list_item(
                     '',
-                    nodes.term('', '', nodes.strong(
-                        text=subcmd['bare_usage'])),
-                    nodes.definition('', *subcmd_items)))
+                    nodes.term('', '', 
nodes.strong(text=subcmd['bare_usage'])),
+                    nodes.definition('', *subcmd_items),
+                )
+            )
         return nodes.definition_list('', *items)
 
     def _nested_parse_paragraph(self, text):
@@ -436,20 +476,27 @@
             func = mod[attr_name]
         else:
             raise self.error(
-                ':module: and :func: should be specified, or :ref:, or 
:filename: and :func:')
+                ':module: and :func: should be specified, or :ref:, or 
:filename: and :func:'
+            )
 
         # Skip this if we're dealing with a local file, since it obviously 
can't be imported
         if 'filename' not in self.options:
             try:
                 mod = __import__(module_name, globals(), locals(), [attr_name])
             except:
-                raise self.error('Failed to import "%s" from "%s".\n%s' % 
(attr_name, module_name, sys.exc_info()[1]))
+                raise self.error(
+                    'Failed to import "%s" from "%s".\n%s'
+                    % (attr_name, module_name, sys.exc_info()[1])
+                )
 
             if not hasattr(mod, attr_name):
-                raise self.error((
-                    'Module "%s" has no attribute "%s"\n'
-                    'Incorrect argparse :module: or :func: values?'
-                ) % (module_name, attr_name))
+                raise self.error(
+                    (
+                        'Module "%s" has no attribute "%s"\n'
+                        'Incorrect argparse :module: or :func: values?'
+                    )
+                    % (module_name, attr_name)
+                )
             func = getattr(mod, attr_name)
 
         if isinstance(func, ArgumentParser):
@@ -465,7 +512,10 @@
         if 'prog' in self.options:
             parser.prog = self.options['prog']
         result = parse_parser(
-            parser, skip_default_values='nodefault' in self.options, 
skip_default_const_values='nodefaultconst' in self.options)
+            parser,
+            skip_default_values='nodefault' in self.options,
+            skip_default_const_values='nodefaultconst' in self.options,
+        )
         result = parser_navigate(result, path)
         if 'manpage' in self.options:
             return self._construct_manpage_specific_structure(result)
@@ -475,10 +525,10 @@
         nested_content = nodes.paragraph()
         if 'markdown' in self.options:
             from sphinxarg.markdown import parseMarkDownBlock
+
             items.extend(parseMarkDownBlock('\n'.join(self.content) + '\n'))
         else:
-            self.state.nested_parse(
-                self.content, self.content_offset, nested_content)
+            self.state.nested_parse(self.content, self.content_offset, 
nested_content)
             nested_content = nested_content.children
         # add common content between
         for item in nested_content:
@@ -494,11 +544,23 @@
             else:
                 
items.append(self._nested_parse_paragraph(result['description']))
         items.append(nodes.literal_block(text=result['usage']))
-        items.extend(print_action_groups(result, nested_content, markDownHelp,
-                                         
settings=self.state.document.settings))
+        items.extend(
+            print_action_groups(
+                result,
+                nested_content,
+                markDownHelp,
+                settings=self.state.document.settings,
+            )
+        )
         if 'nosubcommands' not in self.options:
-            items.extend(print_subcommands(result, nested_content, 
markDownHelp,
-                                           
settings=self.state.document.settings))
+            items.extend(
+                print_subcommands(
+                    result,
+                    nested_content,
+                    markDownHelp,
+                    settings=self.state.document.settings,
+                )
+            )
         if 'epilog' in result and 'noepilog' not in self.options:
             items.append(self._nested_parse_paragraph(result['epilog']))
 
@@ -510,3 +572,4 @@
 
 def setup(app):
     app.add_directive('argparse', ArgParseDirective)
+    return {'parallel_read_safe': True, 'version': __version__}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-argparse-0.2.5/sphinxarg/markdown.py 
new/sphinx-argparse-0.3.1/sphinxarg/markdown.py
--- old/sphinx-argparse-0.2.5/sphinxarg/markdown.py     2018-10-12 
14:07:43.000000000 +0200
+++ new/sphinx-argparse-0.3.1/sphinxarg/markdown.py     2021-09-06 
21:59:31.252555800 +0200
@@ -20,9 +20,9 @@
     >>> customWalker(content)
     document
         heading
-            text       Some big text block
+            text    Some big text block
         paragraph
-            text       with content
+            text    with content
 
     Spaces are used to convey nesting
     """
@@ -252,7 +252,11 @@
     if node.list_data['type'] == u'bullet':
         o = nodes.bullet_list(bullet=node.list_data['bullet_char'])
     else:
-        o = nodes.enumerated_list(suffix=node.list_data['delimiter'], 
enumtype='arabic', start=node.list_data['start'])
+        o = nodes.enumerated_list(
+            suffix=node.list_data['delimiter'],
+            enumtype='arabic',
+            start=node.list_data['start'],
+        )
     for n in MarkDown(node):
         o += n
     return o
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-argparse-0.2.5/sphinxarg/parser.py 
new/sphinx-argparse-0.3.1/sphinxarg/parser.py
--- old/sphinx-argparse-0.2.5/sphinxarg/parser.py       2018-11-14 
09:53:26.000000000 +0100
+++ new/sphinx-argparse-0.3.1/sphinxarg/parser.py       2021-09-06 
21:59:31.252555800 +0200
@@ -1,5 +1,5 @@
-from argparse import _HelpAction, _SubParsersAction, _StoreConstAction
 import re
+from argparse import _HelpAction, _StoreConstAction, _SubParsersAction
 
 
 class NavigationException(Exception):
@@ -10,22 +10,25 @@
     if isinstance(path, str):
         if path == '':
             return parser_result
-        path = re.split('\s+', path)
+        path = re.split(r'\s+', path)
     current_path = current_path or []
     if len(path) == 0:
         return parser_result
     if 'children' not in parser_result:
         raise NavigationException(
-            'Current parser has no child elements.  (path: %s)' %
-            ' '.join(current_path))
+            'Current parser has no child elements.  (path: %s)' % ' 
'.join(current_path)
+        )
     next_hop = path.pop(0)
     for child in parser_result['children']:
-        if child['name'] == next_hop:
+        # identifer is only used for aliased subcommands
+        identifier = child['identifier'] if 'identifier' in child else 
child['name']
+        if identifier == next_hop:
             current_path.append(next_hop)
             return parser_navigate(child, path, current_path)
     raise NavigationException(
-        'Current parser has no child element with name: %s  (path: %s)' % (
-            next_hop, ' '.join(current_path)))
+        'Current parser has no child element with name: %s  (path: %s)'
+        % (next_hop, ' '.join(current_path))
+    )
 
 
 def _try_add_parser_attribute(data, parser, attribname):
@@ -44,8 +47,9 @@
     the 'usage: ' prefix.
     """
     fmt = parser._get_formatter()
-    fmt.add_usage(parser.usage, parser._actions,
-                  parser._mutually_exclusive_groups, prefix='')
+    fmt.add_usage(
+        parser.usage, parser._actions, parser._mutually_exclusive_groups, 
prefix=''
+    )
     return fmt.format_help().strip()
 
 
@@ -83,19 +87,23 @@
             subalias = subsection_alias[subaction]
             subaction.prog = '%s %s' % (parser.prog, name)
             subdata = {
-                'name': name if not subalias else '%s (%s)' % (name, ', 
'.join(subalias)),
+                'name': name
+                if not subalias
+                else '%s (%s)' % (name, ', '.join(subalias)),
                 'help': helps.get(name, ''),
                 'usage': subaction.format_usage().strip(),
                 'bare_usage': _format_usage_without_prefix(subaction),
             }
+            if subalias:
+                subdata['identifier'] = name
             parse_parser(subaction, subdata, **kwargs)
             data.setdefault('children', []).append(subdata)
 
     show_defaults = True
-    if 'skip_default_values' in kwargs and kwargs['skip_default_values'] is 
True:
+    if kwargs.get('skip_default_values', False) is True:
         show_defaults = False
     show_defaults_const = show_defaults
-    if 'skip_default_const_values' in kwargs and 
kwargs['skip_default_const_values'] is True:
+    if kwargs.get('skip_default_const_values', False) is True:
         show_defaults_const = False
 
     # argparse stores the different groups as a list in parser._action_groups
@@ -111,7 +119,11 @@
 
             # Quote default values for string/None types
             default = action.default
-            if action.default not in ['', None, True, False] and action.type 
in [None, str] and isinstance(action.default, str):
+            if (
+                action.default not in ['', None, True, False]
+                and action.type in [None, str]
+                and isinstance(action.default, str)
+            ):
                 default = '"%s"' % default
 
             # fill in any formatters, like %(default)s
@@ -138,13 +150,13 @@
                 option = {
                     'name': name,
                     'default': default if show_defaults_const else 
'==SUPPRESS==',
-                    'help': helpStr
+                    'help': helpStr,
                 }
             else:
                 option = {
                     'name': name,
                     'default': default if show_defaults else '==SUPPRESS==',
-                    'help': helpStr
+                    'help': helpStr,
                 }
             if action.choices:
                 option['choices'] = action.choices
@@ -160,9 +172,11 @@
         if action_group.title == 'positional arguments':
             action_group.title = 'Positional Arguments'
 
-        group = {'title': action_group.title,
-                 'description': action_group.description,
-                 'options': options_list}
+        group = {
+            'title': action_group.title,
+            'description': action_group.description,
+            'options': options_list,
+        }
 
         action_groups.append(group)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-argparse-0.2.5/test/sample.py 
new/sphinx-argparse-0.3.1/test/sample.py
--- old/sphinx-argparse-0.2.5/test/sample.py    1970-01-01 01:00:00.000000000 
+0100
+++ new/sphinx-argparse-0.3.1/test/sample.py    2021-09-06 21:10:52.618904400 
+0200
@@ -0,0 +1,62 @@
+import argparse
+
+parser = argparse.ArgumentParser()
+
+subparsers = parser.add_subparsers()
+
+my_command1 = subparsers.add_parser(
+    'apply', help='Execute provision script, collect all resources and apply 
them.'
+)
+
+my_command1.add_argument(
+    'path',
+    help='Specify path to provision script. provision.py in current'
+    'directory by default. Also may include url.',
+    default='provision.py',
+)
+my_command1.add_argument(
+    '-r',
+    '--rollback',
+    action='store_true',
+    default=False,
+    help='If specified will rollback all' 'resources applied.',
+)
+my_command1.add_argument(
+    '--tree', action='store_true', default=False, help='Print resource tree'
+)
+my_command1.add_argument(
+    '--dry', action='store_true', default=False, help='Just print changes list'
+)
+my_command1.add_argument(
+    '--force', action='store_true', default=False, help='Apply without 
confirmation'
+)
+my_command1.add_argument(
+    'default_string',
+    default='I am a default',
+    help='Ensure variables are filled in %(prog)s (default %(default)s)',
+)
+
+my_command2 = subparsers.add_parser('game', help='Decision games')
+my_command2.add_argument(
+    'move', choices=['rock', 'paper', 'scissors'], help='Choices for argument 
example'
+)
+my_command2.add_argument(
+    '--opt', choices=['rock', 'paper', 'scissors'], help='Choices for option 
example'
+)
+
+optional = my_command2.add_argument_group('Group 1')
+
+optional.add_argument(
+    '--addition',
+    choices=['Spock', 'lizard'],
+    help='Extra choices for additional group.',
+)
+optional.add_argument(
+    '--lorem_ipsum',
+    help='Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do 
eiusmod '
+    'tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim 
veniam, '
+    'quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo '
+    'consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse 
'
+    'cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat 
'
+    'non proident, sunt in culpa qui officia deserunt mollit anim id est 
laborum.',
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-argparse-0.2.5/test/sample2.py 
new/sphinx-argparse-0.3.1/test/sample2.py
--- old/sphinx-argparse-0.2.5/test/sample2.py   1970-01-01 01:00:00.000000000 
+0100
+++ new/sphinx-argparse-0.3.1/test/sample2.py   2021-09-06 21:10:52.618904400 
+0200
@@ -0,0 +1,13 @@
+import argparse
+
+
+def blah():
+    parser = argparse.ArgumentParser(
+        description="""
+### Example of MarkDown inside programs
+
+[I'm a link](http://www.google.com)
+"""
+    )
+    parser.add_argument('cmd', help='execute a `command`')
+    return parser
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sphinx-argparse-0.2.5/test/test_parser.py 
new/sphinx-argparse-0.3.1/test/test_parser.py
--- old/sphinx-argparse-0.2.5/test/test_parser.py       2017-03-31 
10:08:31.000000000 +0200
+++ new/sphinx-argparse-0.3.1/test/test_parser.py       2021-09-06 
21:59:31.252555800 +0200
@@ -1,4 +1,7 @@
 import argparse
+
+import six
+
 from sphinxarg.parser import parse_parser, parser_navigate
 
 
@@ -10,15 +13,8 @@
     data = parse_parser(parser)
 
     assert data['action_groups'][0]['options'] == [
-        {
-            'name': ['--foo'],
-            'default': False,
-            'help': 'foo help'
-        }, {
-            'name': ['--bar'],
-            'default': False,
-            'help': ''
-        }
+        {'name': ['--foo'], 'default': False, 'help': 'foo help'},
+        {'name': ['--bar'], 'default': False, 'help': ''},
     ]
 
 
@@ -29,11 +25,7 @@
     data = parse_parser(parser)
 
     assert data['action_groups'][0]['options'] == [
-        {
-            'name': ['--foo'],
-            'default': '"123"',
-            'help': ''
-        }
+        {'name': ['--foo'], 'default': '"123"', 'help': ''}
     ]
 
 
@@ -48,7 +40,7 @@
             'name': ['move'],
             'help': '',
             'choices': ['rock', 'paper', 'scissors'],
-            'default': None
+            'default': None,
         }
     ]
 
@@ -64,7 +56,7 @@
             'name': ['--move'],
             'default': None,
             'help': '',
-            'choices': ['rock', 'paper', 'scissors']
+            'choices': ['rock', 'paper', 'scissors'],
         }
     ]
 
@@ -76,11 +68,7 @@
     data = parse_parser(parser, skip_default_values=True)
 
     assert data['action_groups'][0]['options'] == [
-        {
-            'name': ['--foo'],
-            'default': '==SUPPRESS==',
-            'help': ''
-        }
+        {'name': ['--foo'], 'default': '==SUPPRESS==', 'help': ''}
     ]
 
 
@@ -92,15 +80,8 @@
     data = parse_parser(parser)
 
     assert data['action_groups'][0]['options'] == [
-        {
-            'name': ['foo'],
-            'help': 'foo help',
-            'default': False
-        }, {
-            'name': ['bar'],
-            'help': '',
-            'default': False
-        }
+        {'name': ['foo'], 'help': 'foo help', 'default': False},
+        {'name': ['bar'], 'help': '', 'default': False},
     ]
 
 
@@ -116,20 +97,13 @@
     assert data['epilog'] == 'epilogged'
 
     assert data['action_groups'][0]['options'] == [
-        {
-            'name': ['foo'],
-            'help': 'foo help',
-            'default': False
-        }, {
-            'name': ['bar'],
-            'help': '',
-            'default': False
-        }
+        {'name': ['foo'], 'help': 'foo help', 'default': False},
+        {'name': ['bar'], 'help': '', 'default': False},
     ]
 
 
 def test_parse_nested():
-    parser = argparse.ArgumentParser()
+    parser = argparse.ArgumentParser(prog='under-test')
     parser.add_argument('foo', default=False, help='foo help')
     parser.add_argument('bar', default=False)
 
@@ -137,58 +111,116 @@
 
     subparser = subparsers.add_parser('install', help='install help')
     subparser.add_argument('ref', type=str, help='foo1 help')
-    subparser.add_argument('--upgrade', action='store_true', default=False, 
help='foo2 help')
+    subparser.add_argument(
+        '--upgrade', action='store_true', default=False, help='foo2 help'
+    )
 
     data = parse_parser(parser)
 
     assert data['action_groups'][0]['options'] == [
-        {
-            'name': ['foo'],
-            'help': 'foo help',
-            'default': False
-        }, {
-            'name': ['bar'],
-            'help': '',
-            'default': False
-        }
+        {'name': ['foo'], 'help': 'foo help', 'default': False},
+        {'name': ['bar'], 'help': '', 'default': False},
     ]
 
     assert data['children'] == [
         {
             'name': 'install',
             'help': 'install help',
-            'usage': 'usage: py.test install [-h] [--upgrade] ref',
-            'bare_usage': 'py.test install [-h] [--upgrade] ref',
+            'usage': 'usage: under-test install [-h] [--upgrade] ref',
+            'bare_usage': 'under-test install [-h] [--upgrade] ref',
             'action_groups': [
                 {
                     'title': 'Positional Arguments',
                     'description': None,
                     'options': [
-                        {
-                            'name': ['ref'],
-                            'help': 'foo1 help',
-                            'default': None
-                        }
-                    ]
+                        {'name': ['ref'], 'help': 'foo1 help', 'default': None}
+                    ],
                 },
                 {
                     'description': None,
                     'title': 'Named Arguments',
                     'options': [
-                        {
-                            'name': ['--upgrade'],
-                            'default': False,
-                            'help': 'foo2 help'
-                        }
-                    ]
-                }
-            ]
+                        {'name': ['--upgrade'], 'default': False, 'help': 
'foo2 help'}
+                    ],
+                },
+            ],
         }
     ]
 
 
+if six.PY3:
+
+    def test_parse_nested_with_alias():
+        parser = argparse.ArgumentParser(prog='under-test')
+        parser.add_argument('foo', default=False, help='foo help')
+        parser.add_argument('bar', default=False)
+
+        subparsers = parser.add_subparsers()
+
+        subparser = subparsers.add_parser('install', aliases=['i'], 
help='install help')
+        subparser.add_argument('ref', type=str, help='foo1 help')
+        subparser.add_argument(
+            '--upgrade', action='store_true', default=False, help='foo2 help'
+        )
+
+        data = parse_parser(parser)
+
+        assert data['action_groups'][0]['options'] == [
+            {'name': ['foo'], 'help': 'foo help', 'default': False},
+            {'name': ['bar'], 'help': '', 'default': False},
+        ]
+
+        assert data['children'] == [
+            {
+                'name': 'install (i)',
+                'identifier': 'install',
+                'help': 'install help',
+                'usage': 'usage: under-test install [-h] [--upgrade] ref',
+                'bare_usage': 'under-test install [-h] [--upgrade] ref',
+                'action_groups': [
+                    {
+                        'title': 'Positional Arguments',
+                        'description': None,
+                        'options': [
+                            {'name': ['ref'], 'help': 'foo1 help', 'default': 
None}
+                        ],
+                    },
+                    {
+                        'description': None,
+                        'title': 'Named Arguments',
+                        'options': [
+                            {
+                                'name': ['--upgrade'],
+                                'default': False,
+                                'help': 'foo2 help',
+                            }
+                        ],
+                    },
+                ],
+            }
+        ]
+
+    def test_aliased_traversal():
+        parser = argparse.ArgumentParser(prog='under-test')
+
+        subparsers1 = parser.add_subparsers()
+        subparsers1.add_parser('level1', aliases=['l1'])
+
+        data = parse_parser(parser)
+
+        data2 = parser_navigate(data, 'level1')
+
+        assert data2 == {
+            'bare_usage': 'under-test level1 [-h]',
+            'help': '',
+            'usage': 'usage: under-test level1 [-h]',
+            'name': 'level1 (l1)',
+            'identifier': 'level1',
+        }
+
+
 def test_parse_nested_traversal():
-    parser = argparse.ArgumentParser()
+    parser = argparse.ArgumentParser(prog='under-test')
 
     subparsers1 = parser.add_subparsers()
     subparser1 = subparsers1.add_parser('level1')
@@ -207,15 +239,8 @@
     data3 = parser_navigate(data, 'level1 level2 level3')
 
     assert data3['action_groups'][0]['options'] == [
-        {
-            'name': ['foo'],
-            'help': 'foo help',
-            'default': None
-        }, {
-            'name': ['bar'],
-            'help': '',
-            'default': None
-        }
+        {'name': ['foo'], 'help': 'foo help', 'default': None},
+        {'name': ['bar'], 'help': '', 'default': None},
     ]
 
     data2 = parser_navigate(data, 'level1 level2')
@@ -223,25 +248,18 @@
         {
             'name': 'level3',
             'help': '',
-            'usage': 'usage: py.test level1 level2 level3 [-h] foo bar',
-            'bare_usage': 'py.test level1 level2 level3 [-h] foo bar',
+            'usage': 'usage: under-test level1 level2 level3 [-h] foo bar',
+            'bare_usage': 'under-test level1 level2 level3 [-h] foo bar',
             'action_groups': [
                 {
                     'title': 'Positional Arguments',
                     'description': None,
                     'options': [
-                        {
-                            'default': None,
-                            'name': ['foo'],
-                            'help': 'foo help'
-                        }, {
-                            'name': ['bar'],
-                            'help': '',
-                            'default': None
-                        }
-                    ]
+                        {'default': None, 'name': ['foo'], 'help': 'foo help'},
+                        {'name': ['bar'], 'help': '', 'default': None},
+                    ],
                 }
-            ]
+            ],
         }
     ]
 
@@ -260,7 +278,7 @@
         {
             'default': '"foo"',
             'name': ['bar'],
-            'help': 'test_fill_in_default_prog (default: "foo")'
+            'help': 'test_fill_in_default_prog (default: "foo")',
         }
     ]
 
@@ -271,14 +289,16 @@
     This prevents things like '--optLSFConf=-q short' when '--optLSFConf="-q 
short"' is correct.
     """
     parser = argparse.ArgumentParser(prog='test_string_quoting_prog')
-    parser.add_argument('--bar', default='foo bar', help='%(prog)s (default: 
%(default)s)')
+    parser.add_argument(
+        '--bar', default='foo bar', help='%(prog)s (default: %(default)s)'
+    )
     data = parse_parser(parser)
 
     assert data['action_groups'][0]['options'] == [
         {
             'default': '"foo bar"',
             'name': ['--bar'],
-            'help': 'test_string_quoting_prog (default: "foo bar")'
+            'help': 'test_string_quoting_prog (default: "foo bar")',
         }
     ]
 
@@ -297,15 +317,18 @@
             'description': None,
             'options': [
                 {'default': False, 'help': 'foo help', 'name': ['--foo']},
-                {'default': False, 'help': '', 'name': ['--bar']}],
-            'title': 'Named Arguments'},
+                {'default': False, 'help': '', 'name': ['--bar']},
+            ],
+            'title': 'Named Arguments',
+        },
         {
             'description': None,
             'options': [
                 {'default': None, 'help': 'option #1', 'name': ['--option1']},
-                {'default': None, 'help': 'option #2', 'name': ['--option2']}],
-            'title': 'Group 1'
-        }
+                {'default': None, 'help': 'option #2', 'name': ['--option2']},
+            ],
+            'title': 'Group 1',
+        },
     ]
 
 
@@ -334,13 +357,70 @@
     data = parse_parser(parser)
 
     assert data['action_groups'] == [
-        {'options': [{'default': None, 'name': ['foo2 metavar'], 'help': 'foo2 
help'}], 'description': None, 'title': 'Positional Arguments'},
-        {'options': [{'default': None, 'name': ['--foo'], 'help': 'foo 
help'}], 'description': None, 'title': 'Named Arguments'},
-        {'options': [{'default': None, 'name': ['--bar'], 'help': 'bar help'}, 
{'default': None, 'name': ['quux'], 'help': 'quux help'}], 'description': None, 
'title': 'bar options'},
-        {'options': [{'default': None, 'name': ['--blah'], 'help': 'blah 
help'}, {'default': None, 'name': ['sniggly'], 'help': 'sniggly help'}], 
'description': None, 'title': 'bla options'}
+        {
+            'options': [
+                {'default': None, 'name': ['foo2 metavar'], 'help': 'foo2 
help'}
+            ],
+            'description': None,
+            'title': 'Positional Arguments',
+        },
+        {
+            'options': [{'default': None, 'name': ['--foo'], 'help': 'foo 
help'}],
+            'description': None,
+            'title': 'Named Arguments',
+        },
+        {
+            'options': [
+                {'default': None, 'name': ['--bar'], 'help': 'bar help'},
+                {'default': None, 'name': ['quux'], 'help': 'quux help'},
+            ],
+            'description': None,
+            'title': 'bar options',
+        },
+        {
+            'options': [
+                {'default': None, 'name': ['--blah'], 'help': 'blah help'},
+                {'default': None, 'name': ['sniggly'], 'help': 'sniggly help'},
+            ],
+            'description': None,
+            'title': 'bla options',
+        },
     ]
 
     assert data['children'] == [
-        {'usage': 'usage: foo A [-h] baz', 'action_groups': [{'options': 
[{'default': None, 'name': ['baz'], 'help': 'An integer'}], 'description': 
None, 'title': 'Positional Arguments'}], 'bare_usage': 'foo A [-h] baz', 
'name': 'A', 'help': 'A subparser'},
-        {'usage': 'usage: foo B [-h] [--barg {X,Y,Z}]', 'action_groups': 
[{'options': [{'default': None, 'choices': 'XYZ', 'name': ['--barg'], 'help': 
'A list of choices'}], 'description': None, 'title': 'Named Arguments'}], 
'bare_usage': 'foo B [-h] [--barg {X,Y,Z}]', 'name': 'B', 'help': 'B subparser'}
+        {
+            'usage': 'usage: foo A [-h] baz',
+            'action_groups': [
+                {
+                    'options': [
+                        {'default': None, 'name': ['baz'], 'help': 'An 
integer'}
+                    ],
+                    'description': None,
+                    'title': 'Positional Arguments',
+                }
+            ],
+            'bare_usage': 'foo A [-h] baz',
+            'name': 'A',
+            'help': 'A subparser',
+        },
+        {
+            'usage': 'usage: foo B [-h] [--barg {X,Y,Z}]',
+            'action_groups': [
+                {
+                    'options': [
+                        {
+                            'default': None,
+                            'choices': 'XYZ',
+                            'name': ['--barg'],
+                            'help': 'A list of choices',
+                        }
+                    ],
+                    'description': None,
+                    'title': 'Named Arguments',
+                }
+            ],
+            'bare_usage': 'foo B [-h] [--barg {X,Y,Z}]',
+            'name': 'B',
+            'help': 'B subparser',
+        },
     ]

Reply via email to