Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
bfbb4e8
Move uv config
Joseph-Edwards Nov 10, 2025
0b78c37
pylint: Update config options
Joseph-Edwards Nov 10, 2025
b11a70a
remove black config
Joseph-Edwards Nov 10, 2025
d9ddc90
pylint: remove unnecessary supressions
Joseph-Edwards Nov 10, 2025
f09f206
pylint: fix docstring empty first line
Joseph-Edwards Nov 10, 2025
4c36ef4
pylint: fix missing-type-doc
Joseph-Edwards Nov 10, 2025
9734359
pylint: fix missing-raises-doc
Joseph-Edwards Nov 10, 2025
1545443
pylint: fix deprecated-typing-alias
Joseph-Edwards Nov 10, 2025
2a49e73
pylint: locally suppress line-too-long
Joseph-Edwards Nov 10, 2025
e129351
pylint: fix consider-using-tuple
Joseph-Edwards Nov 10, 2025
680bec7
pylint: locally suppress misplaced-comparison-constant
Joseph-Edwards Nov 10, 2025
a598b3a
pylint: fix bad-docstring-quotes
Joseph-Edwards Nov 10, 2025
a9e3444
pylint: locally suppress/fix missing-docstring
Joseph-Edwards Nov 11, 2025
55ec74b
pylint: fix bad-builtin
Joseph-Edwards Nov 10, 2025
1ed92d5
pylint: fix else-if-used
Joseph-Edwards Nov 10, 2025
67e8586
pylint: locally suppress/fix invalid-name
Joseph-Edwards Nov 11, 2025
30e4304
pylint: fix redefined-outer-name
Joseph-Edwards Nov 11, 2025
fc70180
pylint: locally suppress consider-using-any-or-all
Joseph-Edwards Nov 11, 2025
7c7bc9a
pylint: locally suppress inconsistent-return-statements
Joseph-Edwards Nov 11, 2025
b01b43c
Update ruff config
Joseph-Edwards Nov 10, 2025
9cda03b
ruff: fix unsorted-imports
Joseph-Edwards Nov 10, 2025
35eaa73
ruff: fix utf8-encoding-declaration
Joseph-Edwards Nov 10, 2025
1be40c5
ruff: fix yoda-conditions
Joseph-Edwards Nov 10, 2025
abe1b35
ruff: fix redundant-open-modes
Joseph-Edwards Nov 10, 2025
da636f2
ruff: fix extraneous-parentheses
Joseph-Edwards Nov 10, 2025
40b5a1b
ruff: locally suppress/fix line-too-long
Joseph-Edwards Nov 10, 2025
68f43fb
ruff: fix suppressible-exception
Joseph-Edwards Nov 10, 2025
5b7020f
ruff: fix super-call-with-parameters
Joseph-Edwards Nov 11, 2025
3ba5f6d
ruff: fix formatting
Joseph-Edwards Nov 11, 2025
439e745
etc: Update lint recipe
Joseph-Edwards Nov 11, 2025
e9e5e2c
make: Update format recipe
Joseph-Edwards Nov 11, 2025
a450cad
CI: lint in separate workflow
Joseph-Edwards Nov 11, 2025
f3b84b3
CI: Only check conda for pr into stable or rc
Joseph-Edwards Nov 11, 2025
20c72b3
Fix spelling
Joseph-Edwards Nov 11, 2025
41bfe11
Fix workflow triggers
Joseph-Edwards Nov 11, 2025
b69f556
CI: Check ruff formatting
Joseph-Edwards Nov 11, 2025
29e5394
make: Update format recipe
Joseph-Edwards Nov 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: Lint
on: [pull_request, workflow_dispatch]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
lint:
name: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
compiler: g++
- os: macOS-latest
compiler: clang++
runs-on: ${{ matrix.os }}
timeout-minutes: 15
defaults:
run:
shell: bash -l {0}
env:
CXX: "ccache ${{ matrix.compiler }}"
CXXFLAGS: "-O2 -g"
UV_NO_SYNC: "1"
LD_LIBRARY_PATH: "/usr/local/lib"
steps:
# Setup environment
- uses: actions/checkout@v5
- name: Set up Python . . .
uses: actions/setup-python@v6
with:
python-version-file: "pyproject.toml"
- name: Install uv . . .
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
- name: "Install libsemigroups_pybind11 dependencies . . ."
run: uv sync --locked --no-install-project --no-dev --group lint
- name: "Find the names of the Python files that will be linted"
run: echo "PYTHON_FILES=$(uv run ruff check --show-files | grep '\.py$' | tr -s '\n' ' ')" >> $GITHUB_ENV

# Lint with ruff and cpplint
- name: "Lint with ruff . . ."
run: uv run ruff check
- name: "Check ruff formatting . . ."
run: uv run ruff format --diff
- name: "Lint with cpplint . . ."
run: uv run cpplint src/*.hpp src/*.cpp

# Build libsemigroups
- name: "macOS only: Install libsemigroups dependencies . . ."
if: ${{ matrix.os == 'macOS-latest' }}
run: brew install autoconf automake libtool
- name: "Setup ccache . . ."
uses: Chocobo1/setup-ccache-action@v1
with:
update_packager_index: false
install_ccache: true
- name: "Install libsemigroups . . ."
run: |
git clone --depth 1 --branch main https://github.com/libsemigroups/libsemigroups.git
cd libsemigroups
./autogen.sh && ./configure CXX="$CXX" CXXFLAGS="$CXXFLAGS" --disable-hpcombi && sudo make install -j8
ccache -s

# Build libsemigroups_pybind11
- name: "Install libsemigroups_pybind11 . . ."
run: uv sync --locked --all-extras --no-dev --group lint

# Lint with ruff and cpplint
- name: "Lint with pylint . . ."
run: uv run pylint $PYTHON_FILES
7 changes: 6 additions & 1 deletion .github/workflows/test-conda.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
name: Run tests (Conda libsemigroups)
on: [pull_request, workflow_dispatch]
on:
workflow_dispatch:
pull_request:
branches:
- "stable-*"
- "rc-*"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Run tests and lint (GitHub libsemigroups)
name: Run tests (GitHub libsemigroups)
on: [pull_request, workflow_dispatch]

concurrency:
Expand Down Expand Up @@ -62,5 +62,3 @@ jobs:
run: uv run pytest
- name: "Running doc tests . . ."
run: uv run make doctest
- name: "Running ruff, pylint and cpplint . . ."
run: uv run make lint
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ doctest:
install:
pip3 install . --use-feature=in-tree-build

black:
black setup.py tests/*.py src/libsemigroups_pybind11/*.py docs/source/conf.py
format:
# ruff format can't yet sort imports, so we require the ruff check line too
# See https://github.com/astral-sh/ruff/issues/8232 for updates.
ruff check --select I --fix-only
ruff format

check: doctest
pytest -vv tests/test_*.py
Expand Down
9 changes: 2 additions & 7 deletions build_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
# -*- coding: utf-8 -*-

# Copyright (c) 2021-2024 J. D. Mitchell
#
# Distributed under the terms of the GPL license version 3.
#
# The full license is in the file LICENSE, distributed with this software.

"""
This module provides some tools for building libsemigroups_pybind11.
"""
"""This module provides some tools for building libsemigroups_pybind11."""


def minimum_libsemigroups_version():
"""
Returns the minimum required version of libsemigroups required to build
"""Returns the minimum required version of libsemigroups required to build
libsemigroups_pybind11.
"""
return "3.2.0"
36 changes: 16 additions & 20 deletions build_tools/packaging_helpers.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
# -*- coding: utf-8 -*-

# Copyright (c) 2021-2024 J. D. Mitchell
#
# Distributed under the terms of the GPL license version 3.
#
# The full license is in the file LICENSE, distributed with this software.

"""
This submodule provides some more tools for building libsemigroups_pybind11.
These tools rely on some non-built-in packages, so they have been placed in
their own submodule to separate from the functions that need to be run in a bare
Python environment.
"""This submodule provides some more tools for building libsemigroups_pybind11.

These tools rely on some non-built-in packages, so they have been placed in their own submodule to
separate from the functions that need to be run in a bare Python environment.
"""

import re
from packaging import version

import pkgconfig
from packaging import version

from . import minimum_libsemigroups_version


def libsemigroups_version():
"Get the version of libsemigroups installed using pkg-config."
"""Get the version of libsemigroups installed using pkg-config."""

vers = pkgconfig.modversion("libsemigroups")
if re.search(r"\d+\.\d+\.\d+-\d+-\w{7}", vers):
Expand All @@ -35,10 +34,8 @@ def compare_version_numbers(supplied, required):
if isinstance(supplied, str) and isinstance(required, str):
if "dev" in supplied:
print(
(
"\033[93mWarning: You are using a development version of libsemigroups. This "
"may cause undocumented behaviour\033[0m"
)
"\033[93mWarning: You are using a development version of libsemigroups. This may "
"cause undocumented behaviour\033[0m"
)
return True
return version.parse(supplied) >= version.parse(required)
Expand Down Expand Up @@ -73,15 +70,11 @@ def ld_library_path() -> str:


def validate_libsemigroups():
DISCLAIMER = """
(You should not see this message unless you are installing
libsemigroups_pybind11 from its sources. If you are not installing from the
sources, please raise an issue at:
https://github.com/libsemigroups/libsemigroups_pybind11)"""
"""Check if the installed version of libsemigroups is compatible with libsemigroups_pybind11"""

if not pkgconfig.exists("libsemigroups"):
raise ImportError(
f"""cannot locate the libsemigroups library.
"""cannot locate the libsemigroups library.
For more information about installing the libsemigroups library see
https://libsemigroups.github.io/libsemigroups_pybind11/install.html.

Expand All @@ -93,7 +86,10 @@ def validate_libsemigroups():
* $CONDA_PREFIX/lib/pkgconfig if your active conda environment has pkgconfig
installed, and libsemigroups was installed with conda/mamba in this
environment.
{DISCLAIMER}"""
(You should not see this message unless you are installing
libsemigroups_pybind11 from its sources. If you are not installing from the
sources, please raise an issue at:
https://github.com/libsemigroups/libsemigroups_pybind11)"""
)

if not compare_version_numbers(libsemigroups_version(), minimum_libsemigroups_version()):
Expand Down
56 changes: 13 additions & 43 deletions docs/source/_ext/libsemigroups_pybind11_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
"""Custom functions and class for building the docs of libsemigroups_pybind11"""

import re

from inspect import getdoc

from sphinx.addnodes import desc_content, desc, index
from sphinx.addnodes import desc, desc_content, index
from sphinx.ext.autodoc.directive import AutodocDirective
from sphinx.util import logging
from sphinx.util.display import progress_message
Expand Down Expand Up @@ -99,22 +98,16 @@ def no_doc_run(self):
# This dictionary should be of the form "bad type" -> "good type", and
# replacements will be performed globally. Hyperlinks will be added in the
# signature if "good type" is a valid (potentially user defined) python type
type_replacements = {
r"_?libsemigroups_pybind11\.": "",
}
type_replacements = {r"_?libsemigroups_pybind11\.": ""}

# This dictionary should be of the form class_name -> (pattern, repl), where
# "pattern" should be replaced by "repl" in the signature of all functions in
# "class_name"
class_specific_replacements = {
"Sims1": [("SimsSettingsSims1", "Sims1")],
"Sims2": [("SimsSettingsSims2", "Sims2")],
"MinimalRepOrc": [
("SimsSettingsMinimalRepOrc", "MinimalRepOrc"),
],
"RepOrc": [
("SimsSettingsRepOrc", "RepOrc"),
],
"MinimalRepOrc": [("SimsSettingsMinimalRepOrc", "MinimalRepOrc")],
"RepOrc": [("SimsSettingsRepOrc", "RepOrc")],
"PathsToRoots": [("forest_PathsFromToRootsCommon", "PathsToRoots")],
"PathsFromRoots": [("forest_PathsFromToRootsCommon", "PathsFromRoots")],
}
Expand Down Expand Up @@ -186,13 +179,7 @@ def sig_alternative(doc, signature, return_annotation):


def change_sig(
app=None,
what=None,
name=None,
obj=None,
options=None,
signature=None,
return_annotation=None,
app=None, what=None, name=None, obj=None, options=None, signature=None, return_annotation=None
):
"""Make type replacement in function signatures"""
if what == "class":
Expand All @@ -212,9 +199,7 @@ def change_sig(


def make_only_doc(lines):
"""
Extract the unique docstrings from a sequence of overloaded functions.
"""
"""Extract the unique docstrings from a sequence of overloaded functions."""

# To keep track of unique strings
sigs = set()
Expand All @@ -240,9 +225,7 @@ def make_only_doc(lines):
deleting = False
sigs.add(sig)
lines[i - 3] = re.sub(
r"\d+(\. .*)\(.*$",
str(overload_counter) + r"\1" + sig,
lines[i - 3],
r"\d+(\. .*)\(.*$", str(overload_counter) + r"\1" + sig, lines[i - 3]
)
overload_counter += 1

Expand Down Expand Up @@ -273,8 +256,7 @@ def make_only_doc(lines):


def only_doc_once(app, what, name, obj, options, lines):
"""
Edit docstring to only include one version of the doc for an overloaded
"""Edit docstring to only include one version of the doc for an overloaded
function if necessary
"""

Expand Down Expand Up @@ -327,9 +309,7 @@ def fix_overloads(app, what, name, obj, options, lines):
return_annotation = m.group(3)
# Make replacements in signature
signature, return_annotation = change_sig(
name=name,
signature=signature,
return_annotation=return_annotation,
name=name, signature=signature, return_annotation=return_annotation
)

# Add adjusted content to the output
Expand All @@ -338,10 +318,7 @@ def fix_overloads(app, what, name, obj, options, lines):
f"{new_name}{signature} -> {return_annotation}"
)
lines[i + offset] = new_line
lines.insert(
i + offset + 1,
f"{parent_indent}{indent}:noindex:",
)
lines.insert(i + offset + 1, f"{parent_indent}{indent}:noindex:")
overload_counter += 1
offset += 1
else:
Expand Down Expand Up @@ -397,26 +374,19 @@ def check_string_replacements(app, env):
for bad_type, good_type in type_replacements.items():
if bad_type not in strings_replaced:
any_warnings = True
logger.warning(
f'"{bad_type}" -> "{good_type}"',
type="unused-replacement",
)
logger.warning(f'"{bad_type}" -> "{good_type}"', type="unused-replacement")

for class_name, repls in class_specific_replacements.items():
for pattern, repl in repls:
if pattern not in strings_replaced:
any_warnings = True
logger.warning(
f'"{pattern}" -> "{repl}" in {class_name}',
type="unused-replacement",
f'"{pattern}" -> "{repl}" in {class_name}', type="unused-replacement"
)
for bad_string, good_string in docstring_replacements.items():
if bad_string not in strings_replaced:
any_warnings = True
logger.warning(
f'"{bad_string}" -> "{good_string}"',
type="unused-replacement",
)
logger.warning(f'"{bad_string}" -> "{good_string}"', type="unused-replacement")
if any_warnings:
logger.info(f"Please correct this in {__file__}")

Expand Down
17 changes: 3 additions & 14 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# pylint: disable=invalid-name, line-too-long
"""
This provides configuration for the generation of the docs
"""This provides configuration for the generation of the docs.

More detail of the available configuration options can be found in the
following places:
Expand Down Expand Up @@ -110,10 +108,7 @@
# The titles_only option stops the page sections and toc (which have the
# same names) from being duplicated in the sidebar on the Konieczny and
# FroidurePin pages.
html_theme_options = {
"titles_only": True,
"style_nav_header_background": "#2980B9",
}
html_theme_options = {"titles_only": True, "style_nav_header_background": "#2980B9"}

# The project logo
html_logo = "../pictures/libsemigroups_pybind11_logo.svg"
Expand All @@ -137,13 +132,7 @@

# How to group the document tree into manual pages.
man_pages = [
(
master_doc,
"libsemigroups_pybind11",
"libsemigroups_pybind11 Documentation",
author,
1,
)
(master_doc, "libsemigroups_pybind11", "libsemigroups_pybind11 Documentation", author, 1)
]

############ Options for the Python domain ############
Expand Down
Loading