You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
4.7 KiB
Python
131 lines
4.7 KiB
Python
import os
|
|
import sys
|
|
import unittest
|
|
|
|
import mitogen.imports
|
|
|
|
import testlib
|
|
|
|
|
|
def testmod_compile(path):
|
|
path = os.path.join(testlib.MODS_DIR, path)
|
|
f = open(path, 'rb')
|
|
co = compile(f.read(), path, 'exec')
|
|
f.close()
|
|
return co
|
|
|
|
|
|
class ScanCodeImportsTest(testlib.TestCase):
|
|
func = staticmethod(mitogen.imports.codeobj_imports)
|
|
|
|
@unittest.skipIf(sys.version_info < (3, 0), "Py is 2.x, would be relative")
|
|
def test_default_absolute(self):
|
|
co = testmod_compile('scanning/defaults.py')
|
|
expected = [
|
|
(0, 'a', ()), (0, 'a.b', ()), (0, 'c', ()),
|
|
(0, 'e', ()), (0, 'e.f', ()), (0, 'h', ()),
|
|
(0, 'i', ()),
|
|
(0, 'j', ('k', 'l', 'm')),
|
|
(0, 'o', ('*',)),
|
|
]
|
|
self.assertEqual(list(self.func(co)), expected)
|
|
|
|
@unittest.skipIf(sys.version_info >= (3, 0), "Py is 3.x, would be absolute")
|
|
def test_default_relative(self):
|
|
co = testmod_compile('scanning/defaults.py')
|
|
expected = [
|
|
(-1, 'a', ()), (-1, 'a.b', ()), (-1, 'c', ()),
|
|
(-1, 'e', ()), (-1, 'e.f', ()), (-1, 'h', ()),
|
|
(-1, 'i', ()),
|
|
(-1, 'j', ('k', 'l', 'm')),
|
|
(-1, 'o', ('*',)),
|
|
]
|
|
self.assertEqual(list(self.func(co)), expected)
|
|
|
|
@unittest.skipIf(sys.version_info < (2, 5), "Py is 2.4, no absolute_import")
|
|
def test_explicit_absolute(self):
|
|
co = testmod_compile('scanning/has_absolute_import.py')
|
|
expected = [
|
|
(0, '__future__', ('absolute_import',)),
|
|
|
|
(0, 'a', ()), (0, 'a.b', ()), (0, 'c', ()),
|
|
(0, 'e', ()), (0, 'e.f', ()), (0, 'h', ()),
|
|
(0, 'i', ()),
|
|
(0, 'j', ('k', 'l', 'm')),
|
|
(0, 'o', ('*',)),
|
|
]
|
|
self.assertEqual(list(self.func(co)), expected)
|
|
|
|
@unittest.skipIf(sys.version_info < (2, 5), "Py is 2.4, no `from . import x`")
|
|
def test_explicit_relative(self):
|
|
co = testmod_compile('scanning/explicit_relative.py')
|
|
expected = [
|
|
(1, '', ('a',)),
|
|
(1, 'b', ('c', 'd')),
|
|
(3, '', ('f', 'j')),
|
|
]
|
|
self.assertEqual(list(self.func(co)), expected)
|
|
|
|
def test_scoped_class(self):
|
|
# Imports in `class` or `def` are ignored, a bad heuristc to detect
|
|
# lazy imports and skip sending the pre-emptively.
|
|
# See
|
|
# - https://github.com/mitogen-hq/mitogen/issues/682
|
|
# - https://github.com/mitogen-hq/mitogen/issues/1325#issuecomment-3170482014
|
|
co = testmod_compile('scanning/scoped_class.py')
|
|
self.assertEqual(list(self.func(co)), [])
|
|
|
|
pass
|
|
|
|
def test_scoped_function(self):
|
|
co = testmod_compile('scanning/scoped_function.py')
|
|
self.assertEqual(list(self.func(co)), [])
|
|
|
|
@unittest.skipIf(sys.version_info >= (3, 0), "Python is 3.x, which prunes")
|
|
def test_scoped_if_else_unpruned(self):
|
|
co = testmod_compile('scanning/scoped_if_else.py')
|
|
level = (-1, 0)[int(sys.version_info >= (3, 0))]
|
|
expected = [
|
|
(level, 'sys', ()),
|
|
(level, 'in_if_always_true', ()),
|
|
(level, 'in_if_always_true', ('x', 'z')),
|
|
# Python 2.x does no pruning
|
|
(level, 'in_else_never_true', ()),
|
|
(level, 'in_else_never_true', ('x', 'z')),
|
|
(level, 'in_if_py3', ()),
|
|
(level, 'in_if_py3', ('x', 'z')),
|
|
(level, 'in_else_py2', ()),
|
|
(level, 'in_else_py2', ('x', 'z')),
|
|
]
|
|
self.assertEqual(list(self.func(co)), expected)
|
|
|
|
@unittest.skipIf(sys.version_info < (3, 0), "Python is 2.x, which doesn't prune")
|
|
def test_scoped_if_else_pruned(self):
|
|
co = testmod_compile('scanning/scoped_if_else.py')
|
|
level = (-1, 0)[int(sys.version_info >= (3, 0))]
|
|
expected = [
|
|
(level, 'sys', ()),
|
|
(level, 'in_if_always_true', ()),
|
|
(level, 'in_if_always_true', ('x', 'z')),
|
|
# Python 3.x prunes some impossible branches ...
|
|
(level, 'in_if_py3', ()),
|
|
(level, 'in_if_py3', ('x', 'z')),
|
|
# ... but not sys.version_info ones
|
|
(level, 'in_else_py2', ()),
|
|
(level, 'in_else_py2', ('x', 'z')),
|
|
]
|
|
self.assertEqual(list(self.func(co)), expected)
|
|
|
|
def test_scoped_try_except(self):
|
|
co = testmod_compile('scanning/scoped_try_except.py')
|
|
level = (-1, 0)[int(sys.version_info >= (3, 0))]
|
|
expected = [
|
|
(level, 'in_try', ()),
|
|
(level, 'in_try', ('x', 'z')),
|
|
(level, 'in_except_importerror', ()),
|
|
(level, 'in_except_importerror', ('x', 'z')),
|
|
(level, 'in_except_exception', ()),
|
|
(level, 'in_except_exception', ('x', 'z')),
|
|
]
|
|
self.assertEqual(list(self.func(co)), expected)
|