API Reference
This page lists everything that the wrapt package exposes as part of its public API, with a short description of each item and pointers into the rest of the documentation for further detail.
Public API Contract
Everything that wrapt considers part of its public API is re-exported
from the top-level wrapt module and listed in wrapt.__all__. The
intended way to use the package is to import these names from wrapt
directly.
import wrapt
@wrapt.synchronized
def function():
...
The submodules of the wrapt package (for example wrapt.wrappers,
wrapt.decorators, wrapt.synchronization, wrapt.proxies,
wrapt.patches, wrapt.importer, wrapt.caching,
wrapt.signature, wrapt.weakrefs) are private implementation
detail. The internal layout of these modules, and the location of any
individual name within them, can change between releases without notice.
If a name is not listed below, or is not exposed from the top-level
wrapt module, do not import it.
A practical example of why this matters: in version 2.2.0 the
synchronized decorator was moved from wrapt.decorators to a new
wrapt.synchronization submodule as part of a code reorganisation.
Code that was importing wrapt.synchronized continued to work
unchanged. Code that had reached in and imported
wrapt.decorators.synchronized directly broke. The first form is
supported; the second form was never part of the public API.
Public API Surface
The names below are everything currently exported from wrapt. They
are grouped by area of functionality rather than by submodule. Each
entry has a short description and, where applicable, a pointer to the
relevant section of the rest of the documentation.
Decorator Factories
wrapt.decoratorThe primary decorator factory for building well-behaved decorators. Applied to a wrapper function of the form
wrapper(wrapped, instance, args, kwargs), it produces a decorator that preserves introspection, descriptor binding, signatures, and applies correctly to plain functions, instance methods, class methods, static methods, and classes. Supports optionalenabled,adapterandproxykeyword arguments. See Function Decorators for the full guide.wrapt.function_wrapperA lightweight subset of
wrapt.decoratorintended for the straightforward case of wrapping a function with a wrapper of the same shape, with no need forenabled,adapteror a customproxy. Commonly used together withwrapt.wrap_function_wrapperandwrapt.patch_function_wrapperfor monkey patching. See Monkey Patching for usage in patching scenarios.wrapt.AdapterFactoryBase class for factory objects that compute a signature adapter at decoration time from the function being wrapped. Used as the
adapterargument towrapt.decorator. The newerwrapt.with_signaturemechanism is the recommended replacement; see Bundled Decorators for details.wrapt.adapter_factoryConvenience callable that wraps a plain function as an
AdapterFactory. Equivalent to a factory that returns whatever its argument returns when called with the wrapped function. Superseded bywrapt.with_signature(factory=...).wrapt.bind_state_to_wrapperDescriptor decorator that supports the pattern of implementing a decorator as a method on a state-holding class. When the wrapper method is accessed through an instance, the instance is automatically attached as a named attribute on the resulting wrapper, making per-decoration state reachable from the decorated function. See the “Binding State to a Wrapper” section of Bundled Decorators.
Bundled Decorators
wrapt.synchronizedDecorator and context manager that associates a lock with a callable or context. Detects synchronous versus asynchronous use automatically and creates either a
threading.RLockor anasyncio.Lockas appropriate. May also be supplied with an explicit lock primitive. See the “Thread Synchronization” section of Bundled Decorators.wrapt.mark_as_syncPass-through wrapper that asserts the effective calling convention of its target is synchronous, so that
inspect.iscoroutinefunction()(and code that consults it, includingwrapt.synchronized) reports it that way. Useful when an inner decorator has collapsed anasync definto a sync callable. See “Calling Convention Markers and Adapters” in Bundled Decorators.wrapt.mark_as_asyncSymmetric to
mark_as_sync. Marks the target as asynchronous (or as an async generator, via thegeneratorkeyword) without altering how it is called. See “Calling Convention Markers and Adapters” in Bundled Decorators.wrapt.async_to_syncAdapts an async callable so it can be invoked synchronously. Each call runs the coroutine to completion via
asyncio.run()and marks the resulting wrapper as synchronous for introspection purposes. See “Bridging between conventions” in Bundled Decorators.wrapt.sync_to_asyncAdapts a synchronous callable so it can be awaited. Each call schedules the work on the default executor via
loop.run_in_executor()and marks the resulting wrapper as asynchronous for introspection purposes. See “Bridging between conventions” in Bundled Decorators.wrapt.with_signatureOverrides the signature reported by introspection tools (
inspect.signature(),help(), IDE tooling) for a wrapped callable without mutating the wrapped function itself. Accepts a prototype function, aninspect.Signatureobject, or a factory callable. The modern replacement for theadapterargument ofwrapt.decorator. See the “Signature Override” section of Bundled Decorators.wrapt.lru_cacheA drop-in replacement for
functools.lru_cachethat handles instance methods correctly. Each instance maintains its own cache stored as an attribute on the instance, so instances do not need to be hashable, each instance gets its ownmaxsizebudget, and caches are released when the instance is garbage collected. For plain functions, class methods, and static methods, behaves the same asfunctools.lru_cache. See the “LRU Cache” section of Bundled Decorators.
Monkey Patching
wrapt.resolve_pathResolves a dotted attribute path on a target object (which may be a module, class, instance, or the name of a module to import) and returns a
(parent, attribute, original)tuple suitable for subsequent patching. See Monkey Patching.wrapt.apply_patchThin convenience over
setattrfor setting a replacement attribute on a parent object as the final step of a patch. Pairs withwrapt.resolve_path.wrapt.wrap_objectReplaces an attribute on a target object with the result of calling a factory function on the original attribute value. The typical factory is
wrapt.FunctionWrapperor a subclass.wrapt.wrap_object_attributeVariant of
wrap_objectthat wraps an instance attribute by installing a descriptor on the owning class. Useful when the attribute is not defined at the class level itself.wrapt.wrap_function_wrapperConvenience wrapper that combines
resolve_pathandwrap_objectwithFunctionWrapperto patch a function attribute with a wrapper of thewrapper(wrapped, instance, args, kwargs)form. If the target module name is suffixed with?, the patch is deferred via a post-import hook until the module is imported.wrapt.patch_function_wrapperDecorator form of
wrap_function_wrapper. Apply it to a wrapper function and the wrapper will be installed on the named attribute of the target. Supports the same deferred?syntax and an optionalenabledflag.wrapt.transient_function_wrapperDecorator that installs a wrapper on a target attribute only for the duration of a single call to the decorated function. Useful for scoped test fixtures and similar narrow patches.
Post Import Hooks
wrapt.register_post_import_hookRegisters a callback to be invoked when a named module is imported, or immediately if the module is already loaded. The first registration installs an import hook into
sys.meta_pathautomatically. See Monkey Patching.wrapt.when_importedDecorator form of
register_post_import_hook. Apply it to a function with a singlemoduleargument to have the function invoked when the named module is imported.wrapt.notify_module_loadedManually fires any post-import hooks registered against the given module. The import hook finder calls this automatically; this function exists for cases where modules are loaded by other means.
wrapt.discover_post_import_hooksRegisters post-import hooks declared as entry points under a given group name in package metadata. Allows third-party packages to register hooks declaratively.
Object Proxies
wrapt.BaseObjectProxyThe transparent object proxy base class. Forwards attribute access, descriptor binding, equality, hashing, and most special methods to the wrapped object stored on
__wrapped__. The recommended base for custom proxy subclasses. See Proxies and Wrappers and the “Object Proxies” section of Type Hinting.wrapt.ObjectProxyA thin subclass of
BaseObjectProxyretained for backward compatibility. The only behavioural difference fromBaseObjectProxyis that it also forwards__iter__. New code that does not need this can useBaseObjectProxydirectly.wrapt.AutoObjectProxyA proxy that dynamically adds the appropriate special dunder methods (
__call__,__iter__,__await__, descriptor methods, and so on) for the wrapped object at construction time. Has higher per-instance overhead thanBaseObjectProxybecause a fresh subclass is generated for each instance. Useful when the set of methods needed cannot be known up front.wrapt.LazyObjectProxyA proxy whose wrapped object is created lazily on first use, via a callback supplied at construction time. Builds on
AutoObjectProxyand accepts an optionalinterfacekeyword to declare the set of dunder methods to forward without having to instantiate the wrapped object first.wrapt.CallableObjectProxyA proxy subclass that adds
__call__forwarding for cases where the wrapped object is known to be callable but the rest ofAutoObjectProxy’s flexibility is not needed.wrapt.PartialCallableObjectProxyA proxy that combines a callable with a set of pre-bound positional and keyword arguments, analogous to
functools.partialbut implemented as an object proxy.wrapt.partialFactory function that returns a
PartialCallableObjectProxy, providing a drop-in replacement forfunctools.partialwith better introspection.wrapt.lazy_importReturns a
LazyObjectProxyconfigured to import a named module (and optionally retrieve a specific attribute from it) the first time the proxy is used.
Function Wrappers
wrapt.FunctionWrapperThe runtime wrapper class produced by
@wrapt.decoratorand@wrapt.function_wrapperwhen applied to a function. Handles descriptor binding, theenabledpredicate, and dispatch to the user-supplied wrapper. May be constructed directly when more control is needed. See Proxies and Wrappers and the “Function Wrappers” section of Type Hinting.wrapt.BoundFunctionWrapperThe bound counterpart of
FunctionWrapper, produced when a decorated method is accessed via the descriptor protocol on an instance or class. Rarely constructed directly; appears in type annotations and during introspection of bound decorated methods.
Weak References
wrapt.WeakFunctionProxyA proxy that holds a weak reference to a function or bound method. Unlike
weakref.proxy, it correctly handles bound methods, which are transient objects, by holding weak references to the underlying instance and unbound function separately and rebinding on call. Accepts an optional callback invoked when the underlying object is garbage collected.
Type Hints and the Public API
Type hints for wrapt are shipped as a single __init__.pyi stub
file in the wrapt-stubs distribution. The stub declares only the
names that the top-level wrapt module exposes. There are no
.pyi files for the implementation submodules.
This has a direct, practical consequence: if you import a name from one
of the submodules instead of from wrapt, static type checkers will
not see any annotations for it, even if there is an equivalent
annotated name available from wrapt. The two forms below behave
the same at runtime but differ for the type checker:
import wrapt
from wrapt.synchronization import synchronized # not type-hinted
@wrapt.synchronized # type-checked
def good():
...
@synchronized # not type-checked
def bad():
...
For type inference to work, always import from wrapt. See
Type Hinting for a full discussion of how the type hints work and
what they do and do not propagate.
C Extension and Pure Python Implementations
A small number of the most performance-sensitive classes in wrapt
have two implementations: a C extension module compiled from
src/wrapt/_wrappers.c, and an equivalent pure Python implementation
in wrapt.wrappers. The classes that have a C implementation are:
BaseObjectProxy(the C extension exposes this asObjectProxy; wrapt imports it under theBaseObjectProxyname)CallableObjectProxyPartialCallableObjectProxyFunctionWrapperBoundFunctionWrapper
When you import these from the top-level wrapt module, the C
extension version is used whenever it is available. The pure Python
implementation is used only as a fallback when the C extension cannot
be imported.
All of the other names listed above (AutoObjectProxy,
LazyObjectProxy, ObjectProxy, the decorator factories, the
bundled decorators, the monkey-patching helpers, the post-import hook
machinery, WeakFunctionProxy, and so on) are pure Python code
built on top of those core classes. They transparently use whichever
implementation of the core classes is active.
How the choice is made
The wrapt package on PyPI ships binary wheels with the C extension
pre-compiled for the common Python versions and platforms. If
wrapt is installed from one of those wheels (which is what pip
or uv will normally select), the C extension is present and is used
by default.
When wrapt is installed from the source distribution (the
.tar.gz on PyPI), the build system attempts to compile the C
extension. If a working C compiler is not available, the extension is
silently omitted from the install and the package falls back to the
pure Python implementation at import time.
So in a normal installation you will be using the C extension. The pure Python implementation only comes into play when no wheel is available for your platform and your environment has no compiler, or when you deliberately disable the extension.
Forcing the pure Python implementation
There are three escalating ways to make wrapt use the pure Python implementation. Pick the least invasive one that fits your situation.
1. Disable the C extension at runtime. Set
WRAPT_DISABLE_EXTENSIONS=true in the environment before wrapt
is imported. The C extension may be installed, but wrapt will not
import it and will use the pure Python implementation instead. This
is the simplest option and is reversible without touching the install.
2. Disable the C extension at install time. Force installation
from the source distribution and set WRAPT_INSTALL_EXTENSIONS=false
in the environment for the build, so that the extension is not built
even if a compiler is available. For example, with pip:
WRAPT_INSTALL_EXTENSIONS=false pip install --no-binary=wrapt wrapt
3. Install from source with no compiler available. Force installation from the source distribution; if no C compiler is present, the build of the extension is treated as optional and the package is installed with only the pure Python implementation.
pip install --no-binary=wrapt wrapt
Using pure Python core classes while keeping the C extension
If you need the C extension to remain active for the rest of the
package but specifically want the pure Python implementation of
BaseObjectProxy or FunctionWrapper (for example to subclass
them in a way that depends on Python-level implementation details that
the C extension does not expose), the only way to do this is to
import them directly from the private wrapt.wrappers submodule:
from wrapt.wrappers import ObjectProxy as BaseObjectProxy
from wrapt.wrappers import FunctionWrapper
This sidesteps the normal public API contract and comes with several caveats. You should be aware of all of them before relying on this approach:
These names live in a private submodule. The module path
wrapt.wrappersis not part of the public API and may be reorganised in a future release.Type hints are not available for names imported this way (see the “Type Hints and the Public API” section above).
Only these two specific classes can be replaced with their pure Python variants in this way. Everything else that wrapt exposes – including
wrapt.ObjectProxy,wrapt.AutoObjectProxy,wrapt.LazyObjectProxy,wrapt.decorator,wrapt.function_wrapper,wrapt.synchronized, and the monkey-patching helpers – is built on top of the C extension versions of the core classes and will continue to use them.
If you find yourself needing this, consider whether disabling the C
extension entirely via WRAPT_DISABLE_EXTENSIONS would actually
serve you better. The case for the targeted import is narrow: it is
appropriate only when you genuinely need both implementations to be
present in the same process.