pyangbind icon indicating copy to clipboard operation
pyangbind copied to clipboard

Nested "choice" not working

Open pshemk opened this issue 8 years ago • 6 comments

I'm trying to generate bindings for Junipers interfaces junos-interfaces.yang, but that fails with:

TypeError: unhandled keyword with children case at junos-interfaces.yang:196 (at junos-interfaces.yang:548)

full trace here: trace

At closer inspection of the yang file I think this particular sequence is to blame: container->choice->case->choice

         choice scheduler_type {
           case case_1 {
             choice per-unit-scheduler-choice {
               leaf per-unit-scheduler {
                 description "Enable subunit queuing on Frame Relay or VLAN IQ interface";
                 type empty;
               }
               leaf no-per-unit-scheduler {
                 description "Don't enable subunit queuing on Frame Relay or VLAN IQ interface";
                 type empty;
               }
             }
           }

pshemk avatar Jun 07 '17 20:06 pshemk

@robshakir hello,

I face the same issue: I replicate the issue with my vmx (using a diff junos release).

On junos device I retrieve some yang files:

show system schema format yang module configuration module-name junos-interfaces output-directory /tmp filter [/interfaces]
show system schema format yang module configuration module-name junos-protocols-bgp output-directory /tmp filter [/protocols/bgp]

I then copied junos-protocols-bgp.yang and junos-interfaces.yang to my ubuntu vm I also git cloned clone https://github.com/Juniper/yang.git and moved all the yang files into the same directory.

on my ubuntu, this is OK:

ksator@ubuntu:~/masterIAC$ pyang --plugindir /usr/local/lib/python2.7/dist-packages/pyangbind/plugin -f pybind -o bgp.py junos-protocols-bgp.yang

and I can use the bgp class.

this is also OK:

ksator@ubuntu:~/masterIAC$ pyang junos-interfaces.yang 

so no issue with the yang file. but this is KO:

ksator@ubuntu:~/masterIAC$ pyang --plugindir /usr/local/lib/python2.7/dist-packages/pyangbind/plugin -f pybind -o interfaces.py junos-interfaces.yang 
Traceback (most recent call last):
  File "/usr/local/bin/pyang", line 420, in <module>
    run()
  File "/usr/local/bin/pyang", line 394, in run
    emit_obj.emit(ctx, modules, fd)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 211, in emit
    build_pybind(ctx, modules, fd)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 403, in build_pybind
    get_children(ctx, fd, children, m, m)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 791, in get_children
    parent_cfg=parent_cfg, choice=choice, register_paths=register_paths)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 1452, in get_element
    choice=choice, register_paths=register_paths)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 791, in get_children
    parent_cfg=parent_cfg, choice=choice, register_paths=register_paths)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 1452, in get_element
    choice=choice, register_paths=register_paths)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 791, in get_children
    parent_cfg=parent_cfg, choice=choice, register_paths=register_paths)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 1452, in get_element
    choice=choice, register_paths=register_paths)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 785, in get_children
    choice=(ch.arg, choice_ch.arg), register_paths=register_paths)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 1452, in get_element
    choice=choice, register_paths=register_paths)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 791, in get_children
    parent_cfg=parent_cfg, choice=choice, register_paths=register_paths)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 1452, in get_element
    choice=choice, register_paths=register_paths)
  File "/usr/local/lib/python2.7/dist-packages/pyangbind/plugin/pybind.py", line 848, in get_children
    raise TypeError("unhandled keyword with children %s" % parent.keyword)
TypeError: unhandled keyword with children case

Also I had a look to https://tools.ietf.org/html/rfc6020#section-7.9.1 and https://tools.ietf.org/html/rfc6020#section-7.9.2.1, it is valid to use choice as a case's Substatements, and to use case as a choice's Substatements it looks similar to this pyangbind issue https://github.com/robshakir/pyangbind/issues/88

ksator avatar Jun 07 '17 23:06 ksator

I'm also getting this problem

cgmcintyr avatar Sep 28 '18 14:09 cgmcintyr

I'm seeing this problem with the draft for the IETF access control list module . The structure goes [...] choice l4 -> container tcp -> container source-port -> case range-or-operator -> uses pf:port-range-or-operator which comes from module ietf-packet-fields -> grouping port-range-or-operator -> choice port-range-or-operator -> case range

This leads to the following error:

Traceback (most recent call last):`
  File "../../tools/bin/pyang", line 435, in <module>`
    run()
  File "../../tools/bin/pyang", line 409, in run
    emit_obj.emit(ctx, modules, fd)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 217, in emit
    build_pybind(ctx, modules, fd)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 409, in build_pybind
    get_children(ctx, fd, children, m, m)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 725, in get_children
    parent_cfg=parent_cfg, choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 1390, in get_element
    choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 725, in get_children
    parent_cfg=parent_cfg, choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 1390, in get_element
    choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 725, in get_children
    parent_cfg=parent_cfg, choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 1390, in get_element
    choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 725, in get_children
    parent_cfg=parent_cfg, choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 1390, in get_element
    choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 725, in get_children
    parent_cfg=parent_cfg, choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 1390, in get_element
    choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 719, in get_children
    choice=(ch.arg, choice_ch.arg), register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 1390, in get_element
    choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 725, in get_children
    parent_cfg=parent_cfg, choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 1390, in get_element
    choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 719, in get_children
    choice=(ch.arg, choice_ch.arg), register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 1390, in get_element
    choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 725, in get_children
    parent_cfg=parent_cfg, choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 1390, in get_element
    choice=choice, register_paths=register_paths)
  File "../../tools/lib/python2.7/site-packages/pyangbind/plugin/pybind.py", line 783, in get_children
    (parent.keyword, parent.pos))
TypeError: unhandled keyword with children case at [email protected]:456 (at [email protected]:101)`

thebowski avatar Mar 04 '19 21:03 thebowski

@thebowski me too.

elear avatar Mar 05 '19 11:03 elear

Taking a look at the code for the first time, I'm seeing the following in pyangbind/plugin/pybind.py:

            for case_ch in choice_ch.i_children:
                elements += get_element(
                    ctx,
                    fd,
                    case_ch,
                    module,
                    parent,
                    path + "/" + case_ch.arg,
                    parent_cfg=parent_cfg,
                    choice=(ch.arg, choice_ch.arg),
                    register_paths=register_paths,
                )

I'm thinking that parent needs to be iterated upward until you hit something that is expressed in the tree (as opposed to a choice), but I'm not sure if I'm reading the code correctly.

elear avatar Mar 05 '19 12:03 elear

I have same problem wieh ietf-key-chain.yang.

Sharkjuice avatar Jun 05 '19 06:06 Sharkjuice

Possible fix in https://github.com/robshakir/pyangbind/pull/340

JoseIgnacioTamayo avatar Feb 23 '24 07:02 JoseIgnacioTamayo

https://github.com/robshakir/pyangbind/pull/340 was merged and included in https://github.com/robshakir/pyangbind/releases/tag/0.8.5

Considering this issue fixed. Please re-open if not.

JoseIgnacioTamayo avatar Mar 27 '24 21:03 JoseIgnacioTamayo