devbisme / skidl

SKiDL is a module that extends Python with the ability to design electronic circuits.
https://devbisme.github.io/skidl/
MIT License
1.04k stars 118 forks source link

[SKiDL BUG] Python3 - no manf# in xml output #108

Closed bhansconnect closed 3 years ago

bhansconnect commented 3 years ago

Describe the bug Adding a "manf#" attribute to a part does not add that field to the generated xml. It is wanted in the generated xml for use with kicost.

To Reproduce enter python 3 console:

from skidl import *
no_files()
atmega = Part('MCU_Microchip_ATmega', 'ATmega32U4-AU')
atmega.footprint = 'Package_QFP:TQFP-44_10x10mm_P0.8mm'
setattr(atmega, 'manf#', 'ATMEGA32U4-AU')
print(generate_xml())

Expected behavior The printed xml should contain the "manf#" field

Desktop (please complete the following information):

xesscorp commented 3 years ago

Hi, apologies for my late reply. I think this is not so much a bug as a misunderstanding of how to set values of part fields. (I actually had to research this because I had forgotten myself.)

If you're adding a new part field such as manf#, it has to be done like this:

atmega.fields['manf#'] = 'ATMEGA32U4-AU'

After you do the initial setting of the field, then you can reference it as an attribute from then on:

setattr(atmega, 'manf#', 'ATMEGA32U4-SOMETHING_ELSE')

The reason you can't start off using setattr(...) is because it would become impossible to create normal attributes for the Part class instances without them also becoming members of the fields dict. Then all these internal attributes would appear in the XML or netlist outputs when they are generated. SKiDL looks at any setattr(part, field_name, field_value) call and determines if field_name is already an entry in the part.fields dict and stores field_value in it if so. But if field_name is not in the fields dict, then SKiDL creates a new attribute for the Part class instance, but doesn't store it in the fields dict.

Here's your example done so it works as you'd expect:

from skidl import *
no_files()
atmega = Part('MCU_Microchip_ATmega', 'ATmega32U4-AU')
atmega.footprint = 'Package_QFP:TQFP-44_10x10mm_P0.8mm'
atmega.fields['manf#'] = 'ATMEGA32U4-AU'
print(generate_xml())

and the output is:

No errors or warnings found during XML generation.

<?xml version="1.0" encoding="UTF-8"?>
<export version="D">
  <design>
    <source>/media/devb/Main/xesscorp/KiCad/tools/skidl/skidl/circuit.py</source>
    <date>03/22/2021 08:55 PM</date>
    <tool>SKiDL (0.0.31dev)</tool>
  </design>
  <components>
    <comp ref="U1">
      <value>ATmega16U4-AU</value>
      <footprint>Package_QFP:TQFP-44_10x10mm_P0.8mm</footprint>
      <fields>
        (field (name F0) U)
        (field (name F1) ATmega16U4-AU)
        (field (name F2) Package_QFP:TQFP-44_10x10mm_P0.8mm)
        (field (name manf#) ATMEGA32U4-AU)
      </fields>
      <libsource lib="MCU_Microchip_ATmega" part="ATmega16U4-AU"/>
    </comp>
  </components>
  <nets>
  </nets>
</export>
bhansconnect commented 3 years ago

That makes a lot of sense. In that case, the skidl guide just needs to be update: https://xess.com/skidl/docs/_site/index.html

It just directly sets the manf# attribute instead of using fields:

my_part.manf = 'Atmel'
my_part.setattr('manf#', 'ATTINY4-TSHR')