{"id":5357,"library":"ovld","title":"ovld: Overloading Python Functions","description":"Ovld is a Python library that provides fast and feature-rich multiple dispatch for functions using type annotations. Unlike Python's built-in `functools.singledispatch`, `ovld` supports dispatching on multiple arguments, custom predicates, and value-based dispatch. It aims to simplify code that would otherwise rely on complex `if-elif` chains or `isinstance` checks for different argument types. The library is actively maintained, with the current version being 0.5.15, and offers performance superior to other multiple dispatch libraries.","status":"active","version":"0.5.15","language":"en","source_language":"en","source_url":"https://github.com/breuleux/ovld","tags":["overloading","multiple dispatch","type hinting","decorators","recursion","performance"],"install":[{"cmd":"pip install ovld","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"ovld","correct":"from ovld import ovld"},{"note":"Used for variant-aware recursive calls within overloaded functions.","symbol":"recurse","correct":"from ovld import ovld, recurse"},{"note":"For creating value-dependent types for dispatching.","symbol":"Dependent","correct":"from ovld.dependent import Dependent"},{"note":"Commonly used with ovld for dispatching on specific values.","symbol":"Literal","correct":"from typing import Literal"}],"quickstart":{"code":"from ovld import ovld, recurse\nfrom typing import Literal\n\n@ovld\ndef process(x: str): \n    return f\"Processing string: {x!r}\"\n\n@ovld\ndef process(x: int):\n    return f\"Processing integer: {x}\"\n\n@ovld\ndef process(x: int, y: int):\n    return f\"Processing two integers: {x}, {y}\"\n\n@ovld\ndef process(x: Literal[0]):\n    return \"Special case: zero\"\n\n# Example of recursive overload\n@ovld\ndef add_nested(x: list, y: list):\n    return [recurse(a, b) for a, b in zip(x, y)]\n\n@ovld\ndef add_nested(x: int, y: int):\n    return x + y\n\nassert process(\"hello\") == \"Processing string: 'hello'\"\nassert process(10) == \"Processing integer: 10\"\nassert process(1, 2) == \"Processing two integers: 1, 2\"\nassert process(0) == \"Special case: zero\"\n\nassert add_nested([1, 2], [3, 4]) == [4, 6]\nassert add_nested([1, [2]], [3, [4]]) == [4, [6]]\n","lang":"python","description":"This quickstart demonstrates basic function overloading for different types and argument counts. It also includes an example of recursive dispatch using `recurse`, which is essential for ensuring that nested calls respect `ovld`'s dispatch mechanism and any defined variants."},"warnings":[{"fix":"Replace direct recursive calls (e.g., `my_func(a, b)`) with `recurse(a, b)` inside `@ovld` decorated functions.","message":"When defining recursive `ovld` functions, always use `recurse(...)` instead of directly calling the function by its name (e.g., `my_func(...)`). `recurse` is specially designed to work with `ovld`'s variant system, ensuring that recursive calls correctly dispatch to the appropriate variant of the current `ovld` object. Direct calls will bypass this mechanism.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure the first argument to `Dependent` is a valid Python type that acts as a bound, and the second argument is a callable predicate that operates on the argument's value.","message":"Dependent types created with `ovld.dependent.Dependent` require a type bound as their first argument (e.g., `Dependent[int, lambda n: n > 0]`). The provided check function is applied to the *value* of the argument at runtime, not its static type. Incorrectly specifying the type bound or the check predicate can lead to unexpected dispatch behavior or runtime errors.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Be aware of this limitation and implement additional runtime checks if strict validation of all elements in generic collections is required, or define more specific overloads.","message":"When using `ovld` to dispatch on generic collection types (e.g., `list[str]`), `ovld` currently only checks the type of the *first element* of the collection. It does not perform a full validation of all elements within the collection against the generic type parameter. This can lead to a dispatch if the first element matches, even if subsequent elements do not.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If intermediate results need processing, wrap the `recurse()` calls explicitly or define custom dispatch logic instead of relying solely on `postprocess`.","message":"The `postprocess` argument in the `@ovld` decorator (or `ovld.dispatch`) only applies to the *top-level* call of the overloaded function. Intermediate recursive calls made via `recurse()` will *not* have their results processed by the `postprocess` function.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-13T00:00:00.000Z","next_check":"2026-07-12T00:00:00.000Z"}