Skip to content

FIX: Misc. fixes for pyedb unit tests. #539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
May 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "flit_core.buildapi"
[project]
# Check https://flit.readthedocs.io/en/latest/pyproject_toml.html for all available sections
name = "ansys-edb-core"
version = "0.2.0.dev3"
version = "0.2.0.dev4"
description = "A python wrapper for Ansys Edb service"
readme = "README.rst"
requires-python = ">=3.8"
Expand All @@ -25,7 +25,7 @@ classifiers = [


dependencies = [
"ansys-api-edb==0.2.dev5",
"ansys-api-edb==0.2.dev6",
"protobuf>=3.19.3,<5",
"grpcio>=1.44.0",
"Django>=4.2.16"
Expand Down
2 changes: 1 addition & 1 deletion src/ansys/edb/core/definition/component_def.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def component_models(self):
This property is read-only.
"""
objs = self.__stub.GetComponentModels(self.msg).items
return map_list(objs, component_model.ComponentModel)
return map_list(objs, lambda msg: component_model.ComponentModel(msg).cast())

@property
def component_pins(self):
Expand Down
59 changes: 57 additions & 2 deletions src/ansys/edb/core/definition/component_model.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
"""Component model definition."""
from enum import Enum

from ansys.api.edb.v1.component_model_pb2 import ComponentModelType as pb_comp_model_Type
from ansys.api.edb.v1.component_model_pb2_grpc import (
ComponentModelServiceStub,
DynamicLinkComponentModelServiceStub,
Expand All @@ -10,6 +13,14 @@
from ansys.edb.core.session import StubAccessor, StubType


class ComponentModelType(Enum):
"""Enum representing component model types."""

N_PORT = pb_comp_model_Type.N_PORT
DYNAMIC_LINK = pb_comp_model_Type.DYNAMIC_LINK
UNKNOWN_COMPONENT_MODEL_TYPE = pb_comp_model_Type.UNKNOWN_MODEL_TYPE


class ComponentModel(ObjBase):
"""Represents a component model."""

Expand Down Expand Up @@ -42,7 +53,7 @@ def find_by_name(cls, comp_def, value):
"""
return ComponentModel(
cls.__stub.FindByName(messages.string_property_message(comp_def, value))
)
).cast()

@classmethod
def find_by_id(cls, comp_def, value):
Expand All @@ -60,7 +71,51 @@ def find_by_id(cls, comp_def, value):
ComponentModel
Component model that is found, ``None`` otherwise.
"""
return ComponentModel(cls.__stub.FindById(messages.int_proprty_message(comp_def, value)))
return ComponentModel(
cls.__stub.FindById(messages.int_property_message(comp_def, value))
).cast()

@property
def name(self) -> str:
""":obj:`str`: The name of the component model.

This property is read-only.
"""
return self.__stub.GetName(self.msg).value

@property
def component_model_type(self) -> ComponentModelType:
""":class:`.ComponentModelType`: The type of the component model.

This property is read-only.
"""
return ComponentModelType(self.__stub.GetType(self.msg).type)

@property
def component_model_id(self) -> int:
""":obj:`int`: The id of the component model.

This property is read-only.
"""
return self.__stub.GetId(self.msg).value

def cast(self) -> "ComponentModel":
"""Cast the component model object to the correct concrete type.

Returns
-------
.ComponentModel
"""
comp_model_type = (
ComponentModelType.UNKNOWN_COMPONENT_MODEL_TYPE
if self.is_null
else self.component_model_type
)
if comp_model_type == ComponentModelType.N_PORT:
return NPortComponentModel(self.msg)
elif comp_model_type == ComponentModelType.DYNAMIC_LINK:
return DynamicLinkComponentModel(self.msg)
return ComponentModel(self.msg)


class NPortComponentModel(ComponentModel):
Expand Down
4 changes: 3 additions & 1 deletion src/ansys/edb/core/definition/padstack_def_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,15 @@ def get_pad_parameters(self, layer, pad_type):
Value(message.generic.offset_y),
Value(message.generic.rotation),
)
else:
elif message.HasField("polygon"):
return (
parser.to_polygon_data(message.polygon.fp),
Value(message.polygon.offset_x),
Value(message.polygon.offset_y),
Value(message.polygon.rotation),
)
else:
return ()

def set_pad_parameters(
self, layer, pad_type, offset_x, offset_y, rotation, type_geom=None, sizes=None, fp=None
Expand Down
12 changes: 8 additions & 4 deletions src/ansys/edb/core/hierarchy/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from ansys.edb.core.edb_defs import LayoutObjType
from ansys.edb.core.hierarchy.hierarchy_obj import HierarchyObj
from ansys.edb.core.inner import messages
from ansys.edb.core.inner.utils import query_lyt_object_collection
from ansys.edb.core.session import StubAccessor, StubType


Expand Down Expand Up @@ -113,7 +114,10 @@ def members(self):

This property is read-only.
"""
from ansys.edb.core.inner import factory

objs = self.__stub.GetMembers(self.msg).items
return [factory.create_conn_obj(co) for co in objs]
return query_lyt_object_collection(
self,
LayoutObjType.INVALID_LAYOUT_OBJ,
self.__stub.GetMembers,
self.__stub.StreamMembers,
False,
)
10 changes: 10 additions & 0 deletions src/ansys/edb/core/inner/conn_obj.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from ansys.edb.core.edb_defs import LayoutObjType
from ansys.edb.core.inner import layout_obj, messages
from ansys.edb.core.inner.factory import create_lyt_obj
from ansys.edb.core.layout import mcad_model as mm
from ansys.edb.core.session import ConnectableServiceStub, StubAccessor, StubType

Expand Down Expand Up @@ -48,6 +49,15 @@ def get_client_prim_type_from_class():
return client_obj
return cls(None)

def cast(self):
"""Cast the ConnObj object to the correct concrete type.

Returns
-------
.ConnObj
"""
return create_lyt_obj(self.msg, self.obj_type)

@property
def obj_type(self):
""":class:`LayoutObjType <ansys.edb.core.edb_defs.LayoutObjType>`: Layout object type.
Expand Down
4 changes: 2 additions & 2 deletions src/ansys/edb/core/inner/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def _initialize_type_creator_params_dict():
LayoutObjType.EXTENDED_NET: _CreatorParams(ExtendedNet),
LayoutObjType.DIFFERENTIAL_PAIR: _CreatorParams(DifferentialPair),
LayoutObjType.NET: _CreatorParams(Net),
LayoutObjType.INVALID_LAYOUT_OBJ: _CreatorParams(ConnObj),
LayoutObjType.INVALID_LAYOUT_OBJ: _CreatorParams(ConnObj, True),
}
return _type_creator_params_dict

Expand Down Expand Up @@ -158,4 +158,4 @@ def create_conn_obj(msg):
-------
ansys.edb.core.inner.ConnObj
"""
return create_lyt_obj(msg, create_lyt_obj(msg, LayoutObjType.INVALID_LAYOUT_OBJ).obj_type)
return create_lyt_obj(msg, LayoutObjType.INVALID_LAYOUT_OBJ)
2 changes: 1 addition & 1 deletion src/ansys/edb/core/inner/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,4 +507,4 @@ def _to_mesh_op(message):

def _to_string_dict(message):
"""Convert a message to a dictionary of strings."""
return {key: value for (key, value) in message.string_map}
return {key: value for (key, value) in message.string_map.items()}
4 changes: 4 additions & 0 deletions src/ansys/edb/core/inner/rpc_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ def invalidates_cache(self):
"GetReferenceFile": _RpcInfo(cache=True),
"FindByName": _RpcInfo(cache=True),
"FindById": _RpcInfo(cache=True),
"GetName": _RpcInfo(cache=True),
"GetType": _RpcInfo(cache=True),
"GetId": _RpcInfo(cache=True),
},
"ansys.api.edb.v1.NPortComponentModelService": {
"Create": _RpcInfo(buffer=True, returns_future=True, write_no_cache_invalidation=True)
Expand Down Expand Up @@ -1045,6 +1048,7 @@ def invalidates_cache(self):
"GetParameters": _RpcInfo(cache=True),
"SetParameters": _RpcInfo(buffer=True),
"Render": _RpcInfo(cache=True),
"GetPolygonData": _RpcInfo(cache=True),
},
"ansys.api.edb.v1.RLCComponentPropertyService": {
"Create": _RpcInfo(buffer=True, returns_future=True, write_no_cache_invalidation=True),
Expand Down
3 changes: 2 additions & 1 deletion src/ansys/edb/core/primitive/padstack_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ def set_layer_range(self, top_layer, bottom_layer):
@property
def solderball_layer(self):
""":class:`.Layer`: Solderball layer of the padstack instance."""
return Layer(self.__stub.GetSolderBallLayer(self.msg)).cast()
sb_layer = Layer(self.__stub.GetSolderBallLayer(self.msg))
return sb_layer if sb_layer.is_null() else sb_layer.cast()

@solderball_layer.setter
def solderball_layer(self, solderball_layer):
Expand Down
3 changes: 2 additions & 1 deletion src/ansys/edb/core/primitive/rectangle.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,14 @@ def can_be_zone_primitive(self):
return True

@property
@parser.to_polygon_data
def polygon_data(self):
""":class:`.PolygonData`: \
Polygon data object of the rectangle.

This property is read-only.
"""
return Rectangle.render(*self.get_parameters())
return self.__stub.GetPolygonData(self.msg)

@classmethod
@parser.to_polygon_data
Expand Down
8 changes: 7 additions & 1 deletion src/ansys/edb/core/simulation_setup/simulation_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,13 @@ def _msg_to_sweep_data(msg):
"""Create a ``SweepData`` from a ``SweepDataMessage``."""
freq_str_params = msg.frequency_string.split()
sweep_data = SweepData(
msg.name, freq_str_params[0], freq_str_params[1], freq_str_params[2], freq_str_params[3]
msg.name,
FrequencyData(
Distribution[freq_str_params[0]],
freq_str_params[1],
freq_str_params[2],
freq_str_params[3],
),
)
sweep_data.enabled = msg.enabled
sweep_data.type = FreqSweepType(msg.type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def si_slider_pos(self):

@si_slider_pos.setter
def si_slider_pos(self, si_slider_pos):
self.__stub.SetSISliderPos(messages.int_property_message(self, si_slider_pos))
self.__stub.SetSISliderPos(messages.uint64_property_message(self, si_slider_pos))

@property
def pi_slider_pos(self):
Expand All @@ -123,7 +123,7 @@ def pi_slider_pos(self):

@pi_slider_pos.setter
def pi_slider_pos(self, pi_slider_pos):
self.__stub.SetPISliderPos(messages.int_property_message(self, pi_slider_pos))
self.__stub.SetPISliderPos(messages.uint64_property_message(self, pi_slider_pos))


class SIWaveAdvancedSettings(SimulationSettingsBase):
Expand Down Expand Up @@ -388,7 +388,7 @@ def dc_slider_pos(self):

@dc_slider_pos.setter
def dc_slider_pos(self, dc_slider_pos):
self.__stub.SetDCSliderPos(messages.int_property_message(self, dc_slider_pos))
self.__stub.SetDCSliderPos(messages.uint64_property_message(self, dc_slider_pos))


class SIWaveDCAdvancedSettings(SimulationSettingsBase):
Expand Down Expand Up @@ -449,7 +449,7 @@ def max_num_passes(self):

@max_num_passes.setter
def max_num_passes(self, max_num_passes):
self.__stub.SetMaxNumPasses(messages.int_property_message(self, max_num_passes))
self.__stub.SetMaxNumPasses(messages.uint64_property_message(self, max_num_passes))

@property
def min_num_passes(self):
Expand All @@ -458,7 +458,7 @@ def min_num_passes(self):

@min_num_passes.setter
def min_num_passes(self, min_num_passes):
self.__stub.SetMinNumPasses(messages.int_property_message(self, min_num_passes))
self.__stub.SetMinNumPasses(messages.uint64_property_message(self, min_num_passes))

@property
def percent_local_refinement(self):
Expand All @@ -468,7 +468,7 @@ def percent_local_refinement(self):
@percent_local_refinement.setter
def percent_local_refinement(self, percent_local_refinement):
self.__stub.SetPercentLocalRefinement(
messages.int_property_message(self, percent_local_refinement)
messages.uint64_property_message(self, percent_local_refinement)
)

@property
Expand Down Expand Up @@ -523,7 +523,7 @@ def num_bw_sides(self):

@num_bw_sides.setter
def num_bw_sides(self, num_bw_sides):
self.__stub.SetNumBwSides(messages.int_property_message(self, num_bw_sides))
self.__stub.SetNumBwSides(messages.uint64_property_message(self, num_bw_sides))

@property
def num_via_sides(self):
Expand All @@ -532,7 +532,7 @@ def num_via_sides(self):

@num_via_sides.setter
def num_via_sides(self, num_via_sides):
self.__stub.SetNumViaSides(messages.int_property_message(self, num_via_sides))
self.__stub.SetNumViaSides(messages.uint64_property_message(self, num_via_sides))


class SIWaveSParameterSettings(SimulationSettingsBase):
Expand Down
2 changes: 1 addition & 1 deletion src/ansys/edb/core/terminal/bundle_terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def create(cls, terminals):
@property
def terminals(self):
""":obj:`list` of Terminal: All terminals grouped in the terminal."""
return [Terminal(msg).cast() for msg in self.__stub.GetTerminals(self.msg)]
return [Terminal(msg).cast() for msg in self.__stub.GetTerminals(self.msg).items]

def ungroup(self):
"""Delete the grouping."""
Expand Down
4 changes: 2 additions & 2 deletions src/ansys/edb/core/terminal/edge_terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def _create(cls, **params):

@property
def _type(self):
return EdgeType(self.__stub.GetType(self.msg))
return EdgeType(self.__stub.GetEdgeType(self.msg).t)

@property
def _params(self):
Expand Down Expand Up @@ -163,7 +163,7 @@ def create(cls, layout, name, edges, net=None, is_ref=False):
@property
def edges(self):
""":obj:`list` of :class:`.Edge`: All edges on the terminal."""
return [Edge(msg).cast() for msg in self.__stub.GetEdges(self.msg)]
return [Edge(msg).cast() for msg in self.__stub.GetEdges(self.msg).items]

@edges.setter
def edges(self, edges):
Expand Down
6 changes: 3 additions & 3 deletions tests/mock/test_terminals.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ansys.api.edb.v1.layer_pb2 as layer_pb2
import ansys.api.edb.v1.term_pb2 as term_pb2
from utils.fixtures import * # noqa
from utils.test_utils import create_edb_obj_msgs, equals
from utils.test_utils import create_edb_obj_collection_msg, equals

from ansys.edb.core.geometry.point_data import PointData
from ansys.edb.core.inner import messages
Expand Down Expand Up @@ -68,7 +68,7 @@ def test_bundle_terminal_get_terminals(mocked_stub, bundle_terminal, term_type,
get_terminals = mocked_stub(
bundle_terminal_mod, bundle_terminal_mod.BundleTerminal
).GetTerminals
get_terminals.return_value = expected = create_edb_obj_msgs(2)
get_terminals.return_value = expected = create_edb_obj_collection_msg(2)
get_params = mocked_stub(terminal_mod, terminal_mod.Terminal).GetParams
get_params.return_value = term_pb2.TermParamsMessage(term_type=term_type)

Expand All @@ -79,7 +79,7 @@ def test_bundle_terminal_get_terminals(mocked_stub, bundle_terminal, term_type,
assert len(terms) == 2
for t in terms:
assert isinstance(t, term_cls)
assert sorted([t.id for t in terms]) == sorted([msg.id for msg in expected])
assert sorted([t.id for t in terms]) == sorted([msg.id for msg in expected.items])


def test_bundle_terminal_ungroup(mocked_stub, bundle_terminal):
Expand Down
Loading