Skip to content

medcat.components.contracting_utils

Classes:

Functions:

Attributes:

logger module-attribute

logger = Logger(__name__)

AccessType

Bases: Enum

Attributes:

READ class-attribute instance-attribute

READ = auto()

WRITE class-attribute instance-attribute

WRITE = auto()

ContractViolation

Bases: Exception

WrappedMember

WrappedMember(part: Any, member_name: str, feedback: list[Any], access_type: AccessType)

Attributes:

Source code in medcat/medcat/components/contracting_utils.py
36
37
38
39
40
41
42
43
44
45
46
47
48
def __init__(
    self,
    part: Any,
    member_name: str,
    feedback: list[Any],
    access_type: AccessType,
) -> None:
    self.part = part
    self.member_name = member_name
    self.feedback = feedback
    self.access_type = access_type
    self._oirg_class = type(self.part)
    self._install()

access_type instance-attribute

access_type = access_type

feedback instance-attribute

feedback = feedback

member_name instance-attribute

member_name = member_name

part instance-attribute

part = part

iter_relevant_parts

iter_relevant_parts(doc: MutableDocument, path: str) -> Iterator[Any]
Source code in medcat/medcat/components/contracting_utils.py
24
25
26
27
28
29
30
31
def iter_relevant_parts(doc: MutableDocument, path: str) -> Iterator[Any]:
    if path.startswith("doc."):
        yield doc
        return
    if path.startswith("token."):
        yield from doc[:]
    else:
        raise ValueError(f"Unknown path: {path}")

spy_token_class

spy_token_class(token_cls: Type, watched_attr: str, access_type: AccessType)
Source code in medcat/medcat/components/contracting_utils.py
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
@contextmanager
def spy_token_class(
    token_cls: Type,
    watched_attr: str,
    access_type: AccessType,
):
    prev_getattr = token_cls.__dict__.get('__getattribute__', _SENTINEL)
    prev_setattr = token_cls.__dict__.get('__setattr__', _SENTINEL)

    per_instance_spied: dict[Any, list[Any]] = defaultdict(list)

    def __getattribute__(self, name: str) -> Any:
        val = object.__getattribute__(self, name)
        if name == watched_attr:
            per_instance_spied[self].append(str(val))
        return val

    def __setattr__(self, name: str, value: Any):
        old = object.__getattribute__(self, name)
        object.__setattr__(self, name, value)
        if name == watched_attr:
            per_instance_spied[self].append((str(old), str(value)))

    if access_type == AccessType.READ:
        # NOTE: this should be fine, but mypy complains due to self
        token_cls.__getattribute__ = __getattribute__  # type: ignore
    elif access_type == AccessType.WRITE:
        # NOTE: this should be fine, but mypy complains due to self
        token_cls.__setattr__ = __setattr__  # type: ignore
    else:
        raise ValueError(f"Unknown access type: {access_type}")
    try:
        yield per_instance_spied
    finally:
        if prev_getattr is _SENTINEL:
            del token_cls.__getattribute__
        else:
            token_cls.__getattribute__ = prev_getattr

        if prev_setattr is _SENTINEL:
            # NOTE: this should be fine, but mypy complains due to self
            token_cls.__setattr__ = object.__setattr__  # type: ignore
        else:
            token_cls.__setattr__ = prev_setattr

wrap_relevant_parts

wrap_relevant_parts(doc: MutableDocument, path: str, access_type: AccessType = READ)
Source code in medcat/medcat/components/contracting_utils.py
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
@contextmanager
def wrap_relevant_parts(
    doc: MutableDocument,
    path: str,
    access_type: AccessType = AccessType.READ,
):
    if path.startswith("doc."):
        with wrap_relevant_persistant_parts(
            doc, path, access_type
        ) as feedbacks:
            yield feedbacks
    elif path.startswith("token."):
        with wrap_relevant_token_cls(
            doc, path, access_type
        ) as feedbacks:
            yield feedbacks

wrap_relevant_persistant_parts

wrap_relevant_persistant_parts(doc: MutableDocument, path: str, access_type: AccessType = READ)
Source code in medcat/medcat/components/contracting_utils.py
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
@contextmanager
def wrap_relevant_persistant_parts(
    doc: MutableDocument,
    path: str,
    access_type: AccessType = AccessType.READ,
):
    member_name = path.split(".", 1)[1]
    out_list: list[list[Any]] = []
    with ExitStack() as exit_stack:
        for part in iter_relevant_parts(doc, path):
            feedback: list[Any] = []
            exit_stack.enter_context(
                WrappedMember(
                    part, member_name,
                    feedback, access_type=access_type)
            )
            out_list.append(feedback)
        yield out_list

wrap_relevant_token_cls

wrap_relevant_token_cls(doc: MutableDocument, path: str, access_type: AccessType = READ)
Source code in medcat/medcat/components/contracting_utils.py
152
153
154
155
156
157
158
159
160
161
162
163
@contextmanager
def wrap_relevant_token_cls(
    doc: MutableDocument,
    path: str,
    access_type: AccessType = AccessType.READ,
):
    _, attr_name = path.split(".", 1)
    tkn_cls = type(next(iter(doc)))
    with spy_token_class(
        tkn_cls, attr_name, access_type
    ) as per_instance_spied:
        yield per_instance_spied.values()