Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

style: Added black formatting & refactored configs into pyproject.toml #58

Merged
merged 14 commits into from
May 31, 2022
5 changes: 5 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[flake8]
max-line-length = 120
ignore = E203, E402, E265, F403, W503, W504, E731
exclude = .github, .git, venv*, docs, build
per-file-ignores = **/__init__.py:F401
44 changes: 16 additions & 28 deletions .github/validate_deps.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
from pathlib import Path

import requirements
import toml
from requirements.requirement import Requirement

# All req files to check
EXTRA_MAP = {
"test": "tests/requirements.txt",
"docs": "docs/requirements.txt",
}
EXTRA_IGNORE = ["dev"]


def parse_deps(deps):
def check_deps(deps):
reqs = {}
for _dep in deps:
lib, specs = _dep
Expand All @@ -26,10 +26,10 @@ def get_conficts(setup_reqs, requirement_file):
# Parse the deps from the requirements.txt
folder = Path(__file__).parent.parent.absolute()
req_deps = {}
with open(folder.joinpath(requirement_file), 'r') as f:
with open(folder.joinpath(requirement_file), "r") as f:
_deps = [(req.name, req.specs) for req in requirements.parse(f)]

req_deps = parse_deps(_deps)
req_deps = check_deps(_deps)

# Compare them
assert len(req_deps) == len(setup_reqs)
Expand All @@ -46,32 +46,18 @@ def main():

# Collect the one from setup.py
folder = Path(__file__).parent.parent.absolute()
with open(folder.joinpath("setup.cfg"), 'r') as f:
setup = f.readlines()
toml_reqs = toml.load(folder.joinpath("pyproject.toml"))

# install_requires
lines = setup[setup.index("install_requires =\n") + 1:]
lines = [_dep.strip() for _dep in lines[:lines.index("\n")]]
_reqs = [Requirement.parse(_line) for _line in lines]
install_requires = parse_deps([(req.name, req.specs) for req in _reqs])
_reqs = [Requirement.parse(_line) for _line in toml_reqs["project"]["dependencies"]]
install_requires = check_deps([(req.name, req.specs) for req in _reqs])

# extras
extras_require = {}
lines = setup[setup.index("[options.extras_require]\n") + 1:]
lines = lines[:lines.index("\n")]
# Split each extra
extra_lines = [_line for _line in lines if str.isalpha(_line[0])]
extra_names = [_line.strip().replace("=", "").strip() for _line in extra_lines]
for current_extra, start_line, end_line in zip(extra_names, extra_lines, extra_lines[1:] + [None]):
if current_extra in EXTRA_IGNORE:
continue
_lines = [_dep for _dep in lines[lines.index(start_line) + 1:]]
if isinstance(end_line, str):
_lines = _lines[:_lines.index(end_line)]
# Remove comments
_lines = [_line.strip() for _line in _lines]
_reqs = [Requirement.parse(_line.strip()) for _line in _lines if not _line.strip().startswith("#")]
extras_require[current_extra] = parse_deps([(req.name, req.specs) for req in _reqs])
extras_require = {
k: [Requirement.parse(_line) for _line in lines]
for k, lines in toml_reqs["project"]["optional-dependencies"].items()
}
extras_require = {k: check_deps([(req.name, req.specs) for req in _reqs]) for k, _reqs in extras_require.items()}

# Resolve conflicts
mismatches = {}
Expand All @@ -82,11 +68,13 @@ def main():
# Display the results
if any(len(mismatch) > 0 for mismatch in mismatches.values()):
mismatch_str = "version specifiers mismatches:\n"
mismatch_str += '\n'.join(
mismatch_str += "\n".join(
f"- {lib}: {setup} (from setup.cfg) | {reqs} (from {req_file})"
for req_file, issues in mismatches.items() for lib, setup, reqs in issues
for req_file, issues in mismatches.items()
for lib, setup, reqs in issues
)
raise AssertionError(mismatch_str)


if __name__ == "__main__":
main()
19 changes: 6 additions & 13 deletions .github/validate_headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,16 @@
current_year = datetime.now().year

year_options = [f"{current_year}"] + [f"{year}-{current_year}" for year in range(starting_year, current_year)]
copyright_notices = [
[f"# Copyright (C) {year_str}, François-Guillaume Fernandez.\n"]
for year_str in year_options
]
copyright_notices = [[f"# Copyright (C) {year_str}, François-Guillaume Fernandez.\n"] for year_str in year_options]
license_notice = [
"# This program is licensed under the Apache License version 2.\n",
"# See LICENSE or go to <https://www.apache.org/licenses/LICENSE-2.0.txt> for full license details.\n"
"# See LICENSE or go to <https://www.apache.org/licenses/LICENSE-2.0.txt> for full license details.\n",
]

# Define all header options
HEADERS = [
shebang + [blank_line] + copyright_notice + [blank_line] + license_notice
for copyright_notice in copyright_notices
] + [
copyright_notice + [blank_line] + license_notice
for copyright_notice in copyright_notices
]
shebang + [blank_line] + copyright_notice + [blank_line] + license_notice for copyright_notice in copyright_notices
] + [copyright_notice + [blank_line] + license_notice for copyright_notice in copyright_notices]


IGNORED_FILES = ["version.py", "__init__.py"]
Expand All @@ -38,7 +31,7 @@ def main():

# For every python file in the repository
for folder in FOLDERS:
for source_path in Path(__file__).parent.parent.joinpath(folder).rglob('**/*.py'):
for source_path in Path(__file__).parent.parent.joinpath(folder).rglob("**/*.py"):
if source_path.name not in IGNORED_FILES:
# Parse header
header_length = max(len(option) for option in HEADERS)
Expand All @@ -50,7 +43,7 @@ def main():
break
# Validate it
if not any(
"".join(current_header[:min(len(option), len(current_header))]) == "".join(option)
"".join(current_header[: min(len(option), len(current_header))]) == "".join(option)
for option in HEADERS
):
invalid_files.append(source_path)
Expand Down
12 changes: 7 additions & 5 deletions .github/verify_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
"topic: ci",
}

GH_ORG = 'frgfm'
GH_REPO = 'torch-scan'
GH_ORG = "frgfm"
GH_REPO = "torch-scan"


def query_repo(cmd: str, *, accept) -> Any:
Expand All @@ -61,10 +61,12 @@ def main(args):

def parse_args():
import argparse
parser = argparse.ArgumentParser(description='PR label checker',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)

parser.add_argument('pr', type=int, help='PR number')
parser = argparse.ArgumentParser(
description="PR label checker", formatter_class=argparse.ArgumentDefaultsHelpFormatter
)

parser.add_argument("pr", type=int, help="PR number")
args = parser.parse_args()

return args
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,6 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requirements-parser==0.2.0
pip install requirements-parser==0.2.0 toml
- name: Run unittests
run: python .github/validate_deps.py
22 changes: 20 additions & 2 deletions .github/workflows/style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
- name: Run mypy
run: |
mypy --version
mypy --config-file mypy.ini torchscan/
mypy torchscan/

pydocstyle-py3:
runs-on: ${{ matrix.os }}
Expand All @@ -91,7 +91,25 @@ jobs:
architecture: x64
- name: Run pydocstyle
run: |
pip install pydocstyle
pip install "pydocstyle[toml]"
pydocstyle --version
pydocstyle torchscan/

black-py3:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
python: [3.7]
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python }}
architecture: x64
- name: Run black
run: |
pip install black
black --version
black --check --diff .
18 changes: 13 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,19 @@ make quality

##### Lint verification

To ensure that your incoming PR complies with the lint settings, you need to install [flake8](https://flake8.pycqa.org/en/latest/) and run the following command from the repository's root folder:
To ensure that your incoming PR complies with the lint settings, you need to install [flake8](https://flake8.pycqa.org/en/latest/), [black](https://black.readthedocs.io/en/stable/) and run the following command from the repository's root folder:

```shell
flake8 ./
black --check .
```
This will read the `.flake8` setting file and let you know whether your commits need some adjustments.

##### Import order

In order to ensure there is a common import order convention, run [isort](https://github.com/PyCQA/isort) as follows:

```shell
isort **/*.py
isort .
```
This will reorder the imports of your local files.

Expand All @@ -108,9 +108,17 @@ This will reorder the imports of your local files.
Additionally, to catch type-related issues and have a cleaner codebase, annotation typing are expected. After installing [mypy](https://github.com/python/mypy), you can run the verifications as follows:

```shell
mypy --config-file mypy.ini
mypy torchscan/
```
The `mypy.ini` file will be read to check your typing.

##### Docstring style

Finally, documentation being important, [pydocstyle](https://github.com/PyCQA/pydocstyle) will be checking the docstrings:

```shell
pydocstyle torchscan/
```


### Submit your modifications

Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ quality:
flake8 ./
mypy torchscan/
pydocstyle torchscan/
black --check .

# this target runs checks on all files and potentially modifies some of them
style:
isort .
black .

# Run tests for the library
test:
Expand Down
47 changes: 24 additions & 23 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@

import sphinx_rtd_theme

sys.path.insert(0, os.path.abspath('../..'))
sys.path.insert(0, os.path.abspath("../.."))
from datetime import datetime

import torchscan

# -- Project information -----------------------------------------------------

master_doc = 'index'
project = 'torchscan'
master_doc = "index"
project = "torchscan"
copyright = f"2020-{datetime.now().year}, François-Guillaume Fernandez"
author = 'François-Guillaume Fernandez'
author = "François-Guillaume Fernandez"

# The full version, including alpha/beta/rc tags
version = torchscan.__version__
release = torchscan.__version__ + '-git'
release = torchscan.__version__ + "-git"


# -- General configuration ---------------------------------------------------
Expand All @@ -43,54 +43,55 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.viewcode',
'sphinx.ext.mathjax',
'sphinxemoji.sphinxemoji', # cf. https://sphinxemojicodes.readthedocs.io/en/stable/
'sphinx_copybutton',
"sphinx.ext.autodoc",
"sphinx.ext.napoleon",
"sphinx.ext.viewcode",
"sphinx.ext.mathjax",
"sphinxemoji.sphinxemoji", # cf. https://sphinxemojicodes.readthedocs.io/en/stable/
"sphinx_copybutton",
]

napoleon_use_ivar = True

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store']
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]


# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
highlight_language = 'python3'
pygments_style = "sphinx"
highlight_language = "python3"

# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]

# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
'collapse_navigation': False,
'display_version': False,
'logo_only': False,
'analytics_id': 'UA-148140560-3',
"collapse_navigation": False,
"display_version": False,
"logo_only": False,
"analytics_id": "UA-148140560-3",
}


# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_static_path = ["_static"]


def setup(app):
app.add_css_file('css/custom.css')
app.add_js_file('js/custom.js')
app.add_css_file("css/custom.css")
app.add_js_file("js/custom.js")
Loading