From b4152dca5934b747c804e81a46f7adaec84dbe16 Mon Sep 17 00:00:00 2001 From: James Mitchell Date: Wed, 11 Jun 2025 16:53:02 +0100 Subject: [PATCH] runner: add dummy base classes Runner + Reporter --- docs/source/data-structures/misc/runner.rst | 11 +--- src/libsemigroups_pybind11/__init__.py | 2 + src/libsemigroups_pybind11/action.py | 4 +- .../detail/congruence_common.py | 9 ++- src/libsemigroups_pybind11/froidure_pin.py | 3 +- src/libsemigroups_pybind11/konieczny.py | 3 +- src/libsemigroups_pybind11/runner.py | 55 +++++++++++++++++++ src/libsemigroups_pybind11/sims.py | 5 +- src/libsemigroups_pybind11/stephen.py | 5 +- tests/test_runner.py | 7 ++- 10 files changed, 84 insertions(+), 20 deletions(-) create mode 100644 src/libsemigroups_pybind11/runner.py diff --git a/docs/source/data-structures/misc/runner.rst b/docs/source/data-structures/misc/runner.rst index eec289673..4d4fc4177 100644 --- a/docs/source/data-structures/misc/runner.rst +++ b/docs/source/data-structures/misc/runner.rst @@ -5,7 +5,7 @@ The full license is in the file LICENSE, distributed with this software. -.. currentmodule:: _libsemigroups_pybind11 +.. currentmodule:: libsemigroups_pybind11 Runner ====== @@ -40,12 +40,5 @@ Full API -------- .. autoclass:: Runner - :no-doc: + :class-doc-from: init :members: - -Methods inherited from Reporter -------------------------------- - -.. autoclass:: Reporter - :members: - :noindex: diff --git a/src/libsemigroups_pybind11/__init__.py b/src/libsemigroups_pybind11/__init__.py index b437c2d70..88221eb30 100644 --- a/src/libsemigroups_pybind11/__init__.py +++ b/src/libsemigroups_pybind11/__init__.py @@ -24,6 +24,7 @@ from .konieczny import Konieczny from .matrix import _Matrix as Matrix, _MatrixKind as MatrixKind from .presentation import Presentation, InversePresentation +from .runner import Runner, Reporter from .schreier_sims import SchreierSims from .sims import ( MinimalRepOrc, @@ -75,6 +76,7 @@ WordGraph, WordRange, congruence_kind, + delta, error_message_with_prefix, freeband_equal_to, lexicographical_compare, diff --git a/src/libsemigroups_pybind11/action.py b/src/libsemigroups_pybind11/action.py index 26f3da1d5..64bb47aef 100644 --- a/src/libsemigroups_pybind11/action.py +++ b/src/libsemigroups_pybind11/action.py @@ -46,6 +46,8 @@ ImageLeftAction as _ImageLeftAction, ImageRightAction as _ImageRightAction, ) + +from .runner import Runner as _Runner from .transf import PPerm as _PPerm, Transf as _Transf from .detail.cxx_wrapper import ( @@ -64,7 +66,7 @@ ######################################################################## -class Action(_CxxWrapper): # pylint: disable=missing-class-docstring +class Action(_Runner): # pylint: disable=missing-class-docstring __doc__ = _RightActionPPerm1List.__doc__ Element = _TypeVar("Element") diff --git a/src/libsemigroups_pybind11/detail/congruence_common.py b/src/libsemigroups_pybind11/detail/congruence_common.py index ed902c48d..5d588fd2c 100644 --- a/src/libsemigroups_pybind11/detail/congruence_common.py +++ b/src/libsemigroups_pybind11/detail/congruence_common.py @@ -18,11 +18,12 @@ ) from libsemigroups_pybind11.presentation import Presentation as _Presentation +from libsemigroups_pybind11.runner import Runner as _Runner -from .cxx_wrapper import CxxWrapper as _CxxWrapper, to_cxx as _to_cxx +from .cxx_wrapper import to_cxx as _to_cxx -class CongruenceCommon(_CxxWrapper): +class CongruenceCommon(_Runner): """ A base class for Congruence, Kambites, KnuthBendix, and ToddCoxeter, collecting the common behaviour required by __init__ @@ -40,7 +41,9 @@ def __init__(self: Self, *args, wrong_num_args_msg="", **kwargs) -> None: # checks that we have 0 args and 1 kwarg or 2 args and 0 kwargs, and # that the types of these are correct if len(args) not in (0, 2): - raise TypeError(f"expected 0 or 2 positional arguments, found {len(args)}") + raise TypeError( + f"expected 0 or 2 positional arguments, found {len(args)}" + ) if len(args) != 0 and len(kwargs) != 0: if len(wrong_num_args_msg) == 0: wrong_num_args_msg = ( diff --git a/src/libsemigroups_pybind11/froidure_pin.py b/src/libsemigroups_pybind11/froidure_pin.py index 2bb59a69f..fb7e55d35 100644 --- a/src/libsemigroups_pybind11/froidure_pin.py +++ b/src/libsemigroups_pybind11/froidure_pin.py @@ -88,13 +88,14 @@ from .detail.decorators import copydoc as _copydoc +from .runner import Runner as _Runner ######################################################################## # The FroidurePin python class ######################################################################## -class FroidurePin(_CxxWrapper): # pylint: disable=missing-class-docstring +class FroidurePin(_Runner): # pylint: disable=missing-class-docstring Element = _TypeVar("Element") __doc__ = _FroidurePinPBR.__doc__ diff --git a/src/libsemigroups_pybind11/konieczny.py b/src/libsemigroups_pybind11/konieczny.py index 860d69b70..5278c90a8 100644 --- a/src/libsemigroups_pybind11/konieczny.py +++ b/src/libsemigroups_pybind11/konieczny.py @@ -49,6 +49,7 @@ copy_cxx_mem_fns as _copy_cxx_mem_fns, ) from .detail.decorators import copydoc as _copydoc +from .runner import Runner as _Runner ######################################################################## @@ -56,7 +57,7 @@ ######################################################################## -class Konieczny(_CxxWrapper): # pylint: disable=missing-class-docstring +class Konieczny(_Runner): # pylint: disable=missing-class-docstring Element = _TypeVar("Element") __doc__ = _KoniecznyBMat.__doc__ diff --git a/src/libsemigroups_pybind11/runner.py b/src/libsemigroups_pybind11/runner.py new file mode 100644 index 000000000..647455985 --- /dev/null +++ b/src/libsemigroups_pybind11/runner.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2025, 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 package provides a class named Runner that shadows the same class in +libsemigroups. It exists for those python classes in libsemigroups_pybind11 +that wrap multiple C++ types. +""" + +from abc import ABC as _ABC +from typing_extensions import Self as _Self + +from _libsemigroups_pybind11 import ( # pylint: disable=no-name-in-module + Runner as _Runner, + Reporter as _Reporter, +) + +from .detail.cxx_wrapper import ( + CxxWrapper as _CxxWrapper, + copy_cxx_mem_fns as _copy_cxx_mem_fns, + to_cxx as _to_cxx, +) + +from .detail.decorators import copydoc as _copydoc + + +# It is possible to create Reporter objects in C++ but not here due to the way +# that CxxWrapper works. +class Reporter( + _ABC, _CxxWrapper +): # pylint: disable=too-few-public-methods, missing-class-docstring + __doc__ = _Reporter.__doc__ + + +_copy_cxx_mem_fns(_Reporter, Reporter) + + +# This class exists so that python classes derived from CxxWrapper can +# also be derived from a class call Runner. I.e. Action objects in +# libsemigroups C++ are Runners, Action objects in python are +# CxxWrappers, but should also inherit from Runner, they cannot inherit +# from the C++ runner (because this already has run etc mem fns which +# won't work for python classes) This class is used so +# that classes such as Action have the same interface as Runner C++ objects. +class Runner(Reporter): # pylint: disable=missing-class-docstring + __doc__ = _Runner.__doc__ + + +_copy_cxx_mem_fns(_Runner, Runner) diff --git a/src/libsemigroups_pybind11/sims.py b/src/libsemigroups_pybind11/sims.py index 526f94b2f..51f1b0d80 100644 --- a/src/libsemigroups_pybind11/sims.py +++ b/src/libsemigroups_pybind11/sims.py @@ -41,9 +41,10 @@ from .detail.decorators import copydoc as _copydoc from .presentation import Presentation as _Presentation +from .runner import Reporter as _Reporter -class _SimsBase(_CxxWrapper): +class _SimsBase(_Reporter): def __init__(self: _Self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) if _to_cxx(self) is not None: @@ -192,6 +193,8 @@ def __init__(self: _Self, *args, **kwargs) -> None: ######################################################################## +# TODO is this correct to derive from _SimsBase and not from _CxxWrapper as per +# SimsRefinerFaithful class SimsRefinerIdeals(_SimsBase): # pylint: disable=missing-class-docstring __doc__ = _SimsRefinerIdeals.__doc__ diff --git a/src/libsemigroups_pybind11/stephen.py b/src/libsemigroups_pybind11/stephen.py index a97706079..a8333eb50 100644 --- a/src/libsemigroups_pybind11/stephen.py +++ b/src/libsemigroups_pybind11/stephen.py @@ -36,20 +36,21 @@ from .detail.decorators import copydoc as _copydoc from .detail.cxx_wrapper import ( - CxxWrapper as _CxxWrapper, to_cxx as _to_cxx, copy_cxx_mem_fns as _copy_cxx_mem_fns, wrap_cxx_free_fn as _wrap_cxx_free_fn, register_cxx_wrapped_type as _register_cxx_wrapped_type, ) +from .runner import Runner as _Runner + ######################################################################## # The Stephen python class ######################################################################## # TODO(2): Make this work with string presentations once it works -class Stephen(_CxxWrapper): # pylint: disable=missing-class-docstring +class Stephen(_Runner): # pylint: disable=missing-class-docstring __doc__ = _StephenPresentationWord.__doc__ _py_template_params_to_cxx_type = { diff --git a/tests/test_runner.py b/tests/test_runner.py index 373af7606..8694ae45f 100644 --- a/tests/test_runner.py +++ b/tests/test_runner.py @@ -13,8 +13,11 @@ from datetime import timedelta -from _libsemigroups_pybind11 import ( # pylint: disable=no-name-in-module - Reporter, +# See the comments in runner.py for why we don't import from +# libsemigroups_pybind11 itself. +from _libsemigroups_pybind11 import Reporter + +from libsemigroups_pybind11 import ( # pylint: disable=no-name-in-module delta, )