summaryrefslogtreecommitdiff
path: root/tests/unittest_modutils.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unittest_modutils.py')
-rw-r--r--tests/unittest_modutils.py336
1 files changed, 336 insertions, 0 deletions
diff --git a/tests/unittest_modutils.py b/tests/unittest_modutils.py
new file mode 100644
index 00000000..1747dc22
--- /dev/null
+++ b/tests/unittest_modutils.py
@@ -0,0 +1,336 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2014-2016 Claudiu Popa <pcmanticore@gmail.com>
+# Copyright (c) 2014 Google, Inc.
+# Copyright (c) 2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
+# Copyright (c) 2015 Florian Bruhin <me@the-compiler.org>
+# Copyright (c) 2015 Radosław Ganczarek <radoslaw@ganczarek.in>
+# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
+# Copyright (c) 2018 Mario Corchero <mcorcherojim@bloomberg.net>
+# Copyright (c) 2018 Mario Corchero <mariocj89@gmail.com>
+
+# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
+# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
+
+"""
+unit tests for module modutils (module manipulation utilities)
+"""
+import distutils.version
+import email
+import os
+import sys
+import unittest
+import xml
+from xml import etree
+from xml.etree import ElementTree
+import tempfile
+import shutil
+
+import astroid
+from astroid.interpreter._import import spec
+from astroid import modutils
+from . import resources
+
+
+def _get_file_from_object(obj):
+ return modutils._path_from_filename(obj.__file__)
+
+
+class ModuleFileTest(unittest.TestCase):
+ package = "mypypa"
+
+ def tearDown(self):
+ for k in list(sys.path_importer_cache):
+ if "MyPyPa" in k:
+ del sys.path_importer_cache[k]
+
+ def test_find_zipped_module(self):
+ found_spec = spec.find_spec(
+ [self.package], [resources.find("data/MyPyPa-0.1.0-py2.5.zip")]
+ )
+ self.assertEqual(found_spec.type, spec.ModuleType.PY_ZIPMODULE)
+ self.assertEqual(
+ found_spec.location.split(os.sep)[-3:],
+ ["data", "MyPyPa-0.1.0-py2.5.zip", self.package],
+ )
+
+ def test_find_egg_module(self):
+ found_spec = spec.find_spec(
+ [self.package], [resources.find("data/MyPyPa-0.1.0-py2.5.egg")]
+ )
+ self.assertEqual(found_spec.type, spec.ModuleType.PY_ZIPMODULE)
+ self.assertEqual(
+ found_spec.location.split(os.sep)[-3:],
+ ["data", "MyPyPa-0.1.0-py2.5.egg", self.package],
+ )
+
+ def test_find_distutils_submodules_in_virtualenv(self):
+ found_spec = spec.find_spec(["distutils", "version"])
+ self.assertEqual(found_spec.location, distutils.version.__file__)
+
+
+class LoadModuleFromNameTest(unittest.TestCase):
+ """ load a python module from it's name """
+
+ def test_knownValues_load_module_from_name_1(self):
+ self.assertEqual(modutils.load_module_from_name("sys"), sys)
+
+ def test_knownValues_load_module_from_name_2(self):
+ self.assertEqual(modutils.load_module_from_name("os.path"), os.path)
+
+ def test_raise_load_module_from_name_1(self):
+ self.assertRaises(
+ ImportError, modutils.load_module_from_name, "os.path", use_sys=0
+ )
+
+
+class GetModulePartTest(unittest.TestCase):
+ """given a dotted name return the module part of the name"""
+
+ def test_knownValues_get_module_part_1(self):
+ self.assertEqual(
+ modutils.get_module_part("astroid.modutils"), "astroid.modutils"
+ )
+
+ def test_knownValues_get_module_part_2(self):
+ self.assertEqual(
+ modutils.get_module_part("astroid.modutils.get_module_part"),
+ "astroid.modutils",
+ )
+
+ def test_knownValues_get_module_part_3(self):
+ """relative import from given file"""
+ self.assertEqual(
+ modutils.get_module_part("node_classes.AssName", modutils.__file__),
+ "node_classes",
+ )
+
+ def test_knownValues_get_compiled_module_part(self):
+ self.assertEqual(modutils.get_module_part("math.log10"), "math")
+ self.assertEqual(modutils.get_module_part("math.log10", __file__), "math")
+
+ def test_knownValues_get_builtin_module_part(self):
+ self.assertEqual(modutils.get_module_part("sys.path"), "sys")
+ self.assertEqual(modutils.get_module_part("sys.path", "__file__"), "sys")
+
+ def test_get_module_part_exception(self):
+ self.assertRaises(
+ ImportError, modutils.get_module_part, "unknown.module", modutils.__file__
+ )
+
+
+class ModPathFromFileTest(unittest.TestCase):
+ """ given an absolute file path return the python module's path as a list """
+
+ def test_knownValues_modpath_from_file_1(self):
+ self.assertEqual(
+ modutils.modpath_from_file(ElementTree.__file__),
+ ["xml", "etree", "ElementTree"],
+ )
+
+ def test_knownValues_modpath_from_file_2(self):
+ self.assertEqual(
+ modutils.modpath_from_file(
+ "unittest_modutils.py", {os.getcwd(): "arbitrary.pkg"}
+ ),
+ ["arbitrary", "pkg", "unittest_modutils"],
+ )
+
+ def test_raise_modpath_from_file_Exception(self):
+ self.assertRaises(Exception, modutils.modpath_from_file, "/turlututu")
+
+ def test_import_symlink_with_source_outside_of_path(self):
+ with tempfile.NamedTemporaryFile() as tmpfile:
+ linked_file_name = "symlinked_file.py"
+ try:
+ os.symlink(tmpfile.name, linked_file_name)
+ self.assertEqual(
+ modutils.modpath_from_file(linked_file_name), ["symlinked_file"]
+ )
+ finally:
+ os.remove(linked_file_name)
+
+ def test_import_symlink_both_outside_of_path(self):
+ with tempfile.NamedTemporaryFile() as tmpfile:
+ linked_file_name = os.path.join(tempfile.gettempdir(), "symlinked_file.py")
+ try:
+ os.symlink(tmpfile.name, linked_file_name)
+ self.assertRaises(
+ ImportError, modutils.modpath_from_file, linked_file_name
+ )
+ finally:
+ os.remove(linked_file_name)
+
+ def test_load_from_module_symlink_on_symlinked_paths_in_syspath(self):
+ # constants
+ tmp = tempfile.gettempdir()
+ deployment_path = os.path.join(tmp, "deployment")
+ path_to_include = os.path.join(tmp, "path_to_include")
+ real_secret_path = os.path.join(tmp, "secret.py")
+ symlink_secret_path = os.path.join(path_to_include, "secret.py")
+
+ # setup double symlink
+ # /tmp/deployment
+ # /tmp/path_to_include (symlink to /tmp/deployment)
+ # /tmp/secret.py
+ # /tmp/deployment/secret.py (points to /tmp/secret.py)
+ try:
+ os.mkdir(deployment_path)
+ self.addCleanup(shutil.rmtree, deployment_path)
+ os.symlink(deployment_path, path_to_include)
+ self.addCleanup(os.remove, path_to_include)
+ except OSError:
+ pass
+ with open(real_secret_path, "w"):
+ pass
+ os.symlink(real_secret_path, symlink_secret_path)
+ self.addCleanup(os.remove, real_secret_path)
+
+ # add the symlinked path to sys.path
+ sys.path.append(path_to_include)
+ self.addCleanup(sys.path.pop)
+
+ # this should be equivalent to: import secret
+ self.assertEqual(modutils.modpath_from_file(symlink_secret_path), ["secret"])
+
+
+class LoadModuleFromPathTest(resources.SysPathSetup, unittest.TestCase):
+ def test_do_not_load_twice(self):
+ modutils.load_module_from_modpath(["data", "lmfp", "foo"])
+ modutils.load_module_from_modpath(["data", "lmfp"])
+ # pylint: disable=no-member; just-once is added by a test file dynamically.
+ self.assertEqual(len(sys.just_once), 1)
+ del sys.just_once
+
+
+class FileFromModPathTest(resources.SysPathSetup, unittest.TestCase):
+ """given a mod path (i.e. splited module / package name), return the
+ corresponding file, giving priority to source file over precompiled file
+ if it exists"""
+
+ def test_site_packages(self):
+ filename = _get_file_from_object(modutils)
+ result = modutils.file_from_modpath(["astroid", "modutils"])
+ self.assertEqual(os.path.realpath(result), os.path.realpath(filename))
+
+ def test_std_lib(self):
+ path = modutils.file_from_modpath(["os", "path"]).replace(".pyc", ".py")
+ self.assertEqual(
+ os.path.realpath(path),
+ os.path.realpath(os.path.__file__.replace(".pyc", ".py")),
+ )
+
+ def test_builtin(self):
+ self.assertIsNone(modutils.file_from_modpath(["sys"]))
+
+ def test_unexisting(self):
+ self.assertRaises(ImportError, modutils.file_from_modpath, ["turlututu"])
+
+ def test_unicode_in_package_init(self):
+ # file_from_modpath should not crash when reading an __init__
+ # file with unicode characters.
+ modutils.file_from_modpath(["data", "unicode_package", "core"])
+
+
+class GetSourceFileTest(unittest.TestCase):
+ def test(self):
+ filename = _get_file_from_object(os.path)
+ self.assertEqual(
+ modutils.get_source_file(os.path.__file__), os.path.normpath(filename)
+ )
+
+ def test_raise(self):
+ self.assertRaises(modutils.NoSourceFile, modutils.get_source_file, "whatever")
+
+
+class StandardLibModuleTest(resources.SysPathSetup, unittest.TestCase):
+ """
+ return true if the module may be considered as a module from the standard
+ library
+ """
+
+ def test_datetime(self):
+ # This is an interesting example, since datetime, on pypy,
+ # is under lib_pypy, rather than the usual Lib directory.
+ self.assertTrue(modutils.is_standard_module("datetime"))
+
+ def test_builtins(self):
+ self.assertFalse(modutils.is_standard_module("__builtin__"))
+ self.assertTrue(modutils.is_standard_module("builtins"))
+
+ def test_builtin(self):
+ self.assertTrue(modutils.is_standard_module("sys"))
+ self.assertTrue(modutils.is_standard_module("marshal"))
+
+ def test_nonstandard(self):
+ self.assertFalse(modutils.is_standard_module("astroid"))
+
+ def test_unknown(self):
+ self.assertFalse(modutils.is_standard_module("unknown"))
+
+ def test_4(self):
+ self.assertTrue(modutils.is_standard_module("hashlib"))
+ self.assertTrue(modutils.is_standard_module("pickle"))
+ self.assertTrue(modutils.is_standard_module("email"))
+ self.assertTrue(modutils.is_standard_module("io"))
+ self.assertFalse(modutils.is_standard_module("StringIO"))
+ self.assertTrue(modutils.is_standard_module("unicodedata"))
+
+ def test_custom_path(self):
+ datadir = resources.find("")
+ if any(datadir.startswith(p) for p in modutils.EXT_LIB_DIRS):
+ self.skipTest("known breakage of is_standard_module on installed package")
+
+ self.assertTrue(modutils.is_standard_module("data.module", (datadir,)))
+ self.assertTrue(
+ modutils.is_standard_module("data.module", (os.path.abspath(datadir),))
+ )
+
+ def test_failing_edge_cases(self):
+ # using a subpackage/submodule path as std_path argument
+ self.assertFalse(modutils.is_standard_module("xml.etree", etree.__path__))
+ # using a module + object name as modname argument
+ self.assertTrue(modutils.is_standard_module("sys.path"))
+ # this is because only the first package/module is considered
+ self.assertTrue(modutils.is_standard_module("sys.whatever"))
+ self.assertFalse(modutils.is_standard_module("xml.whatever", etree.__path__))
+
+
+class IsRelativeTest(unittest.TestCase):
+ def test_knownValues_is_relative_1(self):
+ self.assertTrue(modutils.is_relative("utils", email.__path__[0]))
+
+ def test_knownValues_is_relative_3(self):
+ self.assertFalse(modutils.is_relative("astroid", astroid.__path__[0]))
+
+
+class GetModuleFilesTest(unittest.TestCase):
+ def test_get_module_files_1(self):
+ package = resources.find("data/find_test")
+ modules = set(modutils.get_module_files(package, []))
+ expected = [
+ "__init__.py",
+ "module.py",
+ "module2.py",
+ "noendingnewline.py",
+ "nonregr.py",
+ ]
+ self.assertEqual(modules, {os.path.join(package, x) for x in expected})
+
+ def test_get_all_files(self):
+ """test that list_all returns all Python files from given location
+ """
+ non_package = resources.find("data/notamodule")
+ modules = modutils.get_module_files(non_package, [], list_all=True)
+ self.assertEqual(modules, [os.path.join(non_package, "file.py")])
+
+ def test_load_module_set_attribute(self):
+ del xml.etree.ElementTree
+ del sys.modules["xml.etree.ElementTree"]
+ m = modutils.load_module_from_modpath(["xml", "etree", "ElementTree"])
+ self.assertTrue(hasattr(xml, "etree"))
+ self.assertTrue(hasattr(xml.etree, "ElementTree"))
+ self.assertTrue(m is xml.etree.ElementTree)
+
+
+if __name__ == "__main__":
+ unittest.main()