Skip to content

Commit d5c3670

Browse files
committed
Miscellaneous small changes...
* stopit -> timed_threads * Add editorconfig and precommit hook * black, flynt, and isort everything
1 parent 3d1eda0 commit d5c3670

File tree

11 files changed

+111
-133
lines changed

11 files changed

+111
-133
lines changed

.editorconfig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# This is an EditorConfig file:
1+
# This is an EditorConfig file
22
# https://EditorConfig.org
33

44
root = true
@@ -9,7 +9,6 @@ insert_final_newline = true
99
charset = utf-8
1010
indent_style = tab
1111
indent_size = 4
12-
insert_final_newline = true
1312

1413
[*.yml]
1514
indent_style = space

.github/workflows/macos.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
strategy:
1616
matrix:
1717
os: [macOS]
18-
python-version: ['3.10', '3.11', '3.12']
18+
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
1919
steps:
2020
- uses: actions/checkout@v4
2121
- name: Set up Python ${{ matrix.python-version }}
@@ -25,7 +25,7 @@ jobs:
2525
- name: Install OS dependencies
2626
run: |
2727
python -m pip install --upgrade pip
28-
- name: Install stopit
28+
- name: Install timed_threads
2929
run: |
3030
pip install "setuptools>=70.0.0" packaging pytest
3131
pip install -e .[dev]

.github/workflows/pyodide.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ jobs:
5454
pip install "setuptools>=70.0.0" PyYAML click packaging pytest
5555
5656
pip install --no-build-isolation -v -v -v -e .
57-
- name: Test stopit
57+
- name: Test Timed Threads
5858
run: |
5959
# Activate the virtual environment
6060
. .venv-pyodide/bin/activate
6161
echo $PATH
62-
python -c "import sys; print(sys.path); import stopit"
62+
python -c "import sys; print(sys.path); import timed_threads"
6363
# python test

.github/workflows/ubuntu.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
matrix:
14-
python-version: ['3.12', '3.11', '3.9', '3.10']
14+
python-version: ['3.13', '3.11', '3.10', '3.12', '3.14']
1515
steps:
1616
- uses: actions/checkout@v4
1717
- name: Set up Python ${{ matrix.python-version }}

.pre-commit-config.yaml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,24 @@ default_language_version:
22
python: python
33
repos:
44
- repo: https://github.com/pre-commit/pre-commit-hooks
5-
rev: v5.0.0
5+
rev: v4.5.0
66
hooks:
77
- id: check-merge-conflict
8-
- id: check-yaml
98
- id: debug-statements
109
stages: [pre-commit]
10+
exclude: ChangeLog-spell-corrected.diff|mathics/builtin/system.py
1111
- id: end-of-file-fixer
1212
stages: [pre-commit]
1313
exclude: ChangeLog-spell-corrected.diff
14-
- id: trailing-whitespace
15-
exclude: ChangeLog-spell-corrected.diff
16-
- id: check-json
17-
exclude: mathics_scanner/data/character-tables.json
1814
- repo: https://github.com/pycqa/isort
19-
rev: 6.0.1
15+
rev: 5.13.2
2016
hooks:
2117
- id: isort
2218
stages: [pre-commit]
23-
args: ["--profile", "black"]
2419
- repo: https://github.com/psf/black
25-
rev: 25.1.0
20+
rev: 23.12.1
2621
hooks:
2722
- id: black
2823
language_version: python3
24+
exclude: 'mathics/version.py'
2925
stages: [pre-commit]
30-
exclude: version.py

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ clean:
3939
@find . -name *.pyc -type f -delete;
4040

4141
#: Run py.test tests. Use environment variable "o" for pytest options
42-
pytest: mathics_scanner/data/character-tables.json
42+
pytest:
4343
$(PYTHON) -m pytest test $o
4444

4545
#: Remove ChangeLog

README.rst

Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
Timed Threads
33
==============
44

5-
Adds the ability to set absolute time deadlines on asynchronous threads, and allows one thread to stop
6-
another by means of raising an exception.
5+
Adds the ability to set relative elapsed time deadlines on asynchronous threads, and allows one thread to stop another by means of raising an exception.
6+
7+
Note that due to the GIL lock in Python 3.14, this does not give us any more concurrency.
8+
9+
It is hoped that in the future, in conjunction with an implementation of Python that does not have a global GIL lock there can be and implementation that improves concurrency of hardware threads.
10+
11+
The main motivation of this module is to support TimedConstraint in the open-source implementation of Mathematica, called Mathics3.
712

813

914
Overview
@@ -18,7 +23,7 @@ This module provides:
1823

1924
- decorators that may stop its decorated callables on timeout.
2025

21-
Developed and tested with CPython 3.9+ using Python's threading model.
26+
Developed and tested with CPython 3.10+ using Python's threading model.
2227

2328
.. note::
2429

@@ -29,45 +34,35 @@ Developed and tested with CPython 3.9+ using Python's threading model.
2934
Installation
3035
============
3136

32-
Using ``stopit`` in your application
33-
------------------------------------
34-
35-
Both work identically:
36-
3737
.. code:: bash
3838
39-
pip install -e .
39+
pip install Timed-Threads
4040
41-
Developing ``stopit``
42-
---------------------
41+
42+
To install from source:
4343

4444
.. code:: bash
4545
46-
# You should prefer forking if you have a Github account
47-
git clone https://github.com/glenfant/stopit.git
48-
cd stopit
49-
python setup.py develop
46+
pip install -e .
5047
51-
# Does it work for you ?
52-
python setup.py test
5348
5449
Public API
5550
==========
5651

5752
Exception
5853
---------
5954

60-
``stopit.TimeoutException``
55+
``timed_threads.TimeoutException``
6156
...........................
6257

63-
A ``stopit.TimeoutException`` may be raised in a timeout context manager
58+
A ``timed_threads.TimeoutException`` may be raised in a timeout context manager
6459
controlled block.
6560

6661
This exception may be propagated in your application at the end of execution
6762
of the context manager controlled block, see the ``swallow_ex`` parameter of
6863
the context managers.
6964

70-
Note that the ``stopit.TimeoutException`` is always swallowed after the
65+
Note that the ``timed_threads.TimeoutException`` is always swallowed after the
7166
execution of functions decorated with ``xxx_timeoutable(...)``. Anyway, you
7267
may catch this exception **within** the decorated function.
7368

@@ -85,7 +80,7 @@ Threading based resources
8580
executing a ``time.sleep(20)``, the asynchronous exception is effective
8681
**after** its execution.
8782

88-
``stopit.async_raise``
83+
``timed_threads.async_raise``
8984
......................
9085

9186
A function that raises an arbitrary exception in another thread
@@ -98,7 +93,7 @@ A function that raises an arbitrary exception in another thread
9893

9994
- ``exception`` is the exception class or object to raise in the thread.
10095

101-
``stopit.ThreadingTimeout``
96+
``timed_threads.ThreadingTimeout``
10297
...........................
10398

10499
A context manager that "kills" its inner block execution that exceeds the
@@ -109,13 +104,13 @@ provided time.
109104
- ``seconds`` is the number of seconds allowed to the execution of the context
110105
managed block.
111106

112-
- ``swallow_exc`` : if ``False``, the possible ``stopit.TimeoutException`` will
107+
- ``swallow_exc`` : if ``False``, the possible ``timed_threads.TimeoutException`` will
113108
be re-raised when quitting the context managed block. **Attention**: a
114109
``True`` value does not swallow other potential exceptions.
115110

116111
**Methods and attributes**
117112

118-
of a ``stopit.ThreadingTimeout`` context manager.
113+
of a ``timed_threads.ThreadingTimeout`` context manager.
119114

120115
.. list-table::
121116
:header-rows: 1
@@ -150,7 +145,7 @@ of a ``stopit.ThreadingTimeout`` context manager.
150145

151146
* - ``.INTERRUPTED``
152147
- The code under timeout control may itself raise explicit
153-
``stopit.TimeoutException`` for any application logic reason that may
148+
``timed_threads.TimeoutException`` for any application logic reason that may
154149
occur. This intentional exit can be spotted from outside the timeout
155150
controlled block with this state value.
156151

@@ -164,9 +159,9 @@ A typical usage:
164159

165160
.. code:: python
166161
167-
import stopit
162+
import timed_threads
168163
# ...
169-
with stopit.ThreadingTimeout(10) as to_ctx_mgr:
164+
with timed_threads.ThreadingTimeout(10) as to_ctx_mgr:
170165
assert to_ctx_mgr.state == to_ctx_mgr.EXECUTING
171166
# Something potentially very long but which
172167
# ...
@@ -195,13 +190,13 @@ indicating (if ``True``) that the block executed normally:
195190
# Yes, the code under timeout control completed
196191
# Objects it created or changed may be considered consistent
197192
198-
``stopit.threading_timeoutable``
193+
``timed_threads.threading_timeoutable``
199194
................................
200195

201196
A decorator that kills the function or method it decorates, if it does not
202197
return within a given time frame.
203198

204-
``stopit.threading_timeoutable([default [, timeout_param]])``
199+
``timed_threads.threading_timeoutable([default [, timeout_param]])``
205200

206201
- ``default`` is the value to be returned by the decorated function or method of
207202
when its execution timed out, to notify the caller code that the function
@@ -212,7 +207,7 @@ return within a given time frame.
212207

213208
.. code:: python
214209
215-
@stopit.threading_timeoutable(default='not finished')
210+
@timed_threads.threading_timeoutable(default='not finished')
216211
def infinite_loop():
217212
# As its name says...
218213
@@ -226,7 +221,7 @@ return within a given time frame.
226221

227222
.. code:: python
228223
229-
@stopit.threading_timeoutable(timeout_param='my_timeout')
224+
@timed_threads.threading_timeoutable(timeout_param='my_timeout')
230225
def some_slow_function(a, b, timeout='whatever'):
231226
# As its name says...
232227
@@ -252,24 +247,24 @@ Signaling based resources
252247
Using signaling based resources will **not** work under Windows or any OS
253248
that's not based on Unix.
254249

255-
``stopit.SignalTimeout`` and ``stopit.signal_timeoutable`` have exactly the
250+
``timed_threads.SignalTimeout`` and ``timed_threads.signal_timeoutable`` have exactly the
256251
same API as their respective threading based resources, namely
257-
`stopit.ThreadingTimeout`_ and `stopit.threading_timeoutable`_.
252+
`timed_threads.ThreadingTimeout`_ and `timed_threads.threading_timeoutable`_.
258253

259254
See the `comparison chart`_ that warns on the more or less subtle differences
260255
between the `Threading based resources`_ and the `Signaling based resources`_.
261256

262257
Logging
263258
-------
264259

265-
The ``stopit`` named logger emits a warning each time a block of code
260+
The ``timed_threads`` named logger emits a warning each time a block of code
266261
execution exceeds the associated timeout. To turn logging off, just:
267262

268263
.. code:: python
269264
270265
import logging
271-
stopit_logger = logging.getLogger('stopit')
272-
stopit_logger.setLevel(logging.ERROR)
266+
timed_threads_logger = logging.getLogger('timed_threads')
267+
timed_threads_logger.setLevel(logging.ERROR)
273268
274269
.. _comparison chart:
275270

@@ -357,27 +352,27 @@ managed block or decorated functions are executing.
357352
Threading timeout control as mentioned in `Threading based resources`_ does not work as expected
358353
when used in the context of a gevent worker.
359354

360-
See the discussion in `Issue 13 <https://github.com/glenfant/stopit/issues/13>`_ for more details.
355+
See the discussion in `Issue 13 <https://github.com/glenfant/timed_threads/issues/13>`_ for more details.
361356

362357
Tests and demos
363358
===============
364359

365360
.. code:: pycon
366361
367362
>>> import threading
368-
>>> from stopit import async_raise, TimeoutException
363+
>>> from timed_threads import async_raise, TimeoutException
369364
370365
In a real application, you should either use threading based timeout resources:
371366

372367
.. code:: pycon
373368
374-
>>> from stopit import ThreadingTimeout as Timeout, threading_timeoutable as timeoutable #doctest: +SKIP
369+
>>> from timed_threads import ThreadingTimeout as Timeout, threading_timeoutable as timeoutable #doctest: +SKIP
375370
376371
Or the POSIX signal based resources:
377372

378373
.. code:: pycon
379374
380-
>>> from stopit import SignalTimeout as Timeout, signal_timeoutable as timeoutable #doctest: +SKIP
375+
>>> from timed_threads import SignalTimeout as Timeout, signal_timeoutable as timeoutable #doctest: +SKIP
381376
382377
Let's define some utilities:
383378

@@ -621,17 +616,18 @@ Links
621616
=====
622617

623618
Source code (clone, fork, ...)
624-
https://github.com/glenfant/stopit
619+
https://github.com/glenfant/timed_threads
625620

626621
Issues tracker
627-
https://github.com/glenfant/stopit/issues
622+
https://github.com/glenfant/timed_threads/issues
628623

629624
PyPI
630-
https://pypi.python.org/pypi/stopit
625+
https://pypi.python.org/pypi/timed_threads
631626

632627
Credits
633628
=======
634629

630+
- This is a modernization for newer Python of Gilles Lenfant `stopit <https://pypi.org/project/stopit/>`_ with some slight changes.
635631
- This is a NIH package which is mainly a theft of `Gabriel Ahtune's recipe
636632
<http://gahtune.blogspot.fr/2013/08/a-timeout-context-manager.html>`_ with
637633
tests, minor improvements and refactorings, documentation and setuptools

pyproject.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,23 @@ requires = ["setuptools"]
33
build-backend = "setuptools.build_meta"
44

55
[project]
6-
name = "Timed_Threads"
6+
name = "Timed-Threads"
77
description = "Absolute time deadlines and thread cancelling for Python asynchronous threads"
8-
requires-python = ">=3.9"
8+
requires-python = ">=3.10"
99
readme = "README.rst"
1010
license = {text = "MIT"}
11-
keywords = ["Mathematica", "Wolfram", "Interpreter", "Shell", "Math", "CAS"]
1211
maintainers = [
1312
{name = "Mathics3 Group"},
1413
]
1514
classifiers = [
1615
"Topic :: Utilities",
1716
"Programming Language :: Python",
1817
"Programming Language :: Python :: Implementation :: CPython",
19-
"Programming Language :: Python :: 3.9",
2018
"Programming Language :: Python :: 3.10",
2119
"Programming Language :: Python :: 3.11",
2220
"Programming Language :: Python :: 3.12",
2321
"Programming Language :: Python :: 3.13",
22+
"Programming Language :: Python :: 3.14",
2423
"Operating System :: OS Independent",
2524
"License :: OSI Approved :: MIT License",
2625
"Intended Audience :: Developers",

0 commit comments

Comments
 (0)