Package: varmeth
varmethMethod Variant DecoratorSimple library that allows a method to choose dynamically implementation at runtime depending on the
context viadecorators.Varmethwas originally part ofManageIQ Integration testlibrary.Installation and usageInstallationvarmethcan be installed by runningpip install varmethUsageBelow example can show you how to usevarmeth. You can see a differentmethod variant.
You’ll have to decoratedefault methodwithvariableand register it with differentmethod variant.
You can also registervariantwith multiple names.The following code snippet shows how to usevarmethin a real world example:In this example, thetigermethod will change it's implementation based on the context at
runtime, so it must be annotated with the@variableannotation in order to do so. It will be
thevariablemethod.The body of this method will be thedefaultimplementation - the implementation used for this
method when no context is explicitly used.Thesiberian_tigerandbengal_tigerare two different implementations for thetigermethod,
and need to be annotated with@tiger.variant("variant-name")annotations, wherevariant-nameis a string identifier that will be used at runtime to select the requiredvariantimplementation.
These will be thevariants.Note that thevariablemethod can be associated with multiple implementations orvariants.fromvarmethimportvariableclassCatFamily(object):@variabledeftiger(self):print("Default Method!")print("Tiger")@tiger.variant("siberian")defsiberian_tiger(self):print("Siberian Tiger")@tiger.variant("indian","bengal")defbengal_tiger(self):print("Bengal Tiger")To choose between the differentvariants, themethodparameter is used to select
the proper context, using the propervariant-nameas a value.In[1]:cat=CatFamily()In[2]:cat.tiger()DefaultMethod!
Tiger

In[3]:cat.tiger(method="siberian")SiberianTiger

In[4]:cat.tiger(method="indian")BengalTiger

In[5]:cat.tiger(method="bengal")BengalTigerYou can also add and alias name to thedefaultmethod using thealiasparameter, though note
that only onedefaultmethod is allowed.fromvarmethimportvariableclassReptiles(object):@variable(alias="python")defsnake(self):print("Python Snake")@snake.variant("kobra")defkobra_snake(self):print("Kobra Snake")In[1]:rep=Reptiles()In[2]:rep.snake()PythonSnake

In[3]:rep.snake(method="python")PythonSnake

In[4]:rep.snake(method="kobra")KobraSnakeUsing Varmeth against plain Python implementationThe following example shows anEntityclass that supports thedeleteoperation for two different contexts, theUI(front-end) and theREST(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, andVarmethwill do the
rest.Plain PythonVarmethclassEntity(object):defdelete_ui(self):print("Delete with UI!")defdelete_rest(self):print("Delete with REST!")entity=Entity()entity.delete_ui()# >> Delete with UI!entity.delete_rest()# >> Delete with REST!fromvarmethimportvariableclassEntity(object):@variable(alias="ui")defdelete(self):print("Delete with UI!")@delete.variant("rest")defdelete_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,Varmethprovides a very convenientcontext switcherinterface, which some may
find handy when implementing integration tests designed to follow test parametrization patterns,
like some popular test frameworks such asPytest.
offer. The following is an example of how to do exactly that with Pytest usingVarmeth: we can
easily parametrize thecontext under testusingUIandRESTas parameters.importpytest@pytest.mark.parametrize("context",["ui","rest"])deftest_delete_entity(context):entity=Entity()entity.delete(method=context)ContributeFeel 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.