Repository: pyca/pyopenssl
Pull request #620 (2017-04-20 17:27:50)

Add an informative __main__.py
Give users an easy way to figure out what versions they're running.

These questions come up with every bug.

codecov[bot]: # [Codecov](https://codecov.io/gh/pyca/pyopenssl/pull/620?src=pr&el=h1) Report
> Merging [#620](https://codecov.io/gh/pyca/pyopenssl/pull/620?src=pr&el=desc) into [master](https://codecov.io/gh/pyca/pyopenssl/commit/7706e1484fe6eab0ae35c103e5b89b7e16fca9a5?src=pr&el=desc) will **decrease** coverage by `0.03%`.
> The diff coverage is `71.42%`.

[![Impacted file tree graph](https://codecov.io/gh/pyca/pyopenssl/pull/620/graphs/tree.svg?width=650&token=KKfpMZOTgK&height=150&src=pr)](https://codecov.io/gh/pyca/pyopenssl/pull/620?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #620      +/-   ##
==========================================
- Coverage   96.78%   96.75%   -0.04%     
==========================================
  Files          16       17       +1     
  Lines        5628     5635       +7     
  Branches      392      393       +1     
==========================================
+ Hits         5447     5452       +5     
- Misses        121      122       +1     
- Partials       60       61       +1
```


| [Impacted Files](https://codecov.io/gh/pyca/pyopenssl/pull/620?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/OpenSSL/\_\_main\_\_.py](https://codecov.io/gh/pyca/pyopenssl/pull/620?src=pr&el=tree#diff-c3JjL09wZW5TU0wvX19tYWluX18ucHk=) | `71.42% <71.42%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pyca/pyopenssl/pull/620?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pyca/pyopenssl/pull/620?src=pr&el=footer). Last update [7706e14...b982875](https://codecov.io/gh/pyca/pyopenssl/pull/620?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

hynek: FTR, on my computer the output looks like this:

```
pyOpenSSL: 17.1.0.dev0
cryptography: 1.7.2
OpenSSL: OpenSSL 1.0.2k  26 Jan 2017
Python: /Users/hynek/.virtualenvs/pyopenssl/bin/python
Python version: 2.7.13 (default, Dec 26 2016, 08:37:46)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]
Platform: darwin
sys.path: ['', '/Users/hynek/.virtualenvs/pyopenssl/lib/python27.zip', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/plat-darwin', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/plat-mac', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/plat-mac/lib-scriptpackages', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/lib-tk', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/lib-old', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/lib-dynload', '/Users/hynek/.pyenv/versions/2.7.13/lib/python2.7', '/Users/hynek/.pyenv/versions/2.7.13/lib/python2.7/plat-darwin', '/Users/hynek/.pyenv/versions/2.7.13/lib/python2.7/lib-tk', '/Users/hynek/.pyenv/versions/2.7.13/lib/python2.7/plat-mac', '/Users/hynek/.pyenv/versions/2.7.13/lib/python2.7/plat-mac/lib-scriptpackages', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/site-packages', '/Users/hynek/Projects/pyopenssl/src']
```

That should be helpful when pinning down packaging problems.

Opinions?
hynek: I would even add a bug template…BUT: not before it’s released?
alex: `-m OpenSSL` is way too generic a name for this; maybe `-m OpenSSL.debug` or something.
hynek: I wasn’t quite sure what you meant with linked/compiled?  I’ve added the OpenSSL the Python ist compiled against, since that is occasionally useful too:

```
pyOpenSSL: 17.1.0.dev0
cryptography: 1.7.2
cryptography's OpenSSL: OpenSSL 1.0.2k  26 Jan 2017
Pythons's OpenSSL: OpenSSL 1.0.2k  26 Jan 2017
Python executable: /Users/hynek/.virtualenvs/pyopenssl/bin/python
Python version: 2.7.13 (default, Dec 26 2016, 08:37:46)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)]
Platform: darwin
sys.path: ['', '/Users/hynek/.virtualenvs/pyopenssl/lib/python27.zip', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/plat-darwin', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/plat-mac', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/plat-mac/lib-scriptpackages', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/lib-tk', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/lib-old', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/lib-dynload', '/Users/hynek/.pyenv/versions/2.7.13/lib/python2.7', '/Users/hynek/.pyenv/versions/2.7.13/lib/python2.7/plat-darwin', '/Users/hynek/.pyenv/versions/2.7.13/lib/python2.7/lib-tk', '/Users/hynek/.pyenv/versions/2.7.13/lib/python2.7/plat-mac', '/Users/hynek/.pyenv/versions/2.7.13/lib/python2.7/plat-mac/lib-scriptpackages', '/Users/hynek/.virtualenvs/pyopenssl/lib/python2.7/site-packages', '/Users/hynek/Projects/pyopenssl/src']
```
hynek: I’ve add the cffi version which is (not only) interesting for #622.
reaperhulk: When @alex said linked vs compiled he meant that when cryptography is compiled the OpenSSL headers are used to determine version. You can obtain the version that was seen during the compile phase with `_util.lib.OPENSSL_VERSION_TEXT`. The version that is actually loaded by the dynamic linker is obtained via the mechanism you already have in this PR. The reason it's interesting to see both is that sometimes people install cryptography/pyOpenSSL and then upgrade OpenSSL. This can occasionally cause problems and that makes it useful to see the mismatch

Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 1c7a69d..ae9e359 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -24,7 +24,8 @@ Deprecations:
 Changes:
 ^^^^^^^^
 
-*none*
+- Added ``OpenSSL.debug`` that allows to get an overview of used library versions (including linked OpenSSL) and other useful runtime information using ``python -m OpenSSL.debug``.
+  `#620 <https://github.com/pyca/pyopenssl/pull/620>`_
 
 
 ----
diff --git a/INSTALL.rst b/INSTALL.rst
index d6c9410..71fe1ed 100644
--- a/INSTALL.rst
+++ b/INSTALL.rst
@@ -29,12 +29,13 @@ Currently that means:
 - 1.0.2
 - 1.1.0
 
-
 If you need support for older releases, the following pinned versions will work:
 
 - **OpenSSL 0.9.8**: ``'pyOpenSSL<17.0' 'cryptography<1.4'``
 - **OpenSSL 1.0.0**: ``'pyOpenSSL<17.1' 'cryptography<1.7'``
 
+You can always find out the versions of pyOpenSSL, cryptography, and the linked OpenSSL by running ``python -m OpenSSL.debug``.
+
 
 Documentation
 -------------
diff --git a/src/OpenSSL/debug.py b/src/OpenSSL/debug.py
new file mode 100644
index 0000000..0d37bf5
--- /dev/null
+++ b/src/OpenSSL/debug.py
@@ -0,0 +1,42 @@
+from __future__ import print_function
+
+import ssl
+import sys
+
+import OpenSSL.SSL
+import cffi
+import cryptography
+
+from . import version
+
+
+_env_info = u"""\
+pyOpenSSL: {pyopenssl}
+cryptography: {cryptography}
+cffi: {cffi}
+cryptography's compiled against OpenSSL: {crypto_openssl_compile}
+cryptography's linked OpenSSL: {crypto_openssl_link}
+Pythons's OpenSSL: {python_openssl}
+Python executable: {python}
+Python version: {python_version}
+Platform: {platform}
+sys.path: {sys_path}""".format(
+    pyopenssl=version.__version__,
+    crypto_openssl_compile=OpenSSL._util.ffi.string(
+        OpenSSL._util.lib.OPENSSL_VERSION_TEXT,
+    ).decode("ascii"),
+    crypto_openssl_link=OpenSSL.SSL.SSLeay_version(
+        OpenSSL.SSL.SSLEAY_VERSION
+    ).decode("ascii"),
+    python_openssl=getattr(ssl, "OPENSSL_VERSION", "n/a"),
+    cryptography=cryptography.__version__,
+    cffi=cffi.__version__,
+    python=sys.executable,
+    python_version=sys.version,
+    platform=sys.platform,
+    sys_path=sys.path,
+)
+
+
+if __name__ == "__main__":
+    print(_env_info)
diff --git a/tox.ini b/tox.ini
index 5098d6f..723562e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -17,6 +17,7 @@ setenv =
     PIP_NO_BINARY=cryptography
 commands =
     openssl version
+    coverage run --parallel -m OpenSSL.debug
     coverage run --parallel -m pytest -v {posargs}
 
 [testenv:py27-twistedMaster]


Test patch:
diff --git a/tests/test_debug.py b/tests/test_debug.py
new file mode 100644
index 0000000..2d62a3a
--- /dev/null
+++ b/tests/test_debug.py
@@ -0,0 +1,10 @@
+from OpenSSL.debug import _env_info
+from OpenSSL import version
+
+
+def test_debug_info():
+    """
+    Debug info contains correct data.
+    """
+    # Just check a sample we control.
+    assert version.__version__ in _env_info
diff --git a/tests/test_util.py b/tests/test_util.py
index 78c97b5..91847e0 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -1,7 +1,7 @@
-from OpenSSL._util import exception_from_error_queue, lib
-
 import pytest
 
+from OpenSSL._util import exception_from_error_queue, lib
+
 
 class TestErrors(object):
     """
@@ -9,7 +9,7 @@ class TestErrors(object):
     """
     def test_exception_from_error_queue_nonexistent_reason(self):
         """
-        :py:func:`exception_from_error_queue` raises ``ValueError`` when it
+        :func:`exception_from_error_queue` raises ``ValueError`` when it
         encounters an OpenSSL error code which does not have a reason string.
         """
         lib.ERR_put_error(lib.ERR_LIB_EVP, 0, 1112, b"", 10)