Skip to content

Commit 36afe45

Browse files
authored
Fix OrderedBiMap so that it works in annotations (#253)
The easiest way to do this is to backport `typing.OrderedDict`, in a new `ga._backports` module. This is private, so that unlike `utils`, we can remove it as soon as we don't need it any more.
1 parent d164564 commit 36afe45

File tree

4 files changed

+44
-5
lines changed

4 files changed

+44
-5
lines changed

galgebra/_backports/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"""
2+
Backports of library components from newer python versions.
3+
4+
For internal use only.
5+
"""

galgebra/_backports/typing.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import sys
2+
3+
# shim for typing.OrderedDict
4+
if sys.version_info >= (3, 7, 2):
5+
from typing import OrderedDict
6+
else:
7+
from typing import TypeVar, Mapping
8+
import collections
9+
10+
K = TypeVar('K')
11+
V = TypeVar('K')
12+
13+
class OrderedDict(collections.OrderedDict, Mapping[K, V]):
14+
pass
15+
16+
del K, V, TypeVar, Mapping, collections

galgebra/ga.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
import warnings
55
import operator
66
import copy
7-
from collections import OrderedDict
87
from itertools import combinations
98
import functools
109
from functools import reduce
11-
from typing import Tuple, TypeVar, Callable, Mapping
10+
from typing import Tuple, TypeVar, Callable
11+
from ._backports.typing import OrderedDict
1212

1313
from sympy import (
1414
diff, Rational, Symbol, S, Mul, Add,
@@ -170,15 +170,19 @@ def _map(self, func: Callable[[_T], _U]) -> 'GradedTuple[_U]':
170170
)
171171

172172

173-
class OrderedBiMap(OrderedDict, Mapping):
173+
_K = TypeVar('K')
174+
_V = TypeVar('V')
175+
176+
177+
class OrderedBiMap(OrderedDict[_K, _V]):
174178
""" A dict with an ``.inverse`` attribute mapping in the other direction """
175179
def __init__(self, items):
176180
# set up the inverse mapping, bypassing our __init__
177181
self.inverse = OrderedBiMap.__new__(type(self))
178182

179183
# populate both
180-
OrderedDict.__init__(self, items)
181-
OrderedDict.__init__(self.inverse, [(v, k) for k, v in items])
184+
super(OrderedBiMap, self).__init__(items)
185+
super(OrderedBiMap, self.inverse).__init__([(v, k) for k, v in items])
182186

183187
# and complete the inverse loop
184188
self.inverse.inverse = self

test/test_misc.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from galgebra.ga import OrderedBiMap
2+
3+
4+
class TestOrderedBiMap:
5+
6+
def test_inverse(self):
7+
d = OrderedBiMap([('one', 1), ('two', 2)])
8+
assert d.inverse == OrderedBiMap([(1, 'one'), (2, 'two')])
9+
assert d.inverse.inverse is d
10+
11+
def test_annotation(self):
12+
# check that we can use this like a generic type
13+
def foo() -> OrderedBiMap[str, int]:
14+
pass

0 commit comments

Comments
 (0)