o
    ]                      @   s   d Z ddlZddlZddlZddlZddl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 ddZdd Zdd Zdd Zdd Zdd ZdS )!a  
Checks for stem dependencies.

Aside from Python itself Stem only has soft dependencies, which is to say
module unavailability only impacts features that require it. For example,
descriptor signature validation requires 'cryptography'. If unavailable
stem will still read descriptors - just without signature checks.

::

  check_requirements - checks for minimum requirements for running stem
  is_python_3 - checks if python 3.0 or later is available
  is_sqlite_available - checks if the sqlite3 module is available
  is_crypto_available - checks if the cryptography module is available
  is_zstd_available - checks if the zstd module is available
  is_lzma_available - checks if the lzma module is available
  is_mock_available - checks if the mock module is available
    NzUnable to import the cryptography module. Because of this we'll be unable to verify descriptor signature integrity. You can get cryptography from: https://pypi.org/project/cryptography/zTZSTD compression requires the zstandard module (https://pypi.org/project/zstandard/)zWLZMA compression requires the lzma module (https://docs.python.org/3/library/lzma.html)zUnable to verify descriptor ed25519 certificate integrity. ed25519 is not supported by installed versions of OpenSSL and/or cryptographyc                  C   s:   t jdd \} }| dk s| dkr|dk rtddS dS )z
  Checks that we meet the minimum requirements to run stem. If we don't then
  this raises an ImportError with the issue.

  :raises: **ImportError** with the problem if we don't meet stem's
    requirements
  r         z+stem requires python version 2.6 or greaterN)sysversion_infoImportErrormajor_versionminor_version r
   -/usr/lib/python3/dist-packages/stem/prereq.pycheck_requirements&   s   	r   c                  C   s"   t jdd \} }| dko|dkS )a*  
  Checks if we're running python 2.6. This isn't for users as it'll be removed
  in stem 2.0 (when python 2.6 support goes away).

  .. deprecated:: 1.8.0
     Stem 2.x will remove this method along with Python 2.x support.

  :returns: **True** if we're running python 2.6, **False** otherwise
  r   r   r   r   r   r   r
   r
   r   _is_python_265   s   r   c                  C   s*   t jdd \} }| dkp| dko|dkS )z
  Checks if we're running python 2.7 or above (including the 3.x series).

  .. deprecated:: 1.5.0
     Stem 2.x will remove this method along with Python 2.x support.

  :returns: **True** if we meet this requirement and **False** otherwise
  r   r      r   r   r
   r
   r   is_python_27E   s   
r   c                   C   s   t jd dkS )z
  Checks if we're in the 3.0 - 3.x range.

  .. deprecated:: 1.8.0
     Stem 2.x will remove this method along with Python 2.x support.

  :returns: **True** if we meet this requirement and **False** otherwise
  r      r   r
   r
   r
   r   is_python_3T   s   
r   c                   C   s   t  dkS )zy
  Checks if we're running PyPy.

  .. versionadded:: 1.7.0

  :returns: **True** if running pypy, **False** otherwise
  ZPyPy)platformZpython_implementationr
   r
   r
   r   is_pypya   s   	r   c                  C   s$   zddl } W dS  ty   Y dS w )z
  Checks if the sqlite3 module is available. Usually this is built in, but some
  platforms such as FreeBSD and Gentoo exclude it by default.

  .. versionadded:: 1.6.0

  :returns: **True** if we can use the sqlite3 module and **False** otherwise
  r   NTF)sqlite3r   )r   r
   r
   r   is_sqlite_availablem   s   
r   Fc                 C   s   ddl m} zRddlm}m} ddlm} ddlm} ddl	m
} ddlm}m}m}	 ddlm}
 t|jd	s:t | rVdd
lm} t|drK| sV|d|jt W dS W dS  tyj   |d|jt Y dS w )a  
  Checks if the cryptography functions we use are available. This is used for
  verifying relay descriptor signatures.

  :param bool ed25519: check for `ed25519 support
    <https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ed25519/>`_,
    which requires both cryptography version 2.6 and OpenSSL support

  :returns: **True** if we can use the cryptography module and **False**
    otherwise
  r   log)int_from_bytesint_to_bytes)default_backend)backend)rsa)Cipher
algorithmsmodes)load_der_public_keysign)Ed25519PublicKeyed25519_supportedz(stem.prereq._is_crypto_ed25519_supportedFTzstem.prereq.is_crypto_available)	stem.utilr   Zcryptography.utilsr   r   Zcryptography.hazmat.backendsr   Z,cryptography.hazmat.backends.openssl.backendr   Z)cryptography.hazmat.primitives.asymmetricr   Z&cryptography.hazmat.primitives.ciphersr   r   r    Z,cryptography.hazmat.primitives.serializationr!   hasattrZRSAPrivateKeyr   Z1cryptography.hazmat.primitives.asymmetric.ed25519r#   r$   log_onceINFOED25519_UNSUPPORTEDCRYPTO_UNAVAILABLE)Zed25519r   r   r   r   r   r   r   r   r    r!   r#   r
   r
   r   is_crypto_available~   s(   r+   c                  C   sF   z
ddl } t| dW S  ty"   ddlm} |d|jt Y dS w )z
  Checks if the `zstd module <https://pypi.org/project/zstandard/>`_ is
  available.

  .. versionadded:: 1.7.0

  :returns: **True** if we can use the zstd module and **False** otherwise
  r   NZZstdDecompressorr   zstem.prereq.is_zstd_availableF)zstdr&   r   r%   r   r'   r(   ZSTD_UNAVAILABLE)r,   r   r
   r
   r   is_zstd_available   s   
r.   c                  C   s@   zddl } W dS  ty   ddlm} |d|jt Y dS w )z
  Checks if the `lzma module <https://docs.python.org/3/library/lzma.html>`_ is
  available. This was added as a builtin in Python 3.3.

  .. versionadded:: 1.7.0

  :returns: **True** if we can use the lzma module and **False** otherwise
  r   NTr   zstem.prereq.is_lzma_availableF)lzmar   r%   r   r'   r(   LZMA_UNAVAILABLE)r/   r   r
   r
   r   is_lzma_available   s   
r1   c                  C   sp   zddl } W dS  ty   Y nw zddl}t|jdst dt|jjvr+t W dS  ty7   Y dS w )a  
  Checks if the mock module is available. In python 3.3 and up it is a builtin
  unittest module, but before this it needed to be `installed separately
  <https://pypi.org/project/mock/>`_. Imports should be as follows....

  ::

    try:
      # added in python 3.3
      from unittest.mock import Mock
    except ImportError:
      from mock import Mock

  :returns: **True** if the mock module is available and **False** otherwise
  r   NTdictZnew_callableF)Zunittest.mockr   mockr&   ZpatchinspectZ
getargspecargs)Zunittestr3   r
   r
   r   is_mock_available   s    r6   c                  C   s0   t jdd \} }| dkr|dkrdS ttdS )z
  Functools added lru_cache to the standard library in Python 3.2. Prior to
  this using a bundled implementation. We're also using this with Python 3.5
  due to a buggy implementation. (:trac:`26412`)
  r   r   r      F	lru_cache)r   r   r&   	functoolsr   r
   r
   r   _is_lru_cache_available   s   
r:   c                  C   sH   t tdr
t tdszddl} W n	 ty   Y nw t tdo#t tdS )z
  Check if hashlib has sha3 support. This requires Python 3.6+ *or* the `pysha3
  module <https://github.com/tiran/pysha3>`_.
  Zsha3_256Z	shake_256r   N)r&   hashlibsha3r   )r<   r
   r
   r   _is_sha3_available  s   	r=   )F)__doc__r9   r;   r4   r   r   r*   r-   r0   r)   r   r   r   r   r   r   r+   r.   r1   r6   r:   r=   r
   r
   r
   r   <module>   s,   
**