Skip to content

Exceptions

exceptions

AsymmetricMirrorRequiredError

Bases: ValueError

Raised when connecting two asymmetric ports without mirror=True.

Two ports carrying the same AsymmetricalCrossSection can only be connected via an M90 (mirror) transformation, since R180 would flip the left/right halves of the profile. Pass mirror=True to connect.

Source code in kfactory/exceptions.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
class AsymmetricMirrorRequiredError(ValueError):
    """Raised when connecting two asymmetric ports without `mirror=True`.

    Two ports carrying the same `AsymmetricalCrossSection` can only be
    connected via an M90 (mirror) transformation, since R180 would flip the
    left/right halves of the profile. Pass `mirror=True` to `connect`.
    """

    def __init__(
        self,
        p1: ProtoPort[Any],
        p2: ProtoPort[Any],
        *args: Any,
    ) -> None:
        super().__init__(
            f"Cannot connect ports {p1.name!r} and {p2.name!r} carrying the same"
            " asymmetric cross section without `mirror=True`. Asymmetric profiles"
            " require an M90 transformation (mirror) — R180 would flip the"
            " left/right halves. Pass `mirror=True` to `connect`.",
            *args,
        )

CellNameError

Bases: ValueError

Raised if a KCell is created and the automatic assigned name is taken.

Source code in kfactory/exceptions.py
203
204
class CellNameError(ValueError):
    """Raised if a KCell is created and the automatic assigned name is taken."""

CrossSectionNamingConflictError

Bases: ValueError

Raised when a second name is registered for an existing structural signature.

Cross sections and enclosures are canonicalized by their name-independent structural signature. A given signature may have at most one named canonical entry; attempting to register a second, differently-named entry for the same signature (or to reuse a name for a different signature) raises this error.

Source code in kfactory/exceptions.py
49
50
51
52
53
54
55
56
class CrossSectionNamingConflictError(ValueError):
    """Raised when a second name is registered for an existing structural signature.

    Cross sections and enclosures are canonicalized by their name-independent
    structural signature. A given signature may have at most one *named* canonical
    entry; attempting to register a second, differently-named entry for the same
    signature (or to reuse a name for a different signature) raises this error.
    """

CrossSectionSymmetryMismatchError

Bases: ValueError

Raised when connecting ports whose cross sections differ in symmetry.

A symmetric and an asymmetric cross section cannot be connected even with allow_width_mismatch, since they are structurally different objects.

Source code in kfactory/exceptions.py
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
class CrossSectionSymmetryMismatchError(ValueError):
    """Raised when connecting ports whose cross sections differ in symmetry.

    A symmetric and an asymmetric cross section cannot be connected even with
    `allow_width_mismatch`, since they are structurally different objects.
    """

    def __init__(
        self,
        p1: ProtoPort[Any],
        p2: ProtoPort[Any],
        *args: Any,
    ) -> None:
        kind1 = "symmetric" if p1.base.is_symmetric() else "asymmetric"
        kind2 = "symmetric" if p2.base.is_symmetric() else "asymmetric"
        super().__init__(
            f"Cross section symmetry mismatch between ports {p1.name!r} ({kind1})"
            f" and {p2.name!r} ({kind2}). Symmetric and asymmetric cross sections"
            " cannot be connected.",
            *args,
        )

DuplicateCellNameError

Bases: RuntimeError

Raised when writing a layout with multiple cells sharing the same name.

GDS/OASIS formats require unique cell names. This error provides details about which names are duplicated and which cells are involved.

Source code in kfactory/exceptions.py
207
208
209
210
211
212
class DuplicateCellNameError(RuntimeError):
    """Raised when writing a layout with multiple cells sharing the same name.

    GDS/OASIS formats require unique cell names. This error provides details
    about which names are duplicated and which cells are involved.
    """

FactoriesLockedError

Bases: RuntimeError

Raised when trying to add a factory to a locked Factories collection.

Source code in kfactory/exceptions.py
41
42
class FactoriesLockedError(RuntimeError):
    """Raised when trying to add a factory to a locked Factories collection."""

InvalidLayerError

Bases: ValueError

Raised when a layer is not valid.

Source code in kfactory/exceptions.py
215
216
class InvalidLayerError(ValueError):
    """Raised when a layer is not valid."""

LockedError

Bases: AttributeError

Raised when a locked cell is being modified.

Source code in kfactory/exceptions.py
28
29
30
31
32
33
34
35
36
37
38
class LockedError(AttributeError):
    """Raised when a locked cell is being modified."""

    def __init__(self, kcell: AnyKCell | BaseKCell) -> None:
        """Throw _locked error."""
        super().__init__(
            f"{kcell.name!r} is locked and likely stored in cache. Modifications are "
            "disabled as its associated function is decorated with `cell`. To modify, "
            "update the code in the function or create a copy of "
            f"the {kcell.__class__.__name__}."
        )

__init__

__init__(kcell: AnyKCell | BaseKCell) -> None

Throw _locked error.

Source code in kfactory/exceptions.py
31
32
33
34
35
36
37
38
def __init__(self, kcell: AnyKCell | BaseKCell) -> None:
    """Throw _locked error."""
    super().__init__(
        f"{kcell.name!r} is locked and likely stored in cache. Modifications are "
        "disabled as its associated function is decorated with `cell`. To modify, "
        "update the code in the function or create a copy of "
        f"the {kcell.__class__.__name__}."
    )

MergeError

Bases: ValueError

Raised if two layout's have conflicting cell definitions.

Source code in kfactory/exceptions.py
45
46
class MergeError(ValueError):
    """Raised if two layout's have conflicting cell definitions."""

PortLayerMismatchError

Bases: ValueError

Error thrown when two ports don't have a matching layer.

Source code in kfactory/exceptions.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
class PortLayerMismatchError(ValueError):
    """Error thrown when two ports don't have a matching `layer`."""

    def __init__(
        self,
        kcl: KCLayout,
        inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any],
        other_inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any] | ProtoPort[Any],
        p1: ProtoPort[Any],
        p2: ProtoPort[Any],
        *args: Any,
    ) -> None:
        """Throw error for the two ports `p1`/`p1`."""
        from .instance import ProtoInstance
        from .layer import LayerEnum

        l1 = (
            f"{p1.layer.name}({p1.layer.__int__()})"
            if isinstance(p1.layer, LayerEnum)
            else str(kcl.layout.get_info(p1.layer))
        )
        l2 = (
            f"{p2.layer.name}({p2.layer.__int__()})"
            if isinstance(p2.layer, LayerEnum)
            else str(kcl.layout.get_info(p2.layer))
        )
        if isinstance(other_inst, ProtoInstance):
            super().__init__(
                f'Layer mismatch between the ports {inst.name}["{p1.name}"]'
                f' and {other_inst.name}["{p2.name}"] ("{l1}"/"{l2}")',
                *args,
            )
        else:
            super().__init__(
                f'Layer mismatch between the ports {inst.name}["{p1.name}"]'
                f' and Port "{p2.name}" ("{l1}"/"{l2}")',
                *args,
            )

__init__

__init__(
    kcl: KCLayout,
    inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any],
    other_inst: ProtoInstance[Any]
    | ProtoInstanceGroup[Any, Any]
    | ProtoPort[Any],
    p1: ProtoPort[Any],
    p2: ProtoPort[Any],
    *args: Any,
) -> None

Throw error for the two ports p1/p1.

Source code in kfactory/exceptions.py
 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
def __init__(
    self,
    kcl: KCLayout,
    inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any],
    other_inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any] | ProtoPort[Any],
    p1: ProtoPort[Any],
    p2: ProtoPort[Any],
    *args: Any,
) -> None:
    """Throw error for the two ports `p1`/`p1`."""
    from .instance import ProtoInstance
    from .layer import LayerEnum

    l1 = (
        f"{p1.layer.name}({p1.layer.__int__()})"
        if isinstance(p1.layer, LayerEnum)
        else str(kcl.layout.get_info(p1.layer))
    )
    l2 = (
        f"{p2.layer.name}({p2.layer.__int__()})"
        if isinstance(p2.layer, LayerEnum)
        else str(kcl.layout.get_info(p2.layer))
    )
    if isinstance(other_inst, ProtoInstance):
        super().__init__(
            f'Layer mismatch between the ports {inst.name}["{p1.name}"]'
            f' and {other_inst.name}["{p2.name}"] ("{l1}"/"{l2}")',
            *args,
        )
    else:
        super().__init__(
            f'Layer mismatch between the ports {inst.name}["{p1.name}"]'
            f' and Port "{p2.name}" ("{l1}"/"{l2}")',
            *args,
        )

PortTypeMismatchError

Bases: ValueError

Error thrown when two ports don't have a matching port_type.

Source code in kfactory/exceptions.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
class PortTypeMismatchError(ValueError):
    """Error thrown when two ports don't have a matching `port_type`."""

    def __init__(
        self,
        inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any],
        other_inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any] | ProtoPort[Any],
        p1: ProtoPort[Any],
        p2: ProtoPort[Any],
        *args: Any,
    ) -> None:
        """Throw error for the two ports `p1`/`p1`."""
        from .instance import ProtoInstance

        if isinstance(other_inst, ProtoInstance):
            super().__init__(
                f'Type mismatch between the ports {inst.name}["{p1.name}"]'
                f' and {other_inst.name}["{p2.name}"]'
                f" ({p1.port_type}/{p2.port_type})",
                *args,
            )
        else:
            super().__init__(
                f'Type mismatch between the ports {inst.name}["{p1.name}"]'
                f' and Port "{p2.name}" ({p1.port_type}/{p2.port_type})',
                *args,
            )

__init__

__init__(
    inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any],
    other_inst: ProtoInstance[Any]
    | ProtoInstanceGroup[Any, Any]
    | ProtoPort[Any],
    p1: ProtoPort[Any],
    p2: ProtoPort[Any],
    *args: Any,
) -> None

Throw error for the two ports p1/p1.

Source code in kfactory/exceptions.py
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def __init__(
    self,
    inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any],
    other_inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any] | ProtoPort[Any],
    p1: ProtoPort[Any],
    p2: ProtoPort[Any],
    *args: Any,
) -> None:
    """Throw error for the two ports `p1`/`p1`."""
    from .instance import ProtoInstance

    if isinstance(other_inst, ProtoInstance):
        super().__init__(
            f'Type mismatch between the ports {inst.name}["{p1.name}"]'
            f' and {other_inst.name}["{p2.name}"]'
            f" ({p1.port_type}/{p2.port_type})",
            *args,
        )
    else:
        super().__init__(
            f'Type mismatch between the ports {inst.name}["{p1.name}"]'
            f' and Port "{p2.name}" ({p1.port_type}/{p2.port_type})',
            *args,
        )

PortWidthMismatchError

Bases: ValueError

Error thrown when two ports don't have a matching width.

Source code in kfactory/exceptions.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
class PortWidthMismatchError(ValueError):
    """Error thrown when two ports don't have a matching `width`."""

    def __init__(
        self,
        inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any],
        other_inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any] | ProtoPort[Any],
        p1: ProtoPort[Any],
        p2: ProtoPort[Any],
        *args: Any,
    ) -> None:
        """Throw error for the two ports `p1`/`p1`."""
        from .instance import ProtoInstance

        if isinstance(other_inst, ProtoInstance):
            super().__init__(
                f'Width mismatch between the ports {inst.name}["{p1.name}"] '
                f'and {other_inst.name}["{p2.name}"]'
                f'("{p1.width}"/"{p2.width}")',
                *args,
            )
        else:
            super().__init__(
                f'Width mismatch between the ports {inst.name}["{p1.name}"] '
                f'and Port "{p2.name}" ("{p1.width}"/"{p2.width}")',
                *args,
            )

__init__

__init__(
    inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any],
    other_inst: ProtoInstance[Any]
    | ProtoInstanceGroup[Any, Any]
    | ProtoPort[Any],
    p1: ProtoPort[Any],
    p2: ProtoPort[Any],
    *args: Any,
) -> None

Throw error for the two ports p1/p1.

Source code in kfactory/exceptions.py
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
def __init__(
    self,
    inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any],
    other_inst: ProtoInstance[Any] | ProtoInstanceGroup[Any, Any] | ProtoPort[Any],
    p1: ProtoPort[Any],
    p2: ProtoPort[Any],
    *args: Any,
) -> None:
    """Throw error for the two ports `p1`/`p1`."""
    from .instance import ProtoInstance

    if isinstance(other_inst, ProtoInstance):
        super().__init__(
            f'Width mismatch between the ports {inst.name}["{p1.name}"] '
            f'and {other_inst.name}["{p2.name}"]'
            f'("{p1.width}"/"{p2.width}")',
            *args,
        )
    else:
        super().__init__(
            f'Width mismatch between the ports {inst.name}["{p1.name}"] '
            f'and Port "{p2.name}" ("{p1.width}"/"{p2.width}")',
            *args,
        )