Returns a generator which `walks` the input `obj` model. Each iteration yields a triple containing a list of ancestor nodes, the name of the field, and the field value. Example: An Indicator Title with a value of "Test" could be yielded as follows: ([STIXPackage, Indicat
(obj, path=None)
| 68 | |
| 69 | |
| 70 | def iterpath(obj, path=None): |
| 71 | """Returns a generator which `walks` the input `obj` model. Each |
| 72 | iteration yields a triple containing a list of ancestor nodes, the name |
| 73 | of the field, and the field value. |
| 74 | |
| 75 | Example: |
| 76 | An Indicator Title with a value of "Test" could be yielded as follows: |
| 77 | ([STIXPackage, Indicators, Indicator], "title", "Test") |
| 78 | |
| 79 | This is performed depth-first. |
| 80 | |
| 81 | """ |
| 82 | def yield_and_descend(name, item): |
| 83 | yield (path, attr_name(name), item) |
| 84 | |
| 85 | if item is None: |
| 86 | return |
| 87 | |
| 88 | for path_info in iterpath(item, path): |
| 89 | yield path_info |
| 90 | |
| 91 | if path is None: |
| 92 | path = [] |
| 93 | |
| 94 | path.append(obj) |
| 95 | |
| 96 | for varname, varobj in _iter_vars(obj): |
| 97 | if _is_skippable(obj, varname, varobj): |
| 98 | continue |
| 99 | |
| 100 | if varname == "_inner" and is_entitylist(obj): |
| 101 | for item in varobj: |
| 102 | for path_info in iterpath(item, path): |
| 103 | yield path_info |
| 104 | elif is_sequence(varobj) and not is_entitylist(varobj): |
| 105 | for item in varobj: |
| 106 | for path_info in yield_and_descend(varname, item): |
| 107 | yield path_info |
| 108 | |
| 109 | else: |
| 110 | for path_info in yield_and_descend(varname, varobj): |
| 111 | yield path_info |
| 112 | |
| 113 | path.pop() |
no test coverage detected