title: Test for import of optional dependencies in __init__.py with pytest: Python 3.5 /3.6 differs in behaviour
body: <p>I have a package for python 3.5 and 3.6 that has optional dependencies for which I want tests (pytest) that run on either version. </p>
  
  <p>I made a reduced example below consisting of two files, a simple <code>__init__.py</code> where the optional package "requests" (just an example) is imported and a flag is set to indicate the availability of requests.</p>
  
  <pre><code>mypackage/
  ├── mypackage
  │   └── __init__.py
  └── test_init.py
  </code></pre>
  
  <p>The <code>__init__.py</code> file content:</p>
  
  <pre><code>#!/usr/bin/env python
  # -*- coding: utf-8 -*-
  
  requests_available = True
  
  try:
      import requests
  except ImportError:
      requests_available = False
  </code></pre>
  
  <p>The <code>test_init.py</code> file content:</p>
  
  <pre><code>#!/usr/bin/env python
  # -*- coding: utf-8 -*-
  import pytest, sys
  
  def test_requests_missing(monkeypatch):
      import mypackage
      import copy
      fakesysmodules = copy.copy(sys.modules)
      fakesysmodules["requests"] = None
      monkeypatch.delitem(sys.modules,"requests")
      monkeypatch.setattr("sys.modules", fakesysmodules)
      from importlib import reload
      reload(mypackage)
      assert mypackage.requests_available == False
  
  
  if __name__ == '__main__':
      pytest.main([__file__, "-vv", "-s"])
  </code></pre>
  
  <p>The <code>test_requests_missing</code> test works on Python 3.6.5:</p>
  
  <pre><code>runfile('/home/bjorn/python_packages/mypackage/test_init.py', wdir='/home/bjorn/python_packages/mypackage')
  ============================= test session starts ==============================
  platform linux -- Python 3.6.5, pytest-3.6.1, py-1.5.2, pluggy-0.6.0 -- /home/bjorn/anaconda3/envs/bjorn36/bin/python
  cachedir: .pytest_cache
  rootdir: /home/bjorn/python_packages/mypackage, inifile:
  plugins: requests-mock-1.5.0, mock-1.10.0, cov-2.5.1, nbval-0.9.0, hypothesis-3.38.5
  collecting ... collected 1 item
  
  test_init.py::test_requests_missing PASSED
  
  =========================== 1 passed in 0.02 seconds ===========================
  </code></pre>
  
  <p>But not on Python 3.5.4:</p>
  
  <pre><code>runfile('/home/bjorn/python_packages/mypackage/test_init.py', wdir='/home/bjorn/python_packages/mypackage')
  ========================================================= test session starts ==========================================================
  platform linux -- Python 3.5.4, pytest-3.6.1, py-1.5.2, pluggy-0.6.0 -- /home/bjorn/anaconda3/envs/bjorn35/bin/python
  cachedir: .pytest_cache
  rootdir: /home/bjorn/python_packages/mypackage, inifile:
  plugins: requests-mock-1.5.0, mock-1.10.0, cov-2.5.1, nbval-0.9.1, hypothesis-3.38.5
  collecting ... collected 1 item
  
  test_init.py::test_requests_missing FAILED
  
  =============================================================== FAILURES ===============================================================
  ________________________________________________________ test_requests_missing _________________________________________________________
  
  monkeypatch = &lt;_pytest.monkeypatch.MonkeyPatch object at 0x7f9a2953acc0&gt;
  
      def test_requests_missing(monkeypatch):
          import mypackage
          import copy
          fakesysmodules = copy.copy(sys.modules)
          fakesysmodules["requests"] = None
          monkeypatch.delitem(sys.modules,"requests")
          monkeypatch.setattr("sys.modules", fakesysmodules)
          from importlib import reload
  &gt;       reload(mypackage)
  
  test_init.py:13: 
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
  ../../anaconda3/envs/bjorn35/lib/python3.5/importlib/__init__.py:166: in reload
      _bootstrap._exec(spec, module)
  &lt;frozen importlib._bootstrap&gt;:626: in _exec
      ???
  &lt;frozen importlib._bootstrap_external&gt;:697: in exec_module
      ???
  &lt;frozen importlib._bootstrap&gt;:222: in _call_with_frames_removed
      ???
  mypackage/__init__.py:8: in &lt;module&gt;
      import requests
  ../../anaconda3/envs/bjorn35/lib/python3.5/site-packages/requests/__init__.py:97: in &lt;module&gt;
      from . import utils
  
  .... VERY LONG OUTPUT ....
  
      from . import utils
  ../../anaconda3/envs/bjorn35/lib/python3.5/site-packages/requests/__init__.py:97: in &lt;module&gt;
      from . import utils
  &lt;frozen importlib._bootstrap&gt;:968: in _find_and_load
      ???
  &lt;frozen importlib._bootstrap&gt;:953: in _find_and_load_unlocked
      ???
  &lt;frozen importlib._bootstrap&gt;:896: in _find_spec
      ???
  &lt;frozen importlib._bootstrap_external&gt;:1171: in find_spec
      ???
  &lt;frozen importlib._bootstrap_external&gt;:1145: in _get_spec
      ???
  &lt;frozen importlib._bootstrap_external&gt;:1273: in find_spec
      ???
  &lt;frozen importlib._bootstrap_external&gt;:1245: in _get_spec
      ???
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
  
  name = 'requests', location = '/home/bjorn/anaconda3/envs/bjorn35/lib/python3.5/site-packages/requests/__init__.py'
  
  &gt;   ???
  E   RecursionError: maximum recursion depth exceeded
  
  &lt;frozen importlib._bootstrap_external&gt;:575: RecursionError
  ======================================================= 1 failed in 2.01 seconds =======================================================
  </code></pre>
  
  <p>I have two questions:</p>
  
  <ol>
  <li><p>Why do I see this difference? Relevant packages seem to be of the same version on both 3.5 and 3.6.</p></li>
  <li><p>Is there a better way to do what I want? The code I have now is stitched together from examples found online. I have tried to patch the import mechanism in an attempt to avoid "reload", but I have not managed.</p></li>
  </ol>