Skip to content

Commit

Permalink
0.11: Update CI & ruff fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
spacemanspiff2007 committed Jan 9, 2024
1 parent 6526245 commit 8fee471
Show file tree
Hide file tree
Showing 23 changed files with 189 additions and 71 deletions.
11 changes: 6 additions & 5 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ jobs:
build-n-publish:
name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
runs-on: ubuntu-latest
environment: release
permissions:
# IMPORTANT: this permission is mandatory for trusted publishing
id-token: write

steps:
- uses: actions/checkout@v3
with:
ref: main
- name: Set up Python 3.8
- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
python-version: '3.10'
Expand All @@ -27,7 +31,4 @@ jobs:
python setup.py sdist bdist_wheel
- name: Publish distribution to PyPI
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.pypi_api_key }}
uses: pypa/gh-action-pypi-publish@release/v1
13 changes: 12 additions & 1 deletion .github/workflows/run_tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,23 @@ name: Tests
on: [push, pull_request]

jobs:
pre-commit:
name: pre-commit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- uses: pre-commit/action@v3.0.0

test:
needs: pre-commit
runs-on: ubuntu-latest
strategy:
max-parallel: 4
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@v3
Expand Down
28 changes: 10 additions & 18 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,35 +1,27 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.5.0
hooks:
- id: check-ast
- id: check-builtin-literals
- id: check-docstring-first
- id: check-merge-conflict
- id: check-toml
- id: check-yaml
- id: debug-statements
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/pycqa/isort
rev: 5.12.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.11 # check that this version matches the requirements.txt
hooks:
- id: isort
name: isort (python)


- repo: https://github.com/PyCQA/flake8
rev: '6.0.0'
hooks:
- id: flake8
additional_dependencies:
- flake8-bugbear==23.1.20
- flake8-comprehensions==3.10.1
- flake8-pytest-style==1.6
- flake8-noqa==1.3
- pep8-naming==0.13.3
- id: ruff

- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
- id: rst-backticks


- repo: meta
hooks:
- id: check-hooks-apply
Expand Down
4 changes: 2 additions & 2 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ formats: all


build:
os: ubuntu-20.04
os: ubuntu-22.04
tools:
python: "3.9"
python: "3.10"

python:
install:
Expand Down
85 changes: 85 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@

line-length = 120
indent-width = 4

target-version = "py38"
src = ["src", "test"]

# https://docs.astral.sh/ruff/settings/#ignore-init-module-imports
ignore-init-module-imports = true

extend-exclude = ["__init__.py"]

select = [
"E", "W", # https://docs.astral.sh/ruff/rules/#pycodestyle-e-w
"I", # https://docs.astral.sh/ruff/rules/#isort-i
"UP", # https://docs.astral.sh/ruff/rules/#pyupgrade-up

"A", # https://docs.astral.sh/ruff/rules/#flake8-builtins-a
"ASYNC", # https://docs.astral.sh/ruff/rules/#flake8-async-async
"C4", # https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4
"EM", # https://docs.astral.sh/ruff/rules/#flake8-errmsg-em
"FIX", # https://docs.astral.sh/ruff/rules/#flake8-fixme-fix
"INP", # https://docs.astral.sh/ruff/rules/#flake8-no-pep420-inp
"ISC", # https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc
"PIE", # https://docs.astral.sh/ruff/rules/#flake8-pie-pie
"PT", # https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt
"PTH", # https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth
"RET", # https://docs.astral.sh/ruff/rules/#flake8-return-ret
"SIM", # https://docs.astral.sh/ruff/rules/#flake8-simplify-sim
"SLOT", # https://docs.astral.sh/ruff/rules/#flake8-slots-slot
"T10", # https://docs.astral.sh/ruff/rules/#flake8-debugger-t10
"TCH", # https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch
"TD", # https://docs.astral.sh/ruff/rules/#flake8-todos-td

"TRY", # https://docs.astral.sh/ruff/rules/#tryceratops-try
"FLY", # https://docs.astral.sh/ruff/rules/#flynt-fly
"PERF", # https://docs.astral.sh/ruff/rules/#perflint-perf
"RUF", # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf

"PL", # https://docs.astral.sh/ruff/rules/#pylint-pl
]

ignore = [
"RET501", # https://docs.astral.sh/ruff/rules/unnecessary-return-none/#unnecessary-return-none-ret501
"TRY400", # https://docs.astral.sh/ruff/rules/error-instead-of-exception/

"A003", # https://docs.astral.sh/ruff/rules/builtin-attribute-shadowing/
]


[format]
# Use single quotes for non-triple-quoted strings.
quote-style = "single"



[lint.per-file-ignores]
"doc/*" = [
"A001", # A001 Variable `copyright` is shadowing a Python builtin
"E402", # E402 Module level import not at top of file
"INP001", # INP001 File `FILE_NAME` is part of an implicit namespace package. Add an `__init__.py`.
"PTH100", # PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
"PTH118", # PTH118 `os.path.join()` should be replaced by `Path` with `/` operator
]

"tests/*" = [
"INP001", # INP001 File `FILE_NAME` is part of an implicit namespace package. Add an `__init__.py`.
"ISC002", # ISC002 Implicitly concatenated string literals over multiple lines
]

"setup.py" = ["PTH123"]

"src/sphinx_exec_code/code_exec_error.py" = [
"PERF401", # PERF401 Use a list comprehension to create a transformed list
"PLW2901", # PLW2901 `for` loop variable `tb_line` overwritten by assignment target
]


[lint.isort]
# https://docs.astral.sh/ruff/settings/#isort-lines-after-imports
lines-after-imports = 2


[lint.pylint]
max-args = 6
7 changes: 5 additions & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import logging

import os
import sys

# required for sphinx_exec_code

# required for sphinx_exec_code to be found
sys.path.insert(0, os.path.join(os.path.abspath('..'), 'src'))


import sphinx_exec_code


# -- Project information -----------------------------------------------------
project = 'sphinx-exec-code'
copyright = '2021, spacemanspiff2007'
Expand Down
10 changes: 6 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pytest >= 7.2, < 7.3
pre-commit >= 3.0, < 3.1
pytest == 7.4.4
pre-commit == 3.5.0

sphinx >= 6.1, < 6.2
sphinx-rtd-theme >= 1.2, <1.3
ruff == 0.1.11

sphinx == 7.1.2
sphinx-rtd-theme == 2.0.0
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def load_version() -> str:
package_dir={'': 'src'},
packages=find_packages('src', exclude=['tests*']),
classifiers=[
"Development Status :: 4 - Beta",
"Development Status :: 5 - Production/Stable",
'Intended Audience :: Developers',
'Framework :: Sphinx :: Extension',
"License :: OSI Approved :: Apache Software License",
Expand All @@ -56,6 +56,7 @@ def load_version() -> str:
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3 :: Only",
],
)
1 change: 1 addition & 0 deletions src/sphinx_exec_code/__const__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from sphinx.util import logging


log = logging.getLogger('sphinx-exec-code')
2 changes: 1 addition & 1 deletion src/sphinx_exec_code/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.10'
__version__ = '0.11'
2 changes: 1 addition & 1 deletion src/sphinx_exec_code/code_exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def execute_code(code: str, file: Path, first_loc: int) -> str:
env['PYTHONPATH'] = os.pathsep.join(python_folders)

run = subprocess.run([sys.executable, '-c', code.encode('utf-8')], capture_output=True, text=True,
encoding=encoding, cwd=cwd, env=env)
encoding=encoding, cwd=cwd, env=env, check=False)

if run.returncode != 0:
raise CodeExceptionError(code, file, first_loc, run.returncode, run.stderr) from None
Expand Down
1 change: 1 addition & 0 deletions src/sphinx_exec_code/code_exec_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from pathlib import Path
from typing import List


re_line = re.compile(r'^\s*File "(<string>)", line (\d+), in <module>', re.MULTILINE)


Expand Down
8 changes: 4 additions & 4 deletions src/sphinx_exec_code/code_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ def __init__(self, marker: str):
def is_marker(self, line: str) -> bool:
if line == self.start:
if not self.do_add:
raise VisibilityMarkerError(f'{self.start[1:]} already called! '
f'Use {self.stop[1:]} or {self.toggle[1:]}!')
msg = f'{self.start[1:]} already called! Use {self.stop[1:]} or {self.toggle[1:]}!'
raise VisibilityMarkerError(msg)
self.do_add = False
return True

if line == self.stop:
if self.do_add:
raise VisibilityMarkerError(f'{self.stop[1:]} already called! '
f'Use {self.start[1:]} or {self.toggle[1:]}!')
msg = f'{self.stop[1:]} already called! Use {self.start[1:]} or {self.toggle[1:]}!'
raise VisibilityMarkerError(msg)
self.do_add = True
self.skip_empty = True
return True
Expand Down
7 changes: 5 additions & 2 deletions src/sphinx_exec_code/configuration/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from sphinx_exec_code.__const__ import log


TYPE_VALUE = TypeVar('TYPE_VALUE')


Expand All @@ -18,7 +19,8 @@ def __init__(self, sphinx_name: str, initial_value: Optional[TYPE_VALUE] = None)
@property
def value(self) -> TYPE_VALUE:
if self._value is None:
raise ConfigError(f'{self.sphinx_name} is not set!')
msg = f'{self.sphinx_name} is not set!'
raise ConfigError(msg)
return self._value

def transform_value(self, app: SphinxApp, value):
Expand All @@ -40,5 +42,6 @@ def from_app(self, app: SphinxApp) -> TYPE_VALUE:
self._value = self.validate_value(value)
return self._value

def add_config_value(self, app: SphinxApp, sphinx_default):
def add_config_value(self, app: SphinxApp, sphinx_default: TYPE_VALUE):
self.validate_value(sphinx_default)
app.add_config_value(self.sphinx_name, sphinx_default, 'env', self.SPHINX_TYPE)
5 changes: 5 additions & 0 deletions src/sphinx_exec_code/configuration/flag_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,10 @@
class SphinxConfigFlag(SphinxConfigValue[bool]):
SPHINX_TYPE = bool

def validate_value(self, value) -> bool:
if not isinstance(value, bool):
raise TypeError()
return value

def transform_value(self, app: SphinxApp, value) -> bool:
return bool(value)
10 changes: 6 additions & 4 deletions src/sphinx_exec_code/configuration/path_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from sphinx.application import Sphinx as SphinxApp

from sphinx_exec_code.__const__ import log
from sphinx_exec_code.configuration.base import SphinxConfigValue, TYPE_VALUE
from sphinx_exec_code.configuration.base import TYPE_VALUE, SphinxConfigValue


class InvalidPathError(Exception):
Expand All @@ -18,16 +18,18 @@ def make_path(self, app: SphinxApp, value) -> Path:
try:
path = Path(value)
except Exception:
raise InvalidPathError(f'Could not create Path from "{value}" (type {type(value).__name__}) '
f'(configured by {self.sphinx_name:s})') from None
msg = (f'Could not create Path from "{value}" (type {type(value).__name__}) '
f'(configured by {self.sphinx_name:s})')
raise InvalidPathError(msg) from None

if not path.is_absolute():
path = (Path(app.confdir) / path).resolve()
return path

def check_folder_exists(self, folder: Path) -> Path:
if not folder.is_dir():
raise FileNotFoundError(f'Directory "{folder}" not found! (configured by {self.sphinx_name:s})')
msg = f'Directory "{folder}" not found! (configured by {self.sphinx_name:s})'
raise FileNotFoundError(msg)
return folder


Expand Down
1 change: 1 addition & 0 deletions src/sphinx_exec_code/configuration/values.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .flag_config import SphinxConfigFlag
from .path_config import SphinxConfigFolder, SphinxConfigMultipleFolderStr


EXAMPLE_DIR = SphinxConfigFolder('exec_code_example_dir')

# Options for code execution
Expand Down
3 changes: 1 addition & 2 deletions src/sphinx_exec_code/sphinx_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ def builder_ready(app: SphinxApp):
WORKING_DIR.from_app(app)
PYTHONPATH_FOLDERS.from_app(app)
SET_UTF8_ENCODING.from_app(app)
return None


def setup(app):
Expand All @@ -33,7 +32,7 @@ def setup(app):
EXAMPLE_DIR.add_config_value(app, confdir)
WORKING_DIR.add_config_value(app, confdir.parent)
PYTHONPATH_FOLDERS.add_config_value(app, code_folders)
SET_UTF8_ENCODING.add_config_value(app, True if os.name == 'nt' else False) # Somehow this workaround is required
SET_UTF8_ENCODING.add_config_value(app, os.name == 'nt')

app.connect('builder-inited', builder_ready)
app.add_directive('exec_code', ExecCode)
Expand Down
Loading

0 comments on commit 8fee471

Please sign in to comment.