
    11iA                     ~   S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKJr  SSKJr  / SQr\R                   \\R$                  \R&                  \R(                  \   4   rS\S\4S	 jr " S
 S5      r " S S5      r " S S\5      r " S S\5      r " S S\5      r   S!S\S\R8                  \   S\R8                  \   S\R8                  \   S\R<                  4
S jjr\r S\R                   \\R$                  4   S\RB                  \"\RF                  \   /\R                   S\RF                  \   4   4   4S jr$S\R                   \\R$                  4   S\RF                  \   4S jr%S\R                   \\R$                  4   S\RB                  \&/\4   S\"4S jr' " S S \(5      r)g)"a  Support for reading delimiter-separated value files.

This module contains unicode aware replacements for :func:`csv.reader`
and :func:`csv.writer`. It was stolen/extracted from the ``csvkit``
project to allow re-use when the whole ``csvkit`` package isn't
required.

The original implementations were largely copied from
`examples in the csv module documentation <http://docs.python.org/library/csv.html#examples>`_.

.. seealso:: http://en.wikipedia.org/wiki/Delimiter-separated_values
    N   )utils)Dialect)	UnicodeWriterUnicodeReaderUnicodeReaderWithLineNumberUnicodeDictReaderNamedTupleReaderiterrowsrewriteadd_rowsfilter_rows_as_dictencodingreturnc                 B    [         R                  " U 5      R                  $ N)codecslookupname)r   s    B/home/james-whalen/.local/lib/python3.13/site-packages/csvw/dsv.pynormalize_encodingr   &   s    =="'''    c                   x   \ rS rSrSr  SS\R                  \R                  \\	R                  4      S\R                  \R                  \\4      4S jjrS rS\R                  \   4S	 jrS
 rS\R"                  \R                  \S4      4S jrS\R"                  \R                  \\\4      4S jrSrg)r   *   u  
Write Unicode data to a csv file.

:param f: The target to which to write the data; a local path specified as `str` or     `pathlib.Path` or `None`, in which case the data, formatted as DSV can be retrieved     via :meth:`~UnicodeWriter.read`
:param dialect: Either a dialect name as recognized by `csv.writer` or a     :class:`~Dialect` instance for dialect customization beyond what can be done with     `csv.writer`.
:param kw: Keyword arguments passed through to `csv.writer`.

.. code-block:: python

    >>> from csvw import UnicodeWriter
    >>> with UnicodeWriter('data.tsv', delimiter='  ') as writer:
    ...     writer.writerow(['ä', 'ö', 'ü'])
Nfdialectc                    Xl         UR                  SS5      U l        [        U[        5      (       aB  UR
                  U l        UR                  5       U l        U R                  R                  U5        OX0l        U(       a  X R                  S'   [        U R                  5      U l        U R                  R                  S5      U l        U R                  (       aQ  U R                  R                  S5      [        R                  :w  a$  [        U R                  SU R                  -  4S jnOS nX@l        S	U l        S
U l        g )Nr   utf-8r   
escapecharquoting   c                 t    U  Vs/ s H&  n[        XA5      (       a  UR                  X#5      OUPM(     sn$ s  snf r   )
isinstancereplace)row_type_old_newss        r   _escapedoubled.UnicodeWriter.__init__.<locals>._escapedoubledQ   s9     WZZVYQRA1E1E		$-1LVYZZZs   -5c                     U $ r    )r%   s    r   r*   r+   W   s    
r   Fr   )r   popr   r#   r   python_encodingas_python_formatting_parameterskwupdater   getr   csv
QUOTE_NONEstrr*   _close_rows_written)selfr   r   r1   r*   s        r   __init__UnicodeWriter.__init__=   s    
 z73gw''#33DM==?DGGGNN2G%,	"*4==9''++l3??tww{{95G &)$(OO$%$7[,r   c                    [        U R                  [        [        R                  45      (       a{  [        U R                  [        R                  5      (       a  [        U R                  5      U l        [
        R                  " U R                  SU R                  SS9U l        SU l        O&U R                  c  [
        R                  " SS9U l        [        R                  " U R                  40 U R                  D6U l        U $ )Nwt )r   newlineT)r?   )r#   r   r6   pathlibPathioopenr   r7   StringIOr4   writerr1   r9   s    r   	__enter__UnicodeWriter.__enter__]   s    dffsGLL122$&&',,//TVVWWTVVTDMM2NDFDKVV^[[,DFjj34773r   r   c                     [        U R                  S5      (       a  U R                  R                  S5        [        U R                  S5      (       a)  U R                  R                  5       R	                  S5      $ g)z|
If the writer has been initialized passing `None` as target, the CSV data as `bytes` can be
retrieved calling this method.
seekr   readr   N)hasattrr   rJ   rK   encoderF   s    r   rK   UnicodeWriter.readj   sU    
 4666""FFKKN4666""66;;=''00 #r   c                 \    U R                   (       a  U R                  R                  5         g g r   r7   r   close)r9   typevalue	tracebacks       r   __exit__UnicodeWriter.__exit__t       ;;FFLLN r   r%   c                     U R                   R                  U R                  U5      5        U =R                  S-  sl        g )Nr   )rE   writerowr*   r8   )r9   r%   s     r   rY   UnicodeWriter.writerowx   s0    T0056ar   rowsc                    [        U5       Hq  u  p#[        U[        5      (       aF  US:X  a0  U R                  (       d  U R	                  UR                  5       5        UR                  5       nU R	                  U5        Ms     g)a  
Writes each row in `rows` formatted as CSV row. This behaves as
[`csvwriter.writerows`](https://docs.python.org/3/library/csv.html#csv.csvwriter.writerows)
except when an iterable of `dict` objects is passed. In that case, it is assumed that all
items in `rows` are `dict`s and all have the same keys in the same order (as what would
be read by `UnicodeDictReader`). Then, the keys of the first item are written as header row
and the values of each row are written as subsequent rows.

:param rows: The data to be written.
r   N)	enumerater#   dictr8   rY   keysvalues)r9   r[   ir%   s       r   	writerowsUnicodeWriter.writerows|   sY      oFA#t$$6$"4"4MM#((*-jjlMM# &r   )r7   r*   r8   r   r   r   r1   rE   )NN)__name__
__module____qualname____firstlineno____doc__typingOptionalUnionr6   r@   rA   r   r:   rG   bytesrK   rU   IterablerY   tuplelistr^   rb   __static_attributes__r-   r   r   r   r   *   s    ( CGCGv||C,=>? __V\\'3,%?@@1fooe, 1 FOOFLLd,CD  foofll5$;L.MN r   r   c                       \ rS rSrSr SS\S\R                  \R                  \	\
4      4S jjrS rS rS	 rS
 rS rSrg)r      a  
Read Unicode data from a csv file.

:param f: The source from which to read the data; a local path specified as `str` or     `pathlib.Path`, a file-like object or a `list` of lines.
:param dialect: Either a dialect name as recognized by `csv.reader` or a     :class:`~Dialect` instance for dialect customization beyond what can be done with     `csv.writer`.
:param kw: Keyword arguments passed through to `csv.reader`.

.. code-block:: python

    >>> with UnicodeReader('tests/fixtures/frictionless-data.csv', delimiter='|') as reader:
    ...     for row in reader:
    ...         print(row)
    ...         break
    ...
    ['FK', 'Year', 'Location name', 'Value', 'binary', 'anyURI', 'email', 'boolean', 'array',
    'geojson']
Nr   r   c                    Xl         [        UR                  SS5      5      U l        UR                  SS 5      U l        [        U[        5      (       a  UOS U l        U R                  (       aL  U R                  R                  U l        UR                  5       U l
        U R                  R                  U5        OX0l
        U(       a  X R                  S'   SU l        / U l        U R                  S:X  a  SU l        U R                  U l        g )Nr   z	utf-8-siglineterminatorr   Fr   )r   r   r.   r   r?   r#   r   r   r/   r0   r1   r2   r7   comments_reader_encoding)r9   r   r   r1   s       r   r:   UnicodeReader.__init__   s    
 *266*k+JKvv.5",Wg">">wD<< LL88DM==?DGGGNN2G%,	" ==G#'DM
 !%r   c                    [        U R                  [        [        R                  45      (       a  [        U R                  [        R                  5      (       a  [        U R                  5      U l        [
        R                  " U R                  SU R                  U R                  =(       d    SS9U l        SU l	        Ow[        U R                  S5      (       d\  / nU R                   HD  nUR                  [        U[        5      (       a  UR                  U R                  5      OU5        MF     Xl        [        R                  " U R                  40 U R                   D6U l        SU l        U $ )Nrtr>   )moder   r?   TrK   )r#   r   r6   r@   rA   rB   rC   r   r?   r7   rL   appendrl   decoder4   readerr1   lineno)r9   lineslines      r   rG   UnicodeReader.__enter__   s    dffsGLL122$&&',,//TVVWWTVV$PTP\P\Pb`bcDFDK((E:dE;R;RT[[7X\] Fjj34773r   c           
      |   U =R                   S-  sl         [        U R                  5       Vs/ s H5  n[        U[        5      (       a  UOUR                  U R                  5      PM7     nnU =R                   [        U Vs/ s H  n[        U5      R                  S5      PM     sn5      -  sl         U$ s  snf s  snf )Nr   
)
r   nextr~   r#   r6   r}   rv   sumro   count)r9   r)   r%   s      r   	_next_rowUnicodeReader._next_row   s    q $++&(& As##A$2G2G)HH& 	 ( 	s=ADGMM$/=>>
	( >s   <B4 $B9c                    U R                  5       nU R                  (       Ga  U(       aH  U R                  R                  (       a-  US   R                  U R                  R                  5      (       dW  U(       a  [	        U5      S1:X  a  U R                  R
                  (       d%  U R                  U R                  R                  :  Ga  U(       aH  U R                  R                  (       a-  US   R                  U R                  R                  5      (       d+  U(       a  U R                  U R                  R                  :  a{  U R                  R                  U R                  U R                  R                  R                  U5      R                  U R                  R                  5      R                  5       45        U R                  5       nU(       aK  U R                  R                  (       a0  US   R                  U R                  R                  5      (       a  GMW  U(       a  [	        U5      S1:X  a  U R                  R
                  (       a  GM  U R                  U R                  R                  :  a  GM  U Vs/ s H  o R                  R                  U5      PM     snU R                  R                  S  nU$ s  snf )Nr   r>   )r   r   commentPrefix
startswithsetskipBlankRowsr   skipRowsru   r|   	delimiterjoinlstripstriptrimmerskipColumns)r9   r%   r)   s      r   __next__UnicodeReader.__next__   s   nn<<<4<<55q6$$T\\%?%?@@SbT!1t||7Q7Q[[4<<#8#88DLL66A))$,,*D*DEEt||/D/D!DMM((..33C8??@Z@Z[aac*  nn& 4<<55q6$$T\\%?%?@@SbT!1t||7Q7Q7Q[[4<<#8#88 588Cq<<''*C89Q9Q9RSC
 9s    $K c                 \    U R                   (       a  U R                  R                  5         g g r   rP   )r9   exc_typeexc_valexc_tbs       r   rU   UnicodeReader.__exit__   rW   r   c                     U $ r   r-   rF   s    r   __iter__UnicodeReader.__iter__   s    r   )
r7   rv   ru   r   r   r   r1   r   r?   r~   r   )rd   re   rf   rg   rh   LINES_OR_PATHri   rj   rk   r   r6   r:   rG   r   r   rU   r   rp   r-   r   r   r   r      sU    . DH.. __V\\'3,%?@.@ $r   r   c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )r      z
A `UnicodeReader` yielding (lineno, row) pairs, where "lineno" is the 1-based number of the
the **text line** where the (possibly multi-line) row data starts in the DSV file.
c                 J   > [         [        U ]  5       nU R                  S-   U4$ )z9
:return: a pair (1-based line number in the input, row)
r   )superr   r   r   r9   r%   	__class__s     r   r   $UnicodeReaderWithLineNumber.__next__   s(    
 /?A{{Q##r   r-   )rd   re   rf   rg   rh   r   rp   __classcell__r   s   @r   r   r      s    $ $r   r   c                      ^  \ rS rSrSrS	U 4S jjr\U 4S j5       rS\R                  4U 4S jjr
S\R                  4S jrSrU =r$ )
r	   i  a  
A `UnicodeReader` yielding one `dict` per row.

:param f: As for :class:`UnicodeReader`
:param fieldnames:

.. code-block:: python

    >>> with UnicodeDictReader(
    ...         'tests/fixtures/frictionless-data.csv',
    ...         dialect=Dialect(delimiter='|', header=False),
    ...         fieldnames=[str(i) for i in range(1, 11)]) as reader:
    ...     for row in reader:
    ...         print(row)
    ...         break
    ...
    OrderedDict([('1', 'FK'), ('2', 'Year'), ('3', 'Location name'), ('4', 'Value'),
    ('5', 'binary'), ('6', 'anyURI'), ('7', 'email'), ('8', 'boolean'), ('9', 'array'),
    ('10', 'geojson')])

c                 b   > X l         X0l        X@l        SU l        [        [
        U ]  " U40 UD6  g Nr   )_fieldnamesrestkeyrestvalline_numr   r	   r:   )r9   r   
fieldnamesr   r   r1   r   s         r   r:   UnicodeDictReader.__init__  s/    %/8R8r   c                 t  > U R                   c   [        [        U ]  5       U l         U R
                  R                  U l        U R                   (       aK  [        [        U R                   5      5      [        U R                   5      :w  a  [        R                  " S5        U R                   $ ! [         a     Nf = f)NzDuplicate column names!)r   r   r	   r   StopIterationr~   r   lenr   warningswarn)r9   r   s    r   r   UnicodeDictReader.fieldnames#  s    ##():D#J#L  ,,3t''()S1A1A-BB78 ! s   B* *
B76B7r   c                    > U R                   S:X  a  U R                    [        [        U ]  5       nU R
                  R                   U l         U/ :X  a  [        [        U ]  5       nU/ :X  a  M  U R                  U5      $ r   )r   r   r   r	   r   r~   itemr   s     r   r   UnicodeDictReader.__next__0  sg    ==AOO%t57,,
 Ri)49;C Riyy~r   c                 (   [         R                  " S [        U R                  U5       5       5      n[	        U R                  5      n[	        U5      nX4:  a  XS  X R
                  '   U$ X4:  a$  U R                  US   H  nU R                  X%'   M     U$ )Nc              3   ,   #    U  H
  u  pX4v   M     g 7fr   r-   ).0kvs      r   	<genexpr>)UnicodeDictReader.item.<locals>.<genexpr>?  s     #Q7PtqQF7Ps   )collectionsOrderedDictzipr   r   r   r   )r9   r%   dlflrkeys         r   r   UnicodeDictReader.item>  s    ###Qs4??C7P#QQ!X7!#hAllO  Wrs+ ,r   )r   r   r   r   )NNN)rd   re   rf   rg   rh   r:   propertyr   r   r   r   r   rp   r   r   s   @r   r	   r	     sJ    ,9 
  
 +11 	;22 	 	r   r	   c                   f    \ rS rSrSr\" \R                  5      r\	R                  S 5       rS rSrg)r
   iJ  z
A `UnicodeReader` yielding one `namedtuple` per row.

.. note::

    This reader has some limitations, notably that fieldnames must be normalized to be
    admissible Python names, but also bad performance (compared with `UnicodeDictReader`).
c                     [        [        U R                  U R                  5      5      n[        R
                  " SU5      $ )NRow)ro   map_normalize_fieldnamer   r   
namedtuple)r9   r   s     r   clsNamedTupleReader.clsV  s0    #d77IJ
%%eZ88r   c                 .   [         R                  X5      nU R                   H  nUR                  US 5        M     U R                  " S0 UR                  5        VVs0 s H(  u  pEX@R                  ;   d  M  U R                  U5      U_M*     snnD6$ s  snnf )Nr-   )r	   r   r   
setdefaultr   itemsr   )r9   r%   r   r   r   r   s         r   r   NamedTupleReader.item[  s    ""4-OODLLt$ $xx _;<779]941__H\.t((+Q.9]_ 	_]s   B5Br-   N)rd   re   rf   rg   rh   staticmethodr   normalize_namer   	functoolscached_propertyr   r   rp   r-   r   r   r
   r
   J  s8     ((<(<=9 9_r   r
   lines_or_filenamedtuplesdictsc              +      #    U(       a  U(       a  [        S5      eU(       a  [        nOU(       a  [        nO[        nU" U 4SU0UD6 nU H  nUv   M	     SSS5        g! , (       d  f       g= f7f)ac  Convenience factory function for csv reader.

:param lines_or_file: Content to be read. Either a file handle, a file path or a list    of strings.
:param namedtuples: Yield namedtuples.
:param dicts: Yield dicts.
:param encoding: Encoding of the content.
:param kw: Keyword parameters are passed through to csv.reader.
:return: A generator over the rows.
z:either namedtuples or dicts can be chosen as output formatr   N)
ValueErrorr
   r	   r   )r   r   r   r   r1   _readerrr   s           r   r   r   c  s[      uUVV	"	#		8	8R	8ADJ  
9	8	8s   AA1	A 	A1 
A.*A1fnamevisitorc                 H   [         R                  " U 5      n U R                  5       (       d   e[        R                  " SS9 n[
        R                  " UR                  5      nSSS5        [        U 40 UD6 n[        W40 UD6 n[        U5       H#  u  pxU" Xx5      nUc  M  UR                  U5        M%     SSS5        SSS5        [        R                  " [        W5      [        U 5      5        g! , (       d  f       N= f! , (       d  f       NQ= f! , (       d  f       NZ= f)a4  Utility function to rewrite rows in dsv files.

:param fname: Path of the dsv file to operate on.
:param visitor: A callable that takes a line-number and a row as input and returns a     (modified) row or None to filter out the row.
:param kw: Keyword parameters are passed through to csv.reader/csv.writer.
FdeleteN)r   ensure_pathis_filetempfileNamedTemporaryFiler@   rA   r   r   r   r]   rY   shutilmover6   )	r   r   r1   fptmpreader_rE   ra   r%   s	            r   r   r     s     e$E==???		$	$E	2bll277# 
3 
u	#	#w3%"%#G,ao?OOC( - & 
$ KKC#e*% 
3	2 &% 
$	#s6   !C17DD"D7D1
C?
D	D
D!r[   c                 2   [         R                  " SS9 n[        R                  " UR                  5      nS S S 5        [
        R                  " U 5      n [        W5       nU R                  5       (       a.  [        U 5       nU H  nUR                  U5        M     S S S 5        UR                  U5        S S S 5        [        R                  " [        U5      [        U 5      5        g ! , (       d  f       N= f! , (       d  f       Nb= f! , (       d  f       NZ= f)NFr   )r   r   r@   rA   r   r   r   r   existsr   rY   rb   r   r   r6   )r   r[   r   r   rE   r   r%   s          r   r   r     s    		$	$E	2bll277# 
3 e$E	s	v<<>>u%"COOC( # & 	 
 KKC#e*% 
3	2 &% 
	s/   !C&!D C7D&
C47
D	D
Dfilter_c                 H    [        U5      n[        X40 UD6  UR                  $ )a  Rewrite a dsv file, filtering the rows.

:param fname: Path to dsv file
:param filter_: callable which accepts a `dict` with a row's data as single argument    returning a `Boolean` indicating whether to keep the row (`True`) or to discard it     `False`.
:param kw: Keyword arguments to be passed `UnicodeReader` and `UnicodeWriter`.
:return: The number of rows that have been removed.
)
DictFilterr   removed)r   r   r1   s      r   r   r     s%     !GE!b!??r   c                        \ rS rSrS rS rSrg)r   i  c                 ,    S U l         Xl        SU l        g r   )headerfilterr   )r9   r   s     r   r:   DictFilter.__init__  s    r   c                     US:X  a  X l         U$ U(       aM  [        [        U R                   U5      5      nU R                  U5      (       a  U$ U =R                  S-  sl        g g )Nr   r   )r   r^   r   r   r   )r9   ra   r%   r   s       r   __call__DictFilter.__call__  sR    6KJDKK-.D{{4  
! r   )r   r   r   N)rd   re   rf   rg   r:   r   rp   r-   r   r   r   r     s    
	"r   r   )FFr   )*rh   rB   r4   r   r   ri   r@   r   r   r   r   r>   r   dsv_dialectsr   __all__rk   r6   rA   IOrm   r   r   r   r   r   r	   r
   rj   bool	Generatorr   r~   CallableintListr   r   r^   r   objectr   r-   r   r   <module>r     s   
 
          ! S',,		6??3;OOP( ( (c cLd dN$- $B BJ_( _4 38,1.5M  //$/OOD) s+ &&	: 
&6<<W\\ 12 &__c6;;s+;%<fll4QWQ\Q\]`QaKa>b%bc&0&FLLgll!23 &FKK<L &v||C,=> !'$!>!$"" "r   