{"id":37424044,"url":"https://github.com/erikvanzijst/interruptingcow","last_synced_at":"2026-01-16T06:10:51.621Z","repository":{"id":152971551,"uuid":"10491924","full_name":"erikvanzijst/interruptingcow","owner":"erikvanzijst","description":"Interruptingcow is a generic utility that can relatively gracefully interrupt your Python code when it doesn't execute within a specific number of seconds.","archived":false,"fork":false,"pushed_at":"2014-08-16T22:22:49.000Z","size":164,"stargazers_count":6,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-04-14T03:06:49.992Z","etag":null,"topics":["interrupt","interrupter","python","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erikvanzijst.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-06-05T00:40:27.000Z","updated_at":"2023-04-14T04:05:43.608Z","dependencies_parsed_at":"2023-04-14T04:05:43.486Z","dependency_job_id":null,"html_url":"https://github.com/erikvanzijst/interruptingcow","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/erikvanzijst/interruptingcow","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvanzijst%2Finterruptingcow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvanzijst%2Finterruptingcow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvanzijst%2Finterruptingcow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvanzijst%2Finterruptingcow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erikvanzijst","download_url":"https://codeload.github.com/erikvanzijst/interruptingcow/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikvanzijst%2Finterruptingcow/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28477633,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T03:13:13.607Z","status":"ssl_error","status_checked_at":"2026-01-16T03:11:47.863Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["interrupt","interrupter","python","python3"],"created_at":"2026-01-16T06:10:50.644Z","updated_at":"2026-01-16T06:10:51.614Z","avatar_url":"https://github.com/erikvanzijst.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Interrupting Cow\n================\n\nInterruptingcow is a generic utility that can relatively gracefully interrupt\nyour Python code when it doesn't execute within a specific number of seconds::\n\n    from interruptingcow import timeout\n\n    try:\n        with timeout(5, exception=RuntimeError):\n            # perform a potentially very slow operation\n            pass\n    except RuntimeError:\n        print \"didn't finish within 5 seconds\"\n\nTimeouts are specified in seconds (as floats with theoretical microsecond\nprecision).\n\n\nInstallation\n------------\n::\n\n    $ pip install interruptingcow\n\n\nReentrant\n---------\n\nInterruptingcow is fully reentrant, which means that you can have nested\ntimeouts::\n\n    from interruptingcow import timeout\n\n    class Outer(RuntimeError): pass\n\n    class Inner(RuntimeError): pass\n\n    try:\n        with timeout(20.0, Outer):\n            try:\n                with timeout(1.0, Inner):\n                    # some expensive operation\n                    try_the_expensive_thing()\n            except Inner:\n                do_the_cheap_thing_instead()\n\n    except Outer:\n        print 'Program as a whole failed to return in 20 secs'\n\nNested timeouts allow a large outer timeout to contain smaller timeouts. If the\ninner timeout is larger than the outer timeout, it is treated as a no-op.\n\n\nFunction Decorators\n-------------------\n\nInterruptingcow can be used both as inline with-statements, as shown in the\nabove examples, as well as function decorator::\n\n    from interruptingcow import timeout\n\n    @timeout(.5)\n    def foo():\n        with timeout(.3):\n            # some expensive operation\n            pass\n\n\nQuotas\n------\n\nYou can allocate a quota of time and then share it across multiple invocations\nto ``timeout()``. This is especially useful if you need to use timeouts inside\na loop::\n\n    from interruptingcow import timeout, Quota\n\n    quota = Quota(1.0)\n    for i in something:\n        try:\n            with timeout(quota, RuntimeError):\n                # perform a slow operation\n                pass\n        except RuntimeError:\n            # do a cheaper thing instead\n\nHere the first iterations of the loop will be able to perform the expensive\noperation, until the shared quota of 1 second runs out and then the remaining\niterations will perform the cheaper alternative.\n\nA single quota instance can also be shared across all calls to ``timeout()``\nyour application makes (including nested calls), to give place an upper bound\non the total runtime, regardless of how many calls to ``timeout()`` you have.\n\nCaveats\n-------\n\nInterruptingcow uses ``signal(SIGALRM)`` to let the operating system interrupt\nprogram execution. This has the following limitations:\n\n1. Python signal handlers only apply to the main thread, so you cannot use this\n   from other threads\n2. You must not use this in a program that uses ``SIGALRM`` itself (this\n   includes certain profilers)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferikvanzijst%2Finterruptingcow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferikvanzijst%2Finterruptingcow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferikvanzijst%2Finterruptingcow/lists"}