gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / astroid / tests / unittest_regrtest.py @ 745
History | View | Annotate | Download (10.3 KB)
1 |
# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
|
---|---|
2 |
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
|
3 |
#
|
4 |
# This file is part of astroid.
|
5 |
#
|
6 |
# astroid is free software: you can redistribute it and/or modify it
|
7 |
# under the terms of the GNU Lesser General Public License as published by the
|
8 |
# Free Software Foundation, either version 2.1 of the License, or (at your
|
9 |
# option) any later version.
|
10 |
#
|
11 |
# astroid is distributed in the hope that it will be useful, but
|
12 |
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
13 |
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
14 |
# for more details.
|
15 |
#
|
16 |
# You should have received a copy of the GNU Lesser General Public License along
|
17 |
# with astroid. If not, see <http://www.gnu.org/licenses/>.
|
18 |
import sys |
19 |
import unittest |
20 |
import textwrap |
21 |
|
22 |
import six |
23 |
|
24 |
from astroid import MANAGER, Instance, nodes |
25 |
from astroid.bases import BUILTINS |
26 |
from astroid.builder import AstroidBuilder |
27 |
from astroid import exceptions |
28 |
from astroid.raw_building import build_module |
29 |
from astroid.manager import AstroidManager |
30 |
from astroid.test_utils import require_version, extract_node |
31 |
from astroid.tests import resources |
32 |
from astroid import transforms |
33 |
|
34 |
|
35 |
class NonRegressionTests(resources.AstroidCacheSetupMixin, |
36 |
unittest.TestCase): |
37 |
|
38 |
def setUp(self): |
39 |
sys.path.insert(0, resources.find('data')) |
40 |
MANAGER.always_load_extensions = True
|
41 |
MANAGER.astroid_cache[BUILTINS] = self._builtins
|
42 |
|
43 |
def tearDown(self): |
44 |
# Since we may have created a brainless manager, leading
|
45 |
# to a new cache builtin module and proxy classes in the constants,
|
46 |
# clear out the global manager cache.
|
47 |
MANAGER.clear_cache(self._builtins)
|
48 |
MANAGER.always_load_extensions = False
|
49 |
sys.path.pop(0)
|
50 |
sys.path_importer_cache.pop(resources.find('data'), None) |
51 |
|
52 |
def brainless_manager(self): |
53 |
manager = AstroidManager() |
54 |
# avoid caching into the AstroidManager borg since we get problems
|
55 |
# with other tests :
|
56 |
manager.__dict__ = {} |
57 |
manager._failed_import_hooks = [] |
58 |
manager.astroid_cache = {} |
59 |
manager._mod_file_cache = {} |
60 |
manager._transform = transforms.TransformVisitor() |
61 |
manager.clear_cache() # trigger proper bootstraping
|
62 |
return manager
|
63 |
|
64 |
def test_module_path(self): |
65 |
man = self.brainless_manager()
|
66 |
mod = man.ast_from_module_name('package.import_package_subpackage_module')
|
67 |
package = next(mod.igetattr('package')) |
68 |
self.assertEqual(package.name, 'package') |
69 |
subpackage = next(package.igetattr('subpackage')) |
70 |
self.assertIsInstance(subpackage, nodes.Module)
|
71 |
self.assertTrue(subpackage.package)
|
72 |
self.assertEqual(subpackage.name, 'package.subpackage') |
73 |
module = next(subpackage.igetattr('module')) |
74 |
self.assertEqual(module.name, 'package.subpackage.module') |
75 |
|
76 |
|
77 |
def test_package_sidepackage(self): |
78 |
manager = self.brainless_manager()
|
79 |
assert 'package.sidepackage' not in MANAGER.astroid_cache |
80 |
package = manager.ast_from_module_name('absimp')
|
81 |
self.assertIsInstance(package, nodes.Module)
|
82 |
self.assertTrue(package.package)
|
83 |
subpackage = next(package.getattr('sidepackage')[0].infer()) |
84 |
self.assertIsInstance(subpackage, nodes.Module)
|
85 |
self.assertTrue(subpackage.package)
|
86 |
self.assertEqual(subpackage.name, 'absimp.sidepackage') |
87 |
|
88 |
|
89 |
def test_living_property(self): |
90 |
builder = AstroidBuilder() |
91 |
builder._done = {} |
92 |
builder._module = sys.modules[__name__] |
93 |
builder.object_build(build_module('module_name', ''), Whatever) |
94 |
|
95 |
|
96 |
def test_new_style_class_detection(self): |
97 |
try:
|
98 |
import pygtk # pylint: disable=unused-variable |
99 |
except ImportError: |
100 |
self.skipTest('test skipped: pygtk is not available') |
101 |
# XXX may fail on some pygtk version, because objects in
|
102 |
# gobject._gobject have __module__ set to gobject :(
|
103 |
builder = AstroidBuilder() |
104 |
data = """
|
105 |
import pygtk
|
106 |
pygtk.require("2.6")
|
107 |
import gobject
|
108 |
|
109 |
class A(gobject.GObject):
|
110 |
pass
|
111 |
"""
|
112 |
astroid = builder.string_build(data, __name__, __file__) |
113 |
a = astroid['A']
|
114 |
self.assertTrue(a.newstyle)
|
115 |
|
116 |
|
117 |
def test_pylint_config_attr(self): |
118 |
try:
|
119 |
from pylint import lint # pylint: disable=unused-variable |
120 |
except ImportError: |
121 |
self.skipTest('pylint not available') |
122 |
mod = MANAGER.ast_from_module_name('pylint.lint')
|
123 |
pylinter = mod['PyLinter']
|
124 |
expect = ['OptionsManagerMixIn', 'object', 'MessagesHandlerMixIn', |
125 |
'ReportsHandlerMixIn', 'BaseTokenChecker', 'BaseChecker', |
126 |
'OptionsProviderMixIn']
|
127 |
self.assertListEqual([c.name for c in pylinter.ancestors()], |
128 |
expect) |
129 |
self.assertTrue(list(Instance(pylinter).getattr('config'))) |
130 |
inferred = list(Instance(pylinter).igetattr('config')) |
131 |
self.assertEqual(len(inferred), 1) |
132 |
self.assertEqual(inferred[0].root().name, 'optparse') |
133 |
self.assertEqual(inferred[0].name, 'Values') |
134 |
|
135 |
def test_numpy_crash(self): |
136 |
"""test don't crash on numpy"""
|
137 |
#a crash occured somewhere in the past, and an
|
138 |
# InferenceError instead of a crash was better, but now we even infer!
|
139 |
try:
|
140 |
import numpy # pylint: disable=unused-variable |
141 |
except ImportError: |
142 |
self.skipTest('test skipped: numpy is not available') |
143 |
builder = AstroidBuilder() |
144 |
data = """
|
145 |
from numpy import multiply
|
146 |
|
147 |
multiply(1, 2, 3)
|
148 |
"""
|
149 |
astroid = builder.string_build(data, __name__, __file__) |
150 |
callfunc = astroid.body[1].value.func
|
151 |
inferred = callfunc.inferred() |
152 |
self.assertEqual(len(inferred), 1) |
153 |
|
154 |
@require_version('3.0') |
155 |
def test_nameconstant(self): |
156 |
# used to fail for Python 3.4
|
157 |
builder = AstroidBuilder() |
158 |
astroid = builder.string_build("def test(x=True): pass")
|
159 |
default = astroid.body[0].args.args[0] |
160 |
self.assertEqual(default.name, 'x') |
161 |
self.assertEqual(next(default.infer()).value, True) |
162 |
|
163 |
@require_version('2.7') |
164 |
def test_with_infer_assignnames(self): |
165 |
builder = AstroidBuilder() |
166 |
data = """
|
167 |
with open('a.txt') as stream, open('b.txt'):
|
168 |
stream.read()
|
169 |
"""
|
170 |
astroid = builder.string_build(data, __name__, __file__) |
171 |
# Used to crash due to the fact that the second
|
172 |
# context manager didn't use an assignment name.
|
173 |
list(astroid.nodes_of_class(nodes.Call))[-1].inferred() |
174 |
|
175 |
def test_recursion_regression_issue25(self): |
176 |
builder = AstroidBuilder() |
177 |
data = """
|
178 |
import recursion as base
|
179 |
|
180 |
_real_Base = base.Base
|
181 |
|
182 |
class Derived(_real_Base):
|
183 |
pass
|
184 |
|
185 |
def run():
|
186 |
base.Base = Derived
|
187 |
"""
|
188 |
astroid = builder.string_build(data, __name__, __file__) |
189 |
# Used to crash in _is_metaclass, due to wrong
|
190 |
# ancestors chain
|
191 |
classes = astroid.nodes_of_class(nodes.ClassDef) |
192 |
for klass in classes: |
193 |
# triggers the _is_metaclass call
|
194 |
klass.type # pylint: disable=pointless-statement
|
195 |
|
196 |
def test_decorator_callchain_issue42(self): |
197 |
builder = AstroidBuilder() |
198 |
data = """
|
199 |
|
200 |
def test():
|
201 |
def factory(func):
|
202 |
def newfunc():
|
203 |
func()
|
204 |
return newfunc
|
205 |
return factory
|
206 |
|
207 |
@test()
|
208 |
def crash():
|
209 |
pass
|
210 |
"""
|
211 |
astroid = builder.string_build(data, __name__, __file__) |
212 |
self.assertEqual(astroid['crash'].type, 'function') |
213 |
|
214 |
def test_filter_stmts_scoping(self): |
215 |
builder = AstroidBuilder() |
216 |
data = """
|
217 |
def test():
|
218 |
compiler = int()
|
219 |
class B(compiler.__class__):
|
220 |
pass
|
221 |
compiler = B()
|
222 |
return compiler
|
223 |
"""
|
224 |
astroid = builder.string_build(data, __name__, __file__) |
225 |
test = astroid['test']
|
226 |
result = next(test.infer_call_result(astroid))
|
227 |
self.assertIsInstance(result, Instance)
|
228 |
base = next(result._proxied.bases[0].infer()) |
229 |
self.assertEqual(base.name, 'int') |
230 |
|
231 |
def test_ancestors_patching_class_recursion(self): |
232 |
node = AstroidBuilder().string_build(textwrap.dedent("""
|
233 |
import string
|
234 |
Template = string.Template
|
235 |
|
236 |
class A(Template):
|
237 |
pass
|
238 |
|
239 |
class B(A):
|
240 |
pass
|
241 |
|
242 |
def test(x=False):
|
243 |
if x:
|
244 |
string.Template = A
|
245 |
else:
|
246 |
string.Template = B
|
247 |
"""))
|
248 |
klass = node['A']
|
249 |
ancestors = list(klass.ancestors())
|
250 |
self.assertEqual(ancestors[0].qname(), 'string.Template') |
251 |
|
252 |
def test_ancestors_yes_in_bases(self): |
253 |
# Test for issue https://bitbucket.org/logilab/astroid/issue/84
|
254 |
# This used to crash astroid with a TypeError, because an YES
|
255 |
# node was present in the bases
|
256 |
node = extract_node("""
|
257 |
def with_metaclass(meta, *bases):
|
258 |
class metaclass(meta):
|
259 |
def __new__(cls, name, this_bases, d):
|
260 |
return meta(name, bases, d)
|
261 |
return type.__new__(metaclass, 'temporary_class', (), {})
|
262 |
|
263 |
import lala
|
264 |
|
265 |
class A(with_metaclass(object, lala.lala)): #@
|
266 |
pass
|
267 |
""")
|
268 |
ancestors = list(node.ancestors())
|
269 |
if six.PY3:
|
270 |
self.assertEqual(len(ancestors), 1) |
271 |
self.assertEqual(ancestors[0].qname(), |
272 |
"{}.object".format(BUILTINS))
|
273 |
else:
|
274 |
self.assertEqual(len(ancestors), 0) |
275 |
|
276 |
def test_ancestors_missing_from_function(self): |
277 |
# Test for https://www.logilab.org/ticket/122793
|
278 |
node = extract_node('''
|
279 |
def gen(): yield
|
280 |
GEN = gen()
|
281 |
next(GEN)
|
282 |
''')
|
283 |
self.assertRaises(exceptions.InferenceError, next, node.infer()) |
284 |
|
285 |
def test_unicode_in_docstring(self): |
286 |
# Crashed for astroid==1.4.1
|
287 |
# Test for https://bitbucket.org/logilab/astroid/issues/273/
|
288 |
|
289 |
# In a regular file, "coding: utf-8" would have been used.
|
290 |
node = extract_node(u'''
|
291 |
from __future__ import unicode_literals
|
292 |
|
293 |
class MyClass(object):
|
294 |
def method(self):
|
295 |
"With unicode : %s "
|
296 |
|
297 |
instance = MyClass()
|
298 |
''' % u"\u2019") |
299 |
|
300 |
next(node.value.infer()).as_string()
|
301 |
|
302 |
|
303 |
class Whatever(object): |
304 |
a = property(lambda x: x, lambda x: x) |
305 |
|
306 |
if __name__ == '__main__': |
307 |
unittest.main() |