3 \me#)@sddlmZddlmZddlmZmZmZmZddl Z e j Z GdddZ Gddde j Z d d Zee d d d Ze ee ee dddZGddde j Ze jde jGddde jjZeeeeeffdddZddZdddZdS) ) defaultdict)chain)AnyDictListTupleNc@s2eZdZeejejdddZddZddZdS) SchemaPathMarks)path start_markend_markcCs||_||_||_dS)N)r r r )selfr r r r /usr/lib/python3.6/safeyaml.py__init__szSchemaPathMarks.__init__cCsp|jj|jjks |jj|jjkr$dS|jj|jjkrH|jj|jjkrHdS|jj|jjkrl|jj|jjkrldSdS)z;Return whether other start/end marks are within self marks.FT)r liner column)r otherr r r __contains__szSchemaPathMarks.__contains__cCs@|jj|jjko>|jj|jjko>|jj|jjko>|jj|jjkS)N)r rrr )r rr r r__eq__+szSchemaPathMarks.__eq__N) __name__ __module__ __qualname__stryamlZMarkrrrr r r rrsrcseZdZfddZZS)_CustomSafeLoadercs tj|S)N)superZconstruct_scalar)r node) __class__r rconstruct_python_unicode5sz*_CustomSafeLoader.construct_python_unicode)rrrr __classcell__r r )rrr4srcCs2x,|dddD]}||kr||k r|SqWdS)Nr )Z child_markmarksmarkr r r_find_closest_parent9sr$) line_markscCsbx\|D]T}t||}|r|jjdd\}}|j|jksF|jj|j r|jj||jd|_qWdS)zP Update any SchemaPathMarks.path for items not under the proper parent. .r N)r$r rsplit startswithreplace)r%r#parentZ path_prefixZ _path_idxr r r_reparent_schema_mark_children@s   r+)new_markr"returncCsfg}d}x@|D]8}||kr&|j|q||kr.`. The values in schemamarks will be the line number in the original content where YAML element begins to aid in annotation when encountering schema errors. The example YAML shows expected schemamarks for both dicts and lists: one: val1 two: subtwo: val2 three: [val3, val4] schemamarks == { "one": 1, "two": 2, "two.subtwo": 3, "three": 4, "three.0": 4, "three.1": 4 } cstj|tt|_dS)N)rrrlistschemamarks_by_line)r stream)rr rrs z#_CustomSafeLoaderWithMarks.__init__cCs|jj|jkrf|j|jjd}x2|j|jjddD]}||kr8||kr8|}q8W||krf|jdSxJt|jjddD]4\}}x*|dddD]}||kr|jdSqWqzWdS)Nrr r&T)reverser!)r rr3r sorteditems)r rZmost_specific_markZ path_markZ _line_num schema_marksr#r r r_get_nested_path_prefixs  z2_CustomSafeLoaderWithMarks._get_nested_path_prefixc srtj|}|j|}xV|jD]L\}}||j}|jj}t||j|j}|j|} t || } | |j|<qW|S)N) rconstruct_mappingr:valuer rrr r3r0) r rmappingnested_path_prefixZkey_nodeZ value_node node_key_pathline_numr,r9r/)rr rr;s    z,_CustomSafeLoaderWithMarks.construct_mappingFc stj|dd}|j|}xt|jD]\}}|jj}||}t||j|j} ||j krj| g|j |<q&||jjkr|j |} t | | } | |j |<q&xvt ||jjD]d} | |j kr|j | } t | | } | |ko| dj |kr| j dt|| dj| dj| |j | <qWq&W|S)NT)deeprr r!)rconstruct_sequencer: enumerater<r rrr r3r0ranger insert) r rrAZsequencer>indexZ sequence_itemr@r?r,r9r/Z inner_line)rr rrBs<        z-_CustomSafeLoaderWithMarks.construct_sequencecs8tj}t|tr4tddt|jjD|d<|S)NcSsg|]}|j|jjdfqS)r )r r r).0vr r r sz>_CustomSafeLoaderWithMarks.get_single_data.. schemamarks)rget_single_data isinstancedictrr3values)r data)rr rrKs   z*_CustomSafeLoaderWithMarks.get_single_data)F) rrr__doc__rr:r;rBrKrr r )rrr1rs   *r1z tag:yaml.org,2002:python/unicodec@seZdZdZddZdS)NoAliasSafeDumperz>A class which avoids constructing anchors/aliases on yaml dumpcCsdS)NTr )r rOr r rignore_aliasessz NoAliasSafeDumper.ignore_aliasesN)rrrrPrRr r r rrQsrQ)r-cCs0tj|td}t|tsi}n |jd}||fS)aPerform YAML SafeLoad and track start and end marks during parse. JSON schema errors come with an encoded object path such as: .. YAML loader needs to preserve a mapping of schema path to line and column marks to annotate original content with JSON schema error marks for the command: cloud-init devel schema --annotate )LoaderrJ)rloadr1rLrMpop)blobresultrJr r rload_with_markss   rXcCstj|tdS)N)rS)rrTr)rVr r rrTsrTTFc Cs$tj|dd||d|rtntjjdS)z%Return data in nicely formatted yaml. F)Z line_breakindentexplicit_start explicit_endZdefault_flow_styleZDumper)rdumprQdumper SafeDumper)objr\r]Znoaliasr r rdumpssrb)TTF) collectionsr itertoolsrZtypingrrrrrZ YAMLErrorrZ SafeLoaderrr$r+r0r1Zadd_constructorrr_r`rQrintrXrTrbr r r rs$  "!}