Skip to content

Commit

Permalink
Fixes #729, see #193, #836 - handle 1.1 scoping rules in XPath evalua…
Browse files Browse the repository at this point in the history
…tions
  • Loading branch information
mbj4668 committed Nov 3, 2023
1 parent 4ba83e7 commit dc97553
Show file tree
Hide file tree
Showing 22 changed files with 351 additions and 10 deletions.
11 changes: 10 additions & 1 deletion pyang/statements.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,13 +438,18 @@ def v_init_module(ctx, stmt):
if stmt.keyword == 'module':
prefix = stmt.search_one('prefix')
stmt.i_modulename = stmt.arg
mod = stmt
else:
belongs_to = stmt.search_one('belongs-to')
if belongs_to is not None and belongs_to.arg is not None:
prefix = belongs_to.search_one('prefix')
stmt.i_modulename = belongs_to.arg
mod = ctx.get_module(stmt.i_modulename)
if mod is None:
mod = stmt
else:
stmt.i_modulename = ""
mod = None

if prefix is not None and prefix.arg is not None:
stmt.i_prefixes[prefix.arg] = (stmt.arg, None)
Expand Down Expand Up @@ -484,11 +489,14 @@ def v_init_module(ctx, stmt):
stmt.i_undefined_augment_nodes = {}
# next, set the attribute 'i_module' in each statement to point to the
# module where the statement is defined. if the module is a submodule,
# 'i_module' will point to the main module.
# 'i_main_module' will point to the main module, except if a submodule is
# validated stand-alone (then in points to the submodule)
# 'i_orig_module' will point to the real module / submodule.
# 'i_module' will point to the main module.
def set_i_module(s):
s.i_orig_module = s.top
s.i_module = s.top
s.i_main_module = mod
return
iterate_stmt(stmt, set_i_module)

Expand Down Expand Up @@ -2972,6 +2980,7 @@ class Statement(object):
'i_config', # True or False
'i_module',
'i_orig_module',
'i_main_module',

'i_not_implemented', # if set (True) this statement is not implemented,
# either a false if-feature or status
Expand Down
19 changes: 10 additions & 9 deletions pyang/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ def get_latest_revision(module):
return max(revisions) if revisions else 'unknown'


# module is the (sub)module where the statement is defined
def prefix_to_modulename_and_revision(module, prefix, pos, errors):
if prefix == '':
return module.arg, None
if prefix == module.i_prefix:
return module.arg, None
if prefix == '' or prefix == module.i_prefix:
if module.i_version == '1':
return module.arg, None
return module.i_main_module.arg, None
try:
(modulename, revision) = module.i_prefixes[prefix]
except KeyError:
Expand All @@ -86,12 +87,12 @@ def prefix_to_modulename_and_revision(module, prefix, pos, errors):
del module.i_unused_prefixes[prefix]
return modulename, revision


# module is the (sub)module where the statement is defined
def prefix_to_module(module, prefix, pos, errors):
if prefix == '':
return module
if prefix == module.i_prefix:
return module
if prefix == '' or prefix == module.i_prefix:
if module.i_version == '1':
return module
return module.i_main_module
modulename, revision = \
prefix_to_modulename_and_revision(module, prefix, pos, errors)
if modulename is None:
Expand Down
14 changes: 14 additions & 0 deletions test/test_issues/test_i193/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
test: test1 test2 test3 test4

test1:
$(PYANG) -Werror x-base.yang

test2:
$(PYANG) -Werror y-base.yang

test3:
$(PYANG) -Werror z-base.yang

test4:
$(PYANG) -Werror --print-error-code y1-base.yang 2>&1 \
| grep XPATH_NODE_NOT_FOUND2 >/dev/null || exit 1
7 changes: 7 additions & 0 deletions test/test_issues/test_i193/x-base.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module x-base {
yang-version 1.1;
namespace "http://example.com/x-base";
prefix x-b;
include x-base2;
include x-profiles;
}
10 changes: 10 additions & 0 deletions test/test_issues/test_i193/x-base2.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
submodule x-base2 {
yang-version 1.1;
belongs-to x-base {
prefix x-b;
}
container configs {
container profiles {
}
}
}
14 changes: 14 additions & 0 deletions test/test_issues/test_i193/x-profiles.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
submodule x-profiles {
yang-version 1.1;
belongs-to x-base {
prefix x-b;
}
augment "/x-b:configs/x-b:profiles" {
list profile {
key name;
leaf name {
type string;
}
}
}
}
7 changes: 7 additions & 0 deletions test/test_issues/test_i193/y-base.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module y-base {
yang-version 1.1;
namespace "http://example.com/y-base";
prefix y-b;
include y-base2;
include y-profiles;
}
10 changes: 10 additions & 0 deletions test/test_issues/test_i193/y-base2.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
submodule y-base2 {
yang-version 1.1;
belongs-to y-base {
prefix y-b;
}
container configs {
container profiles {
}
}
}
16 changes: 16 additions & 0 deletions test/test_issues/test_i193/y-profiles.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
submodule y-profiles {
yang-version 1.1;
belongs-to y-base {
prefix y-b;
}

container y {
must "/y-b:configs/y-b:profiles";
list profile {
key name;
leaf name {
type string;
}
}
}
}
6 changes: 6 additions & 0 deletions test/test_issues/test_i193/y1-base.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module y1-base {
namespace "http://example.com/y1-base";
prefix y-b;
include y1-base2;
include y1-profiles;
}
9 changes: 9 additions & 0 deletions test/test_issues/test_i193/y1-base2.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
submodule y1-base2 {
belongs-to y1-base {
prefix y-b;
}
container configs {
container profiles {
}
}
}
15 changes: 15 additions & 0 deletions test/test_issues/test_i193/y1-profiles.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
submodule y1-profiles {
belongs-to y1-base {
prefix y-b;
}

container y {
must "/y-b:configs/y-b:profiles";
list profile {
key name;
leaf name {
type string;
}
}
}
}
7 changes: 7 additions & 0 deletions test/test_issues/test_i193/z-base.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module z-base {
yang-version 1.1;
namespace "http://example.com/z-base";
prefix z-b;
include z-base2;
include z-profiles;
}
13 changes: 13 additions & 0 deletions test/test_issues/test_i193/z-base2.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
submodule z-base2 {
yang-version 1.1;
belongs-to z-base {
prefix z-b;
}
container configs {
container profiles {
leaf foo {
type string;
}
}
}
}
16 changes: 16 additions & 0 deletions test/test_issues/test_i193/z-profiles.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
submodule z-profiles {
yang-version 1.1;
belongs-to z-base {
prefix z-b;
}
augment "/z-b:configs/z-b:profiles" {
list profile {
key name;
leaf name {
type leafref {
path "../../foo";
}
}
}
}
}
14 changes: 14 additions & 0 deletions test/test_issues/test_i729/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
test: test1 test2 test3 test4

test1:
$(PYANG) -Werror -p v1.1 v1.1/native.yang

test2:
$(PYANG) -Werror -p v1.1 v1.1/bgp.yang

test3:
$(PYANG) -Werror -p v1 v1/native.yang

test4:
$(PYANG) -Werror -p v1 --print-error-code v1/bgp.yang 2>&1 \
| grep LEAFREF_IDENTIFIER_NOT_FOUND >/dev/null || exit 1
27 changes: 27 additions & 0 deletions test/test_issues/test_i729/v1.1/bgp.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module bgp {
yang-version 1.1;
namespace "http://example.com/bgp";
prefix ios-bgp;

import native {
prefix ios;
}


grouping config-bgp-grouping {
list bgp {
key "id";
leaf id {
type string;
}

container interface {
uses ios:interface-with-dependency-grouping;
}
}
}

augment "/ios:native/ios:router" {
uses config-bgp-grouping;
}
}
42 changes: 42 additions & 0 deletions test/test_issues/test_i729/v1.1/native-sub.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
submodule native-sub {
yang-version 1.1;
belongs-to native {
prefix ii;
}

grouping interface-with-dependency-grouping {
choice interface-choice {
leaf GigabitEthernet {
description
"Service-Context Virtual Interface Compress";
type leafref {
path "/ii:native/ii:interface/ii:GigabitEthernet/ii:name";
}
}
}
}

grouping config-interface-grouping {
container interface {
description
"Configure Interfaces";
list GigabitEthernet {
description
"Service-Context Virtual Interface Compress";
key "name";
leaf name {
type uint16;
}
uses interface-common-grouping;
}
}
}

grouping interface-common-grouping {
container switchport-conf {
leaf switchport {
type boolean;
}
}
}
}
19 changes: 19 additions & 0 deletions test/test_issues/test_i729/v1.1/native.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module native {
yang-version 1.1;
namespace "http://example.com/native";
prefix ios;

include native-sub;

container native {
container router;
container ip {
container routing-conf {
leaf routing {
type string;
}
}
}
uses config-interface-grouping;
}
}
26 changes: 26 additions & 0 deletions test/test_issues/test_i729/v1/bgp.yang
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module bgp {
namespace "http://example.com/bgp";
prefix ios-bgp;

import native {
prefix ios;
}


grouping config-bgp-grouping {
list bgp {
key "id";
leaf id {
type string;
}

container interface {
uses ios:interface-with-dependency-grouping;
}
}
}

augment "/ios:native/ios:router" {
uses config-bgp-grouping;
}
}
Loading

0 comments on commit dc97553

Please sign in to comment.