a
    ߙfb                    @   s   d dl Z d dlZd dlZd dlmZ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mZ d dlmZ d d	lmZ d d
lmZ dd Zdd Zdd Zdd ZG dd deZG dd deZdd ZdS )    N)StringIOBytesIOfits)VerifyWarning)AstropyUserWarning   )FitsTestCase)_pad)_pad_length)encode_asciic                  C   sH   t ddg} t| }d| d< d|vs,J d|d< | d dksDJ dS )	zQMake sure that operations on a shallow copy do not alter the original.
    #4990.)ar   )br   d   cr   r   r   N)r   Headercopy)original_headerZcopied_header r   @lib/python3.9/site-packages/astropy/io/fits/tests/test_header.pytest_shallow_copy   s    
r   c                  C   sN   t dg} t j| dd}d| d< |d dks2J d|d< | d dksJJ dS )	zVMake sure that creating a Header from another Header makes a copy if
    copy is True.)r   
   T)r      r   r   r   Nr   r   )r   
new_headerr   r   r   test_init_with_header&   s    r   c                  C   s<   dddddd} t | }| D ]}| | || ksJ qd S )N               )r   r   r   der   )dict1h1ir   r   r   test_init_with_dict3   s    
r&   c                     sJ   dd t dD t} t|  t fddt  D sFJ d S )Nc                 S   s   g | ]\}}||fqS r   r   ).0jr%   r   r   r   
<listcomp><       z.test_init_with_ordereddict.<locals>.<listcomp>Zabcdefghijklmnopqrstuvwxyzc                 3   s&   | ]\}} | | d  kV  qdS )r   Nr   )r'   r%   valr$   Zlist1r   r   	<genexpr>A   r*   z-test_init_with_ordereddict.<locals>.<genexpr>)	enumeratecollectionsOrderedDictr   r   all)r#   r   r,   r   test_init_with_ordereddict:   s    

r2   c                   @   s^  e Zd ZdZdd Zejdddgdd Zd	d
 Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Z d9d: Z!d;d< Z"d=d> Z#d?d@ Z$dAdB Z%dCdD Z&dEdF Z'dGdH Z(dIdJ Z)dKdL Z*dMdN Z+dOdP Z,dQdR Z-dSdT Z.dUdV Z/dWdX Z0dYdZ Z1d[d\ Z2d]d^ Z3d_d` Z4dadb Z5dcdd Z6dedf Z7dgdh Z8didj Z9dkdl Z:dmdn Z;dodp Z<dqdr Z=dsdt Z>dudv Z?dwdx Z@dydz ZAd{d| ZBd}d~ ZCdd ZDdd ZEdd ZFdd ZGdd ZHdd ZIdd ZJdd ZKdd ZLdd ZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSdd ZTdd ZUdd ZVdd ZWdd ZXdd ZYdd ZZdd Z[dd Z\dd Z]dd Z^dd Z_dd Z`dd Zadd Zbdd Zcdd Zddd ZeddĄ ZfddƄ ZgddȄ Zhddʄ Zidd̄ Zjdd΄ ZkddЄ Zldd҄ ZmddԄ Znddք Zodd؄ Zpddڄ Zqdd܄ Zrddބ Zsdd Ztdd Zudd Zvdd Zwdd Zxdd Zydd Zzdd Z{dd Z|dd Z}dd Z~dd Zdd Zdd Zdd Zdd Zdd  Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS (  TestHeaderFunctionszTest Header and Card objects.c                 C   sh   t ddg}|dd d|vs&J d|v s2J |d dksBJ |d dksRJ |jd dksdJ dS )z*Test renaming keyword with rename_keyword.ABCDEFr5   r6   r   r7   N)r   r   Zrename_keywordcommentsselfheaderr   r   r   test_rename_keywordG   s    z'TestHeaderFunctions.test_rename_keywordkeyr5   r   c                 C   s   t ddg}||v sJ || dks*J ||dks<J ||dksNJ |j| dks`J ||dksrJ |j|dd d	S )
z'Check that indexing is case insensitiver4   r8   r6   r   r7   r   FZignore_missingN)r   r   getindexr<   countremove)r>   rA   r?   r   r   r   test_indexing_caseQ   s    z&TestHeaderFunctions.test_indexing_casec                 C   s   t  }d|jksJ dS )z3Test Card constructor with default argument values. N)r   Cardkeywordr>   r   r   r   r   "test_card_constructor_default_args]   s    z6TestHeaderFunctions.test_card_constructor_default_argsc                 C   s,   t jd}|jdksJ |jdks(J dS )zX
        Test loading a Card from a `bytes` object (assuming latin-1 encoding).
        s   ABC     = 'abc'ABCabcN)r   rI   
fromstringrJ   valuerK   r   r   r   test_card_from_bytesc   s    z(TestHeaderFunctions.test_card_from_bytesc                 C   sD   t dd}t|tdks J t dd}t|tdks@J dS )z'Test Card constructor with string valuerN   z<8 chzABC     = '<8 ch   'ZnullstrrH   zNULLSTR = ''Nr   rI   strr
   rK   r   r   r   test_string_value_cardl   s    z*TestHeaderFunctions.test_string_value_cardc                 C   s>   t dd}t|tdks J t jd}|jdu s:J dS )z(Test Card constructor with boolean valuerN   TzABC     =                    TzABC     = FFN)r   rI   rS   r
   rO   rP   rK   r   r   r   test_boolean_value_cardt   s    z+TestHeaderFunctions.test_boolean_value_cardc                 C   s$   t dd}t|tdks J dS )z-Test Card constructor with long integer valueZlong_intl tNxwb	B z,LONG_INT= -467374636747637647347374734737437NrR   rK   r   r   r   test_long_integer_value_card}   s    z0TestHeaderFunctions.test_long_integer_value_cardc                 C   sD   t dd}t|tdkr@t|tdkr@t|tdks@J dS )z/Test Card constructor with floating point valueZfloatnumgQzFLOATNUM= -4.6737463674763E+32zFLOATNUM= -4.6737463674763E+032NrR   rK   r   r   r   test_floating_point_value_card   s
    z2TestHeaderFunctions.test_floating_point_value_cardc                 C   sP   t dd}td}td}td}t||krLt||krLt||ksLJ dS )z(Test Card constructor with complex valuerN   ym8R{<z6ABC     = (1.23453774378878E+88, 6.32476736476374E-15)z6ABC     = (1.2345377437887E+088, 6.3247673647637E-015)N)r   rI   r
   rS   )r>   r   f1f2Zf3r   r   r   test_complex_value_card   s    z+TestHeaderFunctions.test_complex_value_cardc                 C   s   t ddd}tt jj  t|dks.J W d   n1 sB0    Y  t ddd}tt jj( t|dd d	ksJ W d   n1 s0    Y  dS )
z.Test that over-long cards truncate the commentrN   	   ZdabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdezPABC     =                    9 / abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabNZDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcdefgzABC     = '')r   rI   pytestwarnsverifyr   rS   rK   r   r   r   $test_card_image_constructed_too_long   s    &z8TestHeaderFunctions.test_card_image_constructed_too_longc                 C   s.   t ttjdddi t ttjdg d dS )z=Test that Card constructor raises exceptions on bad arguments)rN   rP   )      rA   commentN)r^   raises
ValueErrorr   rI   r>   r   r   r   /test_constructor_filter_illegal_data_structures   s    zCTestHeaderFunctions.test_constructor_filter_illegal_data_structuresc                 C   s   t ttjdd dS )z<Test that long Card keywords are allowed, but with a warning	abcdefghiZlongN)r^   r_   UserWarningr   rI   rg   r   r   r   test_keyword_too_long   s    z)TestHeaderFunctions.test_keyword_too_longc                 C   s\   t t}tdd}W d   n1 s,0    Y  t|dksFJ |jtdksXJ dS )z{
        Test that Card constructor allows illegal characters in the keyword,
        but creates a HIERARCH card.
        zabc+r[   Nr   z$HIERARCH abc+ =                    9)r^   r_   r   r   rI   lenimager
   r>   wr   r   r   r   test_illegal_characters_in_key   s    
*z2TestHeaderFunctions.test_illegal_characters_in_keyc                 C   s   t g d}|d t|dks(J |jd jdks<J |d g dksPJ t|d dksdJ |jddd	 t|dksJ |jd
 jdksJ |d g dksJ d S )N)r4   HISTORYr   rr   rb   )rr   rc   rH   rH   rH   rt         rr   )r   rb   rc   ru   z1
2
3
4r   r5   Zafterr   )r   r   rb   rc   ru   )r   r   add_historyrl   cardsrP   reprr=   r   r   r   test_add_history   s    
z$TestHeaderFunctions.test_add_historyc                 C   s   t g d}|d t|dks(J |jd jdks<J |d g dksPJ t|d dksdJ |jdd	d
 t|dksJ |jd jdksJ |d g dksJ d|d< d|d< |d g dksJ |d g dksJ d S )N)r4   )rH   r   )rH   rb   )rH   rc   rt   rt   ru      rv   rH   )r   rb   rc   rH   rH   ru   z	1
2
3


4r   r5   rw      r   )r   r   rb   rc   rH   rH   ru       )	r   r   rb   rc   rH   rH   ru   r~   rv   )r   r   Z	add_blankrl   ry   rP   rz   r=   r   r   r   test_add_blank   s    
z"TestHeaderFunctions.test_add_blankc                 C   s   G dd dt }t }|ddi ||ddg t| h dksPJ |jd d	ksbJ t }d
|d< || t| h dksJ |jd dksJ |jddd t| h dksJ t| h dksJ d S )Nc                   @   s   e Zd Zdd Zdd ZdS )z3TestHeaderFunctions.test_update.<locals>.FakeHeaderc                 S   s   dd | D S )Nc                 S   s   g | ]}|d  qS )r   r   r'   lr   r   r   r)      r*   zLTestHeaderFunctions.test_update.<locals>.FakeHeader.keys.<locals>.<listcomp>r   rg   r   r   r   keys   s    z8TestHeaderFunctions.test_update.<locals>.FakeHeader.keysc                    s   t  fdd| D S )Nc                 3   s&   | ]}|d   kr|dd V  qdS )r   r   Nr   r   rA   r   r   r-      r*   zRTestHeaderFunctions.test_update.<locals>.FakeHeader.__getitem__.<locals>.<genexpr>)next)r>   rA   r   r   r   __getitem__   s    z?TestHeaderFunctions.test_update.<locals>.FakeHeader.__getitem__N)__name__
__module____qualname__r   r   r   r   r   r   
FakeHeader   s   r   FOOBARBAZr5   r   )r6   rb   rd   >   r5   r6   r   r6   rd   )r   this is a commentHELLO>   r   r5   r6   r   r   r   )NAXIS1NAXIS2>   r   r5   r6   r   r   r   >   r   r   rb   r   )listr   r   updatesetr   r<   values)r>   r   r?   Ztmphdrr   r   r   test_update   s    
zTestHeaderFunctions.test_updatec                 C   s>  t | d}|d jddi |d jd dks:J |d jjd dksRJ tt$ |d jddi W d    n1 s0    Y  |	| 
d	 |  t j| 
d	d
d}d|d jjd< |  t | 
d	}|d jjd dksJ |d jjddd t|d jjd  dks2J |  d S )Narange.fitsr   r   r   r   r   FOO2)r   r   ZEXTRA	test.fitsr   modeQUXrw   z	COMMENT 0)r   opendatar?   r   r<   r^   re   rf   writetotempcloseadd_commentrS   ry   stripr>   hdulr   r   r   test_update_comment   s     2"z'TestHeaderFunctions.test_update_commentc                 C   sV   d}t d|}t|td| ks(J d}t d|d}t|td| ksRJ d S )Nz2A commentary card's value has no quotes around it.rr   HISTORY z!A commentary card has no comment.COMMENTrd   zCOMMENT rR   )r>   r+   r   r   r   r   test_commentary_cards  s    z)TestHeaderFunctions.test_commentary_cardsc                 C   s,   t jd}|jdksJ |jdks(J d S )NzLCOMMENT card has no comments. / text after slash is still part of the value.zDcard has no comments. / text after slash is still part of the value.rH   )r   rI   rO   rP   rd   rK   r   r   r   *test_commentary_card_created_by_fromstring   s
    z>TestHeaderFunctions.test_commentary_card_created_by_fromstringc                 C   s$   t jd}t|tdks J d S )NzHISTORY  (1, 2)r   rI   rO   rS   r
   rK   r   r   r   3test_commentary_card_will_not_parse_numerical_value)  s    zGTestHeaderFunctions.test_commentary_card_will_not_parse_numerical_valuec                 C   s$   t jd}t|tdks J d S )NzHISTORY =   (1, 2)r   rK   r   r   r   test_equal_sign_after_column8.  s    z1TestHeaderFunctions.test_equal_sign_after_column8c                 C   sP   t dd}t|tdks J t jt|}|jdks>J |jdksLJ d S )NrH   z       / EXPOSURE INFORMATIONz%               / EXPOSURE INFORMATION)r   rI   rS   r
   rO   rJ   rP   rK   r   r   r   test_blank_keyword4  s
    z&TestHeaderFunctions.test_blank_keywordc                 C   s(   t dt jj}t|tdks$J d S )NZundefz	UNDEF   =)r   rI   card	UNDEFINEDrS   r
   rK   r   r   r   test_specify_undefined_value;  s    z0TestHeaderFunctions.test_specify_undefined_valuec                 C   s$   t jd}t|tdks J d S )NzABC     = (8, 9)r   rK   r   r   r   &test_complex_number_using_string_input@  s    z:TestHeaderFunctions.test_complex_number_using_string_inputc                 C   sd   t jd}|jdksJ tjt jjdd$ t|t	dksBJ W d    n1 sV0    Y  d S )Nzabc     = +  2.1   e + 12g  ~BVerification reported errorsmatchzABC     =             +2.1E+12)
r   rI   rO   rP   r^   r_   r`   r   rS   r
   r>   capsysr   r   r   r   #test_fixable_non_standard_fits_cardE  s    
z7TestHeaderFunctions.test_fixable_non_standard_fits_cardc                 C   sR   t jd}tjt jjdd  t|dks0J W d    n1 sD0    Y  d S )NzGno_quote=  this card's value has no quotes / let's also try the commentr   r   zPNO_QUOTE= 'this card''s value has no quotes' / let's also try the comment       )r   rI   rO   r^   r_   r`   r   rS   rK   r   r   r   test_fixable_non_fscM  s    
z(TestHeaderFunctions.test_fixable_non_fscc                 C   s$   t jd}t|tdks J d S )NzABC     =    z	ABC     =r   rK   r   r   r   'test_undefined_value_using_string_inputY  s    z;TestHeaderFunctions.test_undefined_value_using_string_inputc                 C   sL   t  }d|d< d |d< t| dd gks0J t| ddgksHJ d S )Nr   r   UNDEF)r   r   )r   N)r   r   r   r   itemsr=   r   r   r   test_undefined_keys_values^  s
    z.TestHeaderFunctions.test_undefined_keys_valuesc                 C   sr   t jd}|jdksJ |jdks(J tjt jjdd$ t	|t
dksPJ W d    n1 sd0    Y  d S )NzXYZ= 100ZXYZr   r   r   zXYZ     =                  100)r   rI   rO   rJ   rP   r^   r_   r`   r   rS   r
   r   r   r   r   test_mislocated_equal_signf  s    
z.TestHeaderFunctions.test_mislocated_equal_signc                 C   s   t jd}tjtdd$ t|tdks0J W d    n1 sD0    Y  t jd}tjtdd$ t|tdks~J W d    n1 s0    Y  d S )NzHISTO       =   (1, 2)zheader keyword is invalidr   z   HISTORY          (1, 2))r   rI   rO   r^   r_   r   rS   r
   r   r   r   r   test_equal_only_up_to_column_10o  s    2z3TestHeaderFunctions.test_equal_only_up_to_column_10c                 C   s   t jd}tt}|  W d    n1 s40    Y  d}d}t|dksVJ |t|d j	v slJ |t|d j	v sJ d S )NABC= a6z<Card 'ABC' is not FITS standard (equal sign not at column 8)z;Card 'ABC' is not FITS standard (invalid value string: 'a6'ru   r   rb   )
r   rI   rO   r^   r_   r   r`   rl   rS   message)r>   r   ro   Z	err_text1Z	err_text2r   r   r   test_verify_invalid_equal_sign  s    &z2TestHeaderFunctions.test_verify_invalid_equal_signc                 C   sp   d}t jd}tjt|d}|d W d    n1 s>0    Y  t|dksXJ t|t	dkslJ d S )Nz+Fixed 'ABC' card to meet the FITS standard.r   r   fixru   zABC     = 'a6      ')
r   rI   rO   r^   r_   r   r`   rl   rS   r
   )r>   Zfix_textr   ro   r   r   r   test_fix_invalid_equal_sign  s    (z/TestHeaderFunctions.test_fix_invalid_equal_signc                 C   s"   t ddd}t|dksJ d S )NrN   long string value long string value long string value long string value long string value long string value long string value long string value long string value long string value long comment long comment long comment long comment long comment long comment long comment long comment long comment long comment   ABC     = 'long string value long string value long string value long string &' CONTINUE  'value long string value long string value long string value long &'  CONTINUE  'string value long string value long string value &'                  CONTINUE  '&' / long comment long comment long comment long comment long        CONTINUE  '&' / comment long comment long comment long comment long comment     CONTINUE  '' / long comment                                                     r   rI   rS   rK   r   r   r   test_long_string_value  s    z*TestHeaderFunctions.test_long_string_valuec                 C   s    t dd}t|dksJ dS )zU
        Regression test for https://github.com/astropy/astropy/issues/11298
        ZWHATEVERzSuperCalibrationParameters_XXXX_YYYY_ZZZZZ_KK_01_02_03)-AAABBBCCC.n.h5 SuperNavigationParameters_XXXX_YYYY_ZZZZZ_KK_01_02_03)-AAABBBCCC.n.xmla@  WHATEVER= 'SuperCalibrationParameters_XXXX_YYYY_ZZZZZ_KK_01_02_03)-AAABBBCCC.n&'CONTINUE  '.h5 &'                                                               CONTINUE  'SuperNavigationParameters_XXXX_YYYY_ZZZZZ_KK_01_02_03)-AAABBBCCC.n.&'CONTINUE  'xml'                                                                 Nr   rK   r   r   r   /test_long_string_value_with_multiple_long_words  s    zCTestHeaderFunctions.test_long_string_value_with_multiple_long_wordsc                 C   s8   t  }d|d< t  }d|d< t|t|ks4J dS )zRegression test for
        https://github.com/spacetelescope/PyFITS/issues/1

        So long as a unicode string can be converted to ASCII it should have no
        different behavior in this regard from a byte string.
        ZabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgabcdefgTESTN)r   r   rS   )r>   r$   Zh2r   r   r   test_long_unicode_string  s
    z,TestHeaderFunctions.test_long_unicode_stringc                 C   sd   t  }d|d< d|d< d|d< t| tt ddddd	d
dddtt dddgks`J dS )zRegression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/193

        Ensure that the __repr__() for cards represented with CONTINUE cards is
        split across multiple lines (broken at each *physical* card).
        )Regular valueRegular commentTEST1)r   r   TEST2ZTEST3r   r   zPTEST2   = 'long string value long string value long string value long string &' zPCONTINUE  'value long string value long string value long string value long &'  zPCONTINUE  'string value long string value long string value &'                  zPCONTINUE  '&' / long comment long comment long comment long comment long        zPCONTINUE  '&' / comment long comment long comment long comment long comment     zPCONTINUE  '' / long comment                                                     N)r   r   rz   
splitlinesrS   rI   r=   r   r   r   test_long_string_repr  s    
z)TestHeaderFunctions.test_long_string_reprc                 C   sz   d}t  }||d< t|dks$J d|d | ks>J ||d< ||d< |d |d ksbJ |d |d ksvJ dS )a	  Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/194

        Test that a blank keyword ('') can be assigned a too-long value that is
        continued across multiple cards with blank keywords, just like COMMENT
        and HISTORY cards.
        r   rH   rc   r   r   rr   N)r   r   rl   joinrstrip)r>   rP   r?   r   r   r   test_blank_keyword_long_value  s    z1TestHeaderFunctions.test_blank_keyword_long_valuec                 C   sn   t ddd}t  }|j| || d t | d}|d jjd }|	  t
|dksjJ d S )NrN   r   r   ztest_new.fitsr   r   )r   rI   
PrimaryHDUr?   appendr   r   r   ry   r   rS   )r>   r   hdur   r   r   r   test_long_string_from_file  s    z.TestHeaderFunctions.test_long_string_from_filec                 C   s"   t ddd}t|dksJ d S )NrN   ZlongstringvaluelongstringvaluelongstringvaluelongstringvaluelongstringvaluelongstringvaluelongstringvaluelongstringvaluelongstringvaluelongstringvalueZnlongcommentlongcommentlongcommentlongcommentlongcommentlongcommentlongcommentlongcommentlongcommentlongcommenta  ABC     = 'longstringvaluelongstringvaluelongstringvaluelongstringvaluelongstr&'CONTINUE  'ingvaluelongstringvaluelongstringvaluelongstringvaluelongstringvalu&'CONTINUE  'elongstringvalue&'                                                   CONTINUE  '&' / longcommentlongcommentlongcommentlongcommentlongcommentlongcommeCONTINUE  '' / ntlongcommentlongcommentlongcommentlongcomment                   r   rK   r   r   r   !test_word_in_long_string_too_long  s    z5TestHeaderFunctions.test_word_in_long_string_too_longc                 C   sf   t jtdtd td }tjt jjdd  t|dksDJ W d    n1 sX0    Y  d S )Nz;abc     = 'longstring''s testing  &  ' / comments in line 1zLcontinue  'continue with long string but without the ampersand at the end' /zNcontinue  'continue must have string value (with quotes)' / comments with ''. r   r   zABC     = 'longstring''s testing  continue with long string but without the &'  CONTINUE  'ampersand at the endcontinue must have string value (with quotes)&'  CONTINUE  '' / comments in line 1 comments with ''.                             )	r   rI   rO   r
   r^   r_   r`   r   rS   r   r   r   r   %test_long_string_value_via_fromstring  s    
z9TestHeaderFunctions.test_long_string_value_via_fromstringc                 C   sN   t jtdtd td }|jdks.J |jdks<J |jdksJJ dS )zW
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/117
        zFEXPR    = '/grp/hst/cdbs//grid/pickles/dat_uvk/pickles_uk_10.fits * &'z)CONTINUE  '5.87359e-12 * MWAvg(Av=0.12)&'z CONTINUE  '&' / pysyn expressionZEXPRzU/grp/hst/cdbs//grid/pickles/dat_uvk/pickles_uk_10.fits * 5.87359e-12 * MWAvg(Av=0.12)zpysyn expressionN)r   rI   rO   r
   rJ   rP   rd   rK   r   r   r   'test_continue_card_with_equals_in_value  s    z;TestHeaderFunctions.test_continue_card_with_equals_in_valuec                 C   s0   t  }d|d< t| d tdks,J dS )T
        Regression test for https://github.com/astropy/astropy/issues/3282
        ZEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZSVALUEr   zCONTINUE  'AA'N)r   r   rz   r   r
   r>   hr   r   r   (test_final_continue_card_lacks_ampersand&  s    z<TestHeaderFunctions.test_final_continue_card_lacks_ampersandc                 C   s"   t ddd}t|dksJ dS )r   r   zdlong valuelong valuelong valuelong valuelong valuelong valuelong valuelong valuelong valuelong valuezlong comment &long comment &long comment &long comment &long comment &long comment &long comment &long comment &long comment &long comment &a  TEST    = 'long valuelong valuelong valuelong valuelong valuelong valuelong &'  CONTINUE  'valuelong valuelong valuelong value&'                                CONTINUE  '&' / long comment &long comment &long comment &long comment &long    CONTINUE  '&' / comment &long comment &long comment &long comment &long comment CONTINUE  '' / &long comment &                                                  Nr   rK   r   r   r   ;test_final_continue_card_ampersand_removal_on_long_comments/  s    zOTestHeaderFunctions.test_final_continue_card_ampersand_removal_on_long_commentsc                 C   s   t jtdd}tdd}W d    n1 s00    Y  t|dksJJ t|dksZJ tdd}t|td	kszJ td
d}t|dksJ d S )NzHIERARCH card will be createdr   zESO INS SLIT2 Y1FRMLz/ENC=OFFSET+RESOL*acos((WID-(MAX+MIN))/(MAX-MIN)r   zPHIERARCH ESO INS SLIT2 Y1FRML= 'ENC=OFFSET+RESOL*acos((WID-(MAX+MIN))/(MAX-MIN)'hierarch abcdefghir   zHIERARCH abcdefghi = 10zHIERARCH ESO INS SLIT2 Y1FRML)r^   r_   r   r   rI   rl   rS   r
   rn   r   r   r   test_hierarch_card_creation<  s     "z/TestHeaderFunctions.test_hierarch_card_creationc                 C   s:   t jd}|jdksJ |jdks(J |jdks6J dS )zVRegression test for
        https://github.com/spacetelescope/PyFITS/issues/5
        z$HIERARCH key.META_4='calFileVersion'
key.META_4calFileVersionrH   Nr   rI   rO   rJ   rP   rd   rK   r   r   r   )test_hierarch_with_abbrev_value_indicatorO  s    z=TestHeaderFunctions.test_hierarch_with_abbrev_value_indicatorc                 C   s   t jd}t |}|d j}W d   n1 s60    Y  tjdd}d|d< W d   n1 sj0    Y  t|dksJ |d	 dksJ |d dksJ tj	t j
jd
d d|d< W d   n1 s0    Y  |d dksJ dS )zLCheck that compressed image headers do not issue HIERARCH warnings.
        zcompressed_image.fitsr   NT)record*   zHIERARCH LONG KEYWORDr   zLONG KEYWORDgreater than 8 charactersr   zLONG KEYWORD2)r   utilZget_testdata_filepathr   r?   warningscatch_warningsrl   r^   r_   r`   r   )r>   filenamer   r?   Zwarning_listr   r   r   test_hierarch_not_warnY  s    (&
&z*TestHeaderFunctions.test_hierarch_not_warnc                 C   sp   t jd}|jdksJ |jdks(J |jdks6J t dd}|jdksPJ |jdks^J |jdkslJ dS )z
        Regression test for
        https://github.com/spacetelescope/PyFITS/issues/6

        Make sure any leading or trailing whitespace around HIERARCH
        keywords is stripped from the actual keyword value.
        z*HIERARCH  key.META_4    = 'calFileVersion'r   r   rH   zHIERARCH  key.META_4Nr   rK   r   r   r    test_hierarch_keyword_whitespacek  s    	z4TestHeaderFunctions.test_hierarch_keyword_whitespacec                 C   s   t ddd}|d |jdks&J |jdks4J |jdksBJ t g d}t j|d}|| 	d t 
| 	dF}|d	 j}t|j|d
 t|j|d
 ksJ W d   n1 s0    Y  dS )zRegression test for
        https://github.com/spacetelescope/PyFITS/issues/7

        Assures that HIERARCH keywords with lower-case characters and other
        normally invalid keyword characters are not considered invalid.
        zHIERARCH WeirdCard.~!@#_^$%&z	The value	a comment	exceptionzWeirdCard.~!@#_^$%&))simpleT)BITPIXr}   )NAXISr   )EXTENDTzMay contain datasets)zHIERARCH key.META_0ZdetRowr?   r   r   z
key.META_0N)r   rI   r`   rJ   rP   rd   r   r   r   r   r   r?   rS   ry   rD   )r>   r   r?   r   r   header2r   r   r   test_verify_mixed_case_hierarch  s    

z3TestHeaderFunctions.test_verify_mixed_case_hierarchc                    sX   t   tt fddd tjtdd  d  W d   n1 sJ0    Y  dS )z=Test that accessing a non-existent keyword raises a KeyError.c                    s    |  S Nr   )kr   r   r   <lambda>  r*   z:TestHeaderFunctions.test_missing_keyword.<locals>.<lambda>r   zKeyword 'NAXIS' not found.r   N)r   r   r^   re   KeyErrorrg   r   r   r   test_missing_keyword  s    z(TestHeaderFunctions.test_missing_keywordc                 C   s<   t  }d|d< d|v sJ |d dks,J d|v s8J d S )Nr   r   ri   Z	ABCDEFGHIr   r=   r   r   r   test_hierarch_card_lookup  s
    z-TestHeaderFunctions.test_hierarch_card_lookupc                 C   s   t  }d|d< |d= d S )Nr   r   r   r=   r   r   r   test_hierarch_card_delete  s    z-TestHeaderFunctions.test_hierarch_card_deletec                 C   s   t  }tjt jjdd d|d< W d    n1 s80    Y  d|d< d|d< tjt jjdd |dd W d    n1 s0    Y  |d	= tjt jjdd |dd W d    n1 s0    Y  |d= t| d d	 ksJ d S )
Nr   r   r   ri   Zabcdefghr\   rb   )
abcdefghijr   r  )
r   r   r^   r_   r`   r   insertr   r   upperr=   r   r   r    test_hierarch_card_insert_delete  s$    
&
*
*z4TestHeaderFunctions.test_hierarch_card_insert_deletec                 C   sf  d}t  }tt8}|ddi t|dks8J d|v sDJ |d dksTJ |ddi t|dksrJ |d sJ d|ddi t|dksJ t|dksJ |d sJ d|d	d
i t|dksJ t|dksJ |d sJ d
|ddi t|dksJ t|dks0J |d sBJ d|ddi t|dksbJ |t|d jv szJ |ddi t|dksJ |d sJ d|ddi t|dksJ |d sJ d|dd
i t|dksJ |d sJ d
|ddi t|dks0J |d sBJ dW d   n1 sX0    Y  dS )z
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/158

        Tests several additional use cases for working with HIERARCH cards.
        a HIERARCH card will be createdzHIERARCH BLAH BLAHTESTAr   z	BLAH BLAHTESTBTESTCr   zHIERARCH blah blahTESTDz	blah blahTESTErb   zBLAH BLAH BLAHrc   zHIERARCH BLAH BLAH BLAHru   zHIERARCH blah blah blahzblah blah blahr~   N)	r   r   r^   r_   r   r   rl   rS   r   r>   msgr?   ro   r   r   r   test_hierarch_create_and_update  sJ    z3TestHeaderFunctions.test_hierarch_create_and_updatec                 C   s  d}t  }tt(}|ddi t|dks8J d|v sDJ |d dksTJ |ddi t|dksrJ |d sJ d|ddi t|dksJ |d sJ d|d	d
i t|dksJ t|dksJ |d sJ d
|ddi t|dksJ t|dks J |d s2J dW d   n1 sH0    Y  t  }ttF}|ddi tdd |D  t|dksJ |t|d j	v sJ |ddi t|dksJ |d sJ d|ddi t|dksJ |d sJ d|d	d
i t|dks6J t|dksHJ |d sZJ d
|ddi t|dkszJ t|dksJ |d sJ dW d   n1 s0    Y  dS )aD  
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/158

        Tests several additional use cases for working with HIERARCH cards,
        specifically where the keyword is fewer than 8 characters, but contains
        invalid characters such that it can only be created as a HIERARCH card.
        r  zHIERARCH BLA BLAr	  r   zBLA BLAr
  r  r   zHIERARCH bla blar  zbla blar  rb   Nc                 S   s   g | ]
}|j qS r   )category)r'   xr   r   r   r)   1  r*   zMTestHeaderFunctions.test_short_hierarch_create_and_update.<locals>.<listcomp>rc   )
r   r   r^   r_   r   r   rl   printrS   r   r  r   r   r   %test_short_hierarch_create_and_update  sR    	2z9TestHeaderFunctions.test_short_hierarch_create_and_updatec                    s$   t    fdd}tt| d S )Nc                      s   d d< d S )N)barZbazZquxr   r   r   r   r   r   testL  s    z=TestHeaderFunctions.test_header_setitem_invalid.<locals>.test)r   r   r^   re   rf   )r>   r  r   r   r   test_header_setitem_invalidI  s    z/TestHeaderFunctions.test_header_setitem_invalidc                 C   sp   t  }d|d< d|d< |d dks(J |d d u s8J |d dksHJ |jd dksZJ |jd dkslJ d S )N)r   r   r   r   r   r   rH   r   r   r<   r=   r   r   r   test_header_setitem_1tupleQ  s    z.TestHeaderFunctions.test_header_setitem_1tuplec                 C   s   t  }d|d< d|d< |d dks(J |d d u s8J |d dksHJ |jd dksZJ |jd dkslJ |jd dks~J d S )	Nr   r   )NNr   r   r   r   rH   r  r=   r   r   r   test_header_setitem_2tuple[  s    z.TestHeaderFunctions.test_header_setitem_2tuplec                 C   s"  t  }d|d< |d dks J d|d< |d du s8J d}t jj|dd}t dt jj}||g t jj|d< |jd	d
d |d |d dksJ |d du sJ |d du sJ |d du sJ |d du sJ |d du sJ d|d< d|d< |jD ]}|j	t jjksJ qdS )z
        Setting the value of a card to None should simply give that card an
        undefined value.  Undefined value should map to None.
        r   r   NzUNDEF   = 
DEFINED = 42
sepZUNDEF2ZUNDEF3)UNDEF5NzUndefined valueTendZUNDEF6ZDEFINEDr   r   r  ZUNDEF4)
r   r   rO   rI   r   r   extendr   ry   rP   )r>   r?   hstrr   r   r   r   test_header_set_value_to_nonef  s,    

z1TestHeaderFunctions.test_header_set_value_to_nonec                 C   s@   t dg}|jddd |d dks*J |jd dks<J d S )Nr4   r5   r9   )rd   r6   )r   r   r   r<   r=   r   r   r   test_set_comment_only  s    z)TestHeaderFunctions.test_set_comment_onlyc                 C   s&   t ddg}t|ddgks"J d S )Nr5   r6   r7   r9   r5   r7   )r   r   r   r=   r   r   r   test_header_iter  s    z$TestHeaderFunctions.test_header_iterc                 C   s   t g d}|dd  }t|dks*J d|vs6J d|v sBJ d|v sNJ |d d d }t|dkslJ |d	 d
ks|J |d dksJ |d dksJ |d d d }t|dksJ d|v sJ d|vsJ d|v sJ d S )Nr%  r&  r:   r;   r   rb   r5   r7   r:   r   rc   r   r;   r9   r6   r   r   rl   r>   r?   Z	newheaderr   r   r   test_header_slice  s     z%TestHeaderFunctions.test_header_slicec                 C   s   t g d}d|dd< |d dks*J |d dks:J d|dd< |d dksVJ |d dksfJ ddg|dd< |d dksJ |d dksJ dS )zp
        Assigning to a slice should just assign new values to the cards
        included in the slice.
        r(  r   Nrb   GHHIr   r=   r   r   r   test_header_slice_assignment  s    z0TestHeaderFunctions.test_header_slice_assignmentc                 C   sV   t g d}|dd= t|dks(J |d dks8J |dd= t|dksRJ dS )z/Test deleting a slice of cards from the header.r(  r   Nr   r6   r*  r=   r   r   r   test_header_slice_delete  s    

z,TestHeaderFunctions.test_header_slice_deletec                 C   sJ   t g d}|d }t|dks&J |d dks6J |d dksFJ dS )z>Test selecting a subsection of a header via wildcard matching.rM   r   )DEFr   )ZABDrb   AB*rb   r   r   Nr*  r+  r   r   r   test_wildcard_slice  s
    z'TestHeaderFunctions.test_wildcard_slicec                 C   sN   t g d}t|d dks"J t|d dks6J t|d dksJJ dS )zp
        Regression test for issue where wildcards did not work on keywords
        containing hyphens.
        ))ZDATEr   )zDATE-OBSrb   )zDATE-FOOrc   zDATE*rc   zDATE?*rb   zDATE-*Nr*  r=   r   r   r   test_wildcard_with_hyphen  s    z-TestHeaderFunctions.test_wildcard_with_hyphenc                 C   s   t g d}d|d< |d dks&J |d dks6J d|d< |d dksNJ |d dks^J ddg|d< |d dkszJ |d dksJ d	S )
z@Test assigning to a header slice selected via wildcard matching.r2  r   r5  r   rb   r-  r.  r/  Nr   r=   r   r   r   test_wildcard_slice_assignment  s    z2TestHeaderFunctions.test_wildcard_slice_assignmentc                 C   s8   t g d}|d= t|dks$J |d dks4J dS )z@Test deleting cards from a header that match a wildcard pattern.r2  r5  r   r   Nr*  r=   r   r   r   test_wildcard_slice_deletion  s    z0TestHeaderFunctions.test_wildcard_slice_deletionc                 C   s&   t g d}|d g dks"J d S )N)r3  rq   rs   )r4  rc   )rr   ru   )rr   r~   rr   )r   rb   ru   r~   r   r=   r   r   r   test_header_history  s    z'TestHeaderFunctions.test_header_historyc                 C   sB   t ddg}|  d|vs"J d|vs.J t|dks>J d S )Nr%  r&  r5   r7   r   )r   r   clearrl   r=   r   r   r   test_header_clear	  s
    z%TestHeaderFunctions.test_header_clearc                 C   sp   t jddg}d|v sJ |d d u s,J |jd dks>J d|v sJJ |d d u sZJ |jd dkslJ d S )Nr5   r6   rH   r   r   fromkeysr<   r=   r   r   r   test_header_fromkeys  s    z(TestHeaderFunctions.test_header_fromkeysc                 C   sr   t jddgd}d|v sJ |d dks.J |jd dks@J d|v sLJ |d dks\J |jd dksnJ d S )Nr5   r6   r7   rH   r=  r=   r   r   r   test_header_fromkeys_with_value  s    z3TestHeaderFunctions.test_header_fromkeys_with_valuec                 C   sB   t jdgd}d|v sJ |d dks,J |jd dks>J d S )Nr5   r6   r7   r6   r7   r=  r=   r   r   r   +test_header_fromkeys_with_value_and_comment"  s    z?TestHeaderFunctions.test_header_fromkeys_with_value_and_commentc                 C   s   t jg dd}d|v sJ d|v s*J d|v s6J d|vsBJ |d dksRJ |d dksbJ |d dksrJ |d dksJ |d dksJ d S )	N)r5   r6   r5   r7   r5   )r5   r   r   )r5   rb   r   rb   )r   r   r>  r=   r   r   r   $test_header_fromkeys_with_duplicates(  s    z8TestHeaderFunctions.test_header_fromkeys_with_duplicatesc                 C   s*   t ddg}t| ddgks&J d S Nr%  r&  )r   r   r   r   r=   r   r   r   test_header_items4  s    z%TestHeaderFunctions.test_header_itemsc                 C   s6   t ddg}t| |D ]\}}||ksJ qd S rD  )r   r   zipr   r>   r?   r   r   r   r   r   test_header_iterkeys8  s    z(TestHeaderFunctions.test_header_iterkeysc                 C   s:   t ddg}t| ddgD ]\}}||ks J q d S )Nr%  r&  r6   r9   )r   r   rF  r   rG  r   r   r   test_header_itervalues=  s    z*TestHeaderFunctions.test_header_itervaluesc                 C   sN   t | d*}t|d jg dks,J W d    n1 s@0    Y  d S )Nr   r   )SIMPLEr   r   r   r   ZNAXIS3r   )r   r   r   r   r?   r   r   r   r   test_header_keysB  s    z$TestHeaderFunctions.test_header_keysc                 C   s   t g d}| }|dks"J t|dks2J t|g dksFJ |d}|dks\J t|dkslJ t|dd	gksJ |d
}|dksJ t|dksJ t|d	gksJ tt|jd d S )Nr%  r&  r)  Gr.  r.  rc   r5   r7   r:   r   r9   rb   r5   r:   r   r6   r   )r   r   poprl   r   r^   re   
IndexError)r>   r?   lastmidfirstr   r   r   test_header_list_like_popH  s    

z-TestHeaderFunctions.test_header_list_like_popc                 C   s
  t g d}tt|jddd |d}|dks8J t|dksHJ t|g dks\J |d}|d	ksrJ t|d
ksJ t|ddgksJ |d}|dksJ t|dksJ t|dgksJ |dd}|dksJ t|dksJ tt|jd d S )NrL  r5   r6   r7   rN  r.  rc   rO  r9   rb   r:   r   XY)	r   r   r^   re   	TypeErrorrP  rl   r   r   )r>   r?   rR  rS  rT  defaultr   r   r   test_header_dict_like_pop]  s$    


z-TestHeaderFunctions.test_header_dict_like_popc                 C   s   t g d}| \}}||vs&J t|dks6J | \}}||vsNJ t|dks^J | \}}||vsvJ t|dksJ tt|j d S )Nr(  rb   r   r   )r   r   popitemrl   r^   re   r   )r>   r?   rJ   rP   r   r   r   test_popitemw  s    z TestHeaderFunctions.test_popitemc                 C   s   t g d}|ddks J |ddks2J |ddksDJ t|dksTJ |d	d
d
kshJ t|dksxJ d	|v sJ |d	d
d
ksJ t|dksJ d S )Nr(  r5   r6   r7   r9   r:   r;   rc   rN  r.  ru   )r   r   
setdefaultrl   r=   r   r   r   test_setdefault  s    z#TestHeaderFunctions.test_setdefaultc                 C   s   t ddg}|ddd |d dks.J |d dks>J d|v sJJ |d dksZJ |d	 dksjJ t ddg}|jddd |d dksJ |d dksJ d|v sJ |d dksJ |d	 dksJ d
S )zm
        Test adding new cards and updating existing cards from a dict using
        Header.update()
        r%  r&  r:   rN  r5   r;   r5   r   r;   r   N)r   r   r   r=   r   r   r   test_update_from_dict  s    z)TestHeaderFunctions.test_update_from_dictc                 C   st   t ddg}|dt ddg |d dks4J |d dksDJ d|v sPJ |d dks`J |d	 dkspJ d
S )zv
        Test adding new cards and updating existing cards from an iterable of
        cards and card tuples.
        r%  r&  )r5   r:   r;   rN  r5   r:   r   r   N)r   r   r   rI   r=   r   r   r   test_update_from_iterable  s    z-TestHeaderFunctions.test_update_from_iterablec                 C   s   t  }t  }d|jd< | j|j7  _t|jdks<J |jd dksNJ t  }|j|j |_t|jdksvJ |jd dksJ |jj|jdd t|jdksJ t|jd d	ksJ |jd dksJ d
|jv sJ dS )zr
        Test extending a header both with and without stripping cards from the
        extension header.
        some valzsome commentMYKEYr~   r   rc  Fr   r   ZXTENSIONrd  r   N)r   r   ImageHDUr?   rl   r!  r   r>   r   hdu2r   r   r   test_header_extend  s    
z&TestHeaderFunctions.test_header_extendc                 C   s   t  }t  }d|jd< d|jd< |j|j t|jdksDJ |jd dksVJ |jd dkshJ t  }t  }d|jd< d|jd< |jj|jd	d
 t|jdksJ |jd dksJ dS )zI
        Test extending the header with and without unique=True.
        rb  rd  some other valzsome other commentrv   rc  r   rl  Tuniquer~   Nr   r   rg  r?   r!  rl   rh  r   r   r   test_header_extend_unique  s    



z-TestHeaderFunctions.test_header_extend_uniquec                 C   sz   dD ]p}dD ]f}t  }||jvs&J t  }d|j|< |jj|j|d t|jdks\J |j| d dksJ qqdS )z
        Test extending header with and without unique=True and commentary
        cards in the header being added. Issue astropy/astropy#3967
        rH   r   rr   TFMy textrn  r~   r   Nr   r   r?   rg  r!  rl   )r>   commentary_cardZ	is_uniquer   ri  r   r   r   $test_header_extend_unique_commentary  s    
z8TestHeaderFunctions.test_header_extend_unique_commentaryc                 C   s\  t  }t  }d|jd< d|jd< d|jd< d|jd< d|jd< |j|j t|jdksbJ d|jv spJ d	|jv s~J |jd	 d
ksJ t|jd dksJ |jd dksJ t  }d|jd< d|jd< |jj|jdd t|jdksJ d|jv sJ d	|jvsJ |jd d
ks,J t|jd dksDJ |jd dksXJ dS )zI
        Test extending the header with and without update=True.
        rb  rd  z	history 1rr   rk  z	history 2r[   )rd  r   rf  rl  rc   r   Tr   r|   rb   Nrp  rh  r   r   r   test_header_extend_update  s0    






z-TestHeaderFunctions.test_header_extend_updatec                 C   sz   dD ]p}dD ]f}t  }||jvs&J t  }d|j|< |jj|j|d t|jdks\J |j| d dksJ qqdS )z
        Test extending header with and without unique=True and commentary
        cards in the header being added.

        Though not quite the same as astropy/astropy#3967, update=True hits
        the same if statement as that issue.
        rr  rs  rt  rx  r~   r   Nru  )r>   rv  Z	is_updater   ri  r   r   r   $test_header_extend_update_commentary  s    
z8TestHeaderFunctions.test_header_extend_update_commentaryc                 C   s8   t | d}t  }|j|ddd ||ks4J dS )z
        Test that extending an empty header with the contents of an existing
        header can exactly duplicate that header, given strip=False and
        end=True.
        
test0.fitsFT)r   r   N)r   	getheaderr   r   r!  )r>   r?   r   r   r   r   test_header_extend_exact'  s    z,TestHeaderFunctions.test_header_extend_exactc                 C   sz   t g d}|ddks J |ddks2J |ddksDJ d|d< d|d< |dd	ksfJ tt|jd
 d S )Nr(  r5   r   r7   r:   r   rr   r   rb   rN  )r   r   rE   r^   re   r   r=   r   r   r   test_header_count3  s    z%TestHeaderFunctions.test_header_countc                 C   s   t ddg}|  |  t|dks.J |d dks>J |d dksNJ |d t|dkshJ |d dksxJ |d dksJ |jd	d
d t|dksJ |d dksJ |d dksJ dS )z
        Tests that blank cards can be appended, and that future appends will
        use blank cards when available (unless useblanks=False)
        r%  r&  ru   r   rH   rm  r)  r;   rM  FZ	useblanksr~   r.  N)r   r   r   rl   r=   r   r   r   test_header_append_use_blanks=  s    
z1TestHeaderFunctions.test_header_append_use_blanksc                 C   s   t ddg}|d t|dks(J t|d dks<J |d du sLJ |jd dks^J |d t|dksxJ t|d dksJ |d dksJ |jd dksJ dS )	zi
        Test appending a new card with just the keyword, and no value or
        comment given.
        r%  r&  r:   rc   r   NrH   ru   )r   r   r   rl   r   r<   r=   r   r   r   test_header_append_keyword_onlyX  s    

z3TestHeaderFunctions.test_header_append_keyword_onlyc                 C   s   t ddg}|  |  |dd t|dks:J |d dksJJ |d dksZJ |d	 d
ksjJ |jdddd t|dksJ |d dksJ |d dksJ d S )Nr%  r&  r   r)  ru   r;   r   rH   rm  r9   rM  Fr  r~   r.  )r   r   r   r  rl   r=   r   r   r   test_header_insert_use_blankso  s    z1TestHeaderFunctions.test_header_insert_use_blanksc                 C   sV  t g d}|dd t| d dks2J |d dksBJ |jd dksTJ |jddd	d
 t| d dks|J t| d dksJ |d dksJ |dd |d g dksJ |jddd	d
 |d g dksJ |dd t| d dksJ |jddd	d
 t| d dks8J t| d dksRJ dS )z
        Test that a keyword name or tuple can be used to insert new keywords.

        Also tests the ``after`` keyword argument.

        Regression test for https://github.com/spacetelescope/PyFITS/issues/12
        ))r   r   )r   	Comment 1)r   	Comment 3r   )r   rb   Number of axesr   r   rb   r  )r   r   Trw   r   r   r   )r   r   )r   	Comment 2r   )r  r  r  )r   rb   )r   	Comment 4)r  r  r  r  r   )r   Trm  r   )r   Tr   N)r   r   r  r   r   r<   r=   r   r   r   !test_header_insert_before_keyword  s$    	z5TestHeaderFunctions.test_header_insert_before_keywordc                 C   s   t ddg}|d t|dks(J t|dgks:J d|vsFJ tt |d W d    n1 sp0    Y  |jddd t|dksJ t g d	}|jddd
 d|vsJ t|dksJ t|dgksJ |d dksJ d S )Nr%  r&  r7   r   r5   r;   TrB   )r%  r&  r_  )Z
remove_allr   r9   )r   r   rF   rl   r   r^   re   r   r=   r   r   r   test_remove  s    
(zTestHeaderFunctions.test_removec                 C   s$   t ddg}t|jdks J d S )Nr4   )r4  rN  r.  z       A  C
     DEF  H)r   r   rz   r<   r=   r   r   r   test_header_comments  s    z(TestHeaderFunctions.test_header_commentsc                 C   sv   t g d}|jdd  }t|ddgks0J |jd d d }t|g dksTJ |jd }t|ddgksrJ d S )	N)ABr7   r9   )EFrN  r.  )AIJKr   r.  r  r   )r  r.  r9   A*r9   )r   r   r<   r   )r>   r?   sr   r   r   test_comment_slices_and_filters  s    
z3TestHeaderFunctions.test_comment_slices_and_filtersc                 C   s   t g d}d|jdd < t|jg dks2J |j|d jdksLJ |j|d jdksfJ |j|d jdksJ |jd d  |jd d d	< t|jg d
ksJ ddg|jd< t|jg dksJ d S )Nr  Lr   )r9   r  r  r  r9   r  r  r   )r  r  r9   MNr  )r  r  r  )r   r   r<   r   ry   rD   rd   r=   r   r   r    test_comment_slice_filter_assign  s    z4TestHeaderFunctions.test_comment_slice_filter_assignc                 C   sH  t  }ttd}|D ]}||d< q|d dd  |dd  ksFJ |d d d |d d ksfJ |d d d |d d ksJ |d d d |d d ksJ |d d d d |d d d ksJ |d dd d |dd d ksJ |d ddd |ddd ksJ |d	d
 |jddd t|d dd  |dd  ksTJ t|d d d |d d kszJ t|d d d |d d ksJ t|d d d |d d ksJ t|d d d d |d d d ksJ t|d dd d |dd d ksJ t|d ddd |ddd ksDJ d S )Nr~   rr   r   rc   rv   rm  r   rb   r   r4   r8   Tr  )r   r   r   ranger  r   )r>   r?   indicesidxr   r   r   test_commentary_slicing  s(    
    $$&&&&&**z+TestHeaderFunctions.test_commentary_slicingc                 C   s   t  }d|d< d|d< d|d< d|d< d|d< |d g d	ksDJ d|d d
< |d g dksdJ d|d dd < |d g dksJ ddg|d d d < |d g dksJ d S )Nr   r   rM   rr   BARNEYFREDr4  GHI)rM   r4  r  r   )r   r4  r  r   )r   r   r   r   r   )r   r   r   r   r=   r   r   r   test_update_commentary  s    z*TestHeaderFunctions.test_update_commentaryc                 C   sT   t  }d|d< d|d< d|d< |d |d ks4J d|d< |d |d ksPJ dS )a  
        Regression test for an issue found in *writing* the regression test for
        https://github.com/astropy/astropy/issues/2363, where comparison of
        the list of values for a commentary keyword did not always compare
        correctly with other iterables.
        zhello worldrr   r   Nr   r=   r   r   r   test_commentary_comparison  s    z.TestHeaderFunctions.test_commentary_comparisonc                 C   s<  t  }d|d< d|d< d}||d< d|d< ||d< t|d	ksDJ t|d
 dksXJ t|jd d|d d  kszJ t|jd  d|dd   ksJ |jd|dd t|dksJ t|jd d|d d  ksJ t|jd
  d|dd   ks
J t  }|ddi |ddi d}|	| |ddi |	| t|jd	kshJ |jd
 j
dks~J t|jd d|d d  ksJ t|jd  d|dd   ksJ |j	|dd t|jdksJ t|jd d|d d  ksJ t|jd
  d|dd   ks8J d S )Nr   r   r   r   ZZABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCrr   r  r  r|   rb   rc   r   H   ru   rw   r[   r   )r   r   rl   r   rS   ry   r   r   r   rx   rJ   )r>   r?   Zlongvalr   r   r   test_long_commentary_card'  s<    "&"(

$($z-TestHeaderFunctions.test_long_commentary_cardc                 C   s  t | d&}|d j| d W d    n1 s<0    Y  t  }|jddi |jj|j	| dddd |j
| dd	d
 t | d$}t|d t jsJ W d    n1 s0    Y  t  }|jddi |jj|j	| ddddd d|jv s J d|jvs0J d|jv s@J |j
| dd	dd t | d6}t|dkszJ d|d jv sJ W d    n1 s0    Y  d S )Nr{  r   z
header.txtrd  r   T)r   update_firstr   ignoreoutput_verifyF)r   r  r   Z	EXTENSIONrJ  )r  	overwriterb   r   )r   r   r   r?   
totextfiler   rg  r   r!  fromtextfiler   
isinstancer   rl   )r>   r   r   Zhdul2r   r   r   test_totxtfileL  s0    42z"TestHeaderFunctions.test_totxtfilec                 C   s*   |  d}tj|}|d dks&J dS )zKRegression test for https://github.com/astropy/astropy/issues/8711
        z
scale.fitsZDATASETZ2MASSN)r   r   r   fromfile)r>   r   hdrr   r   r   test_fromfilek  s    
z!TestHeaderFunctions.test_fromfilec                 C   s   t  }d|d< d|d< d|d< t| dd,}|d	d
d |jD  W d   n1 sb0    Y  t j| d}||ksJ dS )zRegression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/122

        Manually write a text file containing some header cards ending with
        newlines and ensure that fromtextfile can read them back in.
        rA  r5   r&  r6   )r9   r:   r7   test.hdrro   r  c                 s   s   | ]}t | V  qd S r   rS   r   r'   r   r   r   r   r-     r*   z?TestHeaderFunctions.test_header_fromtextfile.<locals>.<genexpr>Nr   r   r   r   writer   ry   r  )r>   r?   fr   r   r   r   test_header_fromtextfiler  s    :z,TestHeaderFunctions.test_header_fromtextfilec                 C   s   t ddg}t| dd6}|ddd |jD  |d W d	   n1 sZ0    Y  t j| d}d
|vsJ ||ksJ d	S )zRegression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/154

        Make sure that when a Header is read from a text file that the END card
        is ignored.
        r4   r8   r  ro   r  c                 s   s   | ]}t | V  qd S r   r  r  r   r   r   r-     r*   zMTestHeaderFunctions.test_header_fromtextfile_with_end_card.<locals>.<genexpr>z
ENDNENDr  )r>   r?   r  r   r   r   r   &test_header_fromtextfile_with_end_card  s    (z:TestHeaderFunctions.test_header_fromtextfile_with_end_cardc                    sx   t ddg  fdd}tt|dd tt jd tjt jddd tt jt d tt jd d	S )
z
        Regression test 2 for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/154

        Manually adding an END card to a header should simply result in a
        ValueError (as was the case in PyFITS 3.0 and earlier).
        r4   r8   c                    s   | | < d S r   r   )r   vr   r   r   setitem  s    z9TestHeaderFunctions.test_append_end_card.<locals>.setitemr  rH   Tr  N)	r   r   r^   re   rf   r   r  rl   r   )r>   r  r   r   r   test_append_end_card  s    z(TestHeaderFunctions.test_append_end_cardc                    s  t jtddj  fdd}|dd}tjtdd(}t j	|}| ksRJ W d	   n1 sf0    Y  t
|d
ksJ |dd}tjtdd(}t j	|}| ksJ W d	   n1 s0    Y  t
|d
ksJ |dd}tjtdd*}t j	|}| ksJ W d	   n1 s*0    Y  t
|d
ksFJ |dd}tjtdd.}t jj	|dd}| ks~J W d	   n1 s0    Y  t
|d
ksJ d	S )aX  
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/217

        This tests the case where the END card looks like a normal card like
        'END = ' and other similar oddities.  As long as a card starts with END
        and looks like it was intended to be the END card we allow it, but with
        a warning.
        r   r   c                    sN    j dddd}|| 7 }|r0|dtt| 7 }t|trBt|S t|S d S )NrH   F)r  Zendcardpaddingr   )tostringr   rl   r  bytesr   r   )r   Zpadr  Zhorigr   r   invalid_header  s    
zBTestHeaderFunctions.test_invalid_end_cards.<locals>.invalid_headerzEND =Tz+Unexpected bytes trailing END keyword: ' ='r   Nr   z
END     = z/Unexpected bytes trailing END keyword: '     ='zEND$%&%^*%*z5Unexpected bytes trailing END keyword: '\$%&%\^\*%\*'r  Fz(Missing padding to end of the FITS block)r  )r   r   nparanger?   r^   r_   r   r   r  rl   )r>   r  r  ro   r   r   r  r   test_invalid_end_cards  s4    

*
*
.
.z*TestHeaderFunctions.test_invalid_end_cardsc                 C   sL  t  }d|d< d|d< t j|tdd}|| d t| dd}| }W d	   n1 sj0    Y  |	d
d
d}|	dd
d}t| dd}|| W d	   n1 s0    Y  tjtddD}t | d}|d dksJ |d dksJ W d	   n1 s,0    Y  t|dksHJ d	S )z5
        Test header with invalid characters
        r   r   Zhellor   r~   )r?   r   r   rbNs   hellou   héllolatin1s   BARu   BÀR
test2.fitswbz1non-ASCII characters are present in the FITS filer   zB?Rzh?llor   )r   r   r   r  r  r   r   r   readreplaceencoder  r^   r_   r   r|  rl   )r>   r   r   r  outrY   ro   r   r   r   test_invalid_characters  s"    &(2z+TestHeaderFunctions.test_invalid_charactersc                 C   sN  t g d}|jddd t|g dks0J |jr:J |jddd t|g dks\J |jrfJ |jddd t|g dksJ |jrJ |jdd	d t|g dksJ |jrJ |jddd t|g dksJ |jrJ |jdd
d t|g dksJ |jrJ |jdd
d t|g dks>J |jrJJ dS )z
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/125

        Ensures that a header is not modified when setting the position of a
        keyword that's already in its correct position.
        )r%  rA  r&  r6   rb   Zbeforer4   r   rw   r7   r5   {   N)r   r   r   r   	_modifiedr=   r   r   r   test_unnecessary_move  s,    




z)TestHeaderFunctions.test_unnecessary_movec                 C   sF  d}t jj|dd}|d dks$J |d dks4J tjt jjdd	* t|jd t	d
ksbJ W d   n1 sv0    Y  |jd j
sJ tjt jjdd	* t|jd t	dksJ W d   n1 s0    Y  |jd j
sJ |j
sJ t jj|dd}tjt jjdd	, t|jd t	d
ks6J W d   n1 sL0    Y  |jd j
shJ tjt jjdd	, t|jd t	dksJ W d   n1 s0    Y  |jd j
sJ |d dksJ |d dksJ |j
sJ d|d< d|d< t|jd t	d
ks&J t|jd t	dksBJ dS )zERegression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/137z=FOCALLEN= +1.550000000000e+002
APERTURE= +0.000000000000e+000r  r  ZFOCALLENg     `c@ZAPERTURE        r   r   zFOCALLEN= +1.550000000000E+002NAPERTURE= +0.000000000000E+000)r   r   rO   r^   r_   r`   r   rS   ry   r
   r  )r>   r"  r   r   r   r   test_invalid_float_cards4  sZ    
&
&

*
*
z,TestHeaderFunctions.test_invalid_float_cardsc              	   C   s  t  }d|jd< || d t| dd(}|d |td W d   n1 s`0    Y  t | dN}t	
t$}|j| dd	d
 W d   n1 s0    Y  W d   n1 s0    Y  t|dksJ t|d j}d|v sJ dS )zW
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/140
        gEȠ>r   r   zrb+iZ  r"   Nz	temp.fitswarnr  r~   rc   z'(invalid value string: '5.0022221e-07'))r   r   r?   r   r   r   seekr  r   r^   r_   r   rl   rS   r   )r>   r   r   r  r   ro   r  r   r   r   test_invalid_float_cards2j  s    

,Pz-TestHeaderFunctions.test_invalid_float_cards2c                 C   s   t jd}t|tdks J |jdks.J t jd}t|tdksNJ |jdks\J t jd}t|tdks|J |jdksJ dS )a8  
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/137, part 2

        Ticket https://aeon.stsci.edu/ssb/trac/pyfits/ticket/137 also showed that in
        float values like 0.001 the leading zero was unnecessarily being
        stripped off when rewriting the header.  Though leading zeros should be
        removed from integer values to prevent misinterpretation as octal by
        python (for now Astropy will still maintain the leading zeros if now
        changes are made to the value, but will drop them if changes are made).
        r  r  zAPERTURE= 0.000000000000E+000zAPERTURE= 017   N)r   rI   rO   rS   r
   rP   rK   r   r   r   test_leading_zeros  s    z&TestHeaderFunctions.test_leading_zerosc                 C   sh  t d}t d}t }d|d< d|d< |d du s8J |d du sHJ t|jd |ks^J t|jd |kstJ t }td|d< td|d< |d du sJ |d du sJ t|jd |ksJ t|jd |ksJ t }|tj	| |tj	| |d du s"J |d du s4J t|jd |ksLJ t|jd |ksdJ dS )z
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/123

        Tests assigning Python and Numpy boolean values to keyword values.
        zFOO     =                    TzBAR     =                    FTr   Fr   N)
r
   r   r   rS   ry   r  bool_r   rI   rO   )r>   ZfooimgZbarimgr   r   r   r   test_assign_boolean  s.    z'TestHeaderFunctions.test_assign_booleanc                 C   s8  t g d}t|g dks"J d|v s.J d|v s:J |d dksJJ t|d dks^J d	|d
< |d d	ksvJ t|dksJ |d= t|ddgksJ t|d	ksJ |dd	ksJ |dd |d dksJ |jdddd t|g dksJ |ddksJ t|d	ks*J |ddd	ks@J t|d	ksRJ |d
ddkshJ t|dkszJ t|g dksJ |ddd t|dksJ t|g dksJ |d dksJ |	ddksJ |
ddksJ |d t|dksJ t|g dks4J dS )a  
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/149

        Basically ensures that all public Header methods are case-insensitive
        w.r.t. keywords.

        Provides a reasonably comprehensive test of several methods at once.
        ))abCr   )Defrb   )GeHrc   )rM   r4  GEHrN   ZdEfZgehrc   zg*r   rb   ZaBcZgEhrM   r4  defZAbcr  )r  rM   r4  r  )r  r4  rM   ru   )r  ZiJk)r  r4  rM   IJKr  Zijkr  )r  rM   r  N)r   r   r   rl   rC   r   rP  r]  r   rE   rD   rF   r   r   r   r   (test_header_method_keyword_normalization  sB    

z<TestHeaderFunctions.test_header_method_keyword_normalizationc                 C   s  t ddd}tj|d}d|jd< |j  |j  || d tj	| dddL}d|d	 jv stJ |d	 j|jksJ |d	 j
|k sJ W d
   n1 s0    Y  t|jdk r|j  q|j| ddd t	| dR}d|d	 jv sJ |d	 j|jks&J |d	 j
|k s>J W d
   n1 sT0    Y  |j| d tj| d}|j|ksJ d
S )z
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/142

        Tests a case where the comment of a card ends with END, and is followed
        by several blank cards.
        r   r   r  )zTest valzThis is the ENDZTESTKWr   F)Zmemmapr   N$   Tr  r  )r  r  Zreshaper   r   r?   r   r   r   r   r   r1   rl   r  r   r  )r>   r   r   r   r   r   r   r   test_end_in_comment  s(    


48z'TestHeaderFunctions.test_end_in_commentc                    s  d} fdd}t   d d< d v s,J  d dks<J t tdksPJ tt||d d d<  d dksxJ t tdksJ tt|d| d	 d<  d dksJ  jd dksJ t td
ksJ tt|dd|f tt|d|df tt|d||f dS )aj  
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/134

        Assigning a unicode literal as a header value should not fail silently.
        If the value can be converted to ASCII then it should just work.
        Otherwise it should fail with an appropriate value error.

        Also tests unicode for keywords and comments.
        u   エリックc                    s   | | < d S r   r   )rJ   r+   r   r   r   assign*  s    z7TestHeaderFunctions.test_assign_unicode.<locals>.assignr   r   zFOO     = 'BAR     'r   zFOO     = 'BAZ     'r   z$FOO     = 'BAR     '           / BAZN)r   r   rz   r
   r^   re   rf   r<   )r>   Zerikkur  r   r  r   test_assign_unicode  s&    z'TestHeaderFunctions.test_assign_unicodec                 C   sF   t  }tjtdd |dd W d   n1 s80    Y  dS )a5  
        First regression test for
        https://github.com/spacetelescope/PyFITS/issues/37

        Although test_assign_unicode ensures that `str` objects containing
        non-ASCII characters cannot be assigned to headers.

        It should not be possible to assign bytes to a header at all.
        zIllegal value: b'Hello'.r   r   s   HelloN)r   r   r^   re   rf   r   r   r   r   r   test_assign_non_asciiB  s    z)TestHeaderFunctions.test_assign_non_asciic                 C   sP  t  }d|d< |d dks J t jd}|| |d dksFJ |jd j dks^J |jd j dksvJ t j	dd` |d dksJ |d d	ksJ |jd j dksJ |jd j dksJ W d
   n1 s0    Y  |d dksJ |d dksJ |jd j dks2J |jd j dksLJ d
S )aZ  
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/146, and
        for the solution that is optional stripping of whitespace from the end
        of a header value.

        By default extra whitespace is stripped off, but if
        `fits.conf.strip_header_whitespace` = False it should not be
        stripped.
        z	Bar      r   ZBarzQUX     = 'Bar        'r   zFOO     = 'Bar      'Zstrip_header_whitespaceFzBar        N)
r   r   rI   rO   r   ry   rm   r   ZconfZset_tempr>   r   r   r   r   r   test_header_strip_whitespaceQ  s"    
6z0TestHeaderFunctions.test_header_strip_whitespacec                 C   s   g dd }t  }|D ]}||jd< q|| d t | d&}|d jd |ks`J W d   n1 st0    Y  t j|jd}|jd |jd ksJ || d t | d&}|d jd |ksJ W d   n1 s0    Y  dS )	a{  
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/156

        When creating a new HDU from an existing Header read from an existing
        FITS file, if the original header contains duplicate HISTORY values
        those duplicates should be preserved just as in the original header.

        This bug occurred due to naivete in Header.extend.
        )zCCD parameters table ...z*   reference table oref$n951041ko_ccd.fitsz#     INFLIGHT 12/07/2001 25/02/2002z     all bias framesrc   rr   r   r   Nr   r  )r   r   r?   r   r   r   )r>   historyr   itemr   Znew_hdur   r   r   *test_keep_duplicate_history_in_orig_headerp  s    4z>TestHeaderFunctions.test_keep_duplicate_history_in_orig_headerc              	   C   s  t jd}t jd}t jd}t  }tt4}|j| |j| |j| W d   n1 sp0    Y  t	|dksJ |
| d tt}t | d}t	|dksJ |d j}d|v sJ d	|v sJ d
|v sJ |d dksJ |d	 dksJ |d
 dks,J tt|jdd tt|jd	d tt|jd
d W d   n1 sx0    Y  W d   n1 s0    Y  dS )z
        Test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/109

        Allow opening files with headers containing invalid keywords.
        zCLFIND2D: contour = 0.30zJust some random text.ZPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANrc   r   r   ZCLFIND2DzJust somZAAAAAAAAz: contour = 0.30ze random text.ZHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZfoo)r   rI   rO   r   r^   r_   r   r?   r   rl   r   r   r   re   rf   r   )r>   c1c2Zc3r   ro   r   r?   r   r   r   test_invalid_keyword_cards  s.    *
z.TestHeaderFunctions.test_invalid_keyword_cardsc                 C   s`   t jd}tjt jjdd |d W d   n1 s>0    Y  t|tdks\J dS )z
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/172

        Ensures that when fixing a hierarch card it remains a hierarch card.
        z#HIERARCH ESO DET CHIP PXSPACE = 5e6r   r   r   Nz#HIERARCH ESO DET CHIP PXSPACE = 5E6)	r   rI   rO   r^   r_   r`   r   rS   r
   r   r   r   r   $test_fix_hierarch_with_invalid_value  s    
(z8TestHeaderFunctions.test_fix_hierarch_with_invalid_valuec                 C   sx   t  }tt|jdtd tt|jdtj tt|jdt	d tt|jdtd tt|jdtj
 dS )a  
        Regression test for https://github.com/spacetelescope/PyFITS/issues/11

        For the time being it should not be possible to assign the floating
        point values inf or nan to a header value, since this is not defined by
        the FITS standard.
        r   naninfN)r   r   r^   re   rf   r   floatr  r  Zfloat32r  r   r   r   r   test_assign_inf_nan  s    	z'TestHeaderFunctions.test_assign_inf_nanc                 C   s   t dg}d|d< |d dus$J t|d ts6J |d dksFJ td|d< |d du sdJ d|d< |d du s|J td|d< |d du sJ d|d< |d dusJ t|d tsJ |d dksJ td|d< |d du sJ dS )z
        Regression test for an issue where a value of True in a header
        cannot be updated to a value of 1, and likewise for False/0.
        )r   Tr   r   TFr   N)r   r   r  intr  r  r   r   r   r   test_update_bool  s"    z$TestHeaderFunctions.test_update_boolc                 C   sH  t  }d|d< d|d< t|d ts*J t|ds<J d|d< t|d tsVJ t|dshJ d|d< t|d tsJ t|dsJ d|d< t|d tsJ t|dsJ d|d< t|d tsJ t|dsJ d|d< t|d tsJ t|dsJ d|d< d	|d< t|d ts@J t|d
sTJ d|d< t|d tspJ t|dsJ d|d< t|d tsJ t|dsJ d	|d< t|d tsJ t|d
sJ d|d< t|d ts J t|dsJ d|d< t|d ts0J t|dsDJ dS )a  
        Regression test for https://github.com/spacetelescope/PyFITS/issues/49

        Ensure that numeric values can be upcast/downcast between int, float,
        and complex by assigning values that compare equal to the existing
        value but are a different type.
        r   r         ?zTEST    =                  1.0zTEST    =                    1y      ?        zTEST    =           (1.0, 0.0)r   r  zTEST    =                  0.0zTEST    =                    0y                zTEST    =           (0.0, 0.0)N)r   r   r  r  rS   
startswithr  complexr   r   r   r   test_update_numeric  sN    	z'TestHeaderFunctions.test_update_numericc                 C   s   t  }tt|jdd tt|jdd tt|jdd tt|jdd dg}|D ]6}t j|}d|v rtt j|j	d qZ|	d qZdS )	z
        Regression test for https://github.com/spacetelescope/PyFITS/issues/51

        Test data extracted from a header in an actual FITS file found in the
        wild.  Names have been changed to protect the innocent.
        rr   r  z
abczabc
zabc
defa  HISTORY File modified by user 'wilma' with fv  on 2013-04-22T21:42:18           HISTORY File modified by user ' fred' with fv  on 2013-04-23T11:16:29           HISTORY File modified by user ' fred' with fv  on 2013-11-04T16:59:14           HISTORY File modified by user 'wilma' with fv  on 2013-04-22T21:42:18
File modifHISTORY ied by user 'wilma' with fv  on 2013-04-23T11:16:29
File modified by useHISTORY r ' fred' with fv  on 2013-11-04T16:59:14                               HISTORY File modified by user 'wilma' with fv  on 2013-04-22T21:42:18
File modifHISTORY ied by user 'wilma' with fv  on 2013-04-23T11:16:29
File modified by useHISTORY r ' fred' with fv  on 2013-11-04T16:59:14
File modified by user 'wilma' HISTORY with fv  on 2013-04-22T21:42:18
File modif
ied by user 'wilma' with fv  HISTORY on 2013-04-23T11:16:29
File modified by use
r ' fred' with fv  on 2013-1HISTORY 1-04T16:59:14                                                           r   N)
r   r   r^   re   rf   r   rI   rO   ZVerifyErrorr`   )r>   r   Z
test_cardsZ
card_imager   r   r   r   test_newlines_in_commentary?	  s    
z/TestHeaderFunctions.test_newlines_in_commentaryc                 C   sv   t  }d}|d|f t|jdks,J |jd  \}}|dkrN||ksRJ t j|d}|j| ddd	 d
S )a  
        If a HISTORY or COMMENT card with a too-long value is appended to a
        header with Header.append (as opposed to assigning to hdr['HISTORY']
        it fails verification.

        Regression test for https://github.com/astropy/astropy/issues/11486
        A  abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcr  r   r   rr   r   r   Tr  N)	r   r   r   rl   ry   Z_splitr   r   r   )r>   r?   rP   rA   r+   r   r   r   r   ,test_long_commentary_card_appended_to_headerf	  s    	z@TestHeaderFunctions.test_long_commentary_card_appended_to_headerc                 C   s   t | dd }tj| }W d   n1 s60    Y  t| d}|d |d ksdJ ||kspJ | | ksJ dS )zz
        Test reading a Header from a `bytes` string.

        See https://github.com/astropy/astropy/issues/8706
        r{  r  Nr   )r   r   r   r   rO   r  r|  r  )r>   ZfobjZpri_hdr_from_bytesZpri_hdrr   r   r   test_header_fromstring_bytes~	  s    .z0TestHeaderFunctions.test_header_fromstring_bytesc                 C   sL   t  }d|d< d|d< t|dks(J |d dks8J |d dksHJ dS )zU
        Regression test for https://github.com/astropy/astropy/issues/10479
        rb   zKEY2 ru   zKEY2  r   ZKEY2Nr*  r>   r  r   r   r   test_set_keyword_with_space	  s    z/TestHeaderFunctions.test_set_keyword_with_spacec                 C   sx   t j| ddd}d|d< |  t|ddhks8J t j| ddd}d|d< |jdd}t|ddhkstJ d S )	Nztb.fitsr   )Zextr  r   rr   Tre  )r   r|  r   r   r   r   r   r   r   r   
test_strip	  s    zTestHeaderFunctions.test_stripc                 C   s  t jd}d|_t|dks"J |d t|dks<J t jd}t  }d|_|j	| |j
| d t | d.}d|d	 jd
< || d W d   n1 s0    Y  t | d&}|d	 jd
 dksJ W d   n1 s0    Y  dS )aw  
        Regression test for https://github.com/astropy/astropy/issues/5408

        Tests updating the value of a card that is malformatted (with an
        invalid value literal).

        This tests two ways of reproducing the problem, one working with a
        Card object directly, and one when reading/writing a header containing
        such an invalid card.
        zKW      = INF  / CommentFIXED)KWr  Commentr   zKW      = INFTz
bogus.fitsr   r   r  zbogus_fixed.fitsN)r   rI   rO   rP   tupler`   r   Z	_verifiedr?   r   Ztofiler   r   r   )r>   r   r   r   r   r   r   test_update_invalid_card	  s    
.z,TestHeaderFunctions.test_update_invalid_cardc                 C   s   t g d}td}|| dks(J d||< || dks@J ||d || dks\J |d |d |d	 td
 dksJ |d |dtdf dksJ |dt	d
f dksJ d S )N))r5   r   )r6   rb   )r7   r   rb   r   r   )r9   r   r   r   ZWORLDr   r   )r7   BAZBAZr7   r   r  )
r   r   r  Zint8r  r   Zint64r   Zint16Zuint32)r>   r?   r  r   r   r   test_index_numpy_int	  s    



z(TestHeaderFunctions.test_index_numpy_intN)r   r   r   __doc__r@   r^   markparametrizerG   rL   rQ   rT   rU   rV   rW   rZ   ra   rh   rk   rp   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  r  r#  r$  r'  r,  r0  r1  r6  r7  r8  r9  r:  r<  r?  r@  rB  rC  rE  rH  rI  rK  rU  rZ  r\  r^  r`  ra  rj  rq  rw  ry  rz  r}  r~  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r	  r   r   r   r   r3   D   s  

						
	

=C
-
			
%
%E(6!9'%!*K
' r3   c                       s   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zejd2g d3d4d5 Z  Z S )6TestRecordValuedKeywordCardsa  
    Tests for handling of record-valued keyword cards as used by the
    `FITS WCS distortion paper
    <https://www.atnf.csiro.au/people/mcalabre/WCS/dcs_20040422.pdf>`__.

    These tests are derived primarily from the release notes for PyFITS 1.4 (in
    which this feature was first introduced.
    Note that extra leading spaces in the `value` fields should be parsed on input,
    but will be stripped in the cards.
    c                    s   t    t | _| jdd | jdd | jdd | jdd | jdd | jdd | jdd | jdd	 d S )
NDP1NAXIS: 2z	AXIS.1: 1	AXIS.2: 2z	NAUX:   2zAUX.1.COEFF.0: 0zAUX.1.POWER.0: 1zAUX.1.COEFF.1: 0.00048828125zAUX.1.POWER.1:  1)supersetupr   r   _test_headerr   rg   	__class__r   r   r  	  s    

z"TestRecordValuedKeywordCards.setupc                 C   sF  t jd}|jdksJ |jdks(J |jdks6J |jdksDJ t jd}|jdks^J |jdkslJ |jdkszJ t jd}|jd	ksJ |jd
ksJ |jdu sJ t d	d}|jdksJ |jdksJ |jdksJ t d	d}|jdksJ |jdksJ |jdks"J t d	d
}|jd	ks>J |jd
ksNJ |jdu s^J t dd}|jdkszJ |jdksJ |jdksJ t dd}|jdksJ |jdksJ |jdksJ tt j	j
 t dd}W d   n1 s0    Y  |jdks"J |jdks2J |jdu sBJ dS )zl
        Test different methods for initializing a card that should be
        recognized as a RVKC
         DP1     = 'NAXIS: 2' / A comment	DP1.NAXIS       @r   	A commentzDP1     = 'NAXIS:  2.1'g @zDP1     = 'NAXIS: a'r  zNAXIS: aNr  zNAXIS:  2.0rb   r   )r   rI   rO   rJ   rP   field_specifierrd   r^   r_   r`   r   rK   r   r   r   test_initialize_rvkc	  sL    ,z1TestRecordValuedKeywordCards.test_initialize_rvkcc                 C   sH   t jd}|jdksJ |jdks(J |jdks6J |jdksDJ dS )z
        Tests that the field_specifier can accessed from a card read from a
        string before any other attributes are accessed.
        r  r   r  r  r  N)r   rI   rO   r  rJ   rP   rd   rK   r   r   r   test_parse_field_specifier$
  s
    z7TestRecordValuedKeywordCards.test_parse_field_specifierc                 C   sp   t jd}|jdksJ d|_|jdks.J |jdks<J |jdksJJ |jdksXJ t| dkslJ dS )	zz
        Test setting the field_specifier attribute and updating the card image
        to reflect the new value.
        r  r   r   z
DP1.NAXIS1r  r  z!DP1     = 'NAXIS1: 2' / A commentN)	r   rI   rO   r  rJ   rP   rd   rS   r   rK   r   r   r   test_update_field_specifier0
  s    z8TestRecordValuedKeywordCards.test_update_field_specifierc                 C   sp   t  }|dd |dd |d dks0J |d dks@J |d dksPJ |d dks`J d|vslJ d	S )
z
        The keyword portion of an RVKC should still be case-insensitive, but
        the field-specifier portion should be case-sensitive.
        zabc.defr   zabc.DEFrb   zABC.defzaBc.defzABC.DEFzABC.dEfN)r   r   r   r=   r   r   r   $test_field_specifier_case_senstivity?
  s    zATestRecordValuedKeywordCards.test_field_specifier_case_senstivityc                 C   sP   | j d dksJ t| j d ts&J | j d dks8J t| j d tsLJ dS )zt
        Returning a RVKC from a header via index lookup should return the
        float value of the card.
        r   r  r   r  Nr  r  r  rg   r   r   r   test_get_rvkc_by_indexN
  s    z3TestRecordValuedKeywordCards.test_get_rvkc_by_indexc                 C   s   | j d dksJ dS )aa  
        Returning a RVKC just via the keyword name should return the full value
        string of the first card with that keyword.

        This test was changed to reflect the requirement in ticket
        https://aeon.stsci.edu/ssb/trac/pyfits/ticket/184--previously it required
        _test_header['DP1'] to return the parsed float value.
        r  r  Nr  rg   r   r   r   test_get_rvkc_by_keywordY
  s    
z5TestRecordValuedKeywordCards.test_get_rvkc_by_keywordc                 C   s<   | j d dksJ t| j d ts&J | j d dks8J dS )z
        Returning a RVKC via the full keyword/field-specifier combination
        should return the floating point value associated with the RVKC.
        r  r  zDP1.AUX.1.COEFF.1g      @?Nr  rg   r   r   r   ,test_get_rvkc_by_keyword_and_field_specifiere
  s    zITestRecordValuedKeywordCards.test_get_rvkc_by_keyword_and_field_specifierc                    sR   t t fddd t jtdd  jd  W d   n1 sD0    Y  dS )z
        Accessing a nonexistent RVKC should raise an IndexError for
        index-based lookup, or a KeyError for keyword lookup (like a normal
        card).
        c                    s
    j |  S r   r!  )r  rg   r   r   r   v
  r*   zKTestRecordValuedKeywordCards.test_access_nonexistent_rvkc.<locals>.<lambda>r}   z!Keyword 'DP1\.AXIS\.3' not found.r   
DP1.AXIS.3N)r^   re   rQ  r   r  rg   r   rg   r   test_access_nonexistent_rvkco
  s    z9TestRecordValuedKeywordCards.test_access_nonexistent_rvkcc                 C   sP   d| j d< | j d dksJ t| j d ts0J d| j d< | j d dksLJ dS )z9A RVKC can be updated either via index or keyword access.rc   r   r        @g?
DP1.AXIS.1Nr  rg   r   r   r   test_update_rvkc{
  s
    

z-TestRecordValuedKeywordCards.test_update_rvkcc                 C   s<   t  }d|d< |d dks J d|d< |d dks8J dS )z;Regression test for an issue that appeared after SVN r2412.r   zD2IM1.EXTVERr  rb   r  Nr   r   r   r   r   test_update_rvkc_2
  s
    z/TestRecordValuedKeywordCards.test_update_rvkc_2c                 C   s|   t jd}|jdksJ |jdks(J t dd}|jdksBJ |jdksPJ t dd}|jdksjJ |jdksxJ d S )Nr  r  r  r  rb   z
NAXIS: 2.0r  )r   rI   rO   Z
rawkeywordZrawvaluerK   r   r   r   test_raw_keyword_value
  s    z3TestRecordValuedKeywordCards.test_raw_keyword_valuec                 C   s<   | j jddddd | j d dks&J | j d dks8J d	S )
z
        It should be possible to insert a new RVKC after an existing one
        specified by the full keyword/field-specifier combination.r  z	AXIS.3: 1r   
DP1.AXIS.2rw   rc   r   r$  N)r  r   rg   r   r   r   test_rvkc_insert_after
  s
    z3TestRecordValuedKeywordCards.test_rvkc_insert_afterc                 C   s   | j d= t| j dksJ t| j d dks0J | j d dksBJ t| j d dksXJ | j d= t| j dksrJ t| j d dksJ | j d dksJ t| j d d	ksJ | j d dksJ d
S )z
        Deleting a RVKC should work as with a normal card by using the full
        keyword/field-spcifier combination.
        r'  r|   r   r  rb   r   r+  rv   DP1.NAUXNr  rl   r   rg   r   r   r   test_rvkc_delete
  s    z-TestRecordValuedKeywordCards.test_rvkc_deletec                 C   s   | j d }t|tjsJ dd |jD ddgks6J | j d }dd |jD dd	gks\J | j d
 }dd |jD g dksJ | j d }dd |jD dgksJ | j d }dd |jD ddgksJ dS )z+Test the keyword filter strings with RVKCs.
DP1.AXIS.*c                 S   s   g | ]}t | qS r   r  r  r   r   r   r)   
  r*   zKTestRecordValuedKeywordCards.test_pattern_matching_keys.<locals>.<listcomp>DP1     = 'AXIS.1: 1'DP1     = 'AXIS.2: 2'zDP1.N*c                 S   s   g | ]}t | qS r   r  r  r   r   r   r)   
  r*   zDP1     = 'NAXIS: 2'zDP1     = 'NAUX: 2'z
DP1.AUX...c                 S   s   g | ]}t | qS r   r  r  r   r   r   r)   
  r*   DP1     = 'AUX.1.COEFF.0: 0'DP1     = 'AUX.1.POWER.0: 1'(DP1     = 'AUX.1.COEFF.1: 0.00048828125'DP1     = 'AUX.1.POWER.1: 1'z	DP?.NAXISc                 S   s   g | ]}t | qS r   r  r  r   r   r   r)   
  r*   z	DP1.A*S.*c                 S   s   g | ]}t | qS r   r  r  r   r   r   r)   
  r*   N)r  r  r   r   ry   r>   clr   r   r   test_pattern_matching_keys
  s6    




z7TestRecordValuedKeywordCards.test_pattern_matching_keysc                 C   sn   | j d= t| j dksJ t| j d dks0J | j d dksBJ t| j d dksXJ | j d dksjJ dS )z'Deletion by filter strings should work.	DP1.A*...rb   r   r  r   r-  Nr.  rg   r   r   r   "test_pattern_matching_key_deletion
  s    z?TestRecordValuedKeywordCards.test_pattern_matching_key_deletionc                 C   sN   | j d }dd |jD g dks&J |d }dd |jD g dksJJ dS )	zX
        A card list returned via a filter string should be further filterable.
        r;  c                 S   s   g | ]}t | qS r   r  r  r   r   r   r)   
  r*   zQTestRecordValuedKeywordCards.test_successive_pattern_matching.<locals>.<listcomp>)r1  r2  r4  r5  r6  r7  z	*.*AUX...c                 S   s   g | ]}t | qS r   r  r  r   r   r   r)   
  r*   r3  N)r  ry   )r>   r9  Zcl2r   r   r    test_successive_pattern_matching
  s    
z=TestRecordValuedKeywordCards.test_successive_pattern_matchingc                 C   s"   | j d }t|ddgksJ dS )zl
        The CardList.keys() method should return full keyword/field-spec values
        for RVKCs.
        r0  r'  r+  N)r  r   r8  r   r   r   test_rvkc_in_cardlist_keys
  s    
z7TestRecordValuedKeywordCards.test_rvkc_in_cardlist_keysc                 C   s&   | j d }t| ddgks"J dS )zv
        The CardList.values() method should return the values of all RVKCs as
        floating point values.
        r0  r  r  N)r  r   r   r8  r   r   r   test_rvkc_in_cardlist_values   s    
z9TestRecordValuedKeywordCards.test_rvkc_in_cardlist_valuesc                 C   s8   | j d }|jd jdksJ t|jd jts4J dS )z|
        Individual card values should be accessible by the .value attribute
        (which should return a float).
        r0  r   r  N)r  ry   rP   r  r  r8  r   r   r   test_rvkc_value_attribute	  s    
z6TestRecordValuedKeywordCards.test_rvkc_value_attributec                 C   s   t  }d|d< d|d< d|vs$J d|vs0J d|vs<J |d ddgksPJ t  }d|d< d|vslJ t|jd	 td
ksJ t jd}|jdksJ |jdksJ |j	du sJ t  }d|d< d|vsJ t|jd	 tdksJ dS )a  
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/183

        Ensures that cards with standard commentary keywords are never treated
        as RVKCs.  Also ensures that cards not strictly matching the RVKC
        pattern are not treated as such.
        	AXIS.1: 2rr   r  zHISTORY.AXISzHISTORY.AXIS.1zHISTORY.AXIS.2z Date: 2012-09-19T13:58:53.756061zHISTORY.Dater   z(HISTORY Date: 2012-09-19T13:58:53.756061z*        'Date: 2012-09-19T13:58:53.756061'rH   z"'Date: 2012-09-19T13:58:53.756061'Nr   zFOO.Datez,FOO     = 'Date: 2012-09-19T13:58:53.756061')
r   r   rS   ry   r
   rI   rO   rJ   rP   r  r  r   r   r   test_overly_permissive_parsing  s.    	z;TestRecordValuedKeywordCards.test_overly_permissive_parsingc                    s   t jd}t jd}t ||g  d dks6J  d dksFJ  d dksVJ  d	 d
ksfJ d vsrJ d vs~J d vsJ tt fdd tt fdd tt fdd dS )a  
        Regression test for https://aeon.stsci.edu/ssb/trac/pyfits/ticket/184

        Ensures that looking up a RVKC by keyword only (without the
        field-specifier) in a header returns the full string value of that card
        without parsing it as a RVKC.  Also ensures that a full field-specifier
        is required to match a RVKC--a partial field-specifier that doesn't
        explicitly match any record-valued keyword should result in a KeyError.
        zFOO     = 'AXIS.1: 2'zFOO     = 'AXIS.2: 4'r   rA  )r   r   z	AXIS.2: 4z
FOO.AXIS.1r  z
FOO.AXIS.2      @FOO.AXIS	FOO.AXIS.FOO.c                      s    d S )NrD  r   r   r  r   r   r   M  r*   zQTestRecordValuedKeywordCards.test_overly_aggressive_rvkc_lookup.<locals>.<lambda>c                      s    d S )NrE  r   r   r  r   r   r   N  r*   c                      s    d S )NrF  r   r   r  r   r   r   O  r*   N)r   rI   rO   r   r^   re   r   )r>   r  r  r   r  r   "test_overly_aggressive_rvkc_lookup8  s    z?TestRecordValuedKeywordCards.test_overly_aggressive_rvkc_lookupc                 C   s  ddl m} || d}|jdgd}d|v s6J d|v sBJ |jdgdgd	}d|v s`J d
|vslJ t|ddksJ |jdgddgd	}d|v sJ d
|v sJ t|ddksJ |jdgdgd	}d|v sJ d|v sJ d|v sJ |  || d}d|jdgdv s*J |  || d}d|jdgddv s\J d|jdgddv svJ |  dS )z9Tests the basic functionality of the `fitsheader` script.r   
fitsheaderzerowidth.fitsAIPS FQ
extensionszEXTNAME = 'AIPS FQr   EXTNAMErM  keywordsz	BITPIX  =r  rc   r   z	EXTNAME =ru   zNAXIS*z	NAXIS   =z	NAXIS1  =z	NAXIS2  =r{  zEXTNAME = 'SCIzSCI,2z	comp.fitszXTENSION= 'IMAGEF)rM  Z
compressedzXTENSION= 'BINTABLETN)astropy.io.fits.scriptsrI  ZHeaderFormatterr   parserl   splitr   )r>   rI  Zhfoutputr   r   r   test_fitsheader_scriptQ  s>    

z3TestRecordValuedKeywordCards.test_fitsheader_scriptc                 C   s  ddl m} ddlm} | d}||}|||}|dg}t|t|d j	ks^J |jg dd}t|t|d j	t|d j	 t|d	 j	 ksJ W d
   n1 s0    Y  |jdgd}t
|d |ksJ t
|d dksJ |d |d dk dksJ |jdgdgd}t|dks>J |d d dksTJ |d d dksjJ |d d dksJ |jdgd}|d
u sJ |jdgdgd}|d
u sJ |  d
S )z7Tests the `--table` feature of the `fitsheader` script.r   r   rH  rJ  )rK  rb   4rL  rK  rb   ru   Nr   r   rP   rJ   rN  rO  r   ZDOES_NOT_EXIST)
astropy.ior   rQ  rI  r   ZTableHeaderFormatterr   rR  rl   r?   r  r1   r   )r>   r   rI  Ztest_filenameZ	formatterZfitsobjZmytabler   r   r   test_fitsheader_table_feature|  s>    

(z:TestRecordValuedKeywordCards.test_fitsheader_table_featurer   )r  zwb+Zabzab+c                 C   sR   t | d|d,}tjtdd}|| W d    n1 sD0    Y  d S )Nz	mode.fitsr   r~   r  )r   r   r   rg  r  Zonesr   )r>   r   Zffr   r   r   r   test_hdu_writeto_mode  s    z2TestRecordValuedKeywordCards.test_hdu_writeto_mode)!r   r   r   r
  r  r  r  r  r  r   r"  r#  r%  r(  r)  r*  r,  r/  r:  r<  r=  r>  r?  r@  rB  rG  rU  rX  r^   r  r  rY  __classcell__r   r   r  r   r  	  s6   5

	

		
%+)r  c                  C   s  G dd dt j} | d}|jd dks,J |jd dks>J |jd d	ksPJ |d
d }t|| u slJ |jd dks~J |jd d	ksJ |d }t|| u sJ |jd d	ksJ | }t|| u sJ |jd dksJ |jd d	ksJ |d |jd d	ksJ dS )z?Check that subclasses don't get ignored on slicing and copying.c                       s   e Zd Z fddZ  ZS )ztest_subclass.<locals>.MyHeaderc                    s8   t |trt|dkr|d7 }t j|g|R i |S )Nrb   )
no comment)r  r  rl   r  r   )r>   r   argskwargsr  r   r   r     s    z&test_subclass.<locals>.MyHeader.append)r   r   r   r   rZ  r   r   r  r   MyHeader  s   r^  ))r   r  rT  )r   r  second)r   r&  r   rT  r   r_  r   r[  r   Nzc*))r!   rC  r!   )r   r   r<   typer   r!  )r^  Z	my_headerZslice_Z	selectionZcopy_r   r   r   test_subclass  s$    
ra  )r   r/   r   ior   r   r^   Znumpyr  rW  r   Zastropy.io.fits.verifyr   Zastropy.utils.exceptionsr   rH   r	   Zastropy.io.fits.cardr
   Zastropy.io.fits.headerr   Zastropy.io.fits.utilr   r   r   r&   r2   r3   r  ra  r   r   r   r   <module>   sR   
                   &   Y