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-10-18 12:45:40 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-sphinx-argparse (Old) and /work/SRC/openSUSE:Factory/.python-sphinx-argparse.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-sphinx-argparse" Tue Oct 18 12:45:40 2022 rev:4 rq:1029662 version:0.3.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-sphinx-argparse/python-sphinx-argparse.changes 2022-02-18 23:03:11.433411682 +0100 +++ /work/SRC/openSUSE:Factory/.python-sphinx-argparse.new.2275/python-sphinx-argparse.changes 2022-10-18 12:46:04.313870175 +0200 @@ -1,0 +2,8 @@ +Tue Oct 18 07:46:26 UTC 2022 - Steve Kowalik <steven.kowa...@suse.com> + +- Update to 0.3.2: + * Modernize project: Py3.6+, black, flynt, flake8, Github Actions + * Fix tests for python-3.10 and add 3.10 to CI matrix +- Remove patch python-sphinx-argparse-python310.patch, included upstream. + +------------------------------------------------------------------- Old: ---- python-sphinx-argparse-python310.patch sphinx-argparse-0.3.1.tar.gz New: ---- sphinx-argparse-0.3.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-sphinx-argparse.spec ++++++ --- /var/tmp/diff_new_pack.JSBb9b/_old 2022-10-18 12:46:04.813871313 +0200 +++ /var/tmp/diff_new_pack.JSBb9b/_new 2022-10-18 12:46:04.821871332 +0200 @@ -16,18 +16,14 @@ # -%{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-sphinx-argparse -Version: 0.3.1 +Version: 0.3.2 Release: 0 Summary: Sphinx extension to document argparse commands and options License: MIT -Group: Development/Languages/Python URL: https://github.com/ashb/sphinx-argparse Source0: https://files.pythonhosted.org/packages/source/s/sphinx-argparse/sphinx-argparse-%{version}.tar.gz -# 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} @@ -48,6 +44,8 @@ %install %python_install +# Remove test files, they are in a seperate 'test' module. +%python_expand rm -r %{buildroot}%{$python_sitelib}/test %python_expand %fdupes %{buildroot}%{$python_sitelib} %check ++++++ sphinx-argparse-0.3.1.tar.gz -> sphinx-argparse-0.3.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-argparse-0.3.1/PKG-INFO new/sphinx-argparse-0.3.2/PKG-INFO --- old/sphinx-argparse-0.3.1/PKG-INFO 2021-09-06 22:00:56.387063500 +0200 +++ new/sphinx-argparse-0.3.2/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 @@ -1,20 +1,37 @@ Metadata-Version: 2.1 Name: sphinx-argparse -Version: 0.3.1 +Version: 0.3.2 Summary: A sphinx extension that automatically documents argparse commands and options +Home-page: https://github.com/ashb/sphinx-argparse License: MIT Author: Ash Berlin-Taylor Author-email: ash_git...@firemirror.com -Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* +Requires-Python: >=3.6 +Classifier: Framework :: Sphinx :: Extension 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: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 Provides-Extra: markdown Requires-Dist: CommonMark (>=0.5.6); extra == "markdown" Requires-Dist: sphinx (>=1.2.0) +Project-URL: Repository, https://github.com/ashb/sphinx-argparse +Description-Content-Type: text/markdown + +[](http://sphinx-argparse.readthedocs.org/) +[](https://badge.fury.io/py/sphinx-argparse) +[](https://github.com/conda-forge/sphinx-argparse-feedstock) + + +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). + +This project used to live at [alex-rudakov/sphinx-argparse](https://github.com/alex-rudakov/sphinx-argparse/) that the original maintainer disappears so I have taken over the project under this new home. + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-argparse-0.3.1/README.md new/sphinx-argparse-0.3.2/README.md --- old/sphinx-argparse-0.3.1/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/sphinx-argparse-0.3.2/README.md 2022-10-03 12:31:53.151545000 +0200 @@ -0,0 +1,13 @@ +[](http://sphinx-argparse.readthedocs.org/) +[](https://badge.fury.io/py/sphinx-argparse) +[](https://github.com/conda-forge/sphinx-argparse-feedstock) + + +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). + +This project used to live at [alex-rudakov/sphinx-argparse](https://github.com/alex-rudakov/sphinx-argparse/) that the original maintainer disappears so I have taken over the project under this new home. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-argparse-0.3.1/pyproject.toml new/sphinx-argparse-0.3.2/pyproject.toml --- old/sphinx-argparse-0.3.1/pyproject.toml 2021-09-06 22:00:16.496185300 +0200 +++ new/sphinx-argparse-0.3.2/pyproject.toml 2022-10-03 12:35:12.471066700 +0200 @@ -1,16 +1,21 @@ [tool.poetry] name = "sphinx-argparse" -version = "0.3.1" +version = "0.3.2" description = "A sphinx extension that automatically documents argparse commands and options" +readme = "README.md" +repository = "https://github.com/ashb/sphinx-argparse" authors = ["Ash Berlin-Taylor <ash_git...@firemirror.com>"] license = "MIT" +classifiers = [ + "Framework :: Sphinx :: Extension", +] packages = [ { include = "sphinxarg" }, { include = "test", format = "sdist" }, ] [tool.poetry.dependencies] -python = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" +python = ">=3.6" sphinx = ">=1.2.0" CommonMark = { version = ">=0.5.6", optional = true } @@ -18,17 +23,45 @@ markdown = ["CommonMark"] [tool.poetry.dev-dependencies] -six = "*" flake8 = "*" pytest = "*" -pytest-deadfixtures = "*" +pytest-cov = "^2.7" +pytest-deadfixtures = "^2.2.1" flake8-colors = "^0.1.9" -black = {version = "^20.8b1", allow-prereleases = true, python = ">=3.6h"} +flake8-bugbear = "^19.8" +black = {version = "^21.8b0", allow-prereleases = true, python = ">=3.6.2"} isort = {version = "^5.8.0", python = "^3.6"} +mypy = "^0.910" +types-docutils = "^0.17.0" +pep8-naming = "^0.8.2" [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" [tool.black] +line-length = 160 skip-string-normalization = true + +[tool.isort] +balanced_wrapping = true +default_section = "THIRDPARTY" +include_trailing_comma = true +known_first_party = [ "sphinxarg", "test" ] +line_length = 160 +multi_line_output = 3 + +[[tool.mypy.overrides]] +module = [ + "commonmark.*", + "CommonMark.*", + "docutils.parsers.rst.directives", +] +ignore_missing_imports = true + +[tool.pytest.ini_options] +addopts = "--strict-markers" + +[tool.coverage.run] +omit = ["tests/*","**/__main__.py"] +branch = true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-argparse-0.3.1/setup.py new/sphinx-argparse-0.3.2/setup.py --- old/sphinx-argparse-0.3.1/setup.py 2021-09-06 22:00:56.386750200 +0200 +++ new/sphinx-argparse-0.3.2/setup.py 1970-01-01 01:00:00.000000000 +0100 @@ -15,19 +15,19 @@ setup_kwargs = { 'name': 'sphinx-argparse', - 'version': '0.3.1', + 'version': '0.3.2', 'description': 'A sphinx extension that automatically documents argparse commands and options', - 'long_description': None, + 'long_description': '[](http://sphinx-argparse.readthedocs.org/)\n[](https://badge.fury.io/py/sphinx-argparse)\n[](https://github.com/conda-forge/sphinx-argparse-feedstock)\n\n\nsphinx-argparse\n===============\n\nA sphinx extension that automatically documents argparse commands and options.\n\nFor 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).\n\nThis project used to live at [alex-rudakov/sphinx-argparse](https://github.com/alex-rudakov/sphinx-argparse/) that the original maintainer disappears so I have taken over the project under this new home.\n', 'author': 'Ash Berlin-Taylor', 'author_email': 'ash_git...@firemirror.com', - 'maintainer': None, - 'maintainer_email': None, - 'url': None, + 'maintainer': 'None', + 'maintainer_email': 'None', + 'url': 'https://github.com/ashb/sphinx-argparse', '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.*', + 'python_requires': '>=3.6', } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-argparse-0.3.1/sphinxarg/ext.py new/sphinx-argparse-0.3.2/sphinxarg/ext.py --- old/sphinx-argparse-0.3.1/sphinxarg/ext.py 2021-09-06 21:59:31.252555800 +0200 +++ new/sphinx-argparse-0.3.2/sphinxarg/ext.py 2022-10-03 12:35:12.461066500 +0200 @@ -40,7 +40,7 @@ '@after', '@skip', ): - raise Exception('Unknown classifier: %s' % classifier) + raise Exception(f'Unknown classifier: {classifier}') idx = subitem.first_child_matching_class(nodes.term) if idx is not None: term = subitem[idx] @@ -48,25 +48,25 @@ term = term.children[0].astext() idx = subitem.first_child_matching_class(nodes.definition) if idx is not None: - subContent = [] + subcontent = [] for _ in subitem[idx]: if isinstance(_, nodes.definition_list): - subContent.append(_) - definitions[term] = (classifier, subitem[idx], subContent) + subcontent.append(_) + definitions[term] = (classifier, subitem[idx], subcontent) return definitions -def renderList(l, markDownHelp, settings=None): +def render_list(l, markdown_help, settings=None): """ Given a list of reStructuredText or MarkDown sections, return a docutils node list """ if len(l) == 0: return [] - if markDownHelp: - from sphinxarg.markdown import parseMarkDownBlock + if markdown_help: + from sphinxarg.markdown import parse_markdown_block - return parseMarkDownBlock('\n\n'.join(l) + '\n') + return parse_markdown_block('\n\n'.join(l) + '\n') else: all_children = [] for element in l: @@ -82,7 +82,7 @@ return all_children -def print_action_groups(data, nested_content, markDownHelp=False, settings=None): +def print_action_groups(data, nested_content, markdown_help=False, settings=None): """ Process all 'action groups', which are also include 'Options' and 'Required arguments'. A list of nodes is returned. @@ -99,9 +99,9 @@ if action_group['description']: desc.append(action_group['description']) # Replace/append/prepend content to the description according to nested content - subContent = [] + subcontent = [] if action_group['title'] in definitions: - classifier, s, subContent = definitions[action_group['title']] + classifier, s, subcontent = definitions[action_group['title']] if classifier == '@replace': desc = [s] elif classifier == '@after': @@ -110,18 +110,18 @@ desc.insert(0, s) elif classifier == '@skip': continue - if len(subContent) > 0: - for k, v in map_nested_definitions(subContent).items(): + if len(subcontent) > 0: + for k, v in map_nested_definitions(subcontent).items(): definitions[k] = v # Render appropriately - for element in renderList(desc, markDownHelp): + for element in render_list(desc, markdown_help): section += element - localDefinitions = definitions - if len(subContent) > 0: - localDefinitions = {k: v for k, v in definitions.items()} - for k, v in map_nested_definitions(subContent).items(): - localDefinitions[k] = v + local_definitions = definitions + if len(subcontent) > 0: + local_definitions = {k: v for k, v in definitions.items()} + for k, v in map_nested_definitions(subcontent).items(): + local_definitions[k] = v items = [] # Iterate over action group members @@ -134,11 +134,7 @@ # 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(f"Possible choices: {', '.join(str(c) for c in entry['choices'])}\n") if 'help' in entry: arg.append(entry['help']) if entry['default'] is not None and entry['default'] not in [ @@ -148,13 +144,13 @@ if entry['default'] == '': arg.append('Default: ""') else: - arg.append('Default: {}'.format(entry['default'])) + arg.append(f"Default: {entry['default']}") # Handle nested content, the term used in the dict has the comma removed for simplicity desc = arg term = ' '.join(entry['name']) - if term in localDefinitions: - classifier, s, subContent = localDefinitions[term] + if term in local_definitions: + classifier, s, subcontent = local_definitions[term] if classifier == '@replace': desc = [s] elif classifier == '@after': @@ -166,7 +162,7 @@ n = nodes.option_list_item( '', nodes.option_group('', nodes.option_string(text=term)), - nodes.description('', *renderList(desc, markDownHelp, settings)), + nodes.description('', *render_list(desc, markdown_help, settings)), ) items.append(n) @@ -176,7 +172,7 @@ return nodes_list -def print_subcommands(data, nested_content, markDownHelp=False, settings=None): +def print_subcommands(data, nested_content, markdown_help=False, settings=None): # noqa: N803 """ Each subcommand is a dictionary with the following keys: @@ -189,8 +185,8 @@ definitions = map_nested_definitions(nested_content) items = [] if 'children' in data: - subCommands = nodes.section(ids=["Sub-commands:"]) - subCommands += nodes.title('Sub-commands:', 'Sub-commands:') + subcommands = nodes.section(ids=["Sub-commands"]) + subcommands += nodes.title('Sub-commands', 'Sub-commands') for child in data['children']: sec = nodes.section(ids=[child['name']]) @@ -204,9 +200,9 @@ desc = ['Undocumented'] # Handle nested content - subContent = [] + subcontent = [] if child['name'] in definitions: - classifier, s, subContent = definitions[child['name']] + classifier, s, subcontent = definitions[child['name']] if classifier == '@replace': desc = [s] elif classifier == '@after': @@ -214,30 +210,26 @@ elif classifier == '@before': desc.insert(0, s) - for element in renderList(desc, markDownHelp): + for element in render_list(desc, markdown_help): 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, markdown_help, 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, markdown_help, settings=settings): sec += x if 'epilog' in child and child['epilog']: - for element in renderList([child['epilog']], markDownHelp): + for element in render_list([child['epilog']], markdown_help): sec += element - subCommands += sec - items.append(subCommands) + subcommands += sec + items.append(subcommands) return items -def ensureUniqueIDs(items): +def ensure_unique_ids(items): """ If action groups are repeated, then links in the table of contents will just go to the first of the repeats. This may not be desirable, particularly @@ -255,9 +247,9 @@ s.add(id) else: i = 1 - while "{}_repeat{}".format(id, i) in s: + while f"{id}_repeat{i}" in s: i += 1 - ids[idx] = "{}_repeat{}".format(id, i) + ids[idx] = f"{id}_repeat{i}" s.add(ids[idx]) n['ids'] = ids @@ -328,9 +320,7 @@ 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'] - ) + options_section = nodes.section('', nodes.title(text='Options'), ids=['options-section']) if 'args' in parser_info: options_section += nodes.paragraph() options_section += nodes.subtitle(text='Positional arguments:') @@ -351,9 +341,7 @@ items.append(options_section) if 'nosubcommands' not in self.options: # SUBCOMMANDS section (non-standard) - subcommands_section = nodes.section( - '', nodes.title(text='Sub-Commands'), ids=['subcommands-section'] - ) + subcommands_section = nodes.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: @@ -381,17 +369,11 @@ elif 'choices' not in arg: arg_items.append(nodes.paragraph(text='Undocumented')) if 'choices' in arg: - arg_items.append( - nodes.paragraph( - text='Possible choices: ' + ', '.join(arg['choices']) - ) - ) + arg_items.append(nodes.paragraph(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_group('', nodes.option('', nodes.option_string(text=arg['metavar']))), nodes.description('', *arg_items), ) ) @@ -409,20 +391,14 @@ '"==SUPPRESS=="', '==SUPPRESS==', ]: - option_declaration += nodes.option_argument( - '', text='=' + str(opt['default']) - ) + option_declaration += nodes.option_argument('', text='=' + str(opt['default'])) names.append(nodes.option('', *option_declaration)) if opt['help']: opt_items.append(nodes.paragraph(text=opt['help'])) elif 'choices' not in opt: opt_items.append(nodes.paragraph(text='Undocumented')) if 'choices' in opt: - opt_items.append( - nodes.paragraph( - text='Possible choices: ' + ', '.join(opt['choices']) - ) - ) + opt_items.append(nodes.paragraph(text='Possible choices: ' + ', '.join(opt['choices']))) items.append( nodes.option_list_item( '', @@ -467,7 +443,7 @@ mod = {} try: f = open(self.options['filename']) - except IOError: + except OSError: # try open with abspath f = open(os.path.abspath(self.options['filename'])) code = compile(f.read(), self.options['filename'], 'exec') @@ -475,28 +451,17 @@ attr_name = self.options['func'] func = mod[attr_name] else: - raise self.error( - ':module: and :func: should be specified, or :ref:, or :filename: and :func:' - ) + raise self.error(':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]) - ) + except ImportError: + raise self.error(f'Failed to import "{attr_name}" from "{module_name}".\n{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): @@ -524,9 +489,9 @@ items = [] nested_content = nodes.paragraph() if 'markdown' in self.options: - from sphinxarg.markdown import parseMarkDownBlock + from sphinxarg.markdown import parse_markdown_block - items.extend(parseMarkDownBlock('\n'.join(self.content) + '\n')) + items.extend(parse_markdown_block('\n'.join(self.content) + '\n')) else: self.state.nested_parse(self.content, self.content_offset, nested_content) nested_content = nested_content.children @@ -535,12 +500,12 @@ if not isinstance(item, nodes.definition_list): items.append(item) - markDownHelp = False + markdown_help = False if 'markdownhelp' in self.options: - markDownHelp = True + markdown_help = True if 'description' in result and 'nodescription' not in self.options: - if markDownHelp: - items.extend(renderList([result['description']], True)) + if markdown_help: + items.extend(render_list([result['description']], True)) else: items.append(self._nested_parse_paragraph(result['description'])) items.append(nodes.literal_block(text=result['usage'])) @@ -548,7 +513,7 @@ print_action_groups( result, nested_content, - markDownHelp, + markdown_help, settings=self.state.document.settings, ) ) @@ -557,7 +522,7 @@ print_subcommands( result, nested_content, - markDownHelp, + markdown_help, settings=self.state.document.settings, ) ) @@ -565,7 +530,7 @@ items.append(self._nested_parse_paragraph(result['epilog'])) # Traverse the returned nodes, modifying the title IDs as necessary to avoid repeats - ensureUniqueIDs(items) + ensure_unique_ids(items) return items diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-argparse-0.3.1/sphinxarg/markdown.py new/sphinx-argparse-0.3.2/sphinxarg/markdown.py --- old/sphinx-argparse-0.3.1/sphinxarg/markdown.py 2021-09-06 21:59:31.252555800 +0200 +++ new/sphinx-argparse-0.3.2/sphinxarg/markdown.py 2022-10-03 12:31:53.151545000 +0200 @@ -10,14 +10,14 @@ from docutils.utils.code_analyzer import Lexer -def customWalker(node, space=''): +def custom_walker(node, space=''): """ A convenience function to ease debugging. It will print the node structure that's returned from CommonMark The usage would be something like: >>> content = Parser().parse('Some big text block\n===================\n\nwith content\n') - >>> customWalker(content) + >>> custom_walker(content) document heading text Some big text block @@ -29,18 +29,18 @@ txt = '' try: txt = node.literal - except: + except Exception: pass if txt is None or txt == '': - print('{}{}'.format(space, node.t)) + print(f'{space}{node.t}') else: - print('{}{}\t{}'.format(space, node.t, txt)) + print(f'{space}{node.t}\t{txt}') cur = node.first_child if cur: while cur is not None: - customWalker(cur, space + ' ') + custom_walker(cur, space + ' ') cur = cur.nxt @@ -53,7 +53,7 @@ text = node.string_content o = nodes.paragraph('', ' '.join(text)) o.line = node.sourcepos[0][0] - for n in MarkDown(node): + for n in markdown(node): o.append(n) return o @@ -88,7 +88,7 @@ o['refuri'] = node.destination if node.title: o['name'] = node.title - for n in MarkDown(node): + for n in markdown(node): o += n return o @@ -98,7 +98,7 @@ An italicized section """ o = nodes.emphasis() - for n in MarkDown(node): + for n in markdown(node): o += n return o @@ -108,7 +108,7 @@ A bolded section """ o = nodes.strong() - for n in MarkDown(node): + for n in markdown(node): o += n return o @@ -123,7 +123,7 @@ l = Lexer(node.literal, node.info, tokennames="long") for _ in l: rendered.append(node.inline(classes=_[0], text=_[1])) - except: + except Exception: pass classes = ['code'] @@ -136,7 +136,7 @@ else: o = nodes.literal(text=node.literal, classes=classes) - for n in MarkDown(node): + for n in markdown(node): o += n return o @@ -151,7 +151,7 @@ l = Lexer(node.literal, node.info, tokennames="long") for _ in l: rendered.append(node.inline(classes=_[0], text=_[1])) - except: + except Exception: pass classes = ['code'] @@ -165,7 +165,7 @@ o = nodes.literal_block(text=node.literal, classes=classes) o.line = node.sourcepos[0][0] - for n in MarkDown(node): + for n in markdown(node): o += n return o @@ -177,7 +177,7 @@ o = nodes.raw(node.literal, node.literal, format='html') if node.sourcepos is not None: o.line = node.sourcepos[0][0] - for n in MarkDown(node): + for n in markdown(node): o += n return o @@ -203,10 +203,10 @@ """ title = '' # All sections need an id if node.first_child is not None: - if node.first_child.t == u'heading': + if node.first_child.t == 'heading': title = node.first_child.first_child.literal o = nodes.section(ids=[title], names=[title]) - for n in MarkDown(node): + for n in markdown(node): o += n return o @@ -217,7 +217,7 @@ """ o = nodes.block_quote() o.line = node.sourcepos[0][0] - for n in MarkDown(node): + for n in markdown(node): o += n return o @@ -234,22 +234,22 @@ return o -def listItem(node): +def list_item(node): """ An item in a list """ o = nodes.list_item() - for n in MarkDown(node): + for n in markdown(node): o += n return o -def listNode(node): +def list_node(node): """ A list (numbered or not) For numbered lists, the suffix is only rendered as . in html """ - if node.list_data['type'] == u'bullet': + if node.list_data['type'] == 'bullet': o = nodes.bullet_list(bullet=node.list_data['bullet_char']) else: o = nodes.enumerated_list( @@ -257,12 +257,12 @@ enumtype='arabic', start=node.list_data['start'], ) - for n in MarkDown(node): + for n in markdown(node): o += n return o -def MarkDown(node): +def markdown(node): """ Returns a list of nodes, containing CommonMark nodes converted to docutils nodes """ @@ -301,13 +301,13 @@ elif t == 'image': output.append(image(cur)) elif t == 'list': - output.append(listNode(cur)) + output.append(list_node(cur)) elif t == 'item': - output.append(listItem(cur)) + output.append(list_item(cur)) elif t == 'MDsection': output.append(section(cur)) else: - print('Received unhandled type: {}. Full print of node:'.format(t)) + print(f'Received unhandled type: {t}. Full print of node:') cur.pretty() cur = cur.nxt @@ -315,7 +315,7 @@ return output -def finalizeSection(section): +def finalize_section(section): """ Correct the nxt and parent for each child """ @@ -329,7 +329,7 @@ cur = cur.nxt -def nestSections(block, level=1): +def nest_sections(block, level=1): """ Sections aren't handled by CommonMark at the moment. This function adds sections to a block of nodes. @@ -356,7 +356,7 @@ if cur.t == 'heading' and cur.level == level: # Found a split point, flush the last section if needed if section.first_child is not None: - finalizeSection(section) + finalize_section(section) children.append(section) section = Node('MDsection', 0) nxt = cur.nxt @@ -372,16 +372,16 @@ # If there's only 1 child then don't bother if section.first_child is not None: - finalizeSection(section) + finalize_section(section) children.append(section) block.first_child = None block.last_child = None - nextLevel = level + 1 + next_level = level + 1 for child in children: # Handle nesting if child.t == 'MDsection': - nestSections(child, level=nextLevel) + nest_sections(child, level=next_level) # Append if block.first_child is None: @@ -394,15 +394,15 @@ block.last_child = child -def parseMarkDownBlock(text): +def parse_markdown_block(text): """ Parses a block of text, returning a list of docutils nodes - >>> parseMarkdownBlock("Some\n====\n\nblock of text\n\nHeader\n======\n\nblah\n") + >>> parse_markdown_block("Some\n====\n\nblock of text\n\nHeader\n======\n\nblah\n") [] """ block = Parser().parse(text) # CommonMark can't nest sections, so do it manually - nestSections(block) + nest_sections(block) - return MarkDown(block) + return markdown(block) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-argparse-0.3.1/sphinxarg/parser.py new/sphinx-argparse-0.3.2/sphinxarg/parser.py --- old/sphinx-argparse-0.3.1/sphinxarg/parser.py 2021-09-06 21:59:31.252555800 +0200 +++ new/sphinx-argparse-0.3.2/sphinxarg/parser.py 2022-10-03 12:31:53.151545000 +0200 @@ -15,9 +15,7 @@ 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) - ) + raise NavigationException(f"Current parser has no child elements. (path: {' '.join(current_path)})") next_hop = path.pop(0) for child in parser_result['children']: # identifer is only used for aliased subcommands @@ -25,10 +23,7 @@ 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)) - ) + raise NavigationException(f"Current parser has no child element with name: {next_hop} (path: {' '.join(current_path)})") def _try_add_parser_attribute(data, parser, attribname): @@ -47,9 +42,7 @@ 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() @@ -85,11 +78,9 @@ if name in subsection_alias_names: continue subalias = subsection_alias[subaction] - subaction.prog = '%s %s' % (parser.prog, name) + subaction.prog = f'{parser.prog} {name}' subdata = { - 'name': name - if not subalias - else '%s (%s)' % (name, ', '.join(subalias)), + 'name': name if not subalias else f"{name} ({', '.join(subalias)})", 'help': helps.get(name, ''), 'usage': subaction.format_usage().strip(), 'bare_usage': _format_usage_without_prefix(subaction), @@ -119,20 +110,16 @@ # 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) - ): - default = '"%s"' % default + if action.default not in ['', None, True, False] and action.type in [None, str] and isinstance(action.default, str): + default = f'"{default}"' # fill in any formatters, like %(default)s - formatDict = dict(vars(action), prog=data.get('prog', ''), default=default) - formatDict['default'] = default - helpStr = action.help or '' # Ensure we don't print None + format_dict = dict(vars(action), prog=data.get('prog', ''), default=default) + format_dict['default'] = default + help_str = action.help or '' # Ensure we don't print None try: - helpStr = helpStr % formatDict - except: + help_str = help_str % format_dict + except Exception: pass # Options have the option_strings set, positional arguments don't @@ -150,13 +137,13 @@ option = { 'name': name, 'default': default if show_defaults_const else '==SUPPRESS==', - 'help': helpStr, + 'help': help_str, } else: option = { 'name': name, 'default': default if show_defaults else '==SUPPRESS==', - 'help': helpStr, + 'help': help_str, } if action.choices: option['choices'] = action.choices @@ -167,7 +154,9 @@ 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' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-argparse-0.3.1/test/sample.py new/sphinx-argparse-0.3.2/test/sample.py --- old/sphinx-argparse-0.3.1/test/sample.py 2021-09-06 21:10:52.618904400 +0200 +++ new/sphinx-argparse-0.3.2/test/sample.py 2022-10-03 12:31:53.151545000 +0200 @@ -4,14 +4,11 @@ subparsers = parser.add_subparsers() -my_command1 = subparsers.add_parser( - 'apply', help='Execute provision script, collect all resources and apply them.' -) +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.', + help='Specify path to provision script. provision.py in current' 'directory by default. Also may include url.', default='provision.py', ) my_command1.add_argument( @@ -21,15 +18,9 @@ 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('--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', @@ -37,12 +28,8 @@ ) 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' -) +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') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sphinx-argparse-0.3.1/test/test_parser.py new/sphinx-argparse-0.3.2/test/test_parser.py --- old/sphinx-argparse-0.3.1/test/test_parser.py 2021-09-06 21:59:31.252555800 +0200 +++ new/sphinx-argparse-0.3.2/test/test_parser.py 2022-10-03 12:31:53.151545000 +0200 @@ -1,7 +1,5 @@ import argparse -import six - from sphinxarg.parser import parse_parser, parser_navigate @@ -24,9 +22,7 @@ data = parse_parser(parser) - assert data['action_groups'][0]['options'] == [ - {'name': ['--foo'], 'default': '"123"', 'help': ''} - ] + assert data['action_groups'][0]['options'] == [{'name': ['--foo'], 'default': '"123"', 'help': ''}] def test_parse_arg_choices(): @@ -67,9 +63,7 @@ data = parse_parser(parser, skip_default_values=True) - assert data['action_groups'][0]['options'] == [ - {'name': ['--foo'], 'default': '==SUPPRESS==', 'help': ''} - ] + assert data['action_groups'][0]['options'] == [{'name': ['--foo'], 'default': '==SUPPRESS==', 'help': ''}] def test_parse_positional(): @@ -111,9 +105,7 @@ 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) @@ -132,15 +124,58 @@ { 'title': 'Positional Arguments', 'description': None, - 'options': [ - {'name': ['ref'], 'help': 'foo1 help', 'default': None} - ], + 'options': [{'name': ['ref'], 'help': 'foo1 help', 'default': None}], + }, + { + 'description': None, + 'title': 'Named Arguments', + 'options': [{'name': ['--upgrade'], 'default': False, 'help': 'foo2 help'}], + }, + ], + } + ] + + +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'} + { + 'name': ['--upgrade'], + 'default': False, + 'help': 'foo2 help', + } ], }, ], @@ -148,75 +183,23 @@ ] -if six.PY3: +def test_aliased_traversal(): + parser = argparse.ArgumentParser(prog='under-test') - 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']) + subparsers1 = parser.add_subparsers() + subparsers1.add_parser('level1', aliases=['l1']) - data = parse_parser(parser) + data = parse_parser(parser) - data2 = parser_navigate(data, 'level1') + 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', - } + 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(): @@ -289,9 +272,7 @@ 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'] == [ @@ -340,10 +321,10 @@ """ parser = argparse.ArgumentParser('foo') subparsers = parser.add_subparsers() - parserA = subparsers.add_parser('A', help='A subparser') - parserA.add_argument('baz', type=int, help='An integer') - parserB = subparsers.add_parser('B', help='B subparser') - parserB.add_argument('--barg', choices='XYZ', help='A list of choices') + parser_a = subparsers.add_parser('A', help='A subparser') + parser_a.add_argument('baz', type=int, help='An integer') + parser_b = subparsers.add_parser('B', help='B subparser') + parser_b.add_argument('--barg', choices='XYZ', help='A list of choices') parser.add_argument('--foo', help='foo help') parser.add_argument('foo2', metavar='foo2 metavar', help='foo2 help') @@ -358,9 +339,7 @@ assert data['action_groups'] == [ { - 'options': [ - {'default': None, 'name': ['foo2 metavar'], 'help': 'foo2 help'} - ], + 'options': [{'default': None, 'name': ['foo2 metavar'], 'help': 'foo2 help'}], 'description': None, 'title': 'Positional Arguments', }, @@ -392,9 +371,7 @@ 'usage': 'usage: foo A [-h] baz', 'action_groups': [ { - 'options': [ - {'default': None, 'name': ['baz'], 'help': 'An integer'} - ], + 'options': [{'default': None, 'name': ['baz'], 'help': 'An integer'}], 'description': None, 'title': 'Positional Arguments', }