diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..575f578 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,23 @@ +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version, and other tools you might need +build: + os: ubuntu-24.04 + tools: + python: "3.13" + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + +# Optionally, but recommended, +# declare the Python requirements required to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +# python: +# install: +# - requirements: docs/requirements.txt + diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/caching.rst b/docs/caching.rst new file mode 100644 index 0000000..d2dfa51 --- /dev/null +++ b/docs/caching.rst @@ -0,0 +1,91 @@ +Caching & Optimization +====================== + +This section covers tools for caching and optimizing function execution. + +@memoize +-------- +Cache the results of a function. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @memoize + def expensive_calculation(x, y): + # Perform a costly operation + return x * y + +**Usage as a Function:** + +.. code-block:: python + + def expensive_calculation(x, y): + # Perform a costly operation + return x * y + + memoized_function = memoize(expensive_calculation) + result = memoized_function(5, 10) # Caches the result for (5, 10) + +@cache +------ +Cache the results of a function for a specified duration. + +**Parameters:** +- **duration (timedelta):** The time duration for which the cached result is valid. +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + from datetime import timedelta + + @cache(duration=timedelta(minutes=5)) + def fetch_data(): + # Retrieve data from an API or database + return {"key": "value"} + +**Usage as a Function:** + +.. code-block:: python + + from datetime import timedelta + + def fetch_data(): + # Retrieve data from an API or database + return {"key": "value"} + + cached_function = cache(duration=timedelta(minutes=5))(fetch_data) + result = cached_function() # Caches the result for 5 minutes + +@once +----- +Ensure a function is executed only once. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @once + def initialize_service(): + # Perform a one-time initialization + print("Service initialized") + +**Usage as a Function:** + +.. code-block:: python + + def initialize_service(): + # Perform a one-time initialization + print("Service initialized") + + one_time_function = once(initialize_service) + one_time_function() # Executes the function + one_time_function() # Does nothing, as the function has already been executed \ No newline at end of file diff --git a/docs/concurrency.rst b/docs/concurrency.rst new file mode 100644 index 0000000..97dca57 --- /dev/null +++ b/docs/concurrency.rst @@ -0,0 +1,54 @@ +Concurrency +=========== + +This section covers tools for managing concurrency. + +@run_in_thread +-------------- +Run a function asynchronously in a separate thread. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @run_in_thread + def background_task(): + print("This task is running in a separate thread.") + +**Usage as a Function:** + +.. code-block:: python + + def background_task(): + print("This task is running in a separate thread.") + + threaded_function = run_in_thread(background_task) + threaded_function() # Runs in a separate thread + +@transactional +-------------- +Ensure atomic operations within a transaction. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @transactional + def update_user_balance(user_id, amount): + print(f"Updating user {user_id} balance by {amount}.") + +**Usage as a Function:** + +.. code-block:: python + + def update_user_balance(user_id, amount): + print(f"Updating user {user_id} balance by {amount}.") + + transactional_function = transactional(update_user_balance) + transactional_function(42, 100) # Ensures atomic execution \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..5a51a83 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,28 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'PythonWrap' +copyright = '2025, Mahmoud Ahmed' +author = 'Mahmoud Ahmed' +release = '0.1.0' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [] + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'alabaster' +html_static_path = ['_static'] diff --git a/docs/debugging.rst b/docs/debugging.rst new file mode 100644 index 0000000..8f5e6d8 --- /dev/null +++ b/docs/debugging.rst @@ -0,0 +1,108 @@ +Debugging & Logging +=================== + +This section covers tools for debugging and logging function execution. + +@log_args +--------- +Log the arguments passed to a function. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @log_args + def calculate_sum(a, b): + return a + b + +**Usage as a Function:** + +.. code-block:: python + + def calculate_sum(a, b): + return a + b + + logged_function = log_args(calculate_sum) + result = logged_function(10, 20) # Logs arguments: a=10, b=20 + +@log_return +----------- +Log the return value of a function. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @log_return + def fetch_data(): + return {"key": "value"} + +**Usage as a Function:** + +.. code-block:: python + + def fetch_data(): + return {"key": "value"} + + logged_function = log_return(fetch_data) + result = logged_function() # Logs return value: {"key": "value"} + +@trace +------ +Log the call stack trace of a function. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @trace + def perform_task(): + # Perform a task + print("Task performed") + +**Usage as a Function:** + +.. code-block:: python + + def perform_task(): + # Perform a task + print("Task performed") + + traced_function = trace(perform_task) + traced_function() # Logs the call stack trace + +@audit +------ +Provide comprehensive auditing for function calls. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @audit + def process_data(data): + # Process the input data + return len(data) + +**Usage as a Function:** + +.. code-block:: python + + def process_data(data): + # Process the input data + return len(data) + + audited_function = audit(process_data) + result = audited_function(["item1", "item2"]) # Logs arguments, return value, and execution details \ No newline at end of file diff --git a/docs/development_tools.rst b/docs/development_tools.rst new file mode 100644 index 0000000..28cc00e --- /dev/null +++ b/docs/development_tools.rst @@ -0,0 +1,107 @@ +Development Tools +================= + +This section covers tools for development and testing. + +@deprecate +---------- +Mark a function as deprecated. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @deprecate + def old_function(): + print("This function is deprecated.") + +**Usage as a Function:** + +.. code-block:: python + + def old_function(): + print("This function is deprecated.") + + deprecated_function = deprecate(old_function) + deprecated_function() # Outputs a deprecation warning + +@no_debug +--------- +Disable debug output for a function. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @no_debug + def sensitive_function(): + print("This is a production-safe function.") + +**Usage as a Function:** + +.. code-block:: python + + def sensitive_function(): + print("This is a production-safe function.") + + no_debug_function = no_debug(sensitive_function) + no_debug_function() # Executes without debug output + +@mock_data +---------- +Mock the output of a function for testing. + +**Parameters:** +- **data (Any):** The data to return when the function is called. Can be a value or a callable. +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @mock_data(return_value={"id": 1, "name": "Mock User"}) + def get_user_data(user_id): + pass + +**Usage as a Function:** + +.. code-block:: python + + def get_user_data(user_id): + pass + + mocked_function = mock_data(return_value={"id": 1, "name": "Mock User"})(get_user_data) + result = mocked_function(42) # Returns {"id": 1, "name": "Mock User"} + +@rate_limit +----------- +Limit the frequency of function execution. + +**Parameters:** +- **calls (int):** The maximum number of calls allowed within the specified period. +- **period (float):** The time period (in seconds) for rate limiting. +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @rate_limit(calls=5, period=10) + def api_request(): + print("API request made") + +**Usage as a Function:** + +.. code-block:: python + + def api_request(): + print("API request made") + + rate_limited_function = rate_limit(calls=5, period=10)(api_request) + rate_limited_function() # Enforces rate limiting \ No newline at end of file diff --git a/docs/error_handling.rst b/docs/error_handling.rst new file mode 100644 index 0000000..6605f4f --- /dev/null +++ b/docs/error_handling.rst @@ -0,0 +1,116 @@ +Error Handling & Reliability +============================ + +This section covers tools for improving the reliability of your functions. + +@retry +------ +Retry a function if it fails. + +**Parameters:** +- **max_attempts (int):** The maximum number of retry attempts. Default is ``3``. +- **delay (float):** The delay (in seconds) between retry attempts. Default is ``1.0``. +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @retry(max_attempts=3, delay=2.0) + def unreliable_function(): + # Code that may fail + pass + +**Usage as a Function:** + +.. code-block:: python + + def unreliable_function(): + # Code that may fail + pass + + retried_function = retry(max_attempts=3, delay=2.0)(unreliable_function) + retried_function() # Retries up to 3 times with a 2-second delay + +@retry_on_exception +------------------- +Retry a function only when specific exceptions are raised. + +**Parameters:** +- **exceptions (tuple):** One or more exception types that trigger a retry. +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @retry_on_exception(ValueError, KeyError) + def operation_with_exceptions(): + # Code that may raise exceptions + pass + +**Usage as a Function:** + +.. code-block:: python + + def operation_with_exceptions(): + # Code that may raise exceptions + pass + + retried_function = retry_on_exception(ValueError, KeyError)(operation_with_exceptions) + retried_function() # Retries only on ValueError or KeyError + +@timeout +-------- +Limit the execution time of a function. + +**Parameters:** +- **seconds (int):** The maximum execution time for the function. +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @timeout(seconds=5) + def time_sensitive_task(): + # Code that should finish within 5 seconds + pass + +**Usage as a Function:** + +.. code-block:: python + + def time_sensitive_task(): + # Code that should finish within 5 seconds + pass + + timeout_function = timeout(seconds=5)(time_sensitive_task) + timeout_function() # Raises a timeout exception if execution exceeds 5 seconds + +@revert_on_failure +------------------ +Roll back the system state if a failure occurs. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @revert_on_failure + def critical_operation(): + # Code that needs rollback on failure + pass + +**Usage as a Function:** + +.. code-block:: python + + def critical_operation(): + # Code that needs rollback on failure + pass + + revert_function = revert_on_failure(critical_operation) + revert_function() # Rolls back state on failure \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..70809f8 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,26 @@ +.. PythonWrap documentation master file, created by + sphinx-quickstart on Tue Jan 21 20:45:34 2025. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Python-Wrap's documentation! +======================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + performance + error_handling + caching + debugging + type_safety + development_tools + concurrency + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..32bb245 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/performance.rst b/docs/performance.rst new file mode 100644 index 0000000..c78e881 --- /dev/null +++ b/docs/performance.rst @@ -0,0 +1,113 @@ +Performance & Profiling +======================= + +This section covers tools for measuring and optimizing the performance of your functions. + +@timing +------- +Measure the execution time of a function. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @timing + def my_function(): + # Code to measure + pass + +**Usage as a Function:** + +.. code-block:: python + + def my_function(): + # Code to measure + pass + + timed_function = timing(my_function) + timed_function() # Logs execution time + +@profile +-------- +Profile the performance of a function. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @profile + def profile_function(): + # Function code to profile + pass + +**Usage as a Function:** + +.. code-block:: python + + def profile_function(): + # Function code to profile + pass + + profiled_function = profile(profile_function) + profiled_function() # Generates a performance profile + +@benchmark +---------- +Run a function multiple times and calculate the average execution time. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. +- **iterations (int):** The number of times to run the function. Default is ``10``. + +**Usage as a Decorator:** + +.. code-block:: python + + @benchmark + def benchmark_function(): + # Function code to benchmark + pass + +**Usage as a Function:** + +.. code-block:: python + + def benchmark_function(): + # Function code to benchmark + pass + + benchmarked_function = benchmark(benchmark_function, iterations=5) + benchmarked_function() # Calculates average execution time + +@measure_memory +--------------- +Track the memory usage of a function. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @measure_memory + def memory_intensive_function(): + # Function code that uses a lot of memory + pass + +**Usage as a Function:** + +.. code-block:: python + + def memory_intensive_function(): + # Function code that uses a lot of memory + pass + + memory_measured_function = measure_memory(memory_intensive_function) + memory_measured_function() # Logs memory usage \ No newline at end of file diff --git a/docs/type_safety.rst b/docs/type_safety.rst new file mode 100644 index 0000000..75636fe --- /dev/null +++ b/docs/type_safety.rst @@ -0,0 +1,58 @@ +Type Safety & Validation +======================== + +This section covers tools for runtime type checking and argument validation. + +@check_type +----------- +Enable runtime type checking for function arguments and return values. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @check_type + def add_numbers(a: int, b: int) -> int: + return a + b + +**Usage as a Function:** + +.. code-block:: python + + def add_numbers(a: int, b: int) -> int: + return a + b + + checked_function = check_type(add_numbers) + result = checked_function(10, 20) # Ensures types are checked at runtime + +@validate_args +-------------- +Add custom validation logic for function arguments. + +**Parameters:** +- **func (Callable):** The function to be wrapped. Automatically passed when used as a decorator. + +**Usage as a Decorator:** + +.. code-block:: python + + @validate_args + def create_user(username: str, age: int): + if age < 18: + raise ValueError("Age must be 18 or above") + print(f"User {username} created") + +**Usage as a Function:** + +.. code-block:: python + + def create_user(username: str, age: int): + if age < 18: + raise ValueError("Age must be 18 or above") + print(f"User {username} created") + + validated_function = validate_args(create_user) + validated_function("JohnDoe", 25) # Validates arguments before execution \ No newline at end of file