File: upstream_version.py

package info (click to toggle)
python-graphviz 0.20.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,188 kB
  • sloc: python: 4,098; makefile: 13
file content (62 lines) | stat: -rw-r--r-- 2,015 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
"""Return the version number from running ``dot -V``."""

import logging
import re
import subprocess
import typing

from . import dot_command
from . import execute

VERSION_PATTERN = re.compile(r'''
                             graphviz[ ]
                             version[ ]
                             (\d+)\.(\d+)
                             (?:\.(\d+)
                               (?:
                                 ~dev\.\d{8}\.\d{4}
                                 |
                                 \.(\d+)
                               )?
                             )?
                             [ ]
                             ''', re.VERBOSE)


log = logging.getLogger(__name__)


def version() -> typing.Tuple[int, ...]:
    """Return the upstream version number tuple from ``stderr`` of ``dot -V``.

    Returns:
        Two, three, or four ``int`` version ``tuple``.

    Raises:
        graphviz.ExecutableNotFound: If the Graphviz executable is not found.
        graphviz.CalledProcessError: If the exit status is non-zero.
        RuntimeError: If the output cannot be parsed into a version number.

    Example:
        >>> doctest_mark_exe()
        >>> import graphviz
        >>> graphviz.version()  # doctest: +ELLIPSIS
        (...)

    Note:
        Ignores the ``~dev.<YYYYmmdd.HHMM>`` portion of development versions.

    See also:
        Upstream release version entry format:
        https://gitlab.com/graphviz/graphviz/-/blob/f94e91ba819cef51a4b9dcb2d76153684d06a913/gen_version.py#L17-20
    """
    cmd = [dot_command.DOT_BINARY, '-V']
    proc = execute.run_check(cmd,
                             stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                             encoding='ascii')

    ma = VERSION_PATTERN.search(proc.stdout)
    if ma is None:
        raise RuntimeError(f'cannot parse {cmd!r} output: {proc.stdout!r}')

    return tuple(int(d) for d in ma.groups() if d is not None)