U
    
W[+                     @   sH  d 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 G d	d
 d
eZdd Zdd ZG dd deZG dd deZG dd deZerdddgZnddddddddgZeD ]hZG dd deZe d Zee_er$d ej dd! eg e_e  !e d ei [[q[dS )"zt
Tests for miscellaneous behaviors of the top-level L{twisted} package (ie, for
the code in C{twisted/__init__.py}.
    )divisionabsolute_importN)
ModuleType)_checkPythonVersion)_PY3)reflect)TestCasec                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )SetAsideModulez
    L{SetAsideModule} is a context manager for temporarily removing a module
    from C{sys.modules}.

    @ivar name: The name of the module to remove.
    c                 C   s
   || _ d S N)name)selfr    r   ;/usr/lib/python3/dist-packages/twisted/test/test_twisted.py__init__   s    zSetAsideModule.__init__c                    s6   t  fddttj D }|D ]}tj|= q$|S )z
        Find the given module and all of its hierarchically inferior modules in
        C{sys.modules}, remove them from it, and return whatever was found.
        c                    s2   g | ]*\}}| j ks&| j d  r||fqS ).)r   
startswith).0Z
moduleNamemoduler   r   r   
<listcomp>(   s   
z,SetAsideModule._unimport.<locals>.<listcomp>)dictlistsysmodulesitems)r   r   r   r   r   r   	_unimport#   s    
zSetAsideModule._unimportc                 C   s   |  | j| _d S r
   )r   r   r   r   r   r   r   	__enter__3   s    zSetAsideModule.__enter__c                 C   s   |  | j tj| j d S r
   )r   r   r   r   update)r   ZexcTypeZexcValue	tracebackr   r   r   __exit__7   s    zSetAsideModule.__exit__N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r	      s
   r	   c                 C   s    i }t d| | tj| dS )a  
    Take a mapping defining a package and turn it into real C{ModuleType}
    instances in C{sys.modules}.

    Consider these example::

        a = {"foo": "bar"}
        b = {"twisted": {"__version__": "42.6"}}
        c = {"twisted": {"plugin": {"getPlugins": stub}}}

    C{_install(a)} will place an item into C{sys.modules} with C{"foo"} as the
    key and C{"bar" as the value.

    C{_install(b)} will place an item into C{sys.modules} with C{"twisted"} as
    the key.  The value will be a new module object.  The module will have a
    C{"__version__"} attribute with C{"42.6"} as the value.

    C{_install(c)} will place an item into C{sys.modules} with C{"twisted"} as
    the key.  The value will be a new module object with a C{"plugin"}
    attribute.  An item will also be placed into C{sys.modules} with the key
    C{"twisted.plugin"} which refers to that module object.  That module will
    have an attribute C{"getPlugins"} with a value of C{stub}.

    @param modules: A mapping from names to definitions of modules.  The names
        are native strings like C{"twisted"} or C{"unittest"}.  Values may be
        arbitrary objects.  Any value which is not a dictionary will be added to
        C{sys.modules} unmodified.  Any dictionary value indicates the value is
        a new module and its items define the attributes of that module.  The
        definition of this structure is recursive, so a value in the dictionary
        may be a dictionary to trigger another level of processing.

    @return: L{None}
    N)_makePackagesr   r   r   )r   resultr   r   r   _install=   s    "r&   c                 C   s   i }t | D ]\}}| dkrZt|trPt|}|jt||| |||< q|||< qt|trt| jd | }|jt||| ||| jd | < |||< q|||< q|S )a  
    Construct module objects (for either modules or packages).

    @param parent: L{None} or a module object which is the Python package
        containing all of the modules being created by this function call.  Its
        name will be prepended to the name of all created modules.

    @param attributes: A mapping giving the attributes of the particular module
        object this call is creating.

    @param result: A mapping which is populated with all created module names.
        This is suitable for use in updating C{sys.modules}.

    @return: A mapping of all of the attributes created by this call.  This is
        suitable for populating the dictionary of C{parent}.

    @see: L{_install}.
    Nr   )	r   r   
isinstancer   r   __dict__r   r$   r    )parentZ
attributesr%   Zattrsr   valuer   r   r   r   r$   e   s    





r$   c                   @   sP   e Zd ZdZdZdZdZdZdd Zdd	 Z	d
d Z
dd Zdd Zdd ZdS )RequirementsTestsa  
    Tests for the import-time requirements checking.

    @ivar unsupportedPythonVersion: The newest version of Python 2.x which is
        not supported by Twisted.
    @type unsupportedPythonVersion: C{tuple}

    @ivar supportedPythonVersion: The oldest version of Python 2.x which is
        supported by Twisted.
    @type supportedPythonVersion: C{tuple}

    @ivar Py3unsupportedPythonVersion: The newest version of Python 3.x which
        is not supported by Twisted.
    @type Py3unsupportedPythonVersion: C{tuple}

    @ivar Py3supportedPythonVersion: The oldest version of Python 3.x which is
        supported by Twisted.
    @type supportedPythonVersion: C{tuple}
    )      )r,      )   r/   )r/      c                 C   s   t j| _dS )z|
        Save the original value of C{sys.version_info} so it can be restored
        after the tests mess with it.
        N)r   version_infoversionr   r   r   r   setUp   s    zRequirementsTests.setUpc                 C   s   | j t_dS )z@
        Restore the original values saved in L{setUp}.
        N)r2   r   r1   r   r   r   r   tearDown   s    zRequirementsTests.tearDownc              	   C   s@   | j t_| t}t  W 5 Q R X | d| j t|j	 dS )w
        L{_checkPythonVersion} raises L{ImportError} when run on a version of
        Python that is too old.
        z'Twisted requires Python %d.%d or later.N)
unsupportedPythonVersionr   r1   assertRaisesImportErrorr   assertEqualsupportedPythonVersionstr	exceptionr   Zraisedr   r   r   test_oldPython   s    z RequirementsTests.test_oldPythonc                 C   s   | j t_| t  dS zz
        L{_checkPythonVersion} returns L{None} when run on a version of Python
        that is sufficiently new.
        N)r:   r   r1   assertIsNoner   r   r   r   r   test_newPython   s    z RequirementsTests.test_newPythonc              	   C   s@   | j t_| t}t  W 5 Q R X | d| j t|j	 dS )r5   z3Twisted on Python 3 requires Python %d.%d or later.N)
Py3unsupportedPythonVersionr   r1   r7   r8   r   r9   Py3supportedPythonVersionr;   r<   r=   r   r   r   test_oldPythonPy3   s    z#RequirementsTests.test_oldPythonPy3c                 C   s   | j t_| t  dS r?   )rC   r   r1   r@   r   r   r   r   r   test_newPythonPy3   s    z#RequirementsTests.test_newPythonPy3N)r    r!   r"   r#   r6   r:   rB   rC   r3   r4   r>   rA   rD   rE   r   r   r   r   r+      s   	r+   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	MakePackagesTestszh
    Tests for L{_makePackages}, a helper for populating C{sys.modules} with
    fictional modules.
    c                 C   s,   i }t dtdd| | |tdd dS )z
        A non-C{dict} value in the attributes dictionary passed to L{_makePackages}
        is preserved unchanged in the return value.
        Nreactor)rG   )r$   r   r9   r   r   r   r   r   test_nonModule   s    z MakePackagesTests.test_nonModulec                 C   s`   i }t dttddd| | |t | |d t | d|d j | d|d j dS )z
        A C{dict} value in the attributes dictionary passed to L{_makePackages}
        is turned into a L{ModuleType} instance with attributes populated from
        the items of that C{dict} value.
        NZ123r2   twistedrL   )r$   r   assertIsInstancer   r9   r    r2   rH   r   r   r   test_moduleWithAttribute   s    z*MakePackagesTests.test_moduleWithAttributec                 C   s   i }t dtttdddd| | |t | |d t | d|d j | |d jt | d|d jj | d|d jj dS )z
        Processing of the attributes dictionary is recursive, so a C{dict} value
        it contains may itself contain a C{dict} value to the same effect.
        NZ321rJ   )webrK   rL   ztwisted.web)r$   r   rM   r   r9   r    rO   r2   rH   r   r   r   test_packageWithModule   s    z(MakePackagesTests.test_packageWithModuleN)r    r!   r"   r#   rI   rN   rP   r   r   r   r   rF      s   
rF   c                   @   s$   e Zd ZdZdZdd Zdd ZdS )OldSubprojectDeprecationBasez
    Base L{TestCase} for verifying each former subproject has a deprecated
    C{__version__} and a removed C{_version.py}.
    Nc                 C   sZ   t d| j}| |jtj |  }| dt| | d| j|d d  dS )zS
        The C{__version__} attribute of former subprojects is deprecated.
        z
twisted.{}   zYtwisted.{}.__version__ was deprecated in Twisted 16.0.0: Use twisted.__version__ instead.r   messageN)	r   namedAnyformat
subprojectr9   __version__rL   ZflushWarningslen)r   r   ZwarningsShownr   r   r   test_deprecated  s    
z,OldSubprojectDeprecationBase.test_deprecatedc              	   C   s,   |  t td| j W 5 Q R X dS )zQ
        Former subprojects no longer have an importable C{_version.py}.
        ztwisted.{}._versionN)r7   AttributeErrorr   rT   rU   rV   r   r   r   r   test_noversionpy&  s    
z-OldSubprojectDeprecationBase.test_noversionpy)r    r!   r"   r#   rV   rY   r[   r   r   r   r   rQ     s   rQ   ZconchrO   namesZmailZrunnerZwordsZnewsZpairc                   @   s   e Zd ZdZeZdS )SubprojectTestCasez6
        See L{OldSubprojectDeprecationBase}.
        N)r    r!   r"   r#   rV   r   r   r   r   r]   7  s   r]   ZVersionDeprecationTestsr   )"r#   Z
__future__r   r   r   rL   typesr   Ztwisted.python._setupr   Ztwisted.python.compatr   Ztwisted.pythonr   Ztwisted.trial.unittestr   objectr	   r&   r$   r+   rF   rQ   ZsubprojectsrV   r]   titleZnewNamer    joinr"   splitglobalsr   r   r   r   r   <module>   sJ   %((V-