Skip to content

Commit

Permalink
Merge branch 'release/v0.7.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
juhannc committed Feb 7, 2023
2 parents 781107e + f95826c commit 6bfdf7c
Show file tree
Hide file tree
Showing 13 changed files with 278 additions and 22 deletions.
16 changes: 16 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
# Maintain dependencies for Python packages
- package-ecosystem: pip
directory: /
schedule:
interval: weekly

# Maintain dependencies for GitHub Actions
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
2 changes: 1 addition & 1 deletion .github/workflows/flake8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10']
python-version: ['3.8', '3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand Down
33 changes: 33 additions & 0 deletions .github/workflows/pre-commit-autoupdate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Pre-commit auto-update

on:
schedule:
- cron: 0 0 * * 0 # every Sunday at midnight

permissions:
pull-requests: write

jobs:
auto-update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install pre-commit
run: pip install pre-commit
- name: Run pre-commit autoupdate
run: pre-commit autoupdate
- name: Create Pull Request
uses: peter-evans/create-pull-request@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: update/pre-commit-autoupdate
title: Auto-update pre-commit hooks
commit-message: Auto-update pre-commit hooks
body: |
Update versions of tools in pre-commit
configs to latest version
labels: dependencies
2 changes: 1 addition & 1 deletion .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10']
python-version: ['3.8', '3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10']
python-version: ['3.8', '3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand Down
16 changes: 8 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
rev: v4.4.0
hooks:
- id: check-ast
- id: check-case-conflict
Expand All @@ -11,15 +11,15 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/codespell-project/codespell
rev: v2.1.0
rev: v2.2.2
hooks:
- id: codespell
name: Fixing common spelling mistakes
args:
- --write-changes
- -L compiletime
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.32.2
rev: v0.33.0
hooks:
- id: markdownlint
name: Fixing markdown linting errors
Expand All @@ -30,12 +30,12 @@ repos:
- id: absolufy-imports
name: Make python imports absolute
- repo: https://github.com/psf/black
rev: 22.6.0
rev: 23.1.0
hooks:
- id: black
name: Python formatting (black)
- repo: https://github.com/PyCQA/docformatter
rev: v1.5.0
rev: v1.6.0.rc1
hooks:
- id: docformatter
name: Python docstring formatting (docformatter)
Expand All @@ -46,13 +46,13 @@ repos:
name: Sorting python imports
args: [--profile, black]
- repo: https://github.com/asottile/pyupgrade
rev: v2.37.3
rev: v3.3.1
hooks:
- id: pyupgrade
name: Upgrade common mistakes
args: [--py38-plus]
- repo: https://github.com/PyCQA/flake8
rev: 5.0.4
rev: 6.0.0
hooks:
- id: flake8
name: Linting Python code (flake8)
Expand All @@ -68,7 +68,7 @@ repos:
- id: pretty-format-toml
args: [--autofix]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.971
rev: v0.991
hooks:
- id: mypy
name: Static typechecking (mypy)
Expand Down
69 changes: 67 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# timeoutd

![pytest](https://github.com/juhannc/timeoutd/actions/workflows/pytest.yml/badge.svg)
[![Pypi Status](https://badge.fury.io/py/timeoutd.svg)](https://badge.fury.io/py/timeoutd)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/juhannc/timeoutd/main.svg)](https://results.pre-commit.ci/latest/github/juhannc/timeoutd/main)
[![codecov](https://codecov.io/gh/juhannc/timeoutd/branch/main/graph/badge.svg)](https://codecov.io/gh/juhannc/timeoutd)
[![Maintainability](https://api.codeclimate.com/v1/badges/ba14c01e22ad0343af8c/maintainability)](https://codeclimate.com/github/juhannc/timeoutd/maintainability)

[![Pypi Status](https://badge.fury.io/py/timeoutd.svg)](https://badge.fury.io/py/timeoutd)

## Installation

From [PyPI](https://pypi.org/project/timeoutd/):
Expand All @@ -22,8 +24,12 @@ pip install -e .

## Usage

The `timeoutd` module provides a decorator that can be used to limit the execution time of a function.
The decorator takes a single argument, the number of seconds or a specific date (as a datetime object) after which the function should be terminated.

```python
import time

import timeoutd

@timeoutd.timeout(5)
Expand All @@ -37,10 +43,67 @@ if __name__ == '__main__':
mytest()
```

Specify an alternate exception to raise on timeout:
The `timeout` decorator allows for multiple different ways to specify the timeout, for example with a datetime object:

```python
import time
import datetime

import timeoutd

@timeoutd.timeout(datetime.datetime.now() + datetime.timedelta(0, 5))
def mytest():
print("Start")
for i in range(1, 10):
time.sleep(1)
print(f"{i} seconds have passed")

if __name__ == '__main__':
mytest()
```

It also take a `timedelta` object:

```python
import time
import datetime

import timeoutd

@timeoutd.timeout(datetime.timedelta(0, 5))
def mytest():
print("Start")
for i in range(1, 10):
time.sleep(1)
print(f"{i} seconds have passed")

if __name__ == '__main__':
mytest()
```

But it can also take a delta in form of hours, minutes, and seconds via the kwargs:

```python
import time

import timeoutd

@timeoutd.timeout(hours=0, minutes=0, seconds=5)
def mytest():
print("Start")
for i in range(1, 10):
time.sleep(1)
print(f"{i} seconds have passed")

if __name__ == '__main__':
mytest()
```

The `timeout` decorator also accepts a custom exception to raise on timeout:

```python
import time

import timeoutd

@timeoutd.timeout(5, exception_type=StopIteration)
Expand All @@ -59,6 +122,7 @@ You can also specify a function to be called on timeout instead of raising an ex

```python
import time

import timeoutd

def add_two_numbers(i: int, j: int | None = None):
Expand Down Expand Up @@ -94,6 +158,7 @@ To use it, just pass `use_signals=False` to the timeout decorator function:

```python
import time

import timeoutd

@timeoutd.timeout(5, use_signals=False)
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.6.1
0.7.0
4 changes: 3 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ classifiers =
License :: OSI Approved :: MIT License
Natural Language :: English
Operating System :: OS Independent
Programming Language :: Python
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Topic :: Software Development :: Libraries :: Python Modules
Typing :: Typed
platforms =
any
project_urls =
Expand Down
91 changes: 90 additions & 1 deletion tests/test_timeoutd.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Timeout decorator tests."""
import time
from datetime import datetime, timedelta

import pytest

Expand Down Expand Up @@ -86,6 +87,93 @@ def f():
f()


def test_timeout_with_only_args(use_signals):
@timeout(TIMEOUT, use_signals=use_signals)
def f():
time.sleep(0.2)

with pytest.raises(TimeoutError):
f()


def test_timeout_ok_with_only_args(use_signals):
@timeout(TIMEOUT, use_signals=use_signals)
def f():
time.sleep(TIMEOUT / 2)

f()


def test_timeout_with_datetime_object(use_signals):
@timeout(limit=datetime.now() + timedelta(0, TIMEOUT), use_signals=use_signals)
def f():
time.sleep(0.2)

with pytest.raises(TimeoutError):
f()


def test_timeout_ok_with_datetime_object(use_signals):
@timeout(limit=datetime.now() + timedelta(0, TIMEOUT), use_signals=use_signals)
def f():
time.sleep(TIMEOUT / 2)

f()


def test_timeout_with_timedelta_object(use_signals):
@timeout(limit=timedelta(0, TIMEOUT), use_signals=use_signals)
def f():
time.sleep(0.2)

with pytest.raises(TimeoutError):
f()


def test_timeout_ok_with_timedelta_object(use_signals):
@timeout(limit=timedelta(0, TIMEOUT), use_signals=use_signals)
def f():
time.sleep(TIMEOUT / 2)

f()


def test_timeout_with_hms_tuple(use_signals):
@timeout(hours=0, minutes=0, seconds=TIMEOUT, use_signals=use_signals)
def f():
time.sleep(0.2)

with pytest.raises(TimeoutError):
f()


def test_timeout_with_seconds(use_signals):
@timeout(seconds=TIMEOUT, use_signals=use_signals)
def f():
time.sleep(0.2)

with pytest.raises(TimeoutError):
f()


def test_timeout_with_minutes(use_signals):
@timeout(minutes=TIMEOUT / 60, use_signals=use_signals)
def f():
time.sleep(0.2)

with pytest.raises(TimeoutError):
f()


def test_timeout_with_hours(use_signals):
@timeout(hours=TIMEOUT / 3600, use_signals=use_signals)
def f():
time.sleep(0.2)

with pytest.raises(TimeoutError):
f()


def test_function_name(use_signals):
@timeout(seconds=0.2, use_signals=use_signals)
def func_name():
Expand Down Expand Up @@ -154,9 +242,9 @@ def f():
assert f() == 3


# fmt: off
def test_timeout_pickle_error():
"""Test that when a pickle error occurs a timeout error is raised."""

@timeout(seconds=TIMEOUT, use_signals=False)
def f():
time.sleep(0.1)
Expand All @@ -168,6 +256,7 @@ class Test:

with pytest.raises(TimeoutError):
f()
# fmt: on


def test_timeout_custom_exception_message():
Expand Down
Loading

0 comments on commit 6bfdf7c

Please sign in to comment.