diff --git a/pyang/statements.py b/pyang/statements.py index 80249eaa..4852e1d2 100644 --- a/pyang/statements.py +++ b/pyang/statements.py @@ -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) @@ -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) @@ -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 diff --git a/pyang/util.py b/pyang/util.py index b7542b9e..8143405d 100644 --- a/pyang/util.py +++ b/pyang/util.py @@ -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: @@ -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: diff --git a/test/test_issues/test_i193/Makefile b/test/test_issues/test_i193/Makefile new file mode 100644 index 00000000..28be3390 --- /dev/null +++ b/test/test_issues/test_i193/Makefile @@ -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 diff --git a/test/test_issues/test_i193/x-base.yang b/test/test_issues/test_i193/x-base.yang new file mode 100644 index 00000000..bf1c2039 --- /dev/null +++ b/test/test_issues/test_i193/x-base.yang @@ -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; +} diff --git a/test/test_issues/test_i193/x-base2.yang b/test/test_issues/test_i193/x-base2.yang new file mode 100644 index 00000000..c6eac12d --- /dev/null +++ b/test/test_issues/test_i193/x-base2.yang @@ -0,0 +1,10 @@ +submodule x-base2 { + yang-version 1.1; + belongs-to x-base { + prefix x-b; + } + container configs { + container profiles { + } + } +} diff --git a/test/test_issues/test_i193/x-profiles.yang b/test/test_issues/test_i193/x-profiles.yang new file mode 100644 index 00000000..7c8c6b77 --- /dev/null +++ b/test/test_issues/test_i193/x-profiles.yang @@ -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; + } + } + } +} diff --git a/test/test_issues/test_i193/y-base.yang b/test/test_issues/test_i193/y-base.yang new file mode 100644 index 00000000..99727032 --- /dev/null +++ b/test/test_issues/test_i193/y-base.yang @@ -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; +} diff --git a/test/test_issues/test_i193/y-base2.yang b/test/test_issues/test_i193/y-base2.yang new file mode 100644 index 00000000..d14b82cf --- /dev/null +++ b/test/test_issues/test_i193/y-base2.yang @@ -0,0 +1,10 @@ +submodule y-base2 { + yang-version 1.1; + belongs-to y-base { + prefix y-b; + } + container configs { + container profiles { + } + } +} diff --git a/test/test_issues/test_i193/y-profiles.yang b/test/test_issues/test_i193/y-profiles.yang new file mode 100644 index 00000000..86fc03fd --- /dev/null +++ b/test/test_issues/test_i193/y-profiles.yang @@ -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; + } + } + } +} diff --git a/test/test_issues/test_i193/y1-base.yang b/test/test_issues/test_i193/y1-base.yang new file mode 100644 index 00000000..59453046 --- /dev/null +++ b/test/test_issues/test_i193/y1-base.yang @@ -0,0 +1,6 @@ +module y1-base { + namespace "http://example.com/y1-base"; + prefix y-b; + include y1-base2; + include y1-profiles; +} diff --git a/test/test_issues/test_i193/y1-base2.yang b/test/test_issues/test_i193/y1-base2.yang new file mode 100644 index 00000000..741a6c42 --- /dev/null +++ b/test/test_issues/test_i193/y1-base2.yang @@ -0,0 +1,9 @@ +submodule y1-base2 { + belongs-to y1-base { + prefix y-b; + } + container configs { + container profiles { + } + } +} diff --git a/test/test_issues/test_i193/y1-profiles.yang b/test/test_issues/test_i193/y1-profiles.yang new file mode 100644 index 00000000..2a87bcef --- /dev/null +++ b/test/test_issues/test_i193/y1-profiles.yang @@ -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; + } + } + } +} diff --git a/test/test_issues/test_i193/z-base.yang b/test/test_issues/test_i193/z-base.yang new file mode 100644 index 00000000..f0c827b7 --- /dev/null +++ b/test/test_issues/test_i193/z-base.yang @@ -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; +} diff --git a/test/test_issues/test_i193/z-base2.yang b/test/test_issues/test_i193/z-base2.yang new file mode 100644 index 00000000..0aa5034a --- /dev/null +++ b/test/test_issues/test_i193/z-base2.yang @@ -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; + } + } + } +} diff --git a/test/test_issues/test_i193/z-profiles.yang b/test/test_issues/test_i193/z-profiles.yang new file mode 100644 index 00000000..2754a2d5 --- /dev/null +++ b/test/test_issues/test_i193/z-profiles.yang @@ -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"; + } + } + } + } +} diff --git a/test/test_issues/test_i729/Makefile b/test/test_issues/test_i729/Makefile new file mode 100644 index 00000000..1faba374 --- /dev/null +++ b/test/test_issues/test_i729/Makefile @@ -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 diff --git a/test/test_issues/test_i729/v1.1/bgp.yang b/test/test_issues/test_i729/v1.1/bgp.yang new file mode 100644 index 00000000..ccf86d0c --- /dev/null +++ b/test/test_issues/test_i729/v1.1/bgp.yang @@ -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; + } +} diff --git a/test/test_issues/test_i729/v1.1/native-sub.yang b/test/test_issues/test_i729/v1.1/native-sub.yang new file mode 100644 index 00000000..7398784b --- /dev/null +++ b/test/test_issues/test_i729/v1.1/native-sub.yang @@ -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; + } + } + } +} diff --git a/test/test_issues/test_i729/v1.1/native.yang b/test/test_issues/test_i729/v1.1/native.yang new file mode 100644 index 00000000..46e72b63 --- /dev/null +++ b/test/test_issues/test_i729/v1.1/native.yang @@ -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; + } +} diff --git a/test/test_issues/test_i729/v1/bgp.yang b/test/test_issues/test_i729/v1/bgp.yang new file mode 100644 index 00000000..68491376 --- /dev/null +++ b/test/test_issues/test_i729/v1/bgp.yang @@ -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; + } +} diff --git a/test/test_issues/test_i729/v1/native-sub.yang b/test/test_issues/test_i729/v1/native-sub.yang new file mode 100644 index 00000000..abd19fac --- /dev/null +++ b/test/test_issues/test_i729/v1/native-sub.yang @@ -0,0 +1,41 @@ +submodule native-sub { + 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; + } + } + } +} diff --git a/test/test_issues/test_i729/v1/native.yang b/test/test_issues/test_i729/v1/native.yang new file mode 100644 index 00000000..cf9418be --- /dev/null +++ b/test/test_issues/test_i729/v1/native.yang @@ -0,0 +1,18 @@ +module native { + 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; + } +}