diff --git a/.gitattributes b/.gitattributes index 89af26e..c6f20db 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,2 @@ tests/resource/objects_mkdoc_zlib0.inv binary - +tests/resource/objects_attrs.txt binary diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 18ea8d8..7565e8e 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -63,7 +63,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python: ['3.6', '3.7', '3.8', '3.9', '3.11'] + python: ['3.7', '3.8', '3.9', '3.11'] if: "!contains(github.event.head_commit.message, '[skip ci]')" steps: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ccc2af3..f52668c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,17 +2,17 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v3.2.0' + rev: 'v4.3.0' hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files - repo: https://github.com/psf/black - rev: '22.3.0' + rev: '22.10.0' hooks: - id: black - repo: https://github.com/tox-dev/pyproject-fmt - rev: '0.3.2' + rev: '0.3.5' hooks: - id: pyproject-fmt diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ff2955..4f4c74c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,108 @@ and this project strives to adhere to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +### [2.3.1] - 2022-11-29 + +#### Changed + + * The printout of the inferred `intersphinx_mapping` item for inventories + retrieved by URL (`--url`) in the 'suggest' CLI mode is now relocated to + fall immediately below the inventory-search output. It also now is displayed + even if no objects in the `objects.inv` satisfy the score threshold. + ([#262](https://github.com/bskinn/sphobjinv/issues/262)) + + * The 'suggest' CLI mode output now includes dividers for improved + readability. + +#### Tests + + * The plaintext `tests/resource/objects_attrs.txt` was converted to POSIX EOLs + and declared as binary to git, in order to provide a consistent state for + sdist packaging, regardless of platform (POSIX vs Windows). + + * As a result, it was necessary to modify the `scratch_path` fixture to + "`unix2dos`" this file on Windows systems, in order to provide a + consistent test state. + + * Similarly, the `decomp_cmp_test` fixture was modified to "`unix2dos`" the + `objects_attrs.txt` resource before comparisons, again in order to provide + a consistent reference artifact. Implementing required direct manipulation + of the bytes contents of the file, instead of the `filecmp.cmp` method + that had been used previously. + + * The README doctests and shell tests have been removed from the default + pytest suite. They must be explicitly opted-in with the `--readme` and + `--doctest-glob="README.rst"` flags to pytest. + + * A new job, `readme`, has been added to the `aux_tests` stage of the Azure + Pipelines CI to run these tests for PRs and release branches. + + * The constraint for `pytest-check` was bumped to `>=1.1.2` and all uses of + the `check` fixture were revised from `with check.check(...):` to + `with check(...):`. ([#265](https://github.com/bskinn/sphobjinv/issues/265)) + + * Azure Pipelines now has Python 3.11 available for all of Ubuntu, Windows and + MacOS, so it was added to the core text matrix for all platforms. + + * A new CI job was created on Azure Pipelines that creates an sdist from the + current project, extracts it into a sandboxed environment, installs the dev + dependencies, and runs the pytest suite (`azure-sdisttest.yml`). + + * All uses of `pytest-check` were updated to use the + [v1.1.2 syntax](https://github.com/okken/pytest-check/blob/main/changelog.md#110---2022-nov-21) + (`check` fixture, or `from pytest_check import check`). + +#### Internal + + * The `sys.exit()` in the case of no objects falling above the 'suggest' + search threshold was refactored into the main `do_suggest()` body, to + minimize the surprise of an `exit()` call coming in a subfunction. + ([#263](https://github.com/bskinn/sphobjinv/issues/263)) + +#### Packaging + + * `MANIFEST.in` was revised in order to provide a testable (`pytest --nonloc`) + sdist, in order to streamline packaging of `sphobjinv` for conda-forge. + (Thanks very much to [@anjos](https://github.com/anjos) for getting the + recipes for `sphobjinv` and its dependencies in place! See + [#264](https://github.com/bskinn/sphobjinv/issues/264).) + +#### Administrative + + * `sphobjinv` is now available via conda-forge! A note was added to the docs + to indicate this. + + * The version bump on `pytest-check` no longer permits the use of Python 3.6 + in CI. As Python 3.6 is nearly a year beyond EOL, this seems a reasonable + time to officially drop support for it. `python_requires` will still be at + `>=3.6` for now; it *should* still work for 3.6...but, no guarantees. + + * The hook versions for `pre-commit-hooks`, `black`, and `pyproject-fmt` were + updated to v4.3, v22.10, and v0.3.5, respectively. + + * `CONTENT_LICENSE.txt` was created, to specifically house the full + content/documentation license information. + + * `LICENSE.txt` was revised to only hold the MIT License for the code, + primarily so that Github's automatic systems will recognize the project as + MIT licensed. + + * Caching of pip downloads was added to all of the Azure Pipelines jobs. + + * The version constraint for `pytest-check` was raised to `>=1.1.2`. + + * A temporary upper bound was placed on the `flake8` version (now `>=5,<6`, + instead of `>=5`) to avoid pip resolver failures likely due to conflicts + with constraints declared by plugins. + + * The older versions of `jsonschema` tested in the `tox` matrix were + streamlined down to 3.0 (`==3.0`), 3.x (`<4`), 4.0 (`<4.1`) and 4.8 + (`<4.9`). + + * The pin of `sphinx-issues==0.4.0` in the `tox` matrix was removed, to match + the unpinned package in the `requirements-xxx.txt` files. + + ### [2.3] - 2022-11-08 #### Added @@ -24,6 +126,11 @@ and this project strives to adhere to with the URLs it checks when trying to retrieve a remote inventory. ([#99](https://github.com/bskinn/sphobjinv/issues/99), plus more) + * CLI 'suggest' results output now displays more information about + the total number of objects in the inventory, the search score threshold, + and the number of results falling at/above that threshold. + ([#232](https://github.com/bskinn/sphobjinv/issues/232)) + * A new CLI option, `-p`/`--paginate`, enables paging of the results from the `suggest` feature. ([#70](https://github.com/bskinn/sphobjinv/issues/70)) @@ -61,7 +168,8 @@ and this project strives to adhere to `objects_sphinx.inv`, and the previous v1.6.6 was renamed to `objects_sphinx_1_6_6.inv`. - * The 'valid objects' test cases were updated to reflect the possibility for a colon within `{role}`: + * The 'valid objects' test cases were updated to reflect the possibility for a + colon within `{role}`: * The colon-within-`{role}` test case was moved from 'invalid' to 'valid'. @@ -105,12 +213,6 @@ and this project strives to adhere to ### [2.2.2] - 2022-03-22 -#### Changed - - * CLI 'suggest' results output now displays more information about - the total number of objects in the inventory, the search score threshold, - and the number of results falling at/above that threshold. - #### Fixed * UnicodeDecodeErrors are ignored within the vendored `fuzzywuzzy` package diff --git a/CONTENT_LICENSE.txt b/CONTENT_LICENSE.txt new file mode 100644 index 0000000..d187275 --- /dev/null +++ b/CONTENT_LICENSE.txt @@ -0,0 +1,4 @@ +The sphobjinv documentation (including docstrings and README) is licensed under +a Creative Commons Attribution 4.0 International License (CC-BY). + +See http://creativecommons.org/licenses/by/4.0/. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9561055..b2a915c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -Welcome! +Welcome! -------- Thanks for your interest in contributing to `sphobjinv`! @@ -10,7 +10,7 @@ If you have any questions, please drop me a line on Twitter [issue](https://github.com/bskinn/sphobjinv/issues). -Table of Contents +Table of Contents ----------------- @@ -23,7 +23,7 @@ Table of Contents - [Documentation](#documentation) - [Continuous Integration](#continuous-integration) - [CHANGELOG](#changelog) -- [Issue & PR Templates](#issue--pr-templates) +- [Issue and PR Templates](#issue-and-pr-templates) - [License](#license) @@ -38,7 +38,7 @@ $ git clone https://github.com/{you}/sphobjinv ``` Then, create a virtual environment for the project, in whatever location you -prefer. Any Python interpreter 3.6+ *should* work fine. +prefer. Any Python interpreter 3.7+ *should* work fine. I prefer to use `virtualenv` and create in `./env`: @@ -153,8 +153,8 @@ Note that while [`tox`](https://tox.wiki/en/latest/) *is* configured for the project, it is **not** set up to be an everyday test runner. Instead, it's used to execute an extensive matrix of test environments checking for the compatibility of different Python and dependency versions. You can run it if you -want, but you'll need working versions of all of Python 3.6 through 3.11 -installed and on `PATH` as `python3.6`, `python3.7`, etc. The nonlocal test +want, but you'll need working versions of all of Python 3.7 through 3.11 +installed and on `PATH` as `python3.7`, `python3.8`, etc. The nonlocal test suite is run for each `tox` environment, so it's best to use at most two parallel sub-processes to avoid oversaturating your network bandwidth; e.g.: @@ -250,7 +250,7 @@ with `make linkcheck`. Both Github Actions and Azure Pipelines are set up for the project, and should run on any forks of the repository. -Github Actions runs the test suite on Linux for Python 3.6 through 3.11, as well +Github Actions runs the test suite on Linux for Python 3.7 through 3.11, as well as the `flake8` lints and the Sphinx doctests and link-validity testing, and is configured to run on all commits. The workflow can be skipped per-commit by including `[skip ci]` in the commit message. @@ -279,7 +279,7 @@ settings, etc.) may also warrant a `CHANGELOG` bullet, depending on the situation. When in doubt, ask! -## Issue & PR Templates +## Issue and PR Templates I've set up the project with a PR template and a couple of issue templates, to hopefully make it easier to provide all the information needed to act on code @@ -290,4 +290,4 @@ issue/PR you want to create, though, then don't use them. ## License All code and documentation contributions will respectively take on the MIT -License and CC-BY 4.0 license of the project at large. +License and CC BY 4.0 license of the project at large. diff --git a/LICENSE.txt b/LICENSE.txt index 8cf9895..3a32da7 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,16 +1,3 @@ -The sphobjinv documentation (including docstrings) is licensed under a Creative -Commons Attribution 4.0 International License (CC-BY). - -See http://creativecommons.org/licenses/by/4.0/. - - -The sphobjinv codebase is released under the MIT License, the text of which is -included below. - - -==================================================================================== - - The MIT License (MIT) Copyright (c) 2016-2022 Brian Skinn and community contributors diff --git a/MANIFEST.in b/MANIFEST.in index bf8e0a2..c7069e4 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1,15 @@ -include AUTHORS.md CHANGELOG.md CONTRIBUTING.md LICENSE.txt pyproject.toml README.rst +include AUTHORS.md CHANGELOG.md CONTRIBUTING.md LICENSE.txt pyproject.toml +include README.rst requirements-dev.txt requirements-flake8.txt tox.ini + +graft src/sphobjinv/_vendored/fuzzywuzzy + +graft doc/source +include doc/make.bat doc/Makefile + +include conftest.py +graft tests +prune tests/resource +include tests/resource/objects_attrs* tests/resource/objects_sarge* + +global-exclude __pycache__/* +prune **/*.egg-info diff --git a/README.rst b/README.rst index c1803f5..146eaf6 100644 --- a/README.rst +++ b/README.rst @@ -33,7 +33,7 @@ sphobjinv: Manipulate and inspect Sphinx objects.inv files :target: https://github.com/psf/black .. image:: https://pepy.tech/badge/sphobjinv/month - :target: https://pepy.tech/project/sphobjinv?versions=2.0.1&versions=2.1&versions=2.2.2&versions=2.3 + :target: https://pepy.tech/project/sphobjinv?versions=2.0.1&versions=2.1&versions=2.2.2&versions=2.3&versions=2.3.1 ---- @@ -57,14 +57,21 @@ For internal cross-references, locate ``objects.inv`` within ``build/html``:: $ sphobjinv suggest doc/build/html/objects.inv as_rst -st 58 + ------------------------------------------------ + + Cannot infer intersphinx_mapping from a local objects.inv. + + ------------------------------------------------ + Project: sphobjinv Version: 2.3 - 219 objects in inventory. + 220 objects in inventory. + + ------------------------------------------------ 11 results found at/above current threshold of 58. - Cannot infer intersphinx_mapping from a local objects.inv. Name Score --------------------------------------------------- ------- @@ -103,16 +110,22 @@ cross-reference the ``linspace`` function from numpy (see Attempting "https://numpy.org/doc/1.23/objects.inv" ... ... inventory found. + ------------------------------------------------ + + The intersphinx_mapping for this docset is LIKELY: + + (https://numpy.org/doc/1.23/, None) + + ------------------------------------------------ + Project: NumPy Version: 1.23 8074 objects in inventory. - 8 results found at/above current threshold of 75. - - The intersphinx_mapping for this docset is LIKELY: + ------------------------------------------------ - (https://numpy.org/doc/1.23/, None) + 8 results found at/above current threshold of 75. Name Score @@ -157,7 +170,7 @@ inventory creation/modification:: >>> import sphobjinv as soi >>> inv = soi.Inventory('doc/build/html/objects.inv') >>> print(inv) - + >>> inv.project 'sphobjinv' >>> inv.version @@ -185,7 +198,8 @@ and feature requests are welcomed at the Copyright (c) Brian Skinn 2016-2022 -The ``sphobjinv`` documentation (including docstrings) is licensed under a +The ``sphobjinv`` documentation (including docstrings and README) is licensed +under a `Creative Commons Attribution 4.0 International License `__ (CC-BY). The ``sphobjinv`` codebase is released under the `MIT License `__. See diff --git a/azure-coretest.yml b/azure-coretest.yml index eb1a3b7..9de7ca7 100644 --- a/azure-coretest.yml +++ b/azure-coretest.yml @@ -1,3 +1,6 @@ +# Caching implemented as per +# https://stackoverflow.com/a/70297887/4376000 + parameters: pythons: [] platforms: [] @@ -15,6 +18,7 @@ jobs: image: 'macOS-latest' ${{ if notIn(platform, 'macOs', 'linux', 'windows') }}: image: 'Ubuntu-latest' + pip_cache_dir: $(Pipeline.Workspace)/.pip pool: vmImage: $[ variables.image ] @@ -26,6 +30,14 @@ jobs: architecture: 'x64' displayName: Use cached ${{ coalesce(python.value.name, python.key) }} for tests. + - task: Cache@2 + inputs: + key: 'pip | "$(Agent.OS)" | requirements-dev.txt | requirements-flake8.txt' + restoreKeys: | + pip | "$(Agent.OS)" + path: $(pip_cache_dir) + displayName: Cache pip + - script: pip install -U --force-reinstall -r requirements-ci.txt displayName: Install CI requirements diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 893d097..d3acc29 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -7,8 +7,12 @@ pr: - main - stable +variables: + pip_cache_dir: $(Pipeline.Workspace)/.pip + stages: + - stage: code_quality displayName: Check code quality @@ -18,11 +22,20 @@ stages: pool: vmImage: 'Ubuntu-latest' + steps: - task: UsePythonVersion@0 inputs: versionSpec: '3.10' + - task: Cache@2 + inputs: + key: 'pip | "$(Agent.OS)" | requirements-dev.txt | requirements-flake8.txt' + restoreKeys: | + pip | "$(Agent.OS)" + path: $(pip_cache_dir) + displayName: Cache pip + - script: pip install -U tox displayName: Install tox @@ -35,16 +48,26 @@ stages: - script: tox -e flake8 displayName: Lint the codebase + - job: interrogate displayName: Run interrogate docstrings check pool: vmImage: 'Ubuntu-latest' + steps: - task: UsePythonVersion@0 inputs: versionSpec: '3.10' + - task: Cache@2 + inputs: + key: 'pip | "$(Agent.OS)" | requirements-dev.txt | requirements-flake8.txt' + restoreKeys: | + pip | "$(Agent.OS)" + path: $(pip_cache_dir) + displayName: Cache pip + - script: pip install interrogate displayName: Install interrogate @@ -59,8 +82,6 @@ stages: - template: azure-coretest.yml parameters: pythons: - py36: - spec: '3.6' py37: spec: '3.7' py38: @@ -69,6 +90,8 @@ stages: spec: '3.9' py310: spec: '3.10' + py311: + spec: '3.11' pypy3: spec: 'pypy3' platforms: [linux] @@ -84,8 +107,12 @@ stages: spec: '3.9' py310: spec: '3.10' + py311: + spec: '3.11' platforms: [windows, macOs] + - template: azure-sdisttest.yml + - stage: aux_tests displayName: Run auxiliary tests @@ -102,6 +129,14 @@ stages: inputs: versionSpec: '3.10' + - task: Cache@2 + inputs: + key: 'pip | "$(Agent.OS)" | requirements-dev.txt | requirements-flake8.txt' + restoreKeys: | + pip | "$(Agent.OS)" + path: $(pip_cache_dir) + displayName: Cache pip + - script: pip install . -r requirements-rtd.txt displayName: Install project, plus docs requirements @@ -120,12 +155,50 @@ stages: inputs: versionSpec: '3.10' + - task: Cache@2 + inputs: + key: 'pip | "$(Agent.OS)" | requirements-dev.txt | requirements-flake8.txt' + restoreKeys: | + pip | "$(Agent.OS)" + path: $(pip_cache_dir) + displayName: Cache pip + - script: pip install -r requirements-dev.txt displayName: Install full dev requirements - script: cd doc; make doctest displayName: Run doctests + + - job: readme + displayName: Run README doctests/shell tests + + pool: + vmImage: 'Ubuntu-latest' + + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.10' + + - script: pip install -r requirements-ci.txt + displayName: Install CI requirements + + - task: Cache@2 + inputs: + key: 'pip | "$(Agent.OS)" | requirements-dev.txt | requirements-flake8.txt' + restoreKeys: | + pip | "$(Agent.OS)" + path: $(pip_cache_dir) + displayName: Cache pip + + - script: cd doc; make html + displayName: Build docs + + - script: pytest -k readme --readme --doctest-glob="README.rst" + displayName: Run README doc/shell tests + + - job: linkcheck displayName: Run docs link-check suite @@ -137,6 +210,14 @@ stages: inputs: versionSpec: '3.10' + - task: Cache@2 + inputs: + key: 'pip | "$(Agent.OS)" | requirements-dev.txt | requirements-flake8.txt' + restoreKeys: | + pip | "$(Agent.OS)" + path: $(pip_cache_dir) + displayName: Cache pip + - script: pip install . -r requirements-rtd.txt displayName: Install doc requirements and local project @@ -155,37 +236,26 @@ stages: inputs: versionSpec: '3.10' + - task: Cache@2 + inputs: + key: 'pip | "$(Agent.OS)" | requirements-dev.txt | requirements-flake8.txt' + restoreKeys: | + pip | "$(Agent.OS)" + path: $(pip_cache_dir) + displayName: Cache pip + - script: pip install -r requirements-dev.txt displayName: Install full dev requirements - script: cd doc; make html; mkdir scratch displayName: Build docset - - script: pytest --cov=. --nonloc --flake8_ext + - script: pytest --cov=. --nonloc --flake8_ext --readme displayName: Run pytest with coverage on the entire project tree - script: coverage report --include="tests/*" --fail-under=100 displayName: Check 100% test execution - - job: contributing_toc - displayName: Confirm CONTRIBUTING.md TOC is up to date - - pool: - vmImage: 'Ubuntu-latest' - - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.10' - - - script: pip install -r requirements-ci.txt - displayName: Install CI requirements - - - script: python -m md_toc -p github CONTRIBUTING.md - displayName: Run md-toc on CONTRIBUTING - - - script: if [[ $( git status | grep modified | wc -l ) -ne 0 ]]; then exit 1; fi - displayName: Fail if md-toc modified CONTRIBUTING - job: noqa_info displayName: Report flake8-noqa results for info (never fails) @@ -198,6 +268,14 @@ stages: inputs: versionSpec: '3.10' + - task: Cache@2 + inputs: + key: 'pip | "$(Agent.OS)" | requirements-dev.txt | requirements-flake8.txt' + restoreKeys: | + pip | "$(Agent.OS)" + path: $(pip_cache_dir) + displayName: Cache pip + - script: pip install tox flake8-noqa -r requirements-flake8.txt displayName: Install requirements diff --git a/azure-sdisttest.yml b/azure-sdisttest.yml new file mode 100644 index 0000000..422881b --- /dev/null +++ b/azure-sdisttest.yml @@ -0,0 +1,73 @@ +jobs: +- job: testable_sdist + displayName: Ensure sdist is testable + + variables: + pip_cache_dir: $(Pipeline.Workspace)/.pip + + pool: + vmImage: 'Ubuntu-latest' + + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.10' + + - task: Cache@2 + inputs: + key: 'pip | "$(Agent.OS)" | requirements-dev.txt | requirements-flake8.txt' + restoreKeys: | + pip | "$(Agent.OS)" + path: $(pip_cache_dir) + displayName: Cache pip + + - script: python -m pip install build + displayName: Install 'build' package + + - script: | + python -m build -s + ls -lah dist + displayName: Build sdist + + - script: | + mkdir sandbox + displayName: Create sandbox + + - script: | + cp dist/*.gz sandbox/ + cd sandbox + tar xvf *.gz + displayName: Unpack sdist in sandbox + + - script: | + cd sandbox + python -m venv env + displayName: Create venv + + # Only the dir of the unpacked sdist will have a digit in its name + - script: | + cd sandbox + echo $( find . -maxdepth 1 -type d -regex "./.+[0-9].+" ) + displayName: Check unpack dir name + + - script: | + cd sandbox + source env/bin/activate + cd $( find . -maxdepth 1 -type d -regex "./.+[0-9].+" ) + python -m pip install -r requirements-dev.txt + displayName: Install dev req'ts to venv + + - script: | + cd sandbox + source env/bin/activate + cd $( find . -maxdepth 1 -type d -regex "./.+[0-9].+" ) + cd doc + O=-Ean make html + displayName: Build docs in sandbox + + - script: | + cd sandbox + source env/bin/activate + cd $( find . -maxdepth 1 -type d -regex "./.+[0-9].+" ) + pytest --nonloc + displayName: Run test suite in sandbox diff --git a/conftest.py b/conftest.py index a4e7729..5c10462 100644 --- a/conftest.py +++ b/conftest.py @@ -36,7 +36,6 @@ import shutil import sys from enum import Enum -from filecmp import cmp from functools import partial from io import BytesIO from pathlib import Path @@ -63,6 +62,7 @@ def pytest_addoption(parser): parser.addoption( "--flake8_ext", action="store_true", help="Include flake8 extensions test" ) + parser.addoption("--readme", action="store_true", help="Include README shell tests") @pytest.fixture(scope="session") @@ -138,7 +138,7 @@ class Extensions(str, Enum): @pytest.fixture() -def scratch_path(tmp_path, res_path, misc_info): +def scratch_path(tmp_path, res_path, misc_info, is_win, unix2dos): """Provision pre-populated scratch directory, returned as Path.""" res_base = misc_info.FNames.RES.value scr_base = misc_info.FNames.INIT.value @@ -150,6 +150,13 @@ def scratch_path(tmp_path, res_path, misc_info): str(tmp_path / f"{scr_base}{ext}"), ) + # With the conversion of resources/objects_attrs.txt to Unix EOLs in order to + # provide for a Unix-testable sdist, on Windows systems this resource needs + # to be converted to DOS EOLs for consistency. + if is_win: + win_path = tmp_path / f"{scr_base}{misc_info.Extensions.DEC.value}" + win_path.write_bytes(unix2dos(win_path.read_bytes())) + yield tmp_path @@ -259,13 +266,22 @@ def func(arglist, *, expect=0): # , suffix=None): @pytest.fixture(scope="session") -def decomp_cmp_test(misc_info): +def decomp_cmp_test(misc_info, is_win, unix2dos): """Return function to confirm a decompressed file is identical to resource.""" def func(path): """Perform the round-trip compress/decompress comparison test.""" # The str() calls here are for Python 3.5 compat - assert cmp(str(misc_info.res_decomp_path), str(path), shallow=False) + res_bytes = Path(misc_info.res_decomp_path).read_bytes() + tgt_bytes = Path(path).read_bytes() # .replace(b"\r\n", b"\n") + + if is_win: + # Have to explicitly convert these newlines, now that the + # tests/resource/objects_attrs.txt file is marked 'binary' in + # .gitattributes + res_bytes = unix2dos(res_bytes) + + assert res_bytes == tgt_bytes return func diff --git a/doc/source/index.rst b/doc/source/index.rst index 678d1b7..f285ca2 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -45,6 +45,10 @@ Or, if you only plan to use the |soi| CLI, another option is |pipx|_:: $ pipx install sphobjinv +As of Nov 2022, |soi| is also available via conda-forge. After activating the desired conda environment:: + + $ conda install -c conda-forge sphobjinv + Alternatively, |soi| is packaged with `multiple POSIX distributions `__ and package managers, including: @@ -57,7 +61,7 @@ and package managers, including: * Gentoo: ``dev-python/sphobjinv`` (`info `__) - * Guix: ``python-sphobjinv`` (`info `__) + * Guix: ``python-sphobjinv`` * Manjaro: ``python-sphobjinv`` diff --git a/requirements-ci.txt b/requirements-ci.txt index 0646ec4..e2ab803 100644 --- a/requirements-ci.txt +++ b/requirements-ci.txt @@ -6,7 +6,7 @@ dictdiffer jsonschema md-toc pytest>=4.4.0 -pytest-check>=0.4 +pytest-check>=1.1.2 pytest-cov pytest-ordering pytest-timeout diff --git a/requirements-dev.txt b/requirements-dev.txt index 0cba0c8..3a15831 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -9,7 +9,7 @@ md-toc pep517 pre-commit pytest>=4.4.0 -pytest-check>=0.4 +pytest-check>=1.1.2 pytest-cov pytest-ordering pytest-timeout diff --git a/requirements-flake8.txt b/requirements-flake8.txt index 833ef9e..3151acc 100644 --- a/requirements-flake8.txt +++ b/requirements-flake8.txt @@ -1,5 +1,5 @@ colorama -flake8>=5 +flake8>=5,<6 flake8-2020 flake8-absolute-import flake8-bandit diff --git a/setup.cfg b/setup.cfg index cab8eb0..4d0049d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,6 @@ [metadata] name = sphobjinv +version = attr: sphobjinv.version.__version__ description = Sphinx objects.inv Inspection/Manipulation Tool url = https://github.com/bskinn/sphobjinv project_urls = @@ -24,7 +25,6 @@ classifiers = Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 diff --git a/setup.py b/setup.py index 56ccb7e..9e34359 100644 --- a/setup.py +++ b/setup.py @@ -36,8 +36,6 @@ def content_update(content, pattern, sub): setup( - name=NAME, - version=__version__, long_description=readme(), long_description_content_type="text/x-rst", ) diff --git a/src/sphobjinv/cli/load.py b/src/sphobjinv/cli/load.py index fc8c075..f9bd326 100644 --- a/src/sphobjinv/cli/load.py +++ b/src/sphobjinv/cli/load.py @@ -170,7 +170,7 @@ def attempt_inv_load(url, params): print_stderr(f" ... HTTP error: {e.code} {e.reason}.", params) except URLError: # pragma: no cover print_stderr(" ... error attempting to retrieve URL.", params) - except VersionError: + except VersionError: # pragma: no cover print_stderr(" ... no recognized inventory.", params) except ValueError: print_stderr( diff --git a/src/sphobjinv/cli/suggest.py b/src/sphobjinv/cli/suggest.py index 92c0280..8bd7d65 100644 --- a/src/sphobjinv/cli/suggest.py +++ b/src/sphobjinv/cli/suggest.py @@ -78,14 +78,21 @@ def do_suggest(inv, params): with_score=with_score, ) + print_divider(params) + print_stderr_inferred_mapping(params) + print_divider(params) + print_stderr(f"Project: {inv.project}", params) print_stderr(f"Version: {inv.version}\n", params) print_stderr(f"{inv.count} objects in inventory.\n", params) + print_divider(params) print_stderr_result_count(params, results) - print_stderr_inferred_mapping(params) + if not results: + print_stderr("\nExiting...\n", params) + sys.exit(0) # The query here for printing the full list only occurs in some # circumstances; see the function docstring. @@ -94,6 +101,12 @@ def do_suggest(inv, params): print_results_table(with_index, with_score, results, params) +def print_divider(params): + """Print a visual divider to break up sections of the CLI output.""" + length = shutil.get_terminal_size().columns * 3 // 5 + print_stderr("-" * length + "\n", params) + + def print_stderr_result_count(params, results): """Report the count of found objects from the suggest search.""" if len(results) == 0: @@ -104,7 +117,6 @@ def print_stderr_result_count(params, results): ), params, ) - sys.exit(0) else: print_stderr( ( diff --git a/src/sphobjinv/version.py b/src/sphobjinv/version.py index 566fa7a..c84d65a 100644 --- a/src/sphobjinv/version.py +++ b/src/sphobjinv/version.py @@ -29,4 +29,4 @@ """ -__version__ = "2.3" +__version__ = "2.3.1" diff --git a/tests/test_api_good.py b/tests/test_api_good.py index f3889b7..2712d4b 100644 --- a/tests/test_api_good.py +++ b/tests/test_api_good.py @@ -366,17 +366,17 @@ def test_api_inventory_bytes_fname_instantiation( source = soi.readbytes(source) # General import, without a specified kwarg - with check.check(msg="general"): + with check(msg="general"): attrs_inventory_test(soi.Inventory(source), source_type) # Importing with the respective kwarg for each source type - with check.check(msg="specific"): + with check(msg="specific"): inv = soi.Inventory(**{inv_arg: source}) attrs_inventory_test(inv, source_type) # Special case for plaintext bytes, try decoding it if source_type is soi.SourceTypes.BytesPlaintext: - with check.check(msg="plaintext_bytes"): + with check(msg="plaintext_bytes"): inv = soi.Inventory(**{inv_arg: source.decode("utf-8")}) attrs_inventory_test(inv, source_type) diff --git a/tests/test_cli.py b/tests/test_cli.py index 2fcb3ca..b1d5748 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -479,10 +479,10 @@ def test_clifail_convert_localfile_as_url( (scratch_path / (misc_info.FNames.INIT + misc_info.Extensions.DEC)).unlink() - with check.check(msg="path-style"): + with check(msg="path-style"): run_cmdline_test(["convert", "plain", "-u", str(in_path)], expect=1) - with check.check(msg="url-style"): + with check(msg="url-style"): file_url = "file:///" + str(in_path.resolve()) run_cmdline_test(["convert", "plain", "-u", file_url], expect=1) diff --git a/tests/test_fixture.py b/tests/test_fixture.py index 398cfed..1e94d4a 100644 --- a/tests/test_fixture.py +++ b/tests/test_fixture.py @@ -45,7 +45,7 @@ def test_populate_scratch(misc_info, scratch_path, check): scr_base = misc_info.FNames.INIT.value for ext in [_.value for _ in misc_info.Extensions]: - with check.check(msg=ext): + with check(msg=ext): assert (scratch_path / f"{scr_base}{ext}").is_file(), ext @@ -63,11 +63,13 @@ def test_cli_invoke(run_cmdline_test): run_cmdline_test([]) -def test_decomp_comp_fixture(misc_info, decomp_cmp_test): +def test_decomp_comp_fixture(misc_info, decomp_cmp_test, scratch_path): """Test decomp_cmp_test works in 'identity' case. Basically is telling filecmp.cmp to compare a reference inventory file with itself. """ - decomp_cmp_test(misc_info.res_decomp_path) + decomp_cmp_test( + scratch_path / f"{misc_info.FNames.INIT.value}{misc_info.Extensions.DEC.value}" + ) diff --git a/tests/test_flake8_ext.py b/tests/test_flake8_ext.py index 9bd05bf..2255488 100644 --- a/tests/test_flake8_ext.py +++ b/tests/test_flake8_ext.py @@ -69,5 +69,5 @@ def test_flake8_version_output(check): ) # noqa: S607,S603 for p in plugins: - with check.check(msg=p): + with check(msg=p): assert p in flake8_ver_output.replace("_", "-").replace("\n", "") diff --git a/tests/test_readme.py b/tests/test_readme.py index bddd949..4b5086f 100644 --- a/tests/test_readme.py +++ b/tests/test_readme.py @@ -58,6 +58,20 @@ ) +pytestmark = [pytest.mark.readme] + + +@pytest.fixture(scope="module", autouse=True) +def skip_if_no_readme_option(pytestconfig): + """Skip test if --readme not provided. + + Auto-applied to all functions in module, since module is dedicated to README. + + """ + if not pytestconfig.getoption("--readme"): + pytest.skip("'--readme' not specified") # pragma: no cover + + @pytest.mark.skipif( sphinx_ver != sphinx_req, reason="Skip if Sphinx version mismatches current dev version.", @@ -89,5 +103,5 @@ def test_readme_shell_cmds(ensure_doc_scratch, is_win, check): msg = "\n\nExpected:\n" + out + "\n\nGot:\n" + result - with check.check(): + with check(): assert chk.check_output(out, result, dt_flags), msg diff --git a/tox.ini b/tox.ini index 13d861b..8e13b51 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ minversion=2.0 isolated_build=True envlist= # Test all Python versions on latest lib versions - py3{6,7,8,9,10,11}-sphx_latest-attrs_latest-jsch_latest + py3{7,8,9,10,11}-sphx_latest-attrs_latest-jsch_latest # Test dev Python version on current in-repo dev lib versions py310-sphx_dev-attrs_dev-jsch_dev # Scan across Sphinx versions @@ -13,9 +13,9 @@ envlist= # Scan attrs versions py310-sphx_latest-attrs_{19_2,19_3,20_1,20_2,20_3,21_2,21_3,dev}-jsch_latest # Scan jsonschema versions - py310-sphx_latest-attrs_latest-jsch_{3_0,3_1,3_2,4_0,4_1,dev} + py310-sphx_latest-attrs_latest-jsch_{3_0,3_x,4_0,4_8,dev} # Earliest supported Python and lib versions all together - py36-sphx_1_6_x-attrs_19_2-jsch_3_0 + py37-sphx_1_6_x-attrs_19_2-jsch_3_0 # Spot matrix of early Python, Sphinx, attrs versions py3{7,8,9}-sphx_{1,2}_x-attrs_{19,20}_2-jsch_latest # Test the specific Sphinx threshold cases where behavior changed @@ -56,23 +56,20 @@ deps= attrs_latest: attrs attrs_dev: git+https://github.com/python-attrs/attrs - jsch_3_0: jsonschema<3.1 - jsch_3_1: jsonschema<3.2 - jsch_3_2: jsonschema<3.3 + jsch_3_0: jsonschema==3.0 + jsch_3_x: jsonschema<4 jsch_4_0: jsonschema<4.1 - jsch_4_1: jsonschema<4.2 - jsch_4_2: jsonschema<4.3 - jsch_4_3: jsonschema<4.4 + jsch_4_8: jsonschema<4.9 jsch_latest: jsonschema jsch_dev: git+https://github.com/Julian/jsonschema dictdiffer pytest>=4.4.0 - pytest-check>=0.4 + pytest-check>=1.1.2 pytest-ordering pytest-timeout stdio-mgr>=1.0.1 - sphinx-issues==0.4.0 + sphinx-issues sphinx-rtd-theme sphinxcontrib-programoutput @@ -84,7 +81,6 @@ basepython= py39: python3.9 py38: python3.8 py37: python3.7 - py36: python3.6 [testenv:flake8] skip_install=True @@ -124,7 +120,7 @@ markers = first: Inherited marker from `pytest-ordering` timeout: Inherited marker from `pytest-timeout` -addopts = --strict-markers --doctest-glob="README.rst" -rsxX -Werror +addopts = --strict-markers -rsxX -Werror norecursedirs = .* env* src *.egg dist build