From abbb64d8a133f40821a5f35dc91c4c2207075255 Mon Sep 17 00:00:00 2001 From: JJJHolscher Date: Sat, 1 Jul 2023 14:13:04 +0200 Subject: [PATCH] time_out.time_limit errors if a function call lasts too long --- .gitignore | 18 ++++++++++++++++++ jo3util | 1 + pyproject.toml | 8 ++++---- src/time_out.py | 35 +++++++++++++++++++++++++++++++++++ tests/__init__.py | 2 +- tests/test_main.py | 14 -------------- tests/test_time_out.py | 22 ++++++++++++++++++++++ 7 files changed, 81 insertions(+), 19 deletions(-) create mode 100644 .gitignore create mode 120000 jo3util create mode 100644 src/time_out.py delete mode 100644 tests/test_main.py create mode 100644 tests/test_time_out.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b1d90b0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ + + +# JO3'S DEFAULT IGNORE RULES +/tmp* +## ctags +/tags +/tags.temp +/tags.lock +## python +/build/ +/dist/ +/*.egg-info/ +/.venv/ +__pycache__ +**.egg-info/ +**.ipynb_checkpoints +## rust +/target/ diff --git a/jo3util b/jo3util new file mode 120000 index 0000000..f7ffedd --- /dev/null +++ b/jo3util @@ -0,0 +1 @@ +./src \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 11d3ff9..4fb0ee7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] -name = "NAME" -version = "0.0.0" # TODO; automatically update versions by looking at git +name = "jo3util" +version = "0.0.2" description = "" dependencies = [] dynamic = ["readme"] @@ -16,7 +16,7 @@ classifiers = [ github = "JJJHolscher" [project.urls] -homepage = "https://github.com/JJJHolscher/NAME" +homepage = "https://github.com/JJJHolscher/jo3util" [[project.authors]] name = "Jochem Hölscher" @@ -29,7 +29,7 @@ requires = [ build-backend = "setuptools.build_meta" [tool.setuptools.packages.find] -include = ["NAME"] +include = ["jo3util"] [tool.setuptools.dynamic] readme = {file = ["README.md"], content-type = "text/markdown"} diff --git a/src/time_out.py b/src/time_out.py new file mode 100644 index 0000000..26d3cae --- /dev/null +++ b/src/time_out.py @@ -0,0 +1,35 @@ +#! /usr/bin/env python3 +# vim:fenc=utf-8 + +""" +This code is copied from https://stackoverflow.com/questions/366682/how-to-limit-execution-time-of-a-function-call/601168#601168 +""" + +import signal +from contextlib import contextmanager + + +class TimeoutException(Exception): + pass + + +@contextmanager +def time_limit(seconds): + """ + ## Usage + try: + with time_limit(10): + long_function_call() + except TimeoutException as e: + print("Timed out!") + """ + def signal_handler(signum, frame): + raise TimeoutException("Timed out!") + + signal.signal(signal.SIGALRM, signal_handler) + signal.alarm(seconds) + try: + yield + finally: + signal.alarm(0) + diff --git a/tests/__init__.py b/tests/__init__.py index 7ac2628..207b9b0 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1 +1 @@ -from .test_main import * +from .test_time_out import * diff --git a/tests/test_main.py b/tests/test_main.py deleted file mode 100644 index fb57aa3..0000000 --- a/tests/test_main.py +++ /dev/null @@ -1,14 +0,0 @@ -#! /usr/bin/env python3 -# vim:fenc=utf-8 - -import unittest - -from src.main import * - - -class TestMain(unittest.TestCase): - def test_main(self): - self.assertEqual(UNITTESTS(), 0) - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_time_out.py b/tests/test_time_out.py new file mode 100644 index 0000000..5dfd045 --- /dev/null +++ b/tests/test_time_out.py @@ -0,0 +1,22 @@ +#! /usr/bin/env python3 +# vim:fenc=utf-8 + +import time +import unittest + +from src.time_out import TimeoutException, time_limit + + +class TestTimeOut(unittest.TestCase): + def test_exception(self): + with self.assertRaises(TimeoutException): + with time_limit(1): + time.sleep(2) + + def test_no_exception(self): + with time_limit(1): + time.sleep(0.5) + + +if __name__ == "__main__": + unittest.main()