Method variant decorator
Project description
varmeth
Method Variant Decorator
Simple library that allows a method to choose dynamically implementation at runtime depending on the context via decorators.
Varmeth was originally part of ManageIQ Integration test library.
Installation and usage
Installation
varmeth
can be installed by running pip install varmeth
Usage
Below example can show you how to use varmeth
. You can see a different method variant.
You’ll have to decorate default method with variable
and register it with different method variant.
You can also register variant with multiple names.
The following code snippet shows how to use varmeth
in a real world example:
In this example, the tiger
method will change it's implementation based on the context at
runtime, so it must be annotated with the @variable
annotation in order to do so. It will be
the variable method.
The body of this method will be the default
implementation - the implementation used for this
method when no context is explicitly used.
The siberian_tiger
and bengal_tiger
are two different implementations for the tiger
method,
and need to be annotated with @tiger.variant("variant-name")
annotations, where variant-name
is a string identifier that will be used at runtime to select the required variant
implementation.
These will be the variants.
Note that the variable method can be associated with multiple implementations or variants.
from varmeth import variable
class CatFamily(object):
@variable
def tiger(self):
print("Default Method!")
print("Tiger")
@tiger.variant("siberian")
def siberian_tiger(self):
print("Siberian Tiger")
@tiger.variant("indian", "bengal")
def bengal_tiger(self):
print("Bengal Tiger")
To choose between the different variants , the method
parameter is used to select
the proper context, using the proper variant-name as a value.
In [1]: cat = CatFamily()
In [2]: cat.tiger()
Default Method!
Tiger
In [3]: cat.tiger(method="siberian")
Siberian Tiger
In [4]: cat.tiger(method="indian")
Bengal Tiger
In [5]: cat.tiger(method="bengal")
Bengal Tiger
You can also add and alias name to the default method using the alias
parameter, though note
that only one default
method is allowed.
from varmeth import variable
class Reptiles(object):
@variable(alias="python")
def snake(self):
print("Python Snake")
@snake.variant("kobra")
def kobra_snake(self):
print("Kobra Snake")
In [1]: rep = Reptiles()
In [2]: rep.snake()
Python Snake
In [3]: rep.snake(method="python")
Python Snake
In [4]: rep.snake(method="kobra")
Kobra Snake
Using Varmeth against plain Python implementation
The following example shows an Entity class that supports the delete operation for two different contexts, the UI
(front-end) and the REST
(back-end) contexts. As you can infer, each context requires very different implementations
to get the entity removed.
Using vanilla Python implementation you will have to call the proper method for each context,
explicitly. Instead, you can simply call the same method and provide the context, and Varmeth
will do the
rest.
Plain Python | Varmeth |
---|---|
class Entity(object):
def delete_ui(self):
print("Delete with UI!")
def delete_rest(self):
print("Delete with REST!")
entity = Entity()
entity.delete_ui() # >> Delete with UI!
entity.delete_rest() # >> Delete with REST!
|
from varmeth import variable
class Entity(object):
@variable(alias="ui")
def delete(self):
print("Delete with UI!")
@delete.variant("rest")
def delete_rest(self):
print("Delete with REST!")
entity = Entity()
entity.delete() # >> Delete with UI!
entity.delete(method="ui") # >> Delete with UI!
entity.delete(method="rest") # >> Delete with REST!
|
As you can see, Varmeth provides a very convenient context switcher interface, which some may
find handy when implementing integration tests designed to follow test parametrization patterns,
like some popular test frameworks such as Pytest.
offer. The following is an example of how to do exactly that with Pytest using Varmeth
: we can
easily parametrize the context under test using UI
and REST
as parameters.
import pytest
@pytest.mark.parametrize("context", ["ui", "rest"])
def test_delete_entity(context):
entity = Entity()
entity.delete(method=context)
Contribute
Feel free to create Issues if you find bugs, or go ahead and submit your own Pull Requests.
Please note: When submitting new PRs, ensure your code passes all checks.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.