Ë
    u™ãj`@  ã            	      ó.  — d Z ddlmZ ddlmZ ddlZddlmZ ddlZddlZ	ddl
mZ ddlmZ ddlmZ ddlZdd	lmZ dd
lmZ erddlmZmZmZmZ dZdZdZdZg d¢ZdZ dZ!dZ"dZ#de › de"› de!› de#› d�	Z$de › de!› d�Z%d d„Z&d!d„Z'd„ Z(d„ Z) G d„ de«      Z*y)"a-  
Read a SAS XPort format file into a Pandas DataFrame.

Based on code from Jack Cushman (github.com/jcushman/xport).

The file format is defined here:

https://support.sas.com/content/dam/SAS/support/en/technical-papers/record-layout-of-a-sas-version-5-or-6-data-set-in-sas-transport-xport-format.pdf
é    )Úannotations)ÚdatetimeN)ÚTYPE_CHECKING)Úlib)ÚPandas4Warning)Úfind_stack_level)Ú
get_handle)Ú	SASReader)ÚCompressionOptionsÚDatetimeNaTTypeÚFilePathÚ
ReadBufferzPHEADER RECORD*******LIBRARY HEADER RECORD!!!!!!!000000000000000000000000000000  zKHEADER RECORD*******MEMBER  HEADER RECORD!!!!!!!000000000000000001600000000zPHEADER RECORD*******DSCRPTR HEADER RECORD!!!!!!!000000000000000000000000000000  zPHEADER RECORD*******OBS     HEADER RECORD!!!!!!!000000000000000000000000000000  )ÚntypeÚnhfunÚfield_lengthÚnvar0ÚnameÚlabelÚnformÚnflÚnum_decimalsÚnfjÚnfillÚniformÚniflÚnifdÚnposÚ_z‚Parameters
----------
filepath_or_buffer : str or file-like object
    Path to SAS file or object implementing binary read method.aB  index : identifier of index column
    Identifier of column that should be used as index of the DataFrame.
encoding : str
    Encoding for text data.  XPORT files do not record an encoding, so
    'infer' is equivalent to the default ISO-8859-1.
chunksize : int
    Read file `chunksize` lines at a time, returns iterator.zBformat : str
    File format, only `xport` is currently supported.z\iterator : bool, default False
    Return XportReader object for reading file incrementally.z#Read a SAS file into a DataFrame.

ú
a  

Returns
-------
DataFrame or XportReader

Examples
--------
Read a SAS Xport file:

>>> df = pd.read_sas('filename.XPT')

Read an Xport file in 10,000 line chunks:

>>> itr = pd.read_sas('filename.XPT', chunksize=10000)
>>> for chunk in itr:
>>>     do_something(chunk)

z$Class for reading SAS Xport files.

zš

Attributes
----------
member_info : list
    Contains information about the file
fields : list
    Contains information about the variables in the file
c                ón   — 	 t        j                  | d«      S # t        $ r t        j                  cY S w xY w)z1Given a date in xport format, return Python date.z%d%b%y:%H:%M:%S)r   ÚstrptimeÚ
ValueErrorÚpdÚNaT)Údatestrs    úb/var/www/html/python-recuperauto-other/env/lib/python3.12/site-packages/pandas/io/sas/sas_xport.pyÚ_parse_dater'   „   s3   € ðä× Ñ  Ð*;Ó<Ð<øÜò Ü�v‰vŠðús   ‚ ˜4³4c                ód   — i }d}|D ]#  \  }}| |||z    j                  «       ||<   ||z  }Œ% |d= |S )a  
    Parameters
    ----------
    s: str
        Fixed-length string to split
    parts: list of (name, length) pairs
        Used to break up string, name '_' will be filtered from output.

    Returns
    -------
    Dict of name:contents of string at given location.
    r   r   )Ústrip)ÚsÚpartsÚoutÚstartr   Úlengths         r&   Ú_split_liner/   �   sU   € ð €CØ€EØò ‰ˆˆfØ�e˜e f™nÐ-×3Ñ3Ó5ˆˆD‰	Ø�‰‰ðð 	ˆCˆØ€Jó    c                óâ   — |dk7  rit        j                  t        | «      t        j                  d«      «      }t        j                  d|› dd|z
  › �«      }|j	                  |¬«      }| |d<   |S | S )Né   ÚS8ÚSz,S©ÚdtypeÚf0)ÚnpÚzerosÚlenr6   Úview)ÚvecÚnbytesÚvec1r6   Úvec2s        r&   Ú_handle_truncated_float_vecr@   £   si   € ð �‚{Ü�x‰xœ˜C›¤"§(¡(¨4£.Ó1ˆÜ—‘˜1˜V˜H B q¨6¡z lÐ3Ó4ˆØ�y‰y˜uˆyÓ%ˆØˆˆT‰
Øˆà€Jr0   c                óˆ  — t        j                  d«      }| j                  |¬«      }|d   }|d   }|dz  }t        j                  t	        | «      t         j
                  ¬«      }d|t        j                  |dz  «      <   d|t        j                  |d	z  «      <   d
|t        j                  |dz  «      <   ||z  }||z	  |dz  dd
|z
  z   z  z  }|dz  }||dz	  dz  dz
  dz  |z   dz   dz  |dz  z  z  }t        j                  t	        |«      fd¬«      }||d<   ||d<   |j                  d¬«      }|j                  d«      }|S )zf
    Parse a vector of float values representing IBM 8 byte floats into
    native 8 byte floats.
    z>u4,>u4r5   r7   Úf1iÿÿÿ é   i    é   i  @ é   i  € é   é   l   ÿß é   é   éA   iÿ  é   l        z>f8Úf8)	r8   r6   r;   r9   r:   Úuint8ÚwhereÚemptyÚastype)	r<   r6   r>   Úxport1Úxport2Úieee1ÚshiftÚieee2Úieees	            r&   Ú_parse_float_vecrW   ¶   sd  € ô
 �H‰H�YÓ€EØ�8‰8˜%ˆ8Ó €DØ�$‰Z€FØ�$‰Z€Fð �ZÑ€Eô �H‰H”S˜“X¤R§X¡XÔ.€EØ+,€EŒ"�(‰(�6˜JÑ&Ó
'Ñ(Ø+,€EŒ"�(‰(�6˜JÑ&Ó
'Ñ(Ø+,€EŒ"�(‰(�6˜JÑ&Ó
'Ñ(ð 
ˆe�O€EØ�u‰_ &¨:Ñ"5¸2ÀÀUÁÑ;KÑ!LÑM€Eð 
ˆZÑ€Eð 
�6˜R‘< 4Ñ'¨2Ñ-°!Ñ3°uÑ<¸tÑCÈÑJØ�Ñññ €Eô �8‰8”S˜“Z�M¨Ô3€DØ€Dˆ�JØ€Dˆ�JØ�9‰9˜5ˆ9Ó!€DØ�;‰;�tÓ€Dà€Kr0   c                  óx   — e Zd ZeZdZdeddf	 	 	 	 	 	 	 	 	 dd„Zdd„Zd„ Zdd„Z	dd„Z
dd	„Zddd
„Zd„ Zddd„Zy)ÚXportReaderz
ISO-8859-1NÚinferc                ót  — |t         j                  u| _        |t         j                  u rd }n|dk(  r| j                  }|| _        d| _        || _        || _        t        |d|d|¬«      | _	        | j                  j                  | _        	 | j                  «        y # t        $ r | j                  «        ‚ w xY w)NrZ   r   ÚrbF)ÚencodingÚis_textÚcompression)r   Ú
no_defaultÚ_encoding_specifiedÚ_default_encodingÚ	_encodingÚ_lines_readÚ_indexÚ
_chunksizer	   ÚhandlesÚhandleÚfilepath_or_bufferÚ_read_headerÚ	ExceptionÚclose)Úselfri   Úindexr]   Ú	chunksizer_   s         r&   Ú__init__zXportReader.__init__ô   s±   € ð $,´3·>±>Ð#AˆÔ Ø”s—~‘~Ñ%Ø‰HØ˜Ò Ø×-Ñ-ˆHØ!ˆŒØˆÔØˆŒØ#ˆŒä!ØØØØØ#ô
ˆŒð #'§,¡,×"5Ñ"5ˆÔð	Ø×ÑÕøÜò 	Ø�J‰JŒLØð	ús   ÂB ÂB7c                ó8   — | j                   j                  «        y ©N)rg   rl   ©rm   s    r&   rl   zXportReader.close  s   € Ø�‰×ÑÕr0   c                óT   — | j                   j                  d«      j                  «       S )NéP   )ri   ÚreadÚdecoders   s    r&   Ú_get_rowzXportReader._get_row  s"   € Ø×&Ñ&×+Ñ+¨BÓ/×6Ñ6Ó8Ð8r0   c           
     óˆ  — | j                   j                  d«       | j                  «       }|t        k7  rd|v rt	        d«      ‚t	        d«      ‚| j                  «       }ddgddgd	dgd
dgddgg}t        ||«      }|d   dk7  rt	        d«      ‚t        |d   «      |d<   || _        | j                  «       }t        |d d «      |d<   | j                  «       }| j                  «       }|j                  t        «      }|t        k(  }	|r|	st	        d«      ‚t        |dd «      }
ddgddgddgddgd	dgd
dgddgg}t        | j                  «       |«      }ddgd
dgddgddgg}|j                  t        | j                  «       |«      «       t        |d   «      |d<   t        |d   «      |d<   || _        dddœ}t        | j                  «       dd «      }|
|z  }|dz  r|d|dz  z
  z  }| j                   j                  |«      }g }d}t        |«      |
k\  rË|d |
 ||
d  }}|j!                  d«      }t#        j$                  d|«      }t'        t)        t*        |d ¬!«      «      }|d
= ||d"      |d"<   |d#   }|d"   dk(  r|d$k  s|dkD  rd%|› d&�}t-        |«      ‚|j/                  «       D ]  \  }}	 |j1                  «       ||<   Œ ||d#   z  }||gz  }t        |«      |
k\  rŒË| j                  «       }|t4        k(  st	        d'«      ‚|| _        | j8                  sDt;        d(„ |D «       «      r2t=        j>                  d)| j@                  ›d*�tB        tE        «       ¬+«       || _#        | j                   jI                  «       | _%        | jM                  «       | _'        | j6                  D �cg c]  }|d,   jQ                  «       ‘Œ c}| _)        tU        | j6                  «      D ��cg c]$  \  }}d-tW        |«      z   d.tW        |d#   «      z   f‘Œ& }}}tY        jZ                  |«      }|| _.        y # t2        $ r Y �ŒŒw xY wc c}w c c}}w )/Nr   z**COMPRESSED**z<Header record indicates a CPORT file, which is not readable.z#Header record is not an XPORT file.ÚprefixrH   Úversionr2   ÚOSr   Úcreatedé   zSAS     SAS     SASLIBz!Header record has invalid prefix.ÚmodifiedzMember header not foundéûÿÿÿéþÿÿÿÚset_nameÚsasdatar   é(   ÚtypeÚnumericÚchar)rC   rD   é6   é:   ru   éŒ   z>hhhh8s40s8shhh2s8shhl52sT)Ústrictr   r   rD   zFloating field width z is not between 2 and 8.zObservation header not found.c              3  ó,   K  — | ]  }|d    dk(  –— Œ y­w)r   r‡   N© )Ú.0Úfields     r&   ú	<genexpr>z+XportReader._read_header.<locals>.<genexpr>  s   è ø€ ò 0
Ø).ˆE�'‰N˜fÕ$ñ0
ùs   ‚zóThe default value of 'encoding' in read_sas is deprecated. In a future version the default will change from None to 'infer', and character columns will be decoded rather than returned as bytes (XPORT files record no encoding, so 'infer' means z`). Pass encoding='infer' to adopt the future behavior, or encoding=None to keep the current one.©Ú
stacklevelr   r*   r4   )/ri   Úseekrx   Ú_correct_line1r"   r/   r'   Ú	file_infoÚ
startswithÚ_correct_header1Ú_correct_header2ÚintÚupdateÚmember_inforv   r:   ÚljustÚstructÚunpackÚdictÚzipÚ
_fieldkeysÚ	TypeErrorÚitemsr)   ÚAttributeErrorÚ_correct_obs_headerÚfieldsra   ÚanyÚwarningsÚwarnrb   r   r   Úrecord_lengthÚtellÚrecord_startÚ_record_countÚnobsrw   ÚcolumnsÚ	enumerateÚstrr8   r6   Ú_dtype)rm   Úline1Úline2Úfifr•   Úline3Úheader1Úheader2Ú	headflag1Ú	headflag2ÚfieldnamelengthÚmemr›   ÚtypesÚ
fieldcountÚ
datalengthÚ	fielddatar¦   Ú
obs_lengthÚ
fieldbytesÚfieldstructr�   ÚflÚmsgÚkÚvÚheaderÚxÚiÚdtypelr6   s                                  r&   rj   zXportReader._read_header  s¶  € Ø×Ñ×$Ñ$ QÔ'ð —‘“ˆØ”NÒ"Ø 5Ñ(ô !ØRóð ô ÐBÓCÐCà—‘“ˆØ˜"ˆ~ 	¨1˜~°°a¨y¸3À¸)ÀiÐQSÀ_ÐUˆÜ  sÓ+ˆ	Ø�XÑÐ":Ò:ÜÐ@ÓAÐAÜ*¨9°YÑ+?Ó@ˆ	�)ÑØ"ˆŒà—‘“ˆÜ +¨E°#°2¨JÓ 7ˆ	�*Ñð —-‘-“/ˆØ—-‘-“/ˆØ×&Ñ&Ô'7Ó8ˆ	ØÔ/Ñ/ˆ	Ù™iÜÐ6Ó7Ð7ä˜g b¨˜nÓ-ˆð �qˆMØ˜ˆOØ˜ˆNØ˜ˆNØ�1ˆIØ�"ˆIØ˜ˆOð
ˆô " $§-¡-£/°3Ó7ˆØ˜BÐ # r ¨W°b¨M¸FÀA¸;ÐGˆØ×Ñœ; t§}¡}£¸Ó<Ô=Ü"-¨k¸*Ñ.EÓ"Fˆ�JÑÜ!,¨[¸Ñ-CÓ!Dˆ�IÑØ&ˆÔð  &Ñ)ˆÜ˜Ÿ™›¨¨BÐ/Ó0ˆ
Ø$ zÑ1ˆ
à˜Š?Ø˜"˜z¨B™Ñ.Ñ.ˆJØ×+Ñ+×0Ñ0°Ó<ˆ	ØˆØˆ
Ü�)‹n Ò/ð Ð*˜?Ð+Ø˜/Ð*Ð+ð "ˆJð $×)Ñ)¨#Ó.ˆJä Ÿ-™-Ð(CÀZÓPˆKÜœœZ¨¸TÔBÓCˆEØ�c�
Ø" 5¨¡>Ñ2ˆE�'‰NØ�~Ñ&ˆBØ�W‰~ Ò*°°a²¸RÀ!ºVØ-¨b¨TÐ1IÐJ�Ü “nÐ$àŸ™›ò ‘��1ðØ Ÿw™w›y�E˜!’Hðð ˜% Ñ/Ñ/ˆJØ�u�gÑˆFô7 �)‹n Ó/ð: —‘“ˆØÔ,Ò,ÜÐ<Ó=Ð=àˆŒØ×'Ò'¬Cñ 0
Ø28ô0
ô -
ô �M‰MðEð ×)Ñ)Ð,ð -Mð	Mô Ü+Ó-õ	ð (ˆÔØ ×3Ñ3×8Ñ8Ó:ˆÔà×&Ñ&Ó(ˆŒ	Ø48·K±KÖ@¨q˜˜&™	×(Ñ(Õ*Ò@ˆŒô
 & d§k¡kÓ2÷
á��5ð ”3�q“6‰\˜3¤ U¨>Ñ%:Ó!;Ñ;Ò<ð
ˆñ 
ô —‘˜Ó ˆØˆ�øôI &ò Úðüò8 Aùó
s   Ê0P)Î&P9Ï )P>Ð)	P6Ð5P6c                óB   — | j                  | j                  xs d¬«      S )NrC   ©Únrows)rv   rf   rs   s    r&   Ú__next__zXportReader.__next__š  s   € Ø�y‰y˜tŸ™Ò3°!ˆyÓ4Ð4r0   c                óð  — | j                   j                  dd«       | j                   j                  «       | j                  z
  }|dz  dk7  rt	        j
                  dt        «       ¬«       | j                  dkD  r4| j                   j                  | j                  «       || j                  z  S | j                   j                  dd«       | j                   j                  d«      }t        j                  |t        j                  ¬«      }t        j                  |dk(  «      }t        |«      dk(  rd}nd	t        |«      z  }| j                   j                  | j                  «       ||z
  | j                  z  S )
zÇ
        Get number of records in file.

        This is maybe suboptimal because we have to seek to the end of
        the file.

        Side effect: returns file position to record_start.
        r   rD   ru   zxport file may be corrupted.r‘   i°ÿÿÿr5   l     @@€  r2   )ri   r“   r«   r¬   r¨   r©   r   rª   rv   r8   Ú
frombufferÚuint64Úflatnonzeror:   )rm   Útotal_records_lengthÚlast_card_bytesÚ	last_cardÚixÚtail_pads         r&   r­   zXportReader._record_count�  s:  € ð 	×Ñ×$Ñ$ Q¨Ô*Ø#×6Ñ6×;Ñ;Ó=À×@QÑ@QÑQÐà "Ñ$¨Ò)Ü�M‰MØ.Ü+Ó-õð
 ×Ñ Ò"Ø×#Ñ#×(Ñ(¨×):Ñ):Ô;Ø'¨4×+=Ñ+=Ñ=Ð=à×Ñ×$Ñ$ S¨!Ô,Ø×1Ñ1×6Ñ6°rÓ:ˆÜ—M‘M /¼¿¹ÔCˆ	ô �^‰^˜IÐ)<Ñ<Ó=ˆäˆr‹7�aŠ<Ø‰Hàœ3˜r›7‘{ˆHà×Ñ×$Ñ$ T×%6Ñ%6Ô7à$ xÑ/°D×4FÑ4FÑFÐFr0   c                óB   — |€| j                   }| j                  |¬«      S )a  
        Reads lines from Xport file and returns as dataframe

        Parameters
        ----------
        size : int, defaults to None
            Number of lines to read.  If None, reads whole file.

        Returns
        -------
        DataFrame
        rÍ   )rf   rv   )rm   Úsizes     r&   Ú	get_chunkzXportReader.get_chunkÃ  s#   € ð ˆ<Ø—?‘?ˆDØ�y‰y˜tˆyÓ$Ð$r0   c                ó®   — |j                  d¬«      }|d   dk(  |d   dk(  z  |d   dk(  z  }|d   dk\  |d   d	k  z  |d   d
k(  z  |d   dk(  z  }||z  }|S )Nzu1,u1,u2,u4r5   rB   r   Úf2Úf3r7   rJ   éZ   é_   é.   )r;   )rm   r<   rÇ   ÚmissÚmiss1s        r&   Ú_missing_doublezXportReader._missing_doubleÔ  s†   € Ø�H‰H˜=ˆHÓ)ˆØ�$‘˜1‘  4¡¨A¡Ñ.°!°D±'¸Q±,Ñ?ˆà�‰g˜‰o ! D¡'¨T¡/Ñ2Ø�‰w˜$‰ñ à�‰w˜$‰ñ ð 	ð
 	�‰ˆØˆr0   c                ó|  — |€| j                   }t        || j                   | j                  z
  «      }|| j                  z  }|dk  r| j	                  «        t
        ‚| j                  j                  |«      }t        j                  || j                  |¬«      }i }t        | j                  «      D ]ò  \  }}|dt        |«      z      }	| j                  |   d   }
|
dk(  rLt        |	| j                  |   d   «      }	| j!                  |	«      }t#        |	«      }t        j$                  ||<   nf| j                  |   d   dk(  rQ|	D �cg c]  }|j'                  «       ‘Œ }}| j(                  �(|D �cg c]  }|j+                  | j(                  «      ‘Œ }}|j-                  |i«       Œô t/        j0                  |«      }| j2                  €<t/        j4                  t7        | j                  | j                  |z   «      «      |_        n|j;                  | j2                  «      }| xj                  |z  c_        |S c c}w c c}w )a  Read observations from SAS Xport file, returning as data frame.

        Parameters
        ----------
        nrows : int
            Number of rows to read from data file; if None, read whole
            file.

        Returns
        -------
        A DataFrame.
        r   )r6   Úcountr*   r   r†   r   r‡   )r®   Úminrd   rª   rl   ÚStopIterationri   rv   r8   rÑ   r²   r°   r¯   r±   r¦   r@   rä   rW   ÚnanÚrstriprc   rw   rš   r#   Ú	DataFramere   ÚIndexÚrangern   Ú	set_index)rm   rÎ   Ú
read_linesÚread_lenÚrawÚdataÚdf_dataÚjrÉ   r<   r   râ   rÇ   ÚyÚdfs                  r&   rv   zXportReader.readß  sè  € ð ˆ=Ø—I‘IˆEä˜ §	¡	¨D×,<Ñ,<Ñ <Ó=ˆ
Ø × 2Ñ 2Ñ2ˆØ�qŠ=Ø�J‰JŒLÜÐØ×%Ñ%×*Ñ*¨8Ó4ˆÜ�}‰}˜S¨¯©¸:ÔFˆàˆÜ˜dŸl™lÓ+ò 	#‰DˆAˆqØ�sœS ›V‘|Ñ$ˆCØ—K‘K ‘N 7Ñ+ˆEØ˜	Ò!Ü1°#°t·{±{À1±~ÀnÑ7UÓV�Ø×+Ñ+¨CÓ0�Ü$ SÓ)�ÜŸ&™&��$’Ø—‘˜Q‘ Ñ(¨FÒ2Ø),Ö- A�Q—X‘X•ZÐ-�Ð-à—>‘>Ð-Ø;<Ö=°a˜Ÿ™ $§.¡.Õ1Ð=�AÐ=à�N‰N˜A˜q˜6Õ"ð	#ô �\‰\˜'Ó"ˆà�;‰;ÐÜ—x‘x¤ d×&6Ñ&6¸×8HÑ8HÈ:Ñ8UÓ VÓWˆB�Hà—‘˜dŸk™kÓ*ˆBà×Ò˜JÑ&Õàˆ	ùò .ùò >s   ÅH4Å,"H9)
ri   zFilePath | ReadBuffer[bytes]r]   zstr | lib.NoDefault | Nonero   ú
int | Noner_   r   ÚreturnÚNone)rø   rù   )rø   úpd.DataFrame)rø   r™   rr   )rÚ   r÷   rø   rú   )rÎ   r÷   rø   rú   )Ú__name__Ú
__module__Ú__qualname__Ú_xport_reader_docÚ__doc__rb   rp   rl   rx   rj   rÏ   r­   rÛ   rä   rv   r�   r0   r&   rY   rY   ï   s}   „ Ø€Gà$Ðð
 Ø/@Ø $Ø*1ð#à8ð#ð -ð	#ð
 ð#ð (ð#ð 
ó#óJò9óyóv5ó$GôL%ò"	õ1r0   rY   )r%   r±   rø   r   )r*   r±   )+rÿ   Ú
__future__r   r   r�   Útypingr   r¨   Únumpyr8   Úpandas._libsr   Úpandas.errorsr   Úpandas.util._exceptionsr   Úpandasr#   Úpandas.io.commonr	   Úpandas.io.sas.sasreaderr
   Úpandas._typingr   r   r   r   r”   r—   r˜   r¥   r¡   Ú_base_params_docÚ_params2_docÚ_format_params_docÚ_iterator_docÚ_read_sas_docrþ   r'   r/   r@   rW   rY   r�   r0   r&   ú<module>r     s  ðñõ #å Û Ý  Û ã å Ý (Ý 4ã å 'Ý -á÷ó ð Wð ð Rð ð Wð ð Wð ò€
ð(CÐ ð@€ð9Ð ðA€ð
àÐ ð ØÐ ð Ø€ð Ø€ð ð€ð2ð Ð ð Ø€ð ð	Ð óóò,ò&6ôra�)õ ar0   