mbj4668 / pyang

An extensible YANG validator and converter in python
ISC License
535 stars 344 forks source link

Inconsistent XPath warning on "when" clause #769

Closed GermanoSMO closed 2 years ago

GermanoSMO commented 2 years ago

I am using pyang 2.5.0 - This issue is not present in pyang 2.1 (I'm using also this version in a production environment)

I have this yang definition (snippet) inside a foo.yang module

1 list box-set {
2   key "index";
3   leaf index {
4       type uint32;
5       description 
6           "Box index";
7   }
8   container box {
9       leaf rule {
10          type boolean;
11          description 
12              "Mutual exclusion flag. 
13              When missing or set to false, indicates 
14              this entry can use only alpha set.
15              When set to true, it indicates this entry
16              can use only beta set.";
17      }
18      uses alpha {
19          when "not(rule) or (false()=rule)"; 
20          description 
21              "Alpha set";
22      }
23      uses beta {
24          when "false() != rule";
25          description 
26              "Beta set";
27      }
28  }
29 }

Parsing the module, pyang returns the following warning: foo.yang:19: warning: node "foo::rule" is not found in "foo::box-set"

If I modify the XPath at line 19 as follows:

when "not(./box/rule) or (false()=./box/rule)";

the warning is not issued, but:

It looks like there is something inconsistent in the XPath handling.

mbj4668 commented 2 years ago

I tried your example but couldn't reproduce the error. Could you attach a complete example (full module) that gives the error?

GermanoSMO commented 2 years ago

Here you are - this is the full module giving the error

module foo-acl {
   yang-version 1.1;
   namespace "http://www.johndoe.com/yang/acl";
   prefix acl;

    import ietf-yang-types { prefix yang;}
    import ietf-inet-types { prefix inet; }

    grouping ipv4sub {
        description 
            "Parameters for IPv4 subnet.";
        leaf address {
            type inet:ipv4-address-no-zone;
            mandatory true;
            description 
                "The IPv4 address.";
        }
        choice subnet {
            description 
                "The subnet can be specified as a prefixLength, or a netmask.";
            leaf prefixLength {
                type uint8 { range "0..32";}
                description 
                    "The length of the subnet prefix.";
            }
            leaf netmask {
                type yang:dotted-quad;
                description 
                    "The subnet specified as a netmask.";
            }
        }
    } // grouping ipv4sub

    grouping ipv6sub {
        description 
            "Parameters for IPv6 subnet.";
        leaf v6Address {
            type inet:ipv6-address-no-zone;
            mandatory true;
            description 
                "The IPv6 address.";
        }
        leaf v6PrefixLength {
            type uint8 { range "0..128";}
            description 
                "The length of the subnet prefix.";
        }
    } // grouping ipv6sub

    container ruleset {
        description
            "System group configuration.";
        list acl {
            key "idx";
            leaf idx {
                type string;
                description "list key";
            }
            leaf allowRule {
                type boolean;
                default true;
                description 
                    "if true, current rule specifies an allow rule,
                     otherwise specifies a deny rule.";
            }
            container ipAddr {
                description "IP address of allowed manager/host.";
                leaf ipv6Rule {
                    type boolean;
                    description 
                        "Mutual exclusion flag. 
                        When set to true, it indicates this entry
                        can use only IPv6 addressing.";
                }
                uses ipv4sub {
                    when "not(ipv6Rule) or (false()=ipv6Rule)"; 
                    description 
                        "IPv4 address and subnet (prefix/netmask)";
                }
                uses ipv6sub {
                    when "false() != ipv6Rule";
                    description 
                        "IPv6 address and prefix length";
                }
            }
        }
    }
}

This is the result of pyang parsing (pyang 2.5.2 running in a bash shell in Windows10 environment):

$ pyang foo-acl.yang
foo-acl.yang:76: warning: node "foo-acl::ipv6Rule" is not found in "foo-acl::acl"

NOTE: parsing the same identical module with pyang 2.1 in Linux environment does not return any error nor warnings:

[10:15:08]host:/home $ pyang -v
pyang 2.1
[10:16:27]host:/home $ pyang foo-acl.yang
[10:16:35]host:/home $ 
mbj4668 commented 2 years ago

Fixed in e15d0da64c7dfca97def04b08e905eebb4a76730