{"id":7776,"library":"tendo","title":"tendo","description":"Tendo is a Python library that extends core functionality, providing tools such as transparent Unicode support for file operations, a `tee` implementation for concurrent output, and an improved `execfile` function. Its prominent `singleton` module ensures that only a single instance of a Python script or application can run at a time on a given machine, leveraging lock files for process management. As of version 0.4.0, it requires Python 3.8+ and uses `SingleInstance` as a context manager.","status":"active","version":"0.4.0","language":"en","source_language":"en","source_url":"https://github.com/pycontribs/tendo","tags":["singleton","locking","process management","utilities"],"install":[{"cmd":"pip install tendo","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"note":"As of v0.4.0, SingleInstance is primarily designed to be used as a context manager.","wrong":"from tendo import singleton; me = singleton.SingleInstance()","symbol":"SingleInstance","correct":"from tendo.singleton import SingleInstance"}],"quickstart":{"code":"import time\nimport os\nfrom tendo.singleton import SingleInstance, SingleInstanceException\n\n# To demonstrate, use a unique flavor_id for this quickstart example.\n# In a real application, you might use a consistent string like 'my_app_name'\n# or rely on the default (based on script path) if appropriate.\n\ntry:\n    # Acquire a single instance lock. If another instance is running, an exception is raised.\n    with SingleInstance(flavor_id=\"my_tendo_quickstart_app\"):\n        print(\"Application started. This instance is the only one running.\")\n        print(\"Lock file location (typically in temp directory): .tendo-my_tendo_quickstart_app.lock\")\n        print(\"Sleeping for 10 seconds. Try running this script again in another terminal to see the SingleInstanceException.\")\n        time.sleep(10)\n        print(\"Application finished.\")\nexcept SingleInstanceException:\n    print(\"Another instance of this application with the same flavor_id is already running.\")\n    print(\"Exiting as only one instance is allowed.\")\nexcept Exception as e:\n    print(f\"An unexpected error occurred: {e}\")","lang":"python","description":"This quickstart demonstrates how to use `tendo.singleton.SingleInstance` as a context manager to ensure only one instance of a Python script runs at a time. If a second instance attempts to acquire the lock, a `SingleInstanceException` is raised."},"warnings":[{"fix":"Update your code to use `with SingleInstance():` instead of `me = SingleInstance()`.","message":"The `tendo.singleton.SingleInstance` class was refactored in v0.4.0 to be a context manager. Direct instantiation without `with` is no longer the recommended or functional pattern.","severity":"breaking","affected_versions":"0.4.0+"},{"fix":"Ensure your Python environment is version 3.8 or newer before installing or upgrading to `tendo` v0.4.0+.","message":"The minimum required Python version for `tendo` was raised from Python 3.6 to Python 3.8.","severity":"breaking","affected_versions":"0.4.0+"},{"fix":"Upgrade `tendo` to version 0.3.0 or higher. If unable to upgrade, avoid using Python 3.9+ with older `tendo` versions.","message":"Older versions of `tendo` (prior to v0.3.0) used the deprecated 'U' mode in `open()` calls, which was removed in Python 3.9 and would cause errors.","severity":"deprecated","affected_versions":"<0.3.0 (when used with Python 3.9+)"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Upgrade `tendo` to the latest version. The refactoring to use a context manager in v0.4.0 and other internal improvements address such shutdown issues more robustly.","cause":"This error, often occurring during script shutdown, indicates that the `sys` module was garbage collected before `tendo.singleton.SingleInstance.__del__` could clean up its resources, particularly in Python 3.4+ with older `tendo` versions.","error":"ImportError: import of 'sys' halted; None in sys.modules"},{"fix":"This is often intended behavior. If you only want one instance, ensure previous runs are terminated. If you want multiple distinct instances of the same script, provide a unique `flavor_id` to `SingleInstance(flavor_id='unique_id')`. Wrap your `SingleInstance` usage in a `try...except SingleInstanceException` block to handle this gracefully.","cause":"You are attempting to run a script that uses `tendo.singleton.SingleInstance` (with a specific `flavor_id` or default lock based on script path) while another instance of the same script is already active on the system.","error":"SingleInstanceException: Another instance is already running, quitting."}]}