"""Check dependencies in setup.cfg and requirements file are the same."""
import configparser
from pathlib import Path

import yaml


def string_to_dependencies(text: str) -> set:
    """Return the set of pip dependencies from a multi-line string.

    Whitespace and empty lines are not significant.
    Comment lines are ignored.
    """
    lines = text.splitlines()
    lines = [line for line in lines if not line.startswith("#")]
    collapsed_lines = [line.replace(" ", "") for line in lines if line]
    items = set(collapsed_lines)
    if "" in items:
        items.remove("")  # empty string from blank lines
    return items


def setup_dependencies(section, option) -> set:
    """Extract set of dependencies from setup.cfg section/option."""
    config = configparser.ConfigParser()
    config.read("setup.cfg", encoding="utf-8")
    text = config.get(section, option)
    return string_to_dependencies(text)


def file_dependencies(filename: str) -> set:
    """Extract set of dependencies from a requirements.txt file."""
    text = Path(filename).read_text(encoding="utf-8")
    return string_to_dependencies(text)


def test_install_requires():
    """setup.cfg install_requires == requirements.txt."""
    setup_values = setup_dependencies("options", "install_requires")
    requirements_values = file_dependencies("requirements.txt")
    assert setup_values == requirements_values


def test_extras_require_test():
    """setup.cfg extras_require|test key is up to date with tests/requirements.txt.

    The test key should have at least all the requirements from the
    requirements file.  It can have more.
    """
    setup_values = setup_dependencies("options.extras_require", "test")
    requirements_values = file_dependencies("tests/requirements.txt")
    assert requirements_values.issubset(setup_values)


def test_extras_require_inspect():
    """setup.cfg extras_require|inspect key == tests/requirements_inspect.txt."""
    setup_values = setup_dependencies("options.extras_require", "inspect")
    requirements_values = file_dependencies("tests/requirements_inspect.txt")
    assert setup_values == requirements_values


def test_extras_require_doc():
    """setup.cfg extras_require|doc key == docs/requirements.txt."""
    setup_values = setup_dependencies("options.extras_require", "docs")
    requirements_values = file_dependencies("doc/requirements.txt")
    assert setup_values == requirements_values


def test_readthedocs_python_version():
    """The build docs Python version == workflow step Python version."""
    with open(".readthedocs.yml", "r", encoding="utf-8") as frtd:
        rtd = yaml.safe_load(frtd)
    with open(".github/workflows/ci.yml", "r", encoding="utf-8") as fwrk:
        workflow = yaml.safe_load(fwrk)
    step = workflow["jobs"]["docs"]["steps"][1]
    assert "Setup Python" in step["name"]
    workflow_version = step["with"]["python-version"]
    assert rtd["python"]["version"] == workflow_version

"""Check dependencies in setup.cfg and requirements file are the same."""
import configparser
from pathlib import Path

import yaml


def string_to_dependencies(text: str) -> set:
    """Return the set of pip dependencies from a multi-line string.

    Whitespace and empty lines are not significant.
    Comment lines are ignored.
    """
    lines = text.splitlines()
    lines = [line for line in lines if not line.startswith("#")]
    collapsed_lines = [line.replace(" ", "") for line in lines if line]
    items = set(collapsed_lines)
    if "" in items:
        items.remove("")  # empty string from blank lines
    return items


def setup_dependencies(section, option) -> set:
    """Extract set of dependencies from setup.cfg section/option."""
    config = configparser.ConfigParser()
    config.read("setup.cfg", encoding="utf-8")
    text = config.get(section, option)
    return string_to_dependencies(text)


def file_dependencies(filename: str) -> set:
    """Extract set of dependencies from a requirements.txt file."""
    text = Path(filename).read_text(encoding="utf-8")
    return string_to_dependencies(text)


def test_install_requires():
    """setup.cfg install_requires == requirements.txt."""
    setup_values = setup_dependencies("options", "install_requires")
    requirements_values = file_dependencies("requirements.txt")
    assert setup_values == requirements_values


def test_extras_require_test():
    """setup.cfg extras_require|test key is up to date with tests/requirements.txt.

    The test key should have at least all the requirements from the
    requirements file.  It can have more.
    """
    setup_values = setup_dependencies("options.extras_require", "test")
    requirements_values = file_dependencies("tests/requirements.txt")
    assert requirements_values.issubset(setup_values)


def test_extras_require_inspect():
    """setup.cfg extras_require|inspect key == tests/requirements_inspect.txt."""
    setup_values = setup_dependencies("options.extras_require", "inspect")
    requirements_values = file_dependencies("tests/requirements_inspect.txt")
    assert setup_values == requirements_values


def test_extras_require_doc():
    """setup.cfg extras_require|doc key == docs/requirements.txt."""
    setup_values = setup_dependencies("options.extras_require", "docs")
    requirements_values = file_dependencies("doc/requirements.txt")
    assert setup_values == requirements_values


def test_readthedocs_python_version():
    """The build docs Python version == workflow step Python version."""
    with open(".readthedocs.yml", "r", encoding="utf-8") as frtd:
        rtd = yaml.safe_load(frtd)
    with open(".github/workflows/ci.yml", "r", encoding="utf-8") as fwrk:
        workflow = yaml.safe_load(fwrk)
    step = workflow["jobs"]["docs"]["steps"][1]
    assert "Setup Python" in step["name"]
    workflow_version = step["with"]["python-version"]
    assert rtd["python"]["version"] == workflow_version

Check dependencies in setup.cfg and requirements file are the same. Return the set of pip dependencies from a multi-line string.      Whitespace and empty lines are not significant.     Comment lines are ignored. # empty string from blank lines Extract set of dependencies from setup.cfg section/option. Extract set of dependencies from a requirements.txt file. setup.cfg install_requires == requirements.txt. setup.cfg extras_require|test key is up to date with tests/requirements.txt.      The test key should have at least all the requirements from the     requirements file.  It can have more. setup.cfg extras_require|inspect key == tests/requirements_inspect.txt. setup.cfg extras_require|doc key == docs/requirements.txt. The build docs Python version == workflow step Python version.