{"id":345,"library":"decorator","title":"decorator","description":"A Python module that simplifies the creation of decorators, ensuring they preserve the original function's signature. Current version: 5.2.1, released on February 24, 2025. Maintained by Michele Simionato. Requires Python 3.8 or higher.","status":"active","version":"5.2.1","language":"python","source_language":"en","source_url":"https://github.com/micheles/decorator","tags":["decorators","Python","function decorators","signature preservation"],"install":[{"cmd":"pip install decorator","lang":"bash","label":"Install decorator"}],"dependencies":[],"imports":[{"note":"Importing the 'decorator' function from the 'decorator' module.","symbol":"decorator","correct":"from decorator import decorator"}],"quickstart":{"code":"import time\nimport logging\nfrom decorator import decorator\n\n@decorator\ndef warn_slow(func, timelimit=60, *args, **kw):\n    t0 = time.time()\n    result = func(*args, **kw)\n    dt = time.time() - t0\n    if dt > timelimit:\n        logging.warning('%s took %d seconds', func.__name__, dt)\n    else:\n        logging.info('%s took %d seconds', func.__name__, dt)\n    return result\n\n@warn_slow  # warn if it takes more than 1 minute\ndef preprocess_input_files(inputdir, tempdir):\n    # Function implementation here\n    pass\n\n@warn_slow(timelimit=600)  # warn if it takes more than 10 minutes\ndef run_calculation(tempdir, outdir):\n    # Function implementation here\n    pass\n\n# Usage\npreprocess_input_files('/path/to/input', '/path/to/temp')\nrun_calculation('/path/to/temp', '/path/to/output')","lang":"python","description":"An example demonstrating how to define and use a decorator with the 'decorator' module."},"warnings":[{"fix":"Use 'from decorator import decorator' to correctly import the function.","message":"Importing the 'decorator' function as 'import decorator' is incorrect and will lead to an ImportError.","severity":"breaking","affected_versions":"all"},{"fix":"Ensure your Python environment is version 3.8 or higher before using the 'decorator' module.","message":"The 'decorator' module requires Python 3.8 or higher. Using it with earlier versions will result in a VersionError.","severity":"gotcha","affected_versions":"all"},{"fix":"It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv","message":"Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T13:11:59.649Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the library using pip: `pip install decorator`","cause":"The 'decorator' library is not installed in your Python environment.","error":"ModuleNotFoundError: No module named 'decorator'"},{"fix":"Ensure you are using `decorator.decorate` correctly to create the decorator, or that your custom decorator function returns a callable. For example, to create a simple decorator preserving signature: `from decorator import decorator\n@decorator\ndef my_decorator(func, *args, **kwargs):\n    print('Before function call')\n    result = func(*args, **kwargs)\n    print('After function call')\n    return result\n\n@my_decorator\ndef my_function():\n    return 'Hello'`","cause":"This error often occurs when you attempt to use the 'decorator' module itself or an object returned by it directly as a decorator without properly applying the `decorate` function to wrap your function, or when a decorator function is not correctly structured to return a callable.","error":"TypeError: 'decorator' object is not callable"},{"fix":"Ensure that the expression after `@` is a valid callable (e.g., a function name, `module.function_name`, or a function call that returns a callable). Complex expressions like `@(lambda f: f)` or chained calls like `@f()()` are not allowed directly. You might need to assign the result of a complex expression to a variable first, then use that variable as the decorator. The `decorator` library's `decorate` function is designed to handle more complex programmatic decorator creation, but the `@` syntax itself has strict rules. Example of incorrect vs. correct usage:\n```python\n# Incorrect\n# @(lambda f: f)\n# def my_func(): pass\n\n# Correct (assign lambda to a name first)\nidentity_decorator = lambda f: f\n@identity_decorator\ndef my_func():\n    pass\n\n# If using 'decorator' library to build a decorator factory:\nfrom decorator import decorator\n\ndef my_decorator_factory(arg):\n    @decorator\n    def my_actual_decorator(func, *args, **kwargs):\n        print(f'Decorator arg: {arg}')\n        return func(*args, **kwargs)\n    return my_actual_decorator\n\n@my_decorator_factory('test')\ndef another_func():\n    return 'World'\n```","cause":"This usually arises when the expression immediately following the `@` symbol in a decorator definition is not a simple dotted name or a function call, which are the only forms allowed by Python's grammar for decorators.","error":"SyntaxError: invalid syntax"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":1,"disk_size":"17.8M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":1,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.1,"disk_size":"19.6M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.1,"disk_size":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1,"disk_size":"11.5M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.3,"disk_size":"11.2M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.1,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":1,"disk_size":"17.3M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":1,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}