Skip to content

Commit

Permalink
ci: add black formatter with pre-commit hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
oleksii-leonov committed Nov 16, 2022
1 parent cfd5da8 commit 2b1ea41
Show file tree
Hide file tree
Showing 158 changed files with 30,510 additions and 17,790 deletions.
4 changes: 3 additions & 1 deletion .devcontainer/dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
scipy >= 0.13.3
matplotlib >= 2.0
jupyterlab
ipympl
ipympl
pre-commit == 2.20.*
black == 22.10.0
5 changes: 3 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
"python.defaultInterpreterPath": "/usr/local/bin/python",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.formatting.provider": "black",
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.formatting.blackPath": "black",
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
Expand All @@ -46,7 +47,7 @@

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r requirements.txt",
"postCreateCommand": "pip3 install --user -e '.[test,doc]' && pip3 freeze > .devcontainer/frozen-requirements.txt",
"postCreateCommand": "pre-commit install && pip3 install --user -e '.[test,doc]' && pip3 freeze > .devcontainer/frozen-requirements.txt",

// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode",
Expand Down
19 changes: 17 additions & 2 deletions .github/workflows/testsuite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,24 @@ jobs:
uses: mstimberg/github-calc-nep29@v0.5
with:
token: ${{ secrets.GITHUB_TOKEN }}


pre-commit:
name: Run linters with pre-commit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
cache: 'pip'
cache-dependency-path: .devcontainer/dev-requirements.txt
- name: Install deps
run: pip3 install -r .devcontainer/dev-requirements.txt
- name: Run pre-commit hooks
run: pre-commit run --all-files --show-diff-on-failure

testing:
needs: [get_python_versions]
needs: [get_python_versions, pre-commit]
name: "Python ${{ matrix.python-version }} on ${{ matrix.os }} (standalone: ${{ matrix.standalone }}, 32bit: ${{ matrix.float_dtype_32 }})"
runs-on: ${{ matrix.os }}
strategy:
Expand Down
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
repos:
- repo: meta
hooks:
- id: check-hooks-apply
- id: check-useless-excludes
- repo: https://github.com/psf/black
rev: '22.10.0'
hooks:
- id: black
files: '^brian2/.*\.pyi?$'
75 changes: 47 additions & 28 deletions brian2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,34 @@
def _check_dependencies():
"""Check basic dependencies"""
import sys

missing = []
try:
import numpy
except ImportError as ex:
sys.stderr.write(f"Importing numpy failed: '{ex}'\n")
missing.append('numpy')
missing.append("numpy")
try:
import sympy
except ImportError as ex:
sys.stderr.write(f"Importing sympy failed: '{ex}'\n")
missing.append('sympy')
missing.append("sympy")
try:
import pyparsing
except ImportError as ex:
sys.stderr.write(f"Importing pyparsing failed: '{ex}'\n")
missing.append('pyparsing')
missing.append("pyparsing")
try:
import jinja2
except ImportError as ex:
sys.stderr.write(f"Importing Jinja2 failed: '{ex}'\n")
missing.append('jinja2')
missing.append("jinja2")

if len(missing):
raise ImportError(f"Some required dependencies are missing:\n{', '.join(missing)}")
raise ImportError(
f"Some required dependencies are missing:\n{', '.join(missing)}"
)


_check_dependencies()

Expand All @@ -42,28 +46,30 @@ def _check_dependencies():
from numpy.random import *
from numpy.linalg import *
import numpy.ma as ma

# don't let numpy's datetime hide stdlib
import datetime

from ._version import get_versions as _get_versions
__version__ = _get_versions()['version']
__release_date__ = _get_versions()['date']

__version__ = _get_versions()["version"]
__release_date__ = _get_versions()["date"]

if __release_date__ is not None:
__release_date__ = __release_date__[:10] #only use date part
__git_revision__ = _get_versions()['full-revisionid']
__release_date__ = __release_date__[:10] # only use date part
__git_revision__ = _get_versions()["full-revisionid"]

# Make sure that Brian's unit-aware functions are used, even when directly
# using names prefixed with numpy or np
import brian2.numpy_ as numpy
import brian2.numpy_ as np

# delete some annoying names from the namespace
if 'x' in globals():
if "x" in globals():
del x
if 'f' in globals():
if "f" in globals():
del f
if 'rate' in globals():
if "rate" in globals():
del rate

__docformat__ = "restructuredtext en"
Expand All @@ -77,26 +83,28 @@ def _check_dependency_version(name, version):
from .core.preferences import prefs
from .utils.logger import get_logger
import sys

logger = get_logger(__name__)

module = sys.modules[name]
if not isinstance(module.__version__, str): # mocked module
return
if not LooseVersion(module.__version__) >= LooseVersion(version):
message = f'{name} is outdated (got version {module.__version__}, need version {version})'
message = (
f"{name} is outdated (got version {module.__version__}, need version"
f" {version})"
)
if prefs.core.outdated_dependency_error:
raise ImportError(message)
else:

logger.warn(message, 'outdated_dependency')
logger.warn(message, "outdated_dependency")


def _check_dependency_versions():
for name, version in [('numpy', '1.10'),
('sympy', '1.2'),
('jinja2', '2.7')]:
for name, version in [("numpy", "1.10"), ("sympy", "1.2"), ("jinja2", "2.7")]:
_check_dependency_version(name, version)


_check_dependency_versions()

# Initialize the logging system
Expand All @@ -107,6 +115,7 @@ def _check_dependency_versions():
# Check the caches
def _get_size_recursively(dirname):
import os

total_size = 0
for dirpath, _, filenames in os.walk(dirname):
for fname in filenames:
Expand All @@ -120,20 +129,24 @@ def _get_size_recursively(dirname):
pass # ignore the file
return total_size


#: Stores the cache directory for code generation targets
_cache_dirs_and_extensions = {}


def check_cache(target):
cache_dir, _ = _cache_dirs_and_extensions.get(target, (None, None))
if cache_dir is None:
return
size = _get_size_recursively(cache_dir)
size_in_mb = int(round(size/1024./1024.))
size_in_mb = int(round(size / 1024.0 / 1024.0))
if size_in_mb > prefs.codegen.max_cache_dir_size:
logger.info(f"Cache size for target '{target}': {size_in_mb} MB.\n"
f"You can call clear_cache('{target}') to delete all "
f"files from the cache or manually delete files in the "
f"'{cache_dir}' directory.")
logger.info(
f"Cache size for target '{target}': {size_in_mb} MB.\n"
f"You can call clear_cache('{target}') to delete all "
"files from the cache or manually delete files in the "
f"'{cache_dir}' directory."
)
else:
logger.debug(f"Cache size for target '{target}': {size_in_mb} MB")

Expand All @@ -158,6 +171,7 @@ def clear_cache(target):
"""
import os
import shutil

cache_dir, extensions = _cache_dirs_and_extensions.get(target, (None, None))
if cache_dir is None:
raise ValueError(f'No cache directory registered for target "{target}".')
Expand All @@ -168,10 +182,12 @@ def clear_cache(target):
if f.endswith(ext):
break
else:
raise IOError(f"The cache directory for target '{target}' contains "
f"the file '{os.path.join(folder, f)}' of an unexpected type and "
f"will therefore not be removed. Delete files in "
f"'{cache_dir}' manually")
raise IOError(
f"The cache directory for target '{target}' contains "
f"the file '{os.path.join(folder, f)}' of an unexpected type and "
"will therefore not be removed. Delete files in "
f"'{cache_dir}' manually"
)

logger.debug(f"Clearing cache for target '{target}' (directory '{cache_dir}').")
shutil.rmtree(cache_dir)
Expand All @@ -181,9 +197,12 @@ def _check_caches():
from brian2.codegen.runtime.cython_rt.extension_manager import get_cython_cache_dir
from brian2.codegen.runtime.cython_rt.extension_manager import get_cython_extensions

for target, (dirname, extensions) in [('cython', (get_cython_cache_dir(), get_cython_extensions()))]:
for target, (dirname, extensions) in [
("cython", (get_cython_cache_dir(), get_cython_extensions()))
]:
_cache_dirs_and_extensions[target] = (dirname, extensions)
if prefs.codegen.max_cache_dir_size > 0:
check_cache(target)


_check_caches()

0 comments on commit 2b1ea41

Please sign in to comment.