|
4 | 4 | from string import Template |
5 | 5 | from pydantic import BaseModel, create_model |
6 | 6 |
|
| 7 | + |
| 8 | +def supercede(cls1: type, cls2: type) -> type: |
| 9 | + """ |
| 10 | + Return the more specific class if one is a subclass of the other. |
| 11 | + Raise ValueError if neither is a subclass of the other. |
| 12 | + """ |
| 13 | + if issubclass(cls1, cls2) and cls1 is not cls2: |
| 14 | + return cls1 |
| 15 | + elif issubclass(cls2, cls1) and cls1 is not cls2: |
| 16 | + return cls2 |
| 17 | + elif cls1 is cls2: |
| 18 | + return cls1 |
| 19 | + else: |
| 20 | + raise ValueError(f"{cls1.__name__} and {cls2.__name__} are unrelated.") |
| 21 | + |
| 22 | + |
7 | 23 | class Pattern: |
8 | 24 |
|
9 | 25 | def __init__(self, pattern:str, **types:type[Any]): |
@@ -46,6 +62,21 @@ def format(self) -> str: |
46 | 62 | ) |
47 | 63 |
|
48 | 64 |
|
| 65 | + def __and__(self, other) -> 'Pattern': |
| 66 | + # WIP. not a final state. |
| 67 | + # We should actually keep the original Pattern instance, rather than immediately merging them, |
| 68 | + # because we must perform query optimization later. |
| 69 | + |
| 70 | + types = self.types.copy() |
| 71 | + for v in other.types.keys(): |
| 72 | + if v in types: |
| 73 | + types[v] = supersede(other.types[v], types[v]) |
| 74 | + |
| 75 | + return Pattern( |
| 76 | + self.pattern.template + " " + other.pattern.template, |
| 77 | + **types) |
| 78 | + |
| 79 | + |
49 | 80 | if __name__ == "__main__": |
50 | 81 |
|
51 | 82 | from mellea import start_session, SimpleContext |
|
0 commit comments