Skip to main content

Method variant decorator

Project description

varmeth

Method Variant Decorator

Python Versions PyPI version github actions License: GPLv3 Code style: black

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.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

varmeth-1.0.1-py3-none-any.whl (29.2 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page