|
2 | 2 |
|
3 | 3 | from types import ModuleType
|
4 | 4 |
|
| 5 | +try: |
| 6 | + from collections.abc import Mapping |
| 7 | +except ImportError: |
| 8 | + from collections import Mapping |
| 9 | + |
5 | 10 | from six import text_type
|
6 | 11 |
|
7 | 12 | try:
|
@@ -64,6 +69,36 @@ def __init__(self, items=()):
|
64 | 69 | def __getitem__(self, key):
|
65 | 70 | return dict.get(self, key, self.default)
|
66 | 71 |
|
| 72 | + def __get__(self, instance, owner=None): |
| 73 | + return BoundMethodDispatcher(instance, self) |
| 74 | + |
| 75 | + |
| 76 | +class BoundMethodDispatcher(Mapping): |
| 77 | + """Wraps a MethodDispatcher, binding its return values to `instance`""" |
| 78 | + def __init__(self, instance, dispatcher): |
| 79 | + self.instance = instance |
| 80 | + self.dispatcher = dispatcher |
| 81 | + |
| 82 | + def __getitem__(self, key): |
| 83 | + # see https://docs.python.org/3/reference/datamodel.html#object.__get__ |
| 84 | + # on a function, __get__ is used to bind a function to an instance as a bound method |
| 85 | + return self.dispatcher[key].__get__(self.instance) |
| 86 | + |
| 87 | + def get(self, key, default): |
| 88 | + if key in self.dispatcher: |
| 89 | + return self[key] |
| 90 | + else: |
| 91 | + return default |
| 92 | + |
| 93 | + def __iter__(self): |
| 94 | + return iter(self.dispatcher) |
| 95 | + |
| 96 | + def __len__(self): |
| 97 | + return len(self.dispatcher) |
| 98 | + |
| 99 | + def __contains__(self, key): |
| 100 | + return key in self.dispatcher |
| 101 | + |
67 | 102 |
|
68 | 103 | # Some utility functions to deal with weirdness around UCS2 vs UCS4
|
69 | 104 | # python builds
|
|
0 commit comments