ó ŸÃÒYc@s.dZy<yddlmZWn!ek r@ddlmZnXWn!ek reddlmZnXddlmZddlmZddl Z ddl m Z ddl mZddlZyddlZWn ek rðddljZnXdd d d gZyeWnek r$eZnXyeWnek rFeZnXyeWnek rheZnXyed ƒWnek r“d „ZnXdZd„Zd„Zd„Z edddƒddd„ƒZ!ddd„Z"d„Z#d„Z$dd„Z%edddƒdd„ƒZ&d„Z'dS(s Read graphs in GML format. "GML, the G>raph Modelling Language, is our proposal for a portable file format for graphs. GML's key features are portability, simple syntax, extensibility and flexibility. A GML file consists of a hierarchical key-value lists. Graphs can be annotated with arbitrary data structures. The idea for a common file format was born at the GD'95; this proposal is the outcome of many discussions. GML is the standard file format in the Graphlet graph editor system. It has been overtaken and adapted by several other systems for drawing graphs." GML files are stored using a 7-bit ASCII encoding with any extended ASCII characters (iso8859-1) appearing as HTML character entities. You will need to give some thought into how the exported data should interact with different languages and even different Python versions. Re-importing from gml is also a concern. Without specifying a `stringizer`/`destringizer`, the code is capable of handling `int`/`float`/`str`/`dict`/`list` data as required by the GML specification. For other data types, you need to explicitly supply a `stringizer`/`destringizer`. For better interoperability of data generated by Python 2 and Python 3, we've provided `literal_stringizer` and `literal_destringizer`. For additional documentation on the GML file format, please see the `GML website `_. Several example graphs in GML format may be found on Mark Newman's `Network data page `_. iÿÿÿÿ(tStringIO(t literal_eval(t defaultdictN(t NetworkXError(t open_filetread_gmlt parse_gmlt generate_gmlt write_gmls u'\u4444'cCs|dS(Ni((ts((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pytQscCs;d„}tjd||ƒ}t|tƒr1|St|ƒS(s¯Use XML character references to escape characters. Use XML character references for unprintable or non-ASCII characters, double quotes and ampersands in a string cSs'|jdƒ}dtt|ƒƒdS(Nis&#t;(tgrouptstrtord(tmtch((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pytfixup\ss [^ -~]|[&"](tretsubt isinstanceR (ttextR((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pytescapeVs cCsd„}tjd||ƒS(s?Replace XML character references with the referenced characterscSsÎ|jdƒ}|ddkr^|ddkrHt|dd!dƒ}q‹t|dd!ƒ}n-ytj|dd!}Wntk rŠ|SXy$|d kr¤t|ƒSt|ƒSWnttfk rÉ|SXdS( Niit#itxiiÿÿÿÿii( R tintthtmlentitydefstname2codepointtKeyErrortchrtunichrt ValueErrort OverflowError(RRtcode((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyRfs $s,&(?:[0-9A-Za-z]+|#(?:[0-9]+|x[0-9A-Fa-f]+));(RR(RR((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pytunescapeds cCs…t|ttfƒrn|}tdk r6t|ƒ}nyt|ƒSWqtk rjtd|fƒ‚qXntd|fƒ‚dS(s(Convert a Python literal to the value it represents. Parameters ---------- rep : string A Python literal. Returns ------- value : object The value of the Python literal. Raises ------ ValueError If `rep` is not a Python literal. s %r is not a valid Python literals%r is not a stringN(RR tunicodetrtp_fix_unicodetNoneRt SyntaxErrorR(treptorig_rep((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pytliteral_destringizer|s  itmodetrbtlabelcCs%d„}t||ƒ||ƒ}|S(sRead graph in GML format from `path`. Parameters ---------- path : filename or filehandle The filename or filehandle to read from. label : string, optional If not None, the parsed nodes will be renamed according to node attributes indicated by `label`. Default value: 'label'. destringizer : callable, optional A `destringizer` that recovers values stored as strings in GML. If it cannot convert a string to a value, a `ValueError` is raised. Default value : None. Returns ------- G : NetworkX graph The parsed graph. Raises ------ NetworkXError If the input cannot be parsed. See Also -------- write_gml, parse_gml, literal_destringizer Notes ----- GML files are stored using a 7-bit ASCII encoding with any extended ASCII characters (iso8859-1) appearing as HTML character entities. Without specifying a `stringizer`/`destringizer`, the code is capable of handling `int`/`float`/`str`/`dict`/`list` data as required by the GML specification. For other data types, you need to explicitly supply a `stringizer`/`destringizer`. For additional documentation on the GML file format, please see the `GML website `_. See the module docstring :mod:`networkx.readwrite.gml` for additional details. Examples -------- >>> G = nx.path_graph(4) >>> nx.write_gml(G, 'test.gml') >>> H = nx.read_gml('test.gml') cssŽx‡|D]}y|jdƒ}Wntk r?tdƒ‚nXt|tƒs^t|ƒ}n|r|ddkr|d }n|VqWdS(Ntasciisinput is not ASCII-encodediÿÿÿÿs (tdecodetUnicodeDecodeErrorRRR (tlinestline((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyt filter_linesÎs   (tparse_gml_lines(tpathR,t destringizerR2tG((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyRšs4 cs4d„‰‡fd†}t||ƒ||ƒ}|S(sParse GML graph from a string or iterable. Parameters ---------- lines : string or iterable of strings Data in GML format. label : string, optional If not None, the parsed nodes will be renamed according to node attributes indicated by `label`. Default value: 'label'. destringizer : callable, optional A `destringizer` that recovers values stored as strings in GML. If it cannot convert a string to a value, a `ValueError` is raised. Default value : None. Returns ------- G : NetworkX graph The parsed graph. Raises ------ NetworkXError If the input cannot be parsed. See Also -------- write_gml, read_gml, literal_destringizer Notes ----- This stores nested GML attributes as dictionaries in the NetworkX graph, node, and edge attribute structures. GML files are stored using a 7-bit ASCII encoding with any extended ASCII characters (iso8859-1) appearing as HTML character entities. Without specifying a `stringizer`/`destringizer`, the code is capable of handling `int`/`float`/`str`/`dict`/`list` data as required by the GML specification. For other data types, you need to explicitly supply a `stringizer`/`destringizer`. For additional documentation on the GML file format, please see the `GML website `_. See the module docstring :mod:`networkx.readwrite.gml` for additional details. cSset|tƒrCy|jdƒWqCtk r?tdƒ‚qCXnt|tƒsat|ƒ}n|S(NR-sinput is not ASCII-encoded(RtbytesR.R/RR (R1((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyt decode_lines c3s³t|ttfƒrFˆ|ƒ}|jƒ}x|D] }|Vq4Wnixf|D]^}ˆ|ƒ}|r‚|ddkr‚|d }n|jdƒdkr¦tdƒ‚n|VqMWdS(Niÿÿÿÿs sinput line contains newline(RR R#t splitlinestfindR(R0R1(R8(sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyR2s       (R3(R0R,R5R2R6((R8sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyRÞs0 cs½‡fd†}d„‰‡‡fd†‰‡‡‡‡fd†‰‡‡fd†‰‡‡‡fd†}|ƒ‰|ƒ}|jdtƒ}|jdtƒ}|sÆ|r·tjƒn tjƒ}n|rØtjƒn tjƒ}|jjd „|j ƒDƒƒd „} |j d gƒ} i} t ƒ} xÖt t | tƒrI| n| gƒD]°\} }| |d d | ƒ}||kr–td |fƒ‚n|d kró| |d d| ƒ}|| krÙtd|fƒ‚n| j|ƒ|| ||jddƒ}|dk r~|j|||ƒr~tjd| ||rhdnd||fƒ‚n|j||||q>W|d kr¹tj|| ƒ}n|S(s$Parse GML `lines` into a graph. c 3s±dddddddg}tjdjd „|Dƒƒƒ}d }xRˆD]J}t|ƒ}d }x%||kr‰|j||ƒ}|dk raxôtt|ƒƒD]¸}|j|d ƒ}|dk r¢|d krâ|jƒ} n<|d krýt |ƒ} n!|d krt |ƒ} n|} |d krF|| |d |d fVn|t|ƒ7}Pq¢q¢Wqet d|||d |d fƒ‚qeW|d 7}qJWdd|d d fVdS(Ns[A-Za-z][0-9A-Za-z_]*\bs:[+-]?(?:[0-9]*\.[0-9]+|[0-9]+\.[0-9]*)(?:[Ee][+-]?[0-9]+)?s [+-]?[0-9]+s".*?"s\[s\]s#.*$|\s+t|css|]}d|dVqdS(t(t)N((t.0tpattern((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pys 9siiiiscannot tokenize %r at (%d, %d)( RtcompiletjointlentmatchR%trangeR trstriptfloatRR( tpatternsttokenstlinenoR1tlengthtposRCtiR tvalue(R0(sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyttokenize.sD          #cSsJ|\}}}}td||dk r3t|ƒnd||fƒ‚dS(Ns!expected %s, found %s at (%d, %d)tEOF(RR%trepr(t curr_tokentexpectedtcategoryRMRIRK((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyt unexpectedVs !cs+|d|krtˆƒSˆ||ƒdS(Ni(tnext(RQRSRR(RHRT(sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pytconsume]s cs2ttƒ}x|ddkr|d}tˆƒ}|d}|dksW|dkrp|d}tˆƒ}n|dkrÏt|ddd!ƒ}ˆrÀyˆ|ƒ}WqÀtk r¼qÀXntˆƒ}n.|dkrðˆ|ƒ\}}n ˆ|dƒ||j|ƒqWd„|jƒDƒ}||fS( Niiiiiÿÿÿÿisan int, float, string or '['cSsKi|]A\}}t|tƒ s4t|ƒdkr:|n|d|“qS(ii(RtlistRB(R>tkeyRM((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pys xs (RRWRUR"Rtappendtitems(RQtdctRXRSRM(R5t parse_dictRHRT(sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pytparse_kvbs.         cs@ˆ|ddƒ}ˆ|ƒ\}}ˆ|ddƒ}||fS(Nis'['is']'((RQR[(RVR](sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyR\|scsˆtˆƒƒ\}}|ddk r8ˆ|dƒnd|krStdƒ‚n|d}t|tƒr{tdƒ‚n|S(NiROtgraphsinput contains no graphs"input contains more than one graph(RUR%RRRW(RQR[R^(R]RHRT(sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyt parse_graph‚s  tdirectedt multigraphcss9|]/\}}|dkr|dkr||fVqdS(tnodetedgeN((R>RXRM((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pys –s cSsBy|j|ƒSWn*tk r=td|||fƒ‚nXdS(Ns%s #%d has no '%s' attribute(tpopRR(R[RStattrRL((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pytpop_attr™s  Rbtidsnode id %r is duplicatedR,snode label %r is duplicatedRctsourcettargets#edge #%d has an undefined source %rs#edge #%d has an undefined target %rsnedge #%d (%r%s%r) is duplicated Hint: If this is a multigraph, add "multigraph 1" to the header of the file.s->s--RXs#edge #%d (%r%s%r, %r) is duplicatedN(RdtFalsetnxtDiGraphtGrapht MultiDiGrapht MultiGraphR^tupdateRZtgettsett enumerateRRWRtaddtadd_nodethas_edgetadd_edgeR%t relabel_nodes(R0R,R5RNR_R^R`RaR6RftnodestmappingtlabelsRLRbRgtedgesRcRhRiRX((RVR5R0R\R]RHRTsl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyR3+sl(   !   1     1  %!( cs/‡‡fd†‰tƒ‰ˆ|ƒˆjƒS(s+Convert a `value` to a Python literal in GML representation. Parameters ---------- value : object The `value` to be converted to GML representation. Returns ------- rep : string A double-quoted Python literal representing value. Unprintable characters are replaced by XML character references. Raises ------ ValueError If `value` cannot be converted to GML. Notes ----- `literal_stringizer` is largely the same as `repr` in terms of functionality but attempts prefix `unicode` and `bytes` literals with `u` and `b` to provide better interoperability of data generated by Python 2 and Python 3. The original value can be recovered using the :func:`networkx.readwrite.gml.literal_destringizer` function. csMt|tttfƒs$|dkr~|tkrFˆjtdƒƒqI|tkrhˆjtdƒƒqIˆjt|ƒƒnËt|t ƒrët |ƒ}|ddkrÛy|j dƒWqÛt k r×d|}qÛXnˆj|ƒn^t|t tttfƒrˆjt |ƒƒn-t|tƒr…ˆjdƒt}x4|D],}|saˆjdƒnt}ˆ|ƒqEWˆjdƒnÄt|tƒrAt|ƒdkrˆjdƒt}x4|D],}|s܈jdƒnt}ˆ|ƒqÀWˆjd ƒqI|r1ˆjdƒˆ|dƒˆjd ƒqIˆjd ƒnt|tƒr͈jd ƒt}xW|jƒD]I\}}|s’ˆjdƒnt}ˆ|ƒˆjd ƒˆ|ƒqpWˆjdƒn|t|tƒr6ˆjd ƒt}x4|D],}|sˆjdƒnt}ˆ|ƒqöWˆjdƒntd|fƒ‚dS(Niitutlatin1t[t,t]R<R=s,)s()t{t:t}s,%r cannot be converted into a Python literal(RRtlongtboolR%tTruetwriteR RjR#RPtencodetUnicodeEncodeErrorRFtcomplexR7RWttupleRBtdictRZRrR(RMRtfirsttitemRX(tbuft stringize(sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyR‘ìs|$              (Rtgetvalue(RM((RR‘sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pytliteral_stringizerÏsG  c #sŽtjdƒ‰t‡‡‡fd†‰|jƒ}dV|jƒrLdVn|rZdVndddd h}xB|jjƒD]1\}}x"ˆ|||d ƒD] }|VqžWq|Wtt|t t |ƒƒƒƒ}d d h}x¡|j jƒD]\}} d Vdt ||ƒVx"ˆd |ddƒD] }|Vq(Wx?| jƒD]1\}}x"ˆ|||dƒD] }|VqfWqDWdVqîWddh}it d6} |r»|jdƒt | d`_. See the module docstring :mod:`networkx.readwrite.gml` for additional details. Examples -------- >>> G = nx.Graph() >>> G.add_node("1") >>> print("\n".join(nx.generate_gml(G))) graph [ node [ id 0 label "1" ] ] >>> G = nx.OrderedMultiGraph([("a", "b"), ("a", "b")]) >>> print("\n".join(nx.generate_gml(G))) graph [ multigraph 1 node [ id 0 label "a" ] node [ id 1 label "b" ] edge [ source 0 target 1 key 0 ] edge [ source 0 target 1 key 1 ] ] s^[A-Za-z][0-9A-Za-z]*$c 3s+t|ttfƒs+td|fƒ‚nˆj|ƒsPtd|fƒ‚nt|tƒsnt|ƒ}n||kr't|tttfƒr|dkr¼||dt|ƒdVq$|tkrØ||dVq$|t krô||dVq$||dt|ƒVq't|t ƒr¶t |ƒj ƒ}|j d ƒ}|d kr~|jd d |ƒd kr~|| d ||}n|dkr¢||dtdVq$||d|Vq't|tƒr*||d V|d}x?|jƒD]1\}}x"ˆ||d|ƒD] }|Vq WqéW|dVq't|ttfƒrž|dkrž|rž| rž|d}x¿|D].} x%ˆ|| d|tƒD] }|VqˆWqiWq'ˆrÞyˆ|ƒ}WqÞtk rÚtd|fƒ‚qÞXnt|ttfƒs td|fƒ‚n||dt|ƒdVndS(Ns%r is not a strings%r is not a valid keyR,s "t"s 1s 0t tEiÿÿÿÿt.is [s Rs$%r cannot be converted into a string(((RR R#RRCRR…R†R‡RjRFRPtuppertrfindR:ttestRRZRWRŒRR( RXRMt ignored_keystindenttin_listRtepost next_indentR1tval(R‘t stringizert valid_keys(sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyR‘sZ    '     !    sgraph [s directed 1s multigraph 1R`RaRbRcs RgR,s node [s id s s ]RhRitdataRXtkeyss edge [s source is target iiiÿÿÿÿRN(((RR@Rjt is_multigrapht is_directedR^RZRtzipRDRBRyR R‡RtR|( R6R¡RaR›ReRMR1tnode_idRbtattrstkwargste((R‘R¡R¢sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyR8sPS6   !            itwbcCs8x1t||ƒD] }|j|djdƒƒqWdS(s§Write a graph `G` in GML format to the file or file handle `path`. Parameters ---------- G : NetworkX graph The graph to be converted to GML. path : filename or filehandle The filename or filehandle to write. Files whose names end with .gz or .bz2 will be compressed. stringizer : callable, optional A `stringizer` which converts non-int/non-float/non-dict values into strings. If it cannot convert a value into a string, it should raise a `ValueError` to indicate that. Default value: None. Raises ------ NetworkXError If `stringizer` cannot convert a value into a string, or the value to convert is not a string while `stringizer` is None. See Also -------- read_gml, generate_gml, literal_stringizer Notes ----- Graph attributes named 'directed', 'multigraph', 'node' or 'edge', node attributes named 'id' or 'label', edge attributes named 'source' or 'target' (or 'key' if `G` is a multigraph) are ignored because these attribute names are used to encode the graph structure. GML files are stored using a 7-bit ASCII encoding with any extended ASCII characters (iso8859-1) appearing as HTML character entities. Without specifying a `stringizer`/`destringizer`, the code is capable of handling `int`/`float`/`str`/`dict`/`list` data as required by the GML specification. For other data types, you need to explicitly supply a `stringizer`/`destringizer`. For additional documentation on the GML file format, please see the `GML website `_. See the module docstring :mod:`networkx.readwrite.gml` for additional details. Examples -------- >>> G = nx.path_graph(4) >>> nx.write_gml(G, "test.gml") Filenames ending in .gz or .bz2 will be compressed. >>> nx.write_gml(G, "test.gml.gz") s R-N(RRˆR‰(R6R4R¡R1((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyRñs9cCsIddl}x6ddgD](}|jj|ƒr|j|ƒqqWdS(Niÿÿÿÿstest.gmls test.gml.gz(tosR4tisfiletunlink(tmoduleR­tfname((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pytteardown_module/s ((t__doc__t cStringIORt ImportErrortiotastRt collectionsRtnetworkxRktnetworkx.exceptionRtnetworkx.utilsRRRt html.entitiestentitiest__all__R…t NameErrorRR#R RRR&R$R%RR"R)RRR3R“RRR²(((sl/private/var/folders/w6/vb91730s7bb1k90y_rnhql1dhvdd44/T/pip-build-w4MwvS/networkx/networkx/readwrite/gml.pyt)s^                CM ¤ i ¹=