Skip to content

Scoped dict

scoped_dict

ScopedDict

Bases: Generic[_Key, _Value]

A tiered mapping from keys to values. A ScopedDict may have a parent dict, which is used as a fallback when a value for a key is not found. If a ScopedDict and its parent have values for the same key, the child value will be returned. This structure is useful for contexts where keys and values have a known scope, such as during IR construction from an Abstract Syntax Tree. ScopedDict instances may have a name property as a hint during debugging.

Source code in xdsl/utils/scoped_dict.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
class ScopedDict(Generic[_Key, _Value]):
    """
    A tiered mapping from keys to values.
    A ScopedDict may have a parent dict, which is used as a fallback when a value for a
    key is not found.
    If a ScopedDict and its parent have values for the same key, the child value will be
    returned.
    This structure is useful for contexts where keys and values have a known scope, such
    as during IR construction from an Abstract Syntax Tree.
    ScopedDict instances may have a `name` property as a hint during debugging.
    """

    _local_scope: dict[_Key, _Value]
    parent: ScopedDict[_Key, _Value] | None
    name: str | None

    def __init__(
        self,
        parent: ScopedDict[_Key, _Value] | None = None,
        *,
        name: str | None = None,
        local_scope: dict[_Key, _Value] | None = None,
    ) -> None:
        self._local_scope = {} if local_scope is None else local_scope
        self.parent = parent
        self.name = name

    @property
    def local_scope(self) -> Mapping[_Key, _Value]:
        return self._local_scope

    @overload
    def get(self, key: _Key, default: None = None) -> _Value | None: ...

    @overload
    def get(self, key: _Key, default: _Value) -> _Value: ...

    def get(self, key: _Key, default: _Value | None = None) -> _Value | None:
        local = self._local_scope.get(key)
        if local is not None:
            return local
        if self.parent is None:
            return default
        return self.parent.get(key, default)

    def __getitem__(self, key: _Key) -> _Value:
        """
        Fetch key from environment. Attempts to first fetch from current scope,
        then from parent scopes. Raises KeyError error if not found.
        """
        cur = self
        if key in cur._local_scope:
            return self._local_scope[key]
        while cur.parent is not None:
            cur = cur.parent
            if key in cur._local_scope:
                return cur._local_scope[key]
        raise KeyError(f"No value for key {key}")

    def __setitem__(self, key: _Key, value: _Value):
        """
        Assign key to current scope. Raises InterpretationError if key already
        assigned to.
        """
        self._local_scope[key] = value

    def __contains__(self, key: _Key) -> bool:
        return (
            key in self._local_scope or self.parent is not None and key in self.parent
        )

parent: ScopedDict[_Key, _Value] | None = parent instance-attribute

name: str | None = name instance-attribute

local_scope: Mapping[_Key, _Value] property

__init__(parent: ScopedDict[_Key, _Value] | None = None, *, name: str | None = None, local_scope: dict[_Key, _Value] | None = None) -> None

Source code in xdsl/utils/scoped_dict.py
28
29
30
31
32
33
34
35
36
37
def __init__(
    self,
    parent: ScopedDict[_Key, _Value] | None = None,
    *,
    name: str | None = None,
    local_scope: dict[_Key, _Value] | None = None,
) -> None:
    self._local_scope = {} if local_scope is None else local_scope
    self.parent = parent
    self.name = name

get(key: _Key, default: _Value | None = None) -> _Value | None

get(key: _Key, default: None = None) -> _Value | None
get(key: _Key, default: _Value) -> _Value
Source code in xdsl/utils/scoped_dict.py
49
50
51
52
53
54
55
def get(self, key: _Key, default: _Value | None = None) -> _Value | None:
    local = self._local_scope.get(key)
    if local is not None:
        return local
    if self.parent is None:
        return default
    return self.parent.get(key, default)

__getitem__(key: _Key) -> _Value

Fetch key from environment. Attempts to first fetch from current scope, then from parent scopes. Raises KeyError error if not found.

Source code in xdsl/utils/scoped_dict.py
57
58
59
60
61
62
63
64
65
66
67
68
69
def __getitem__(self, key: _Key) -> _Value:
    """
    Fetch key from environment. Attempts to first fetch from current scope,
    then from parent scopes. Raises KeyError error if not found.
    """
    cur = self
    if key in cur._local_scope:
        return self._local_scope[key]
    while cur.parent is not None:
        cur = cur.parent
        if key in cur._local_scope:
            return cur._local_scope[key]
    raise KeyError(f"No value for key {key}")

__setitem__(key: _Key, value: _Value)

Assign key to current scope. Raises InterpretationError if key already assigned to.

Source code in xdsl/utils/scoped_dict.py
71
72
73
74
75
76
def __setitem__(self, key: _Key, value: _Value):
    """
    Assign key to current scope. Raises InterpretationError if key already
    assigned to.
    """
    self._local_scope[key] = value

__contains__(key: _Key) -> bool

Source code in xdsl/utils/scoped_dict.py
78
79
80
81
def __contains__(self, key: _Key) -> bool:
    return (
        key in self._local_scope or self.parent is not None and key in self.parent
    )