[test] Fix modutils tests when running inside a python 3 virtualenv (closes #294756)

Virtualenv symlinks a bunch of stdlib modules which confuse modutils.is_standard_module. The better way would obviously be to fix modutils to properly detect virtualenvs, but life is too short.

As for why virtualenv actually needs to symlink a good chunk of the stdlib, anyone's guess is as good as mine. Here's the upstream commit that added hashlib.py to the list of needed symlinks:

https://github.com/pypa/virtualenv/commit/10ba3f3cc0d7a254dd72e2bb9557006da2f85e00#diff-7e83770aa980bd4327db90f4eafeffdfR126

And for the record, 'venv' (the virtualenv-lookalike shipped since python 3.3) does not do _any_ symlink to stdlib modules.

authorRémi Cardona <remi.cardona@logilab.fr>
changeset8d089ae2f65c
branchdefault
phasepublic
hiddenno
parent revision#e16e5879a442 [test] remove check for python < 2.6
child revision#08da823fb5a5 [pkg] Prepare 1.0.0
files modified by this revision
logilab/common/modutils.py
test/unittest_modutils.py
# HG changeset patch
# User Rémi Cardona <remi.cardona@logilab.fr>
# Date 1435598181 -7200
# Mon Jun 29 19:16:21 2015 +0200
# Node ID 8d089ae2f65cbad7b8580967db46e3bdbb01ca79
# Parent e16e5879a44209f14b3b7aa0bccb40aaf6b73d32
[test] Fix modutils tests when running inside a python 3 virtualenv (closes #294756)

Virtualenv symlinks a bunch of stdlib modules which confuse
modutils.is_standard_module. The better way would obviously be to fix
modutils to properly detect virtualenvs, but life is too short.

As for why virtualenv actually needs to symlink a good chunk of the
stdlib, anyone's guess is as good as mine. Here's the upstream commit
that added hashlib.py to the list of needed symlinks:

https://github.com/pypa/virtualenv/commit/10ba3f3cc0d7a254dd72e2bb9557006da2f85e00#diff-7e83770aa980bd4327db90f4eafeffdfR126

And for the record, 'venv' (the virtualenv-lookalike shipped since
python 3.3) does not do _any_ symlink to stdlib modules.

diff --git a/logilab/common/modutils.py b/logilab/common/modutils.py
@@ -493,10 +493,13 @@
1      :rtype: bool
2      :return:
3        true if the module:
4        - is located on the path listed in one of the directory in `std_path`
5        - is a built-in module
6 +
7 +    Note: this function is known to return wrong values when inside virtualenv.
8 +    See https://www.logilab.org/ticket/294756.
9      """
10      modname = modname.split('.')[0]
11      try:
12          filename = file_from_modpath([modname])
13      except ImportError as ex:
diff --git a/test/unittest_modutils.py b/test/unittest_modutils.py
@@ -204,15 +204,18 @@
14      def test_unknown(self):
15          self.assertEqual(modutils.is_standard_module('unknown'), False)
16 
17      def test_4(self):
18          self.assertEqual(modutils.is_standard_module('marshal'), True)
19 -        self.assertEqual(modutils.is_standard_module('hashlib'), True)
20          self.assertEqual(modutils.is_standard_module('pickle'), True)
21          self.assertEqual(modutils.is_standard_module('email'), True)
22 -        self.assertEqual(modutils.is_standard_module('io'), True)
23          self.assertEqual(modutils.is_standard_module('StringIO'), sys.version_info < (3, 0))
24 +        venv_py3 = sys.version_info[0] >= 3 and hasattr(sys, 'real_prefix')
25 +        if not venv_py3:
26 +            # those modules are symlinked by virtualenv (but not by python's venv)
27 +            self.assertEqual(modutils.is_standard_module('hashlib'), True)
28 +            self.assertEqual(modutils.is_standard_module('io'), True)
29 
30      def test_custom_path(self):
31          self.assertEqual(modutils.is_standard_module('data.module', (DATADIR,)), True)
32          self.assertEqual(modutils.is_standard_module('data.module', (path.abspath(DATADIR),)), True)
33