Code Monkey home page Code Monkey logo

gp-libs's Introduction

gp-libs · Python Package License Code Coverage

Incubating / dogfooding some sphinx extensions and pytest plugins on git-pull projects, e.g. cihai, vcs-python, or tmux-python.

doctest for reStructured and markdown

Two components:

  1. doctest_docutils module: Same specification as doctest, but can parse reStructuredText and markdown

  2. pytest_doctest_docutils: Pytest plugin, collects test items for pytest for reStructuredText and markdown files

    This means you can do:

    $ pytest docs

doctest module

This extends standard library doctest to support anything docutils can parse. It can parse reStructuredText (.rst) and markdown (.md).

See more: https://gp-libs.git-pull.com/doctest/

Supported styles

It supports two barebones directives:

  • docutils' doctest_block

    >>> 2 + 2
    4
  • .. doctest:: directive

    reStructuredText:

    .. doctest::
    
       >>> 2 + 2
       4

    Markdown (requires myst-parser):

    ```{doctest}
    >>> 2 + 2
    4
    ```

Usage

The doctest_docutils module preserves standard library's usage conventions:

reStructuredText
$ python -m doctest_docutils README.rst -v

That's what doctest does by design.

Markdown

If you install myst-parser, doctest will run on .md files.

$ python -m doctest_docutils README.md -v

pytest plugin

This plugin disables pytest's standard doctest plugin.

This plugin integrates with the doctest_docutils module with pytest to enable seamless testing of docs, conftest.py fixtures and all.

$ pytest docs/

Like the above module, it supports docutils' own doctest_block and a basic .. doctest:: directive.

See more: https://gp-libs.git-pull.com/doctest/pytest.html

sphinx plugins

Plain-text issue linker (linkify-issues)

We need to parse plain text, e.g. #99999, to point to the project tracker at https://github.com/git-pull/gp-libs/issues/99999. This way the markdown looks good anywhere you render it, including GitHub and GitLab.

Configuration

In your conf.py:

  1. Add 'linkify_issues' to extensions

    extensions = [
        # ...
        "linkify_issues",
    ]
  2. Configure your issue URL, issue_url_tpl:

    # linkify_issues
    issue_url_tpl = 'https://github.com/git-pull/gp-libs/issues/{issue_id}'

    The config variable is formatted via {meth}str.format where issue_id is 42 if the text is #42.

See more: https://gp-libs.git-pull.com/linkify_issues/

Install

$ pip install --user gp-libs

Developmental releases

You can test the unpublished version of g before its released.

  • pip:

    $ pip install --user --upgrade --pre gp-libs

Minimum requirements

To lift the development burden of supporting legacy APIs, as this package is lightly used, minimum constraints have been pinned:

  • docutils: 0.20.1+
  • myst-parser: 2.0.0+

If you have even passing interested in supporting legacy versions, file an issue on the tracker.

More information

Docs Build Status

gp-libs's People

Contributors

tony avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

gp-libs's Issues

sphinx_toctree_autodoc_fix fails with `sphinx-click`

sphinx-click issue when bulding pages

Error log
Traceback (most recent call last):
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx/events.py", line 94, in emit
    results.append(listener.handler(self.app, *args))
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx_toctree_autodoc_fix.py", line 181, in process_doc
    toc = build_toc(doctree)
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx_toctree_autodoc_fix.py", line 82, in build_toc
    sub_item = build_toc(sectionnode, depth + 1)
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx_toctree_autodoc_fix.py", line 104, in build_toc
    fullname = title.attributes["fullname"]
KeyError: 'fullname'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx/cmd/build.py", line 277, in build_main
    app.build(args.force_all, filenames)
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx/application.py", line 349, in build
    self.builder.build_update()
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx/builders/__init__.py", line 301, in build_update
    self.build(to_build,
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx/builders/__init__.py", line 317, in build
    updated_docnames = set(self.read())
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx/builders/__init__.py", line 424, in read
    self._read_serial(docnames)
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx/builders/__init__.py", line 445, in _read_serial
    self.read_doc(docname)
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx/builders/__init__.py", line 498, in read_doc
    publisher.publish()
  File "/cihai-cli/.venv/lib/python3.10/site-packages/docutils/core.py", line 219, in publish
    self.apply_transforms()
  File "/cihai-cli/.venv/lib/python3.10/site-packages/docutils/core.py", line 200, in apply_transforms
    self.document.transformer.apply_transforms()
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx/transforms/__init__.py", line 80, in apply_transforms
    super().apply_transforms()
  File "/cihai-cli/.venv/lib/python3.10/site-packages/docutils/transforms/__init__.py", line 171, in apply_transforms
    transform.apply(**kwargs)
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx/transforms/__init__.py", line 381, in apply
    self.app.emit('doctree-read', self.document)
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx/application.py", line 460, in emit
    return self.events.emit(event, *args, allowed_exceptions=allowed_exceptions)
  File "/cihai-cli/.venv/lib/python3.10/site-packages/sphinx/events.py", line 105, in emit
    raise ExtensionError(__("Handler %r for event %r threw an exception") %
sphinx.errors.ExtensionError: Handler <bound method BetterTocTreeCollector.process_doc of <sphinx_toctree_autodoc_fix.BetterTocTreeCollector object at 0x7f2e19aaee90>> for event 'doctree-read' threw an exception (exception: 'fullname')

Extension error (sphinx_toctree_autodoc_fix):
Handler <bound method BetterTocTreeCollector.process_doc of <sphinx_toctree_autodoc_fix.BetterTocTreeCollector object at 0x7f2e19aaee90>> for event 'doctree-read' threw an exception (exception: 'fullname')
Command exited with exit code: 2
The server will continue serving the build folder, but the contents being served are no longer in sync with the documentation sources. Please fix the cause of the error above or press Ctrl+C to stop the server.

Effects: tmux-python/tmuxp#812, cihai/cihai-cli#283

doctests in python open source: Position paper

I want to improve how tests work in Python in regards to our documentation.

doctest is genius. docutils and sphinx is ubiquitous in our open source projects.

Despite that, in our own documentation (.rst and .md files), doctest does not run out of the box. This leads to documentation examples that are untested.

There is an essential thing open source projects need for good doctests: Readily available test objects in scope.

In the case of libtmux, that'd mean have a new test-friendly session = Session() ready-to-go for every doctest.

>>> session.new_window()
...

In pytest we achieve that through creating a fixture injecting doctest_namespace:

https://github.com/tmux-python/libtmux/blob/v0.15.0a1/libtmux/conftest.py#L107-L117

This works well in pytest 7.1.0 when ran against .py files - but not against .md, .rst etc.

My doctest_docutils module parses .md and .rst, and my pytest plugin pytest_doctest_docutils which implements it, aims to remedy it.

Status: An issue with conftest.py and fixtures was resolved by moving conftest.py on libtmux to a pytest plugin (tmux-python/libtmux#411, tmux-python/libtmux#412)

Doctests inside of `sphinx-inline-tabs` aren't detected

Look at this during the weekend. good night

sphinx-inline-tabs: https://github.com/pradyunsg/sphinx-inline-tabs

(parse)=

# URL Parser - `libvcs.url`

We all love {mod}`urllib.parse`, but what about VCS systems?

Also, things like completions and typings being in demand, what of all these factories? Good python
code, but how to we get editor support and the nice satisfaction of types snapping together?

If there was a type-friendly structure - like writing our own abstract base class - or a
{mod}`dataclasses` - while also being extensible to patterns and groupings, maybe we could strike a
perfect balance.

If we could make it ready-to-go out of the box, but also have framework-like extensibility, it could
satisfy the niche.

## Validate and detect VCS URLs

````{tab} git

{meth}`libvcs.url.git.GitURL.is_valid()`

```python
from libvcs.url.git import GitURL

>>> GitURL.is_valid(url='https://github.com/vcs-python/libvcs.git')
True
```

```python
from libvcs.url.git import GitURL

>>> GitURL.is_valid(url='[email protected]:vcs-python/libvcs.git')
True
```

````

````{tab} hg
{meth}`libvcs.url.hg.HgURL.is_valid()`

```python
>>> HgURL.is_valid(url='https://hg.mozilla.org/mozilla-central/mozilla-central')
True
```

```python
>>> HgURL.is_valid(url='[email protected]:MyProject/project')
True
```

````

````{tab} svn

{meth}`libvcs.url.svn.SvnURL.is_valid()`


```python
>>> SvnURL.is_valid(
... url='https://svn.project.org/project-central/project-central')
True
```

```python
>>> SvnURL.is_valid(url='[email protected]:MyProject/project')
True
```

````

## Parse VCS URLs

_Compare to {class}`urllib.parse.ParseResult`_

````{tab} git

{class}`libvcs.url.git.GitURL`

```python
>>> GitBaseURL(url='[email protected]:vcs-python/libvcs.git')
GitBaseURL([email protected]:vcs-python/libvcs.git,
        user=git,
        hostname=github.com,
        path=vcs-python/libvcs,
        suffix=.git,
        rule=core-git-scp)
```

````

````{tab} hg

{class}`libvcs.url.hg.HgURL`

```python
>>> HgBaseURL(
...     url="http://hugin.hg.sourceforge.net:8000/hgroot/hugin/hugin")
HgBaseURL(url=http://hugin.hg.sourceforge.net:8000/hgroot/hugin/hugin,
        scheme=http,
        hostname=hugin.hg.sourceforge.net,
        port=8000,
        path=hgroot/hugin/hugin,
        rule=core-hg)
```

````

````{tab} svn

{class}`libvcs.url.svn.SvnURL`

```python
>>> SvnURL(
...     url='svn+ssh://svn.debian.org/svn/aliothproj/path/in/project/repository')
SvnURL(url=svn+ssh://svn.debian.org/svn/aliothproj/path/in/project/repository,
       scheme=svn+ssh,
       hostname=svn.debian.org,
       path=svn/aliothproj/path/in/project/repository,
       rule=core-svn)
```

````

## Export usable URLs

- git: {meth}`libvcs.url.git.GitURL.to_url()`
- hg: {meth}`libvcs.url.hg.HgURL.to_url()`
- svn: {meth}`libvcs.url.svn.SvnURL.to_url()`

`pip` knows what a certain URL string means, but `git clone` won't.

e.g. `pip install git+https://github.com/django/[email protected]` works great with `pip`.

```console
$ pip install git+https://github.com/django/[email protected]
...
Successfully installed Django-3.2

```

but `git clone` can't use that:

```console
$ git clone git+https://github.com/django/[email protected]  # Fail
...
Cloning into [email protected]''...'
git: 'remote-git+https' is not a git command. See 'git --help'.
```

It needs something like this:

```console
$ git clone https://github.com/django/django.git --branch 3.2
```

But before we get there, we don't know if we want a URL yet. We return a structure, e.g. `GitURL`.

- Common result primitives across VCS, e.g. `GitURL`.

  Compare to a {class}`urllib.parse.ParseResult` in `urlparse`

  This is where fun can happen, or you can just parse a URL.

- Allow mutating / replacing parse of a vcs (e.g. just the hostname)
- Support common cases with popular VCS systems
- Support extending parsing for users needing to do so

## Scope

### Out of the box

The ambition for this is to build extendable parsers for package-like URLs, e.g.

- Vanilla VCS URLs

  - any URL supported by the VCS binary, e.g. `git(1)`, `svn(1)`, `hg(1)`.

- [pip]-style urls [^pip-url]
  - branches
  - tags
- [NPM]-style urls[^npm-url]
  - branches
  - tags

[pip]: https://pip.pypa.io/en/stable/

[^pip-url]: PIP-style URLs

    https://pip.pypa.io/en/stable/topics/vcs-support/

[npm]: https://docs.npmjs.com/

[^npm-url]: NPM style URLs

    https://docs.npmjs.com/about-packages-and-modules#npm-package-git-url-formats

## Extendability

Patterns can be registered. [Similar behavior](https://stackoverflow.com/a/6264214/1396928) exists
in {mod}`urlparse` (undocumented).

- Any formats not covered by the stock
- Custom urls

  - For orgs on , e.g:

    - `python:mypy` -> `[email protected]:python/mypy.git`
    - `inkscape:inkscape` -> `[email protected]:inkscape/inkscape.git`

  - For out of domain trackers, e.g.

    Direct to site:

    - `cb:python-vcs/libtmux` -> `https://codeberg.org/vcs-python/libvcs`
    - `kde:plasma/plasma-sdk` -> `[email protected]:plasma/plasma-sdk.git`

      Aside: Note [KDE's git docs] use of [`url.<base>.insteadOf`] and [`url.<base>.pushInsteadOf`]

    Direct to site + org / group:

    - `gnome:gedit` -> `[email protected]:GNOME/gedit.git`
    - `openstack:openstack` -> `https://opendev.org/openstack/openstack.git`
    - `mozilla:central` -> `https://hg.mozilla.org/mozilla-central/`

[kde's git docs]: https://community.kde.org/Infrastructure/Git#Pushing
[`url.<base>.insteadof`]:
  https://git-scm.com/docs/git-config#Documentation/git-config.txt-urlltbasegtinsteadOf
[`url.<base>.pushinsteadof`]:
  https://git-scm.com/docs/git-config#Documentation/git-config.txt-urlltbasegtpushInsteadOf

From there, `GitURL` can be used downstream directly by other projects.

In our case, `libvcs`s' own {ref}`cmd` and {ref}`projects`, as well as a {ref}`vcspull:index`
configuration, will be able to detect and accept various URL patterns.

### Matchers: Defaults

When a match occurs, its `defaults` will fill in non-matched groups.

### Matchers: First wins

When registering new matchers, higher `weight`s are checked first. If it's a valid regex grouping,
it will be picked.

[^api-unstable]: Provisional API only

    It's not determined if Location will be mutable or if modifications will return a new object.

## Explore

```{toctree}
:caption: API

git
svn
hg
base
registry
```

Drop Python 3.7 support

Python 3.7:

  • Released 5 years ago (26 Jun 2018)
  • Support Ended 3 weeks and 4 days ago (27 Jun 2023)

doctest: Upstream updates

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.