Intercepts#
Intercepts allows you to intercept function calls in Python and handle them in any manner you choose. For example, you can pre-process the inputs to a function, or apply post-processing on its output. Intercepts also allows you to completely replace a function with a custom implementation.
>>> increment(41)
42
>>> intercepts.register(increment, handler)
>>> increment(41)
40
>>> intercepts.unregister(increment)
>>> intercepts.register(increment, handler2)
>>> increment(41)
'The answer is: 42'
>>> intercepts.unregister_all()
Handler functions receive all paramters to the intercepted function call and
can access the intercepted function through the variable _
.
>>> def handler(num):
... result = _(num)
... return num - (result - num)
>>> def handler2(*args, **kwargs):
... result = _(*args, **kwargs)
... return f"The answer is: {result}"
The intercepts module also allows intercepting python built-in functions, such
as print
and sorted
. For best results, the intercepts module should be the
first module imported.
>>> def print_handler(message):
... return _(''.join(reversed(message)))
>>> print("Hello world")
Hello world
>>> intercepts.register(print, print_handler)
>>> print("Hello world")
dlrow olleH
Further Reading#
Installation#
For general usage, we recommend installing intercepts from PyPI using pip.
Install with pip#
Intercepts requires Python 3.7+ on Linux or Windows. There are currently no additional dependencies. To install intercepts, run:
$ pip install requests
Or, to install the latest version from github, run:
$ pip install -U git+https://github.com/dlshriver/intercepts.git@main
Get the Source#
The source code for intercepts is available on Github.
You can clone the public repository:
$ git clone git://github.com/dlshriver/intercepts.git
Or download the tarball:
$ curl -OL https://github.com/dlshriver/intercepts/tarball/main
Or, download the zip archive:
$ curl -OL https://github.com/dlshriver/intercepts/archive/main.zip
To install intercepts from source, after downloading and extracting the source code and navigating to the root of the source directory, run:
$ pip install .
Quickstart#
Ready to get started? This page provides an introduction on getting started with intercepts.
First, make sure that intercepts is installed.
Then, let’s start with some simple examples.
Register an Intercept#
Intercepting calls with intercepts is very simple.
Begin by importing the intercepts module.
>>> import intercepts
Now lets define an intercept handler, like so:
def handler(*args, **kwargs):
return _(*args, **kwargs) * 2
This intercept handler simply doubles the output of the original call.
In general, an intercept handler is a function that will be called in
place of the original call. The handler will receive the original
all of the parameters passed to the original call. It also has access
to a special variable _
, which is a reference to the intercepted method.
Now that we have defined a handler, we can register it to intercept a call with register()
.
>>> intercepts.register(sum, handler)
That’s it. Now any call to sum, in any module will be intercepted by
handler
, and its result will be doubled.
>>> sum([1, 2, 3, 4, 5, 6])
42
Stacking Intercepts#
Multiple intercept handlers can be registered for a Python call. For example, we can define pre and post processing handlers, such as:
def pre_handler(*args, **kwargs):
print("Executing function:", _.__name__)
return _(*args, **kwargs)
def post_handler(*args, **kwargs):
result = _(*args, **kwargs)
print("Executed function:", _.__name__)
return result
Registering these handlers for a function will print a message before and after that methods execution.
>>> intercepts.register(sum, pre_handler)
>>> intercepts.register(sum, post_handler)
>>> sum([1, 2, 3, 4, 5, 6])
Executing function: sum
Executed function: sum
42
The same handler can even be applied multiple times.
>>> intercepts.register(sum, handler)
>>> intercepts.register(sum, handler)
>>> sum([1, 2, 3, 4, 5, 6])
84
Intercept handlers are stored as a stack, meaning that the last handler registered will be the first one that is executed. For example:
def handler_0(*args, **kwargs):
print("handler 0")
return _(*args, **kwargs)
def handler_1(*args, **kwargs):
print("handler 1")
return _(*args, **kwargs)
intercepts.register(abs, handler_0)
intercepts.register(abs, handler_1)
In this example, a call to abs
will print handler 1
and then
handler_0
.
>>> abs(-42)
handler 1
handler 0
42
Unregister an Intercept#
To unregister the intercept handlers for a function, use the unregister()
function.
>>> intercepts.unregister(sum)
This will remove all handlers from the sum
function.
An integer value, depth
can also be passed to unregister()
to remove
the last depth
handlers from the function.
>>> intercepts.unregister(sum, depth=1)
Finally, you can unregister all intercept handlers with unregister_all()
.
>>> intercepts.unregister_all()
API#
This part of the documentation covers the API of intercepts
.
All of intercepts
functionality can be accessed by these 3 methods.