Skip to main content

About this project

The mdis module allows to quickly extend the classes with the required functionality without modifications inside these classes. This is done via double dispatch pattern: the dispatcher describes the required action based on the the argument type. Use cases mainly include visitors and iterators, but are not limited to them.

Dispatchers

The key concept of this module is dispatcher. A dispatcher object is a callable object; the exact call logic depends on the type of the argument. The main class, mdis.dispatcher.Dispatcher, can register per-type hooks, which modify the call logic depending on the argument. The hook is registered on a dispatcher class level as a method; attempts to call a dispatcher determine the relevant hooks based on argument type.

Walkers

Sometimes objects of different types need to be traversed, but either lack __iter__ method, or its semantics differs from what the users want. For example, let's consider a nested collection, consisting of tuples, dicts and other types. dict.__iter__ method yields just keys, and the values have to be got via __getitem__ calls. Also, in order to support nested collections, users will have to write some recursive code with isinstance checks. With mdis.Walker, users can just install the handlers for the types of interest, and change the iteration logic. A walker is just a particular example of dispatcher, where the call yields some objects in a class-dependent manner. The default mdis.Walker already incorporates the logic to walk over some builtin Python objects. The example below shows how to override the way the dicts are traversed so that keys and values are swapped.

import mdis.dispatcher
import mdis.walker

class CustomWalker(mdis.walker.Walker):
    @mdis.dispatcher.hook(dict)
    def dispatch_dict(self, instance):
        for (key, value) in instance.items():
            yield (value, key)
            yield from self((value, key))

collection = {"a": 1, "b": 2}
walker = CustomWalker()
for item in walker(collection):
    print(item)

The following output is expected:

(1, 'a')
1
a
(2, 'b')
2
b

Visitors

In mdis, a visitor is just another particular example of dispatcher. Whenever the visitor is called, the call is dispatched based on type, and some per-class action is performed. The primary scenario is to combine the visitor calls with context managers. The example below shows how to execute some arbitrary code upon visiting an object.

import contextlib

import mdis.dispatcher
import mdis.visitor

class CustomVisitor(mdis.visitor.ContextVisitor):
    @mdis.dispatcher.hook(int)
    @contextlib.contextmanager
    def dispatch_int(self, instance):
        print("entering int")
        yield (instance + 42)
        print("leaving int")

    @mdis.dispatcher.hook(str)
    @contextlib.contextmanager
    def dispatch_str(self, instance):
        print("entering str")
        yield f"!!!{instance}!!!"
        print("leaving str")

    @mdis.dispatcher.hook(object)
    @contextlib.contextmanager
    def dispatch_object(self, instance):
        print("entering object")
        yield instance
        print("leaving object")

visitor = CustomVisitor()
for item in (42, "cocojamboo", 1.5):
    with visitor(item) as result:
        print(result)

The following output is expected:

entering int
84
leaving int
entering str
!!!cocojamboo!!!
leaving str
entering object
1.5
leaving object

Metadata

Release files for mdis 0.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mdis 0.5.1
File Size Uploaded Provenance Actions
mdis-0.5.1.tar.gz 5.0 kB Without provenance Details for mdis-0.5.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for mdis 0.5.1
File Interpreter ABI Platform Actions
mdis-0.5.1-py3-none-any.whl Python 3 none any Details for mdis-0.5.1-py3-none-any.whl

Total release size: 11.0 kB

Release files / mdis-0.5.1.tar.gz

Download URL mdis-0.5.1.tar.gz
Size 5.0 kB
Tags Source
SHA-256 checksum
How to use checksums
82f5ed3fc34ee573c302cd1731b1a49c6efd16c70dffb971aa6175920de78718
BLAKE2b-256 checksum
How to use checksums
1d96caddd7f619732b1a1c4ee8b2ecf9ab00c35730f00c14c96e448cf48a3a35
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.7.3

Release files / mdis-0.5.1-py3-none-any.whl

Download URL mdis-0.5.1-py3-none-any.whl
Size 5.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b92472b11afa70cea7917f487296d1ba771bbec40d49fc121a2d1b85350bc73f
BLAKE2b-256 checksum
How to use checksums
be904e3fa77969e929ec554e4a78737679b796cda16d8f432b7d2a34a692eb68
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.7.3

Security for mdis 0.5.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page