o
    û›h·K  ã                   @   sN  d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	m
Z ddlmZ ddlZddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ d
d„ Zdd„ Zdd„ Zejdd„ ƒZejdke_ej dd„ ƒZ!ejdke!_dd„ Z"G dd„ dej#ƒZ$G dd„ dej#ƒZ%G dd„ dej&ƒZ'dd„ Z(dd „ Z)d!d"„ Z*d#d$„ Z+dS )%a+  Tests for code execution (%run and related), which is particularly tricky.

Because of how %run manages namespaces, and the fact that we are trying here to
verify subtle object deletion and reference counting issues, the %run tests
will be kept in this separate file.  This makes it easier to aggregate in one
place the tricks needed to handle it; most other magics are much easier to test
and we do so in a common test_magic file.

Note that any test using `run -i` should make sure to do a `reset` afterwards,
as otherwise it may influence later tests.
é    N)Újoin)Úpatch)ÚTemporaryDirectory)Údebugger)Ú
decorators)Útools)Úcapture_outputc                   C   ó   dS )aV  Very nasty problem with references held by multiple runs of a script.
    See: https://github.com/ipython/ipython/issues/141

    In [1]: _ip.clear_main_mod_cache()
    # random

    In [2]: %run refbug

    In [3]: call_f()
    lowercased: hello

    In [4]: %run refbug

    In [5]: call_f()
    lowercased: hello
    lowercased: hello
    N© r
   r
   r
   úQc:\Users\shubh\Videos\agent\nova\Lib\site-packages\IPython/core/tests/test_run.pyÚdoctest_refbug'   ó    r   c                   C   r	   )av  Check that %run doesn't damage __builtins__.

    In [1]: import tempfile

    In [2]: bid1 = id(__builtins__)

    In [3]: fname = tempfile.mkstemp('.py')[1]

    In [3]: f = open(fname, 'w', encoding='utf-8')

    In [4]: dummy= f.write('pass\n')

    In [5]: f.flush()

    In [6]: t1 = type(__builtins__)

    In [7]: %run $fname

    In [7]: f.close()

    In [8]: bid2 = id(__builtins__)

    In [9]: t2 = type(__builtins__)

    In [10]: t1 == t2
    Out[10]: True

    In [10]: bid1 == bid2
    Out[10]: True

    In [12]: try:
       ....:     os.unlink(fname)
       ....: except:
       ....:     pass
       ....:
    Nr
   r
   r
   r
   r   Údoctest_run_builtins;   r   r   c                   C   r	   )zÇTest option parser in %run.

    In [1]: %run print_argv.py
    []

    In [2]: %run print_argv.py print*.py
    ['print_argv.py']

    In [3]: %run -G print_argv.py print*.py
    ['print*.py']

    Nr
   r
   r
   r
   r   Údoctest_run_option_parserb   r   r   c                   C   r	   )a,  Test option parser in %run (Linux/OSX specific).

    You need double quote to escape glob in POSIX systems:

    In [1]: %run print_argv.py print\\*.py
    ['print*.py']

    You can't use quote to escape glob in POSIX systems:

    In [2]: %run print_argv.py 'print*.py'
    ['print_argv.py']

    Nr
   r
   r
   r
   r   Ú#doctest_run_option_parser_for_posixq   r   r   Úwin32c                   C   r	   )a  Test option parser in %run (Windows specific).

    In Windows, you can't escape ``*` `by backslash:

    In [1]: %run print_argv.py print\\*.py
    ['print\\\\*.py']

    You can use quote to escape glob:

    In [2]: %run print_argv.py 'print*.py'
    ["'print*.py'"]

    Nr
   r
   r
   r
   r   Ú%doctest_run_option_parser_for_windows…   r   r   c                   C   r	   )a/  Test that resetting doesn't cause errors in __del__ methods.

    In [2]: class A(object):
       ...:     def __del__(self):
       ...:         print(str("Hi"))
       ...:

    In [3]: a = A()

    In [4]: get_ipython().reset(); import gc; x = gc.collect(0)
    Hi

    In [5]: 1+1
    Out[5]: 2
    Nr
   r
   r
   r
   r   Údoctest_reset_del™   r   r   c                   @   sL   e Z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S )ÚTestMagicRunPassc                 C   s   d}|   |¡ d S )Nza = [1,2,3]
b = 1)Úmktmp)ÚselfÚcontentr
   r
   r   ÚsetUp¯   s   zTestMagicRunPass.setUpc                 C   s   t ƒ }| d| j¡ d S ©NÚrun©Úget_ipythonÚrun_line_magicÚfname©r   Ú_ipr
   r
   r   Úrun_tmpfile³   s   zTestMagicRunPass.run_tmpfilec                 C   s   t ƒ }| dd| j ¡ d S )Nr   z-p %sr   r   r
   r
   r   Úrun_tmpfile_p¹   s   zTestMagicRunPass.run_tmpfile_pc                 C   s:   t ƒ }t|jd ƒ}|  ¡  t|jd ƒ}||ksJ ‚dS )z,Check that %run doesn't damage __builtins__ Ú__builtins__N)r   ÚidÚuser_nsr!   )r   r    Zbid1Zbid2r
   r
   r   Útest_builtins_id¿   s
   z!TestMagicRunPass.test_builtins_idc                 C   s,   t ƒ }|  ¡  t|jd ƒttƒksJ ‚dS )a  Check that the type of __builtins__ doesn't change with %run.

        However, the above could pass if __builtins__ was already modified to
        be a dict (it should be a module) by a previous use of %run.  So we
        also check explicitly that it really is a module:
        r#   N)r   r!   Útyper%   Úsysr   r
   r
   r   Útest_builtins_typeÈ   s   z#TestMagicRunPass.test_builtins_typec                 C   s   |   ¡  dS )z^Test that the option -p, which invokes the profiler, do not
        crash by invoking execfileN)r"   ©r   r
   r
   r   Útest_run_profileÓ   s   z!TestMagicRunPass.test_run_profilec                 C   sˆ   t ƒ }t dg¡� | dd| j ¡ W d   ƒ n1 sw   Y  t dg¡� | dd| j ¡ W d   ƒ d S 1 s=w   Y  d S )NÚcr   ú-d %s)r   ÚttÚ
fake_inputr   r   r   r
   r
   r   Útest_run_debug_twiceØ   s   ÿ"ÿz%TestMagicRunPass.test_run_debug_twicec              	   C   sÄ   t ƒ }t g d¢¡� | dd| j ¡ W d  ƒ n1 sw   Y  t dg¡�/ t d¡� | dd| j ¡ W d  ƒ n1 sCw   Y  W d  ƒ dS W d  ƒ dS 1 s[w   Y  dS )zMake a valid python temp file.)zb 2r,   r,   r   r-   Nr,   ÚKeyError)r   r.   r/   r   r   ÚAssertNotPrintsr   r
   r
   r   Ú$test_run_debug_twice_with_breakpointà   s   ÿÿÿ"ÿz5TestMagicRunPass.test_run_debug_twice_with_breakpointN)Ú__name__Ú
__module__Ú__qualname__r   r!   r"   r&   r)   r+   r0   r3   r
   r
   r
   r   r   ­   s    	r   c                   @   s”   e Zd Zdd„ Zejje ¡ dkdd�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 S )!ÚTestMagicRunSimplec                 C   s@   d}|   |¡ t dt| jƒ¡ t d¡ tjd du sJ ‚dS )z(Test that simple class definitions work.z%class foo: pass
def f(): return foo()r   zt = isinstance(f(), foo)ÚtTN)r   r    r   Ústrr   Úrun_cellr%   ©r   Úsrcr
   r
   r   Útest_simpledefí   s
   

z!TestMagicRunSimple.test_simpledefÚPyPyzGexpecting __del__ call on exit is unreliable and doesn't happen on PyPy)Úreasonc                 C   s&   d}|   |¡ d}t | jd|¡ dS )z6Test that object's __del__ methods are called on exit.zRclass A(object):
    def __del__(self):
        print('object A deleted')
a = A()
Nzobject A deleted)r   r.   Úipexec_validater   )r   r<   Úerrr
   r
   r   Útest_obj_delö   s   
zTestMagicRunSimple.test_obj_delc                 C   s~   t  ¡ �1}| d¡ dd|jf }|  |¡ t dt| jƒ¡ t d¡ tjd dks-J ‚W d  ƒ dS 1 s8w   Y  dS )zxTest that namespace cleanup is not too aggressive GH-238

        Returning from another run magic deletes the namespaceÚ z†ip = get_ipython()
for i in range(5):
   try:
       ip.run_line_magic(%r, %r)
   except NameError as e:
       print(i)
       break
r   zip == get_ipython()Úié   N)	r.   ÚTempFileMixinr   r   r    r   r9   r:   r%   )r   Úemptyr<   r
   r
   r   Ú!test_aggressive_namespace_cleanup  s   

úÿ
	
"ðz4TestMagicRunSimple.test_aggressive_namespace_cleanupc                 C   sr   |   d¡ t ¡ �&}|  d¡ t d| j¡ t d|j¡ tjd ƒ dks'J ‚W d  ƒ dS 1 s2w   Y  dS )zBTest that running a second file doesn't clobber the first, gh-3547z$avar = 1
def afunc():
  return avar
rC   r   Zafuncé   N)r   r.   rF   r    r   r   r%   )r   rG   r
   r
   r   Útest_run_second  s   


"ûz"TestMagicRunSimple.test_run_secondc                 C   sZ   t j t¡}t j |d¡}d|› d|› d|› d�}|  |d¡ d}d }t | j||¡ d S )NZtclasszimport gc
%run "z" C-first
gc.collect(0)
%run "z" C-second
gc.collect(0)
%run "z"" C-third
gc.collect(0)
%reset -f
ú.ipyz­ARGV 1-: ['C-first']
ARGV 1-: ['C-second']
tclass.py: deleting object: C-first
ARGV 1-: ['C-third']
tclass.py: deleting object: C-second
tclass.py: deleting object: C-third
)	ÚosÚpathÚdirnameÚ__file__r   r   r.   r@   r   )r   ÚmydirZtcr<   ÚoutrA   r
   r
   r   Útest_tclass'  s   þüú
zTestMagicRunSimple.test_tclassc              
   C   s¬   d}|   |¡ t d¡ zt dd| j ¡ tjd dksJ ‚W t dd¡ nt dd¡ w t d¡ zt dd| j ¡ tjd dksFJ ‚W t dd¡ d	S t dd¡ w )
z4Check that %run -i still works after %reset (gh-693)zyy = zz
zzz = 23r   z-i %sÚyyé   Úresetú-fN)r   r    r:   r   r   r%   r;   r
   r
   r   Útest_run_i_after_reset@  s   


z)TestMagicRunSimple.test_run_i_after_resetc                 C   s<   t j t¡}t j |d¡}t d|¡ tjd dksJ ‚dS )z/Check that files in odd encodings are accepted.znonascii.pyr   Úuu	   ÐŽÑ‚â„–Ð¤N)rL   rM   rN   rO   r   r    r   r%   )r   rP   Únar
   r
   r   Útest_unicodeR  s   zTestMagicRunSimple.test_unicodec                 C   sb   d}|   |¡ tƒ }tj d|¡}t d| j¡ tj d|¡}tjd | jks)J ‚||ks/J ‚dS )z:Test handling of `__file__` attribute in `%run <file>.py`.út = __file__
rO   r   r8   N©r   Úobjectr    r%   Úgetr   r   ©r   r<   Z_missingZfile1Zfile2r
   r
   r   Útest_run_py_file_attributeY  s   
z-TestMagicRunSimple.test_run_py_file_attributec                 C   sf   d}| j |dd� tƒ }tj d|¡}t d| j¡ tj d|¡}tjd | jks+J ‚||ks1J ‚dS )z;Test handling of `__file__` attribute in `%run <file.ipy>`.r[   rK   ©ÚextrO   r   r8   Nr\   r_   r
   r
   r   Útest_run_ipy_file_attributei  s   z.TestMagicRunSimple.test_run_ipy_file_attributec                 C   s6   d}|   |¡ t dd| j ¡ t dd| j ¡ dS )z> Test that %run -t -N<N> does not raise a TypeError for N > 1.Úpassr   z
-t -N 1 %sz-t -N 10 %sN)r   r    r   r   r;   r
   r
   r   Útest_run_formattingy  s   
z&TestMagicRunSimple.test_run_formattingc                 C   sˆ   d}|   |¡ t d¡� t d| j¡ W d  ƒ n1 sw   Y  t d¡� t dd| j ¡ W d  ƒ dS 1 s=w   Y  dS )z'Test the -e option to ignore sys.exit()zimport sys; sys.exit(1)Ú
SystemExitr   Nz-e %s)r   r.   ZAssertPrintsr    r   r   r2   r;   r
   r
   r   Útest_ignore_sys_exit€  s   
ÿ"ÿz'TestMagicRunSimple.test_ignore_sys_exitc                 C   st   t  d¡ ddlm}m} |j| d¡| d¡gd�}||dd�}| j|d	d
� t	 
d| j¡ t	jd dks8J ‚dS )zTest %run notebook.ipynbÚnbformatr   ©Úv4Úwritesz#The Ultimate Question of Everythingz	answer=42©ÚcellsrE   ©Úversionú.ipynbra   r   Zansweré*   N)ÚpytestÚimportorskiprh   rj   rk   Únew_notebookZnew_markdown_cellÚnew_code_cellr   r    r   r   r%   ©r   rj   rk   Únbr<   r
   r
   r   Útest_run_nbŠ  s   
þÿzTestMagicRunSimple.test_run_nbc                 C   s‚   t  d¡ ddlm}m} t  ttjd¡ t  ttjd¡ |j	| 
d¡gd�}||dd	�}| j|d
d� t  ttjd| j ¡ dS )zTest %run notebook.ipynb errorrh   r   ri   r   zrun foobar.ipynbz0/0rl   rE   rn   rp   ra   zrun %sN)rr   rs   rh   rj   rk   ZraisesÚ	Exceptionr    Úmagicrt   ru   r   r   rv   r
   r
   r   Útest_run_nb_error›  s   
ÿÿz$TestMagicRunSimple.test_run_nb_errorc                 C   s>   d}|   |¡ d}t dd | j|¡¡ tjd |ksJ ‚d S )Nz&import sys
a = " ".join(sys.argv[1:])
z-x 3 --verboser   z{0} {1}Úa)r   r    r   Úformatr   r%   )r   r<   Ú	test_optsr
   r
   r   Útest_file_options°  s
   
z$TestMagicRunSimple.test_file_optionsN)r4   r5   r6   r=   rr   ÚmarkZxfailÚplatformÚpython_implementationrB   rH   rJ   rR   rW   rZ   r`   rc   re   rg   rx   r{   r   r
   r
   r
   r   r7   ë   s&    	
þ


r7   c                   @   s~   e Zd Zdd„ Zdd„ Zdd„ Zddd	„Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zedd„ ƒZedd„ ƒZdd„ Zdd„ ZdS )ÚTestMagicRunWithPackagec                 C   sx   t j | jj|¡}t j |¡}t j |¡st  |¡ t|ddd��}| 	t
 |¡¡ W d   ƒ d S 1 s5w   Y  d S )NÚwúutf-8©Úencoding)rL   rM   r   ÚtempdirÚnamerN   ÚisdirÚmakedirsÚopenÚwriteÚtextwrapÚdedent)r   r‰   r   rM   ÚdÚfr
   r
   r   Ú	writefile»  s   
"ÿz!TestMagicRunWithPackage.writefilec                 C   sâ   d  d dd„ tdƒD ƒ¡¡ | _}	 tt ¡ d ƒ| _tƒ | _t	 
¡ | _tj d| jj¡ |  t	j |d¡d¡ |  t	j |d	¡d
  | j¡¡ |  t	j |d¡d¡ |  t	j |d¡d  |¡¡ |  t	j |d¡d  |¡¡ d S )Nztmp{0}rC   c                 S   s   g | ]}t  tj¡‘qS r
   )ÚrandomÚchoiceÚstringÚascii_letters)Ú.0rD   r
   r
   r   Ú
<listcomp>Ä  s    z1TestMagicRunWithPackage.setUp.<locals>.<listcomp>é
   i'  r   z__init__.pyzsub.pyz
        x = {0!r}
        zrelative.pyz$
        from .sub import x
        zabsolute.pyz'
        from {0}.sub import x
        zargs.pyz?
        import sys
        a = " ".join(sys.argv[1:])
        )r}   r   ÚrangeÚpackageÚintr“   Úvaluer   rˆ   rL   ÚgetcwdÚ"_TestMagicRunWithPackage__orig_cwdr(   rM   Úinsertr‰   r’   )r   r›   r
   r
   r   r   Ã  s"   $
þþýzTestMagicRunWithPackage.setUpc                    s8   t  ˆ j¡ ‡ fdd„tjD ƒtjd d …< ˆ j ¡  d S )Nc                    s   g | ]
}|ˆ j jkr|‘qS r
   )rˆ   r‰   )r—   Úpr*   r
   r   r˜   Þ  s    z4TestMagicRunWithPackage.tearDown.<locals>.<listcomp>)rL   ÚchdirrŸ   r(   rM   rˆ   Úcleanupr*   r
   r*   r   ÚtearDownÜ  s   z TestMagicRunWithPackage.tearDownrC   c                 C   sF   t j dd ¡ t  dd | j||¡¡ |  t jd | jd |¡¡ d S )NÚxr   z{2} -m {0}.{1}z-Variable `x` is not loaded from module `{0}`.)r    r%   Úpopr   r}   r›   ÚassertEqualr�   )r   Ú	submoduleÚoptsr
   r
   r   Úcheck_run_submoduleá  s   ÿýz+TestMagicRunWithPackage.check_run_submodulec                 C   s   |   d¡ d S )NÚabsolute©rª   r*   r
   r
   r   Ú'test_run_submodule_with_absolute_importì  s   z?TestMagicRunWithPackage.test_run_submodule_with_absolute_importc                 C   s   |   d¡ dS )z;Run submodule that has a relative import statement (#2727).ÚrelativeNr¬   r*   r
   r
   r   Ú'test_run_submodule_with_relative_importï  s   z?TestMagicRunWithPackage.test_run_submodule_with_relative_importc                 C   ó   |   dd¡ d S )Nr«   ú-pr¬   r*   r
   r
   r   Ú(test_prun_submodule_with_absolute_importó  ó   z@TestMagicRunWithPackage.test_prun_submodule_with_absolute_importc                 C   r°   )Nr®   r±   r¬   r*   r
   r
   r   Ú(test_prun_submodule_with_relative_importö  r³   z@TestMagicRunWithPackage.test_prun_submodule_with_relative_importc                    s   t  ˆ ¡‡ fdd„ƒ}|S )Nc                     sF   t  tjdttƒ¡� ˆ | i |¤ŽW  d   ƒ S 1 sw   Y  d S r   )r   r]   r   ZPdbÚstaticmethodÚeval)ÚargsÚkwds©Úfuncr
   r   Úwrapperú  s   $ÿz;TestMagicRunWithPackage.with_fake_debugger.<locals>.wrapper)Ú	functoolsÚwraps)rº   r»   r
   r¹   r   Úwith_fake_debuggerù  s   z*TestMagicRunWithPackage.with_fake_debuggerc                 C   r°   )Nr«   ú-dr¬   r*   r
   r
   r   Ú-test_debug_run_submodule_with_absolute_import   ó   zETestMagicRunWithPackage.test_debug_run_submodule_with_absolute_importc                 C   r°   )Nr®   r¿   r¬   r*   r
   r
   r   Ú-test_debug_run_submodule_with_relative_import  rÁ   zETestMagicRunWithPackage.test_debug_run_submodule_with_relative_importc                 C   ó>   t j dd ¡ d}t  dd | j|¡¡ t jd |ksJ ‚d S )Nr|   ú-x abc -m testr   z-m {0}.args {1}©r    r%   r¦   r   r}   r›   ©r   r~   r
   r
   r   Útest_module_options  ó   z+TestMagicRunWithPackage.test_module_optionsc                 C   rÃ   )Nr|   rÄ   r   z-m {0}.args -- {1}rÅ   rÆ   r
   r
   r   Ú"test_module_options_with_separator  rÈ   z:TestMagicRunWithPackage.test_module_options_with_separatorN)rC   )r4   r5   r6   r’   r   r¤   rª   r­   r¯   r²   r´   r¾   rÀ   rÂ   rÇ   rÉ   r
   r
   r
   r   rƒ   ¹  s     


rƒ   c                  C   s  t ƒ �z} t| dƒ}t|ddd��}| d¡ W d   ƒ n1 s w   Y  tj dd ¡ t dd |¡¡ tj d¡d	ks?J ‚t dd
 |¡¡ tj d¡dksRJ ‚zt dd |¡¡ tj d¡dksfJ ‚W t dd¡ nt dd¡ w W d   ƒ d S 1 s€w   Y  d S )Núfoo.pyr„   r…   r†   zq = __name__Úqr   ú{}Ú__main__z-n {}Úfooz-i -n {}rU   rV   )	r   ÚpjoinrŒ   r�   r    r%   r¦   r   r}   )ÚtdrM   r‘   r
   r
   r   Útest_run__name__  s   
ÿ"ðrÑ   c               	   C   sð   t ƒ �k} t| dƒ}t|ddd��}| d g d¢¡¡ W d  ƒ n1 s%w   Y  tƒ �}t dd	 |¡¡ W d  ƒ n1 sAw   Y  |j	}d
|vsOJ ‚d|v sUJ ‚| 
d¡dks^J ‚tjd= tjd= W d  ƒ dS 1 sqw   Y  dS )zTest traceback offset in %runrÊ   r„   r…   r†   Ú
©z
def foo():z    return bar()z
def bar():z     raise RuntimeError('hello!')zfoo()Nr   rÌ   ÚexecfileÚRuntimeErrorú---->é   ÚbarrÎ   )r   rÏ   rŒ   r�   r   r   r    r   r}   ÚstdoutÚcountÚipr%   )rÐ   rM   r‘   ÚiorQ   r
   r
   r   Útest_run_tb)  s&   
ÿÿÿÿ
"ërÝ   c               
   C   s&  t ƒ �†} tj d¡}dtjd< zkz_t| dƒ}t|ddd��}| d¡ W d  ƒ n1 s-w   Y  tƒ �}t 	d|¡ t 
d	¡ W d  ƒ n1 sKw   Y  |j}d
|v sYJ ‚d|vs_J ‚d|v seJ ‚| d¡dksnJ ‚W n   ‚ W |tjd< n|tjd< w W d  ƒ dS 1 sŒw   Y  dS )zßSet we can run mutiprocesgin without messing up up main namespace

    Note that import `nose.tools as nt` modify the values
    sys.module['__mp_main__'] so we need to temporarily set it to None to test
    the issue.
    Ú__mp_main__Nztest.pyr„   r…   r†   z#import multiprocessing
print('hoy')r   Zi_m_undefinedZhoyÚAttributeErrorÚ	NameErrorrÖ   rI   )r   r(   Úmodulesr^   rÏ   rŒ   r�   r   r    r   r:   rÙ   rÚ   )rÐ   ZmpmrM   r‘   rÜ   rQ   r
   r
   r   Útest_multiprocessing_runC  s,   

ÿþþ"îrâ   c               	   C   s°   t ƒ �K} t| dƒ}t|ddd��}| d g d¢¡¡ W d  ƒ n1 s%w   Y  t |¡\}}d|vs7J ‚d	|v s=J ‚| d
¡dksFJ ‚W d  ƒ dS 1 sQw   Y  dS )z,Test traceback offset in `ipython script.py`rÊ   r„   r…   r†   rÒ   rÓ   NrÔ   rÕ   rÖ   r×   )r   rÏ   rŒ   r�   r   r.   ZipexecrÚ   )rÐ   rM   r‘   rQ   rA   r
   r
   r   Útest_script_tb_  s   
ÿÿÿ"ïrã   ),Ú__doc__r¼   rL   r�   r“   r•   r(   rŽ   ZunittestZos.pathr   rÏ   Zunittest.mockr   rr   Útempfiler   ZIPython.corer   ZIPython.testingr   Údecr   r.   ZIPython.utils.ior   r   r   r   Z
skip_win32r   Z__skip_doctest__Zskip_if_not_win32r   r   rF   r   r7   ZTestCaserƒ   rÑ   rÝ   râ   rã   r
   r
   r
   r   Ú<module>   sF   '

> O\