Python pcbnew.wxString() wrong? takes no argument

It seems wrong that the pcbnew.wxString() does not take a string argument. Can anyone confirm?

I would expect the pcbnew.wxString() function to take a string argument and return a wxString object with that value. Currently, pcbnew.wxString() returns an wxString with an empty string value (’’).

I’m using the current stable version of KiCAD (5.1.5)-3 on Windows.

Yup. You can also take a look at the docs.

I hope you don’t mind me asking why would you need wxstring specifically? wxpython deals with ordinary strings, and I’ve had no issues.

1 Like

I’ve been trying to work out how to get netclassptr from name and I’m using the dictionary (from netclass_map) returned from pcbnew.GetBoard().GetAllNetClasses(). It uses wxStrings for keys, and a simple indexing doesn’t work netmapdict[‘NetNameString’]. However, after I posted, I did get the correct lookup using __getitem__ function call on the dictionary using a plain string as the key. So not having wxString at the moment is not blocking me, but it does seem wrong that the dictionary returned from GetAllNetClasses() should accept a basic string index. Now, I think that particular object is not quite implemented correctly. It should accept a string as an index value into it (in my opinion).

You should report this on GitLab. But I agree with you that GetAllNetClasses() should accept a basic string index. And if it would then at least in this case one would not need wxstring class.

1 Like

2 ways you can easily work around this:
just str() the wxString:

a = pcbnew.GetBoard().GetAllNetClasses()
a = {str(k):v for k, v in a.items()}

Rebuild your map using just values, they have class name in them:

a = pcbnew.GetBoard().GetAllNetClasses()
a = {v.GetName():v for v in a.values()}

But yeah, this still can and should be fixed in kicad itself. Easy fix too.

Thanks all. I think the original problem I was having was a simple, embarrassing mistake. There appears to not be a problem with the wxString keys and/or with the dictionary returned from GetAllNetClasses().

It still seems an error, though, for pcbnew.wxString() to not take an initial string argument. I’m going to review the wxWidgets version to verify.

What do you mean? I confirmed the problem, you can’t access any of the netclasses by name, other than the “Default”. At least on nightly.
wxStrings only exist in cpp land, in python wxpython uses standard python strings and they are supposed to have full interoperability but there are always quirks with swig interfaces.

I made a simple mistake when trying to access the netclasses in (5.1.5)-3. I have confirmed that it works correctly for me. After using the Board Setup dialog box to add a new netclass (named “Power”), I can execute the following in the Scripting Console and in prints the correct values as shown in the dialog:

>>> pcbnew.GetBoard().GetAllNetClasses()['Default'].GetTrackWidth()
250000
>>> pcbnew.GetBoard().GetAllNetClasses()['Power'].GetTrackWidth()
500000
>>>

Yeah, that works in 5.1.5 but not in nightly.

1 Like

I think I’ve figured out the details of how it works. The following experiment tests a few “MAP”-type objects. I think it works as expected. The MAP objects properly translate string to find the elements with wxString keys. However, if you use .asdict() on the MAP object, then you get a proper Python dictionary but it has wxString objects as keys. You can’t use a string as the index to the dictionary that has wxString keys, even though you can use a string as the index to a MAP that has wxString keys.

Use “Paste Plus” in the scripting console:

board = pcbnew.GetBoard()
netcode = board.GetNetsByNetcode() # pcbnew.NETCODES_MAP
netname = board.GetNetsByName() #  pcbnew.NETNAMES_MAP
allnetclass = board.GetAllNetClasses() # pcbnew.NETCLASS_MAP
netclass = board.GetNetClasses() # pcbnew.NETCLASSES


netcode[0] # works fine
netname['GND'] # works, but the string representation (when printed) of netname just shows "NETNAMES_MAP", not the keys/values of the dictionary itself.
allnetclass['Default'] # works, but the string representation (when printed) of allnetclass just shows "NETCLASS_MAP", not the keys/values of the dictionary itself.
netclass.NetClasses() # pcbnew.NETCLASS_MAP
netclass.NetClasses()['Default'] # works fine, similar to allnetclass
netclass.NetClasses().asdict()['Default'] # doesn't work, similar to allnetclass
netcode.asdict()[0] # works fine since the key is an integer (even though it's actually a dictionary)
netname.asdict()['GND'] # doesn't work, python dictionary has wxString objects as keys.
allnetclass.asdict()['Default'] # doesn't work, python dictionary has wxString objects as keys.

And here are the results shown:

>>> board = pcbnew.GetBoard()
>>> netcode = board.GetNetsByNetcode() # pcbnew.NETCODES_MAP
>>> netname = board.GetNetsByName() #  pcbnew.NETNAMES_MAP
>>> allnetclass = board.GetAllNetClasses() # pcbnew.NETCLASS_MAP
>>> netclass = board.GetNetClasses() # pcbnew.NETCLASSES


>>> netcode[0] # works fine
<pcbnew.NETINFO_ITEM; proxy of <Swig Object of type 'NETINFO_ITEM *' at 0x000000000bda9420> >
>>> netname['GND'] # works, but the string representation (when printed) of netname just shows "NETNAMES_MAP", not the keys/values of the dictionary itself.
<pcbnew.NETINFO_ITEM; proxy of <Swig Object of type 'NETINFO_ITEM *' at 0x000000000bda9300> >
>>> allnetclass['Default'] # works, but the string representation (when printed) of allnetclass just shows "NETCLASS_MAP", not the keys/values of the dictionary itself.
<pcbnew.NETCLASSPTR; proxy of <Swig Object of type 'std::shared_ptr< NETCLASS > *' at 0x000000000bda96c0> >
>>> netclass.NetClasses() # pcbnew.NETCLASS_MAP
<pcbnew.NETCLASS_MAP; proxy of <Swig Object of type 'NETCLASS_MAP *' at 0x000000000bda9750> >
>>> netclass.NetClasses()['Default'] # works fine, similar to allnetclass
<pcbnew.NETCLASSPTR; proxy of <Swig Object of type 'std::shared_ptr< NETCLASS > *' at 0x000000000bda9690> >
>>> netclass.NetClasses().asdict()['Default'] # doesn't work, similar to allnetclass
Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: 'Default'
>>> netcode.asdict()[0] # works fine since the key is an integer (even though it's actually a dictionary)
<pcbnew.NETINFO_ITEM; proxy of <Swig Object of type 'NETINFO_ITEM *' at 0x000000000bda9750> >
>>> netname.asdict()['GND'] # doesn't work, python dictionary has wxString objects as keys.
Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: 'GND'
>>> allnetclass.asdict()['Default'] # doesn't work, python dictionary has wxString objects as keys.

Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: 'Default'

This is in KiCAD (5.1.5)-3

Application: Pcbnew
Version: (5.1.5)-3, release build
Libraries:
wxWidgets 3.0.4
libcurl/7.66.0 OpenSSL/1.1.1d (Schannel) zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.1.1) nghttp2/1.39.2
Platform: Windows 8 (build 9200), 64-bit edition, 64 bit, Little endian, wxMSW
Build Info:
wxWidgets: 3.0.4 (wchar_t,wx containers,compatible with 2.8)
Boost: 1.71.0
OpenCASCADE Community Edition: 6.9.1
Curl: 7.66.0
Compiler: GCC 9.2.0 with C++ ABI 1013

Build settings:
USE_WX_GRAPHICS_CONTEXT=OFF
USE_WX_OVERLAY=OFF
KICAD_SCRIPTING=ON
KICAD_SCRIPTING_MODULES=ON
KICAD_SCRIPTING_PYTHON3=OFF
KICAD_SCRIPTING_WXPYTHON=ON
KICAD_SCRIPTING_WXPYTHON_PHOENIX=OFF
KICAD_SCRIPTING_ACTION_MENU=ON
BUILD_GITHUB_PLUGIN=ON
KICAD_USE_OCE=ON
KICAD_USE_OCC=OFF
KICAD_SPICE=ON

Edit: the MAP objects work as expected in 5.-.5-3 stable, however wxString() takes no arguments, and I still believe that is a bug.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.