Closed igrush closed 5 years ago
substuff
is a list, but you don't instantiate an item on it, you just go straight for something that would only exist as an element of that list.
Something like, from memory:
thing = dft.staticstuff.substuff.add("mything")
route = thing.route.add("1.2.3.4/5")
I am trying to put together a unit test to demonstrate this but in the meantime, I gave your suggestion a try, adding a line to populate the list name, which I presume would instantiate the list. Thus changing the code to:
#! /usr/bin/env python3
"""What can be done with the files created by pyangbind?"""
import pyangbind.lib.pybindJSON as pyang_json
from donkey import donkey
if __name__ == "__main__":
# use the python class derived from the yang file
donk = donkey()
# get the whole object
dft = donk.donkey
dft.staticstuff.substuff.add(name="aname1")
dft.staticstuff.substuff.route.add(prefix="192.168.0.0/24")
print(dft)
# Try a json conversion first.
print("\n\nTry json Conversion\n")
jzt = pyang_json.dumps(dft,4)
print(jzt)
print("json conversion done")
but the outcome is still the same:
Traceback (most recent call last):
File "/snap/pycharm-professional/116/helpers/pydev/pydevd.py", line 1741, in <module>
main()
File "/snap/pycharm-professional/116/helpers/pydev/pydevd.py", line 1735, in main
globals = debugger.run(setup['file'], None, None, is_module)
File "/snap/pycharm-professional/116/helpers/pydev/pydevd.py", line 1135, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/snap/pycharm-professional/116/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "/home/iang/PycharmProjects/yangtoxml/pybind_out/donkey_test.py", line 16, in <module>
dft.staticstuff.substuff.route.add(prefix="192.168.0.0/24")
AttributeError: 'YANGBaseClass' object has no attribute 'route'
You need to retain the reference to the added object that .add
will return. literally: newitem = item.add(key_value)
Meaning, in your case,
dft.staticstuff.substuff.add(name="aname1")
dft.staticstuff.substuff.route.add(prefix="192.168.0.0/24")
becomes
aname = dft.staticstuff.substuff.add(name="aname1")
aname.route.add(prefix="192.168.0.0/24")
Sorry for the multiple-comment spam :) The reason: .add
adds an instance of an item to the list. It creates that item, sets the value of the key leaf and then adds it to the parent list. Once added, you can either use the reference it returns, or look it up in the list. Something like dft.staticstuss.substuff["aname"].route.add(...)
should also work, and there's also a technique for doing similar for named keys that isn't immediately coming to mind.
Thanks Chris, this has clarified a lot for me and set me on to the correct path. Very helpful. It turns out my main problem was that I was not referencing the list entries correctly. I had some problems when I tried to reference intermediate objects like aname above. I probably just need to work through that some more.
This is what works for me at the moment:
#! /usr/bin/env python3
"""What can be done with the files created by pyangbind?"""
import pyangbind.lib.pybindJSON as pyang_json
from donkey import donkey
if __name__ == "__main__":
# use the python class derived from the yang file
donk = donkey()
# get the whole object
dft = donk.donkey
dft.staticstuff.substuff.add(name="aname1")
dft.staticstuff.substuff["aname1"].route.add(ifindex=5,prefix="192.168.0.0/24")
dft.staticstuff.substuff["aname1"].route["192.168.0.0/24"].ifindex = 9
dft.staticstuff.substuff["aname1"].route["192.168.0.0/24"].ifname = "eth4"
# Try a json conversion first.
print("\n\nTry json Conversion\n")
jzt = pyang_json.dumps(dft,4)
print(jzt)
print("json conversion done")
Which gives the output:
Try json Conversion
{
"staticstuff": {
"substuff": {
"aname1": {
"name": "aname1",
"route": {
"192.168.0.0/24": {
"prefix": "192.168.0.0/24",
"ifname": "eth4",
"ifindex": 9
}
}
}
}
}
}
json conversion done
I have noticed one thing which may be a bug. The default value for distance in the route list, is 1, but it seems to not be set. It also does not seem to be instantiated as it does not show up above. I think a default valued leaf should be there.
leaf distance {
type uint8;
default 1;
}
In my yang model I have a list within a list within a container. When I generate the python bindings I am unable to modify the leaf elements in the inner list. Here is the yang.
I create the bindings with: pyang -f pybind -p ~/PycharmProjects/yangtoxml/yangtoxml -o ~/PycharmProjects/yangtoxml/pybind_out/donkey.py ~/PycharmProjects/yangtoxml/yangtoxml/donkey.yang
and I run the following test code:
Run this and you get:
This is because the substuff object has no reference to the route element.