Qf@HdZddlZddlZddlmZmZmZmZmZm Z m Z m Z m Z m Z mZmZmZmZmZmZddlmZddlmZgdZGddZGd d eZed eGd d eZed eGddeZedeGddZGddZGddZy)z+ csv.py - read/write/investigate CSV files N)Error __version__writerreaderregister_dialectunregister_dialect get_dialect list_dialectsfield_size_limit QUOTE_MINIMAL QUOTE_ALLQUOTE_NONNUMERIC QUOTE_NONE QUOTE_STRINGS QUOTE_NOTNULL__doc__)Dialect)StringIO)r r rrrrrrrexcel excel_tabr rrrr r Snifferrr DictReader DictWriter unix_dialectc@eZdZdZdZdZdZdZdZdZ dZ dZ dZ dZ dZy)rzDescribe a CSV dialect. This must be subclassed (see csv.excel). Valid attributes are: delimiter, quotechar, escapechar, doublequote, skipinitialspace, lineterminator, quoting. FNcX|jtk7rd|_|jy)NT) __class__r_valid _validateselfs */opt/alt/python312/lib64/python3.12/csv.py__init__zDialect.__init__-s >>W $DK cf t|y#t$r}tt|d}~wwxYwN)_Dialect TypeErrorrstr)r"es r#r zDialect._validate2s, TN A-  s  0+0)__name__ __module__ __qualname__r_namer delimiter quotechar escapechar doublequoteskipinitialspacelineterminatorquotingr$r r%r#rrsA E FIIJKNG  r%rc(eZdZdZdZdZdZdZdZe Z y)rz;Describe the usual properties of Excel-generated CSV files.,"TF N) r,r-r.rr0r1r3r4r5r r6r7r%r#rr9s$EIIKNGr%rceZdZdZdZy)rzEDescribe the usual properties of Excel-generated TAB-delimited files. N)r,r-r.rr0r7r%r#rrCs OIr%rz excel-tabc(eZdZdZdZdZdZdZdZe Z y)rz:Describe the usual properties of Unix-generated CSV files.r9r:TF N) r,r-r.rr0r1r3r4r5r r6r7r%r#rrHs$DIIKNGr%runixc|eZdZ ddZdZedZejdZdZe e jZ y)rNc|t||ur t|}||_||_||_t ||g|i||_||_d|_yNr)iterlist _fieldnamesrestkeyrestvalrdialectline_num)r"f fieldnamesrGrHrIargskwdss r#r$zDictReader.__init__TsZ  !d:&6*&Dj)J%  Q7$7$7   r%c|Sr'r7r!s r#__iter__zDictReader.__iter___s r%c|j t|j|_|jj|_|jS#t$rY2wxYwr')rFnextr StopIterationrJr!s r#rLzDictReader.fieldnamesbsW    # #' #4  ,, !  sA AAc||_yr')rF)r"values r#rLzDictReader.fieldnamesls  r%c|jdk(r |jt|j}|jj|_|gk(rt|j}|gk(rt t |j|}t |j}t |}||kr||d||j<|S||kDr#|j|dD]}|j||<|SrC) rJrLrRrdictziplenrGrH)r"rowdlflrkeys r#__next__zDictReader.__next__ps ==A  OO4;; ,, Rit{{#CRi T__c* +  ! X 7!"#hAdllO"Wrs+#,r%)NNNr) r,r-r.r$rPpropertyrLsetterr_ classmethodtypes GenericAlias__class_getitem__r7r%r#rrSsXAE    !!,$E$6$67r%rcTeZdZ ddZdZdZdZdZee jZ y)rc|t||ur t|}||_||_|j }|dvrt d|z||_t||g|i||_y)N)raiseignorez-extrasaction (%s) must be 'raise' or 'ignore')rDrErLrHlower ValueError extrasactionr)r"rKrLrHrlrIrMrNs r#r$zDictWriter.__init__s{  !d:&6*&Dj)J$ #))+ 2 2L+,- -(Q7$7$7 r%cvtt|j|j}|j|Sr')rWrXrLwriterow)r"headers r# writeheaderzDictWriter.writeheaders*c$//4??;<}}V$$r%c jdk(rSjjz }|r4tddj |Dcgc] }t |c}zfdjDScc}w)Nrhz(dict contains fields not in fieldnames: z, c3VK|] }j|j"ywr')getrH).0r^rowdictr"s r# z+DictWriter._dict_to_list..s!J/3 C./s&))rlkeysrLrkjoinrepr)r"ru wrong_fieldsxs`` r# _dict_to_listzDictWriter._dict_to_listst    '"<<>DOO;L !K#'99|-L|!d1g|-L#M"NOOJ$//JJ.MsA;cV|jj|j|Sr')rrnr|)r"rus r#rnzDictWriter.writerows"{{##D$6$6w$?@@r%c`|jjt|j|Sr')r writerowsmapr|)r"rowdictss r#rzDictWriter.writerowss${{$$S););X%FGGr%N)rrhr) r,r-r.r$rpr|rnrrbrcrdrer7r%r#rrs7?F  8%KAH$E$6$67r%rc0eZdZdZdZddZdZdZdZy) rze "Sniffs" the format of a CSV file (i.e. delimiter, quotechar) Returns a Dialect object. cgd|_y)N)r9r=; :) preferredr!s r#r$zSniffer.__init__s 3r%Nc|j||\}}}}|s|j||\}}|s tdGddt}||_||_|xsd|_||_|S)zI Returns a dialect (or None) corresponding to the sample zCould not determine delimiterceZdZdZdZeZy)Sniffer.sniff..dialectsniffedr;N)r,r-r.r/r5r r6r7r%r#rIrsE#N#Gr%rIr:)_guess_quote_and_delimiter_guess_delimiterrrr3r0r1r4)r"sample delimitersr1r3r0r4rIs r#sniffz Sniffer.sniffs 226:F < ; +;*.*?*?@J+L 'I'78 8 $g $ *%%,#3 r%c,g}dD]L}tj|tjtjz}|j |}|sLn|syi}i}d}j } |D]k} | ddz } | | } | r|j | ddz|| < | ddz } | | } | r|| |vr|j | ddz|| < | ddz } | | sg|dz }mt||j } |r't||j }|||k(}|d k(rd }nd }d}tjd tj|| d ztj}|j|rd }nd}| |||fS#t$rYwxYw#t$rY'wxYw)a Looks for text enclosed between two identical quotes (the probable quotechar) which are preceded and followed by the same character (the probable delimiter). For example: ,'some text', The quote with the most wins, same with the delimiter. If there is no quotechar the delimiter can't be determined this way. )zI(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?P=delim)zG(?:^|\n)(?P["\']).*?(?P=quote)(?P[^\w\n"\'])(?P ?)zG(?P[^\w\n"\'])(?P ?)(?P["\']).*?(?P=quote)(?:$|\n)z-(?:^|\n)(?P["\']).*?(?P=quote)(?:$|\n))rFNrrquotedelimspacer^r?rz]((%(delim)s)|^)\W*%(quote)s[^%(delim)s\n]*%(quote)s[^%(delim)s\n]*%(quote)s\W*((%(delim)s)|$))rrTF) recompileDOTALL MULTILINEfindall groupindexrsKeyErrormaxescapesearch)r"datarmatchesrestrregexpquotesdelimsspacesrmnr^r1rr4 dq_regexpr3s r#rz"Sniffer._guess_quote_and_delimitersHEZZryy2<<'?@FnnT*GH'&& A7#a'AA$C$jja014s  w'!+d *cZ.?$jja014s  w'!+t! #&FJJ/ FJJ/E%e}6 }E JJ(* %(8)L MNPll\   D !KK;/?@@I     s$ E6F6 FF FFcttd|jd}tdDcgc] }t |}}t dt |}d}i}i}i} d|} } | t |kr |dz }|| | D]I} |D]B} |j| i}| j| }|j|ddz||<||| <DK|jD]} t|| j}t |dk(r |dddk(r9t |dkDrLt|d|| <|j|| || d|| dtd |Dz f|| <|d|| <|j}tt ||zt |}d }d }t | dk(rR||k\rM|D]/\}}|ddkDs|ddkDs|d|z |k\s$|||vs+|| |<1|d z}t | dk(r||k\rMt | dk(rLt| jd}|dj||djd |zk(}||fS| } | |z } | t |kr | syt | dkDrU|jD]F}|| jvs|dj||djd |zk(}||fcS| jDcgc] \}}||f }}}|j!|dd}|dj||djd |zk(}||fScc}wcc}}w)a The delimiter /should/ occur the same number of times on each row. However, due to malformed data, it may not. We don't want an all or nothing approach, so we allow for small variations in this number. 1) build a table of the frequency of each character on every line. 2) build a table of frequencies of this frequency (meta-frequency?), e.g. 'x occurred 5 times in 10 rows, 6 times in 1000 rows, 7 times in 2 rows' 3) use the mode of the meta-frequency to determine the /expected/ frequency for that character 4) find out how often the character actually meets that goal 5) the character that best meets its goal is the delimiter For performance reasons, the data is evaluated in chunks, so it can try and evaluate the smallest portion of the data possible, evaluating additional chunks as necessary. Nr? rrc |dS)Nrr7)r{s r#z*Sniffer._guess_delimiter..Ns1Q4r%rc3&K|] }|d yw)rNr7)rtitems r#rvz+Sniffer._guess_delimiter..Ss(CUTaUsg?g?g{Gz?z%c )rr)rEfiltersplitrangechrminrYrscountrwitemsrremovesumfloatrsort)r"rrcascii chunkLength iteration charFrequencymodesrstartendlinechar metaFrequencyfreqrmodeListtotal consistency thresholdkvrr4r[s r#rzSniffer._guess_delimiters&F4D!123!&s,AQ,"c$i(    sc$i NIU3!D$1$5$5dB$?M::d+D*7*;*;D!*Dq*HM$'*7M$' "(&**,]406689u:?uQx{a'7u:>"%e"@E$KLLt-#(;q>5;q>%((CU(C%C4D#EE$K#((E$K- {{}H#kI5s4yABEKIf+"{i'?$DAqtaxAaD1HqT%ZK7'/1 ?()F1I % t# f+"{i'?6{aV[[]+A.$(GMM%$8$(GMM%%-$@%A /00E ; Ccc$if v;?^^ %(,Q a(8(,Q eai(@)A$/00 $%+LLN3N5Aa!AN3 b !  GMM%0 GMM%%-89'((_-R4s M8Mctt||j|}t|}t |}i}t |D]}d||< d}|D]d}|dkDrn]|dz }t ||k7rt |jD]+} t} | || | || k7s|| | || <)|| =-fd} |jD]C\} } t| trt || | k7r| dz } -| dz} 3 | || | dz} E| dkDS#ttf$rt || } YwxYw#ttf$r| dz } YwxYw)Nrr)rrrrRrYrrErwcomplexrk OverflowErrorr isinstanceintr)) r"rrdrrocolumns columnTypesicheckedrZcolthisType hasHeadercolTypes r# has_headerzSniffer.has_headersXf%tzz&'9:cf+ wA$QC| qLG3x7"K,,./"-SX& {3//"3'/+3 C((,06 '--/LC'3'vc{#w.NINI#F3K(NI01};#M2-"3s8}H-0#I.#NI#s$ D D=D:9D:=EEr') r,r-r.rr$rrrrr7r%r#rrs%4 :IAXd)N=r%r)rrrc_csvrrrrrrr r r r r rrrrrr(ior__all__rrrrrrr7r%r#rs  %   >G% i(7&3838l 8 8FWWr%