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_builder.py @ 745
History | View | Annotate | Download (28.2 KB)
1 |
# copyright 2003-2013 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 |
"""tests for the astroid builder and rebuilder module"""
|
19 |
|
20 |
import os |
21 |
import sys |
22 |
import unittest |
23 |
|
24 |
import six |
25 |
|
26 |
from astroid import builder |
27 |
from astroid import exceptions |
28 |
from astroid import manager |
29 |
from astroid import nodes |
30 |
from astroid import test_utils |
31 |
from astroid import util |
32 |
from astroid.tests import resources |
33 |
|
34 |
MANAGER = manager.AstroidManager() |
35 |
BUILTINS = six.moves.builtins.__name__ |
36 |
|
37 |
|
38 |
class FromToLineNoTest(unittest.TestCase): |
39 |
|
40 |
def setUp(self): |
41 |
self.astroid = resources.build_file('data/format.py') |
42 |
|
43 |
def test_callfunc_lineno(self): |
44 |
stmts = self.astroid.body
|
45 |
# on line 4:
|
46 |
# function('aeozrijz\
|
47 |
# earzer', hop)
|
48 |
discard = stmts[0]
|
49 |
self.assertIsInstance(discard, nodes.Expr)
|
50 |
self.assertEqual(discard.fromlineno, 4) |
51 |
self.assertEqual(discard.tolineno, 5) |
52 |
callfunc = discard.value |
53 |
self.assertIsInstance(callfunc, nodes.Call)
|
54 |
self.assertEqual(callfunc.fromlineno, 4) |
55 |
self.assertEqual(callfunc.tolineno, 5) |
56 |
name = callfunc.func |
57 |
self.assertIsInstance(name, nodes.Name)
|
58 |
self.assertEqual(name.fromlineno, 4) |
59 |
self.assertEqual(name.tolineno, 4) |
60 |
strarg = callfunc.args[0]
|
61 |
self.assertIsInstance(strarg, nodes.Const)
|
62 |
if hasattr(sys, 'pypy_version_info'): |
63 |
lineno = 4
|
64 |
else:
|
65 |
lineno = 5 # no way for this one in CPython (is 4 actually) |
66 |
self.assertEqual(strarg.fromlineno, lineno)
|
67 |
self.assertEqual(strarg.tolineno, lineno)
|
68 |
namearg = callfunc.args[1]
|
69 |
self.assertIsInstance(namearg, nodes.Name)
|
70 |
self.assertEqual(namearg.fromlineno, 5) |
71 |
self.assertEqual(namearg.tolineno, 5) |
72 |
# on line 10:
|
73 |
# fonction(1,
|
74 |
# 2,
|
75 |
# 3,
|
76 |
# 4)
|
77 |
discard = stmts[2]
|
78 |
self.assertIsInstance(discard, nodes.Expr)
|
79 |
self.assertEqual(discard.fromlineno, 10) |
80 |
self.assertEqual(discard.tolineno, 13) |
81 |
callfunc = discard.value |
82 |
self.assertIsInstance(callfunc, nodes.Call)
|
83 |
self.assertEqual(callfunc.fromlineno, 10) |
84 |
self.assertEqual(callfunc.tolineno, 13) |
85 |
name = callfunc.func |
86 |
self.assertIsInstance(name, nodes.Name)
|
87 |
self.assertEqual(name.fromlineno, 10) |
88 |
self.assertEqual(name.tolineno, 10) |
89 |
for i, arg in enumerate(callfunc.args): |
90 |
self.assertIsInstance(arg, nodes.Const)
|
91 |
self.assertEqual(arg.fromlineno, 10+i) |
92 |
self.assertEqual(arg.tolineno, 10+i) |
93 |
|
94 |
def test_function_lineno(self): |
95 |
stmts = self.astroid.body
|
96 |
# on line 15:
|
97 |
# def definition(a,
|
98 |
# b,
|
99 |
# c):
|
100 |
# return a + b + c
|
101 |
function = stmts[3]
|
102 |
self.assertIsInstance(function, nodes.FunctionDef)
|
103 |
self.assertEqual(function.fromlineno, 15) |
104 |
self.assertEqual(function.tolineno, 18) |
105 |
return_ = function.body[0]
|
106 |
self.assertIsInstance(return_, nodes.Return)
|
107 |
self.assertEqual(return_.fromlineno, 18) |
108 |
self.assertEqual(return_.tolineno, 18) |
109 |
if sys.version_info < (3, 0): |
110 |
self.assertEqual(function.blockstart_tolineno, 17) |
111 |
else:
|
112 |
self.skipTest('FIXME http://bugs.python.org/issue10445 ' |
113 |
'(no line number on function args)')
|
114 |
|
115 |
def test_decorated_function_lineno(self): |
116 |
astroid = builder.parse('''
|
117 |
@decorator
|
118 |
def function(
|
119 |
arg):
|
120 |
print (arg)
|
121 |
''', __name__)
|
122 |
function = astroid['function']
|
123 |
self.assertEqual(function.fromlineno, 3) # XXX discussable, but that's what is expected by pylint right now |
124 |
self.assertEqual(function.tolineno, 5) |
125 |
self.assertEqual(function.decorators.fromlineno, 2) |
126 |
self.assertEqual(function.decorators.tolineno, 2) |
127 |
if sys.version_info < (3, 0): |
128 |
self.assertEqual(function.blockstart_tolineno, 4) |
129 |
else:
|
130 |
self.skipTest('FIXME http://bugs.python.org/issue10445 ' |
131 |
'(no line number on function args)')
|
132 |
|
133 |
|
134 |
def test_class_lineno(self): |
135 |
stmts = self.astroid.body
|
136 |
# on line 20:
|
137 |
# class debile(dict,
|
138 |
# object):
|
139 |
# pass
|
140 |
class_ = stmts[4]
|
141 |
self.assertIsInstance(class_, nodes.ClassDef)
|
142 |
self.assertEqual(class_.fromlineno, 20) |
143 |
self.assertEqual(class_.tolineno, 22) |
144 |
self.assertEqual(class_.blockstart_tolineno, 21) |
145 |
pass_ = class_.body[0]
|
146 |
self.assertIsInstance(pass_, nodes.Pass)
|
147 |
self.assertEqual(pass_.fromlineno, 22) |
148 |
self.assertEqual(pass_.tolineno, 22) |
149 |
|
150 |
def test_if_lineno(self): |
151 |
stmts = self.astroid.body
|
152 |
# on line 20:
|
153 |
# if aaaa: pass
|
154 |
# else:
|
155 |
# aaaa,bbbb = 1,2
|
156 |
# aaaa,bbbb = bbbb,aaaa
|
157 |
if_ = stmts[5]
|
158 |
self.assertIsInstance(if_, nodes.If)
|
159 |
self.assertEqual(if_.fromlineno, 24) |
160 |
self.assertEqual(if_.tolineno, 27) |
161 |
self.assertEqual(if_.blockstart_tolineno, 24) |
162 |
self.assertEqual(if_.orelse[0].fromlineno, 26) |
163 |
self.assertEqual(if_.orelse[1].tolineno, 27) |
164 |
|
165 |
def test_for_while_lineno(self): |
166 |
for code in (''' |
167 |
for a in range(4):
|
168 |
print (a)
|
169 |
break
|
170 |
else:
|
171 |
print ("bouh")
|
172 |
''', ''' |
173 |
while a:
|
174 |
print (a)
|
175 |
break
|
176 |
else:
|
177 |
print ("bouh")
|
178 |
'''):
|
179 |
astroid = builder.parse(code, __name__) |
180 |
stmt = astroid.body[0]
|
181 |
self.assertEqual(stmt.fromlineno, 2) |
182 |
self.assertEqual(stmt.tolineno, 6) |
183 |
self.assertEqual(stmt.blockstart_tolineno, 2) |
184 |
self.assertEqual(stmt.orelse[0].fromlineno, 6) # XXX |
185 |
self.assertEqual(stmt.orelse[0].tolineno, 6) |
186 |
|
187 |
def test_try_except_lineno(self): |
188 |
astroid = builder.parse('''
|
189 |
try:
|
190 |
print (a)
|
191 |
except:
|
192 |
pass
|
193 |
else:
|
194 |
print ("bouh")
|
195 |
''', __name__)
|
196 |
try_ = astroid.body[0]
|
197 |
self.assertEqual(try_.fromlineno, 2) |
198 |
self.assertEqual(try_.tolineno, 7) |
199 |
self.assertEqual(try_.blockstart_tolineno, 2) |
200 |
self.assertEqual(try_.orelse[0].fromlineno, 7) # XXX |
201 |
self.assertEqual(try_.orelse[0].tolineno, 7) |
202 |
hdlr = try_.handlers[0]
|
203 |
self.assertEqual(hdlr.fromlineno, 4) |
204 |
self.assertEqual(hdlr.tolineno, 5) |
205 |
self.assertEqual(hdlr.blockstart_tolineno, 4) |
206 |
|
207 |
|
208 |
def test_try_finally_lineno(self): |
209 |
astroid = builder.parse('''
|
210 |
try:
|
211 |
print (a)
|
212 |
finally:
|
213 |
print ("bouh")
|
214 |
''', __name__)
|
215 |
try_ = astroid.body[0]
|
216 |
self.assertEqual(try_.fromlineno, 2) |
217 |
self.assertEqual(try_.tolineno, 5) |
218 |
self.assertEqual(try_.blockstart_tolineno, 2) |
219 |
self.assertEqual(try_.finalbody[0].fromlineno, 5) # XXX |
220 |
self.assertEqual(try_.finalbody[0].tolineno, 5) |
221 |
|
222 |
|
223 |
def test_try_finally_25_lineno(self): |
224 |
astroid = builder.parse('''
|
225 |
try:
|
226 |
print (a)
|
227 |
except:
|
228 |
pass
|
229 |
finally:
|
230 |
print ("bouh")
|
231 |
''', __name__)
|
232 |
try_ = astroid.body[0]
|
233 |
self.assertEqual(try_.fromlineno, 2) |
234 |
self.assertEqual(try_.tolineno, 7) |
235 |
self.assertEqual(try_.blockstart_tolineno, 2) |
236 |
self.assertEqual(try_.finalbody[0].fromlineno, 7) # XXX |
237 |
self.assertEqual(try_.finalbody[0].tolineno, 7) |
238 |
|
239 |
|
240 |
def test_with_lineno(self): |
241 |
astroid = builder.parse('''
|
242 |
from __future__ import with_statement
|
243 |
with file("/tmp/pouet") as f:
|
244 |
print (f)
|
245 |
''', __name__)
|
246 |
with_ = astroid.body[1]
|
247 |
self.assertEqual(with_.fromlineno, 3) |
248 |
self.assertEqual(with_.tolineno, 4) |
249 |
self.assertEqual(with_.blockstart_tolineno, 3) |
250 |
|
251 |
|
252 |
class BuilderTest(unittest.TestCase): |
253 |
|
254 |
def setUp(self): |
255 |
self.builder = builder.AstroidBuilder()
|
256 |
|
257 |
def test_data_build_null_bytes(self): |
258 |
with self.assertRaises(exceptions.AstroidBuildingException): |
259 |
self.builder.string_build('\x00') |
260 |
|
261 |
def test_data_build_invalid_x_escape(self): |
262 |
with self.assertRaises(exceptions.AstroidBuildingException): |
263 |
self.builder.string_build('"\\x1"') |
264 |
|
265 |
def test_missing_newline(self): |
266 |
"""check that a file with no trailing new line is parseable"""
|
267 |
resources.build_file('data/noendingnewline.py')
|
268 |
|
269 |
def test_missing_file(self): |
270 |
with self.assertRaises(exceptions.AstroidBuildingException): |
271 |
resources.build_file('data/inexistant.py')
|
272 |
|
273 |
def test_inspect_build0(self): |
274 |
"""test astroid tree build from a living object"""
|
275 |
builtin_ast = MANAGER.ast_from_module_name(BUILTINS) |
276 |
if six.PY2:
|
277 |
fclass = builtin_ast['file']
|
278 |
self.assertIn('name', fclass) |
279 |
self.assertIn('mode', fclass) |
280 |
self.assertIn('read', fclass) |
281 |
self.assertTrue(fclass.newstyle)
|
282 |
self.assertTrue(fclass.pytype(), '%s.type' % BUILTINS) |
283 |
self.assertIsInstance(fclass['read'], nodes.FunctionDef) |
284 |
# check builtin function has args.args == None
|
285 |
dclass = builtin_ast['dict']
|
286 |
self.assertIsNone(dclass['has_key'].args.args) |
287 |
# just check type and object are there
|
288 |
builtin_ast.getattr('type')
|
289 |
objectastroid = builtin_ast.getattr('object')[0] |
290 |
self.assertIsInstance(objectastroid.getattr('__new__')[0], nodes.FunctionDef) |
291 |
# check open file alias
|
292 |
builtin_ast.getattr('open')
|
293 |
# check 'help' is there (defined dynamically by site.py)
|
294 |
builtin_ast.getattr('help')
|
295 |
# check property has __init__
|
296 |
pclass = builtin_ast['property']
|
297 |
self.assertIn('__init__', pclass) |
298 |
self.assertIsInstance(builtin_ast['None'], nodes.Const) |
299 |
self.assertIsInstance(builtin_ast['True'], nodes.Const) |
300 |
self.assertIsInstance(builtin_ast['False'], nodes.Const) |
301 |
if six.PY3:
|
302 |
self.assertIsInstance(builtin_ast['Exception'], nodes.ClassDef) |
303 |
self.assertIsInstance(builtin_ast['NotImplementedError'], nodes.ClassDef) |
304 |
else:
|
305 |
self.assertIsInstance(builtin_ast['Exception'], nodes.ImportFrom) |
306 |
self.assertIsInstance(builtin_ast['NotImplementedError'], nodes.ImportFrom) |
307 |
|
308 |
def test_inspect_build1(self): |
309 |
time_ast = MANAGER.ast_from_module_name('time')
|
310 |
self.assertTrue(time_ast)
|
311 |
self.assertEqual(time_ast['time'].args.defaults, []) |
312 |
|
313 |
if os.name == 'java': |
314 |
test_inspect_build1 = unittest.expectedFailure(test_inspect_build1) |
315 |
|
316 |
def test_inspect_build2(self): |
317 |
"""test astroid tree build from a living object"""
|
318 |
try:
|
319 |
from mx import DateTime |
320 |
except ImportError: |
321 |
self.skipTest('test skipped: mxDateTime is not available') |
322 |
else:
|
323 |
dt_ast = self.builder.inspect_build(DateTime)
|
324 |
dt_ast.getattr('DateTime')
|
325 |
# this one is failing since DateTimeType.__module__ = 'builtins' !
|
326 |
#dt_ast.getattr('DateTimeType')
|
327 |
|
328 |
def test_inspect_build3(self): |
329 |
self.builder.inspect_build(unittest)
|
330 |
|
331 |
@test_utils.require_version(maxver='3.0') |
332 |
def test_inspect_build_instance(self): |
333 |
"""test astroid tree build from a living object"""
|
334 |
import exceptions |
335 |
builtin_ast = self.builder.inspect_build(exceptions)
|
336 |
fclass = builtin_ast['OSError']
|
337 |
# things like OSError.strerror are now (2.5) data descriptors on the
|
338 |
# class instead of entries in the __dict__ of an instance
|
339 |
container = fclass |
340 |
self.assertIn('errno', container) |
341 |
self.assertIn('strerror', container) |
342 |
self.assertIn('filename', container) |
343 |
|
344 |
def test_inspect_build_type_object(self): |
345 |
builtin_ast = MANAGER.ast_from_module_name(BUILTINS) |
346 |
|
347 |
inferred = list(builtin_ast.igetattr('object')) |
348 |
self.assertEqual(len(inferred), 1) |
349 |
inferred = inferred[0]
|
350 |
self.assertEqual(inferred.name, 'object') |
351 |
inferred.as_string() # no crash test
|
352 |
|
353 |
inferred = list(builtin_ast.igetattr('type')) |
354 |
self.assertEqual(len(inferred), 1) |
355 |
inferred = inferred[0]
|
356 |
self.assertEqual(inferred.name, 'type') |
357 |
inferred.as_string() # no crash test
|
358 |
|
359 |
def test_inspect_transform_module(self): |
360 |
# ensure no cached version of the time module
|
361 |
MANAGER._mod_file_cache.pop(('time', None), None) |
362 |
MANAGER.astroid_cache.pop('time', None) |
363 |
def transform_time(node): |
364 |
if node.name == 'time': |
365 |
node.transformed = True
|
366 |
MANAGER.register_transform(nodes.Module, transform_time) |
367 |
try:
|
368 |
time_ast = MANAGER.ast_from_module_name('time')
|
369 |
self.assertTrue(getattr(time_ast, 'transformed', False)) |
370 |
finally:
|
371 |
MANAGER.unregister_transform(nodes.Module, transform_time) |
372 |
|
373 |
def test_package_name(self): |
374 |
"""test base properties and method of a astroid module"""
|
375 |
datap = resources.build_file('data/__init__.py', 'data') |
376 |
self.assertEqual(datap.name, 'data') |
377 |
self.assertEqual(datap.package, 1) |
378 |
datap = resources.build_file('data/__init__.py', 'data.__init__') |
379 |
self.assertEqual(datap.name, 'data') |
380 |
self.assertEqual(datap.package, 1) |
381 |
|
382 |
def test_yield_parent(self): |
383 |
"""check if we added discard nodes as yield parent (w/ compiler)"""
|
384 |
code = """
|
385 |
def yiell(): #@
|
386 |
yield 0
|
387 |
if noe:
|
388 |
yield more
|
389 |
"""
|
390 |
func = test_utils.extract_node(code) |
391 |
self.assertIsInstance(func, nodes.FunctionDef)
|
392 |
stmt = func.body[0]
|
393 |
self.assertIsInstance(stmt, nodes.Expr)
|
394 |
self.assertIsInstance(stmt.value, nodes.Yield)
|
395 |
self.assertIsInstance(func.body[1].body[0], nodes.Expr) |
396 |
self.assertIsInstance(func.body[1].body[0].value, nodes.Yield) |
397 |
|
398 |
def test_object(self): |
399 |
obj_ast = self.builder.inspect_build(object) |
400 |
self.assertIn('__setattr__', obj_ast) |
401 |
|
402 |
def test_newstyle_detection(self): |
403 |
data = '''
|
404 |
class A:
|
405 |
"old style"
|
406 |
|
407 |
class B(A):
|
408 |
"old style"
|
409 |
|
410 |
class C(object):
|
411 |
"new style"
|
412 |
|
413 |
class D(C):
|
414 |
"new style"
|
415 |
|
416 |
__metaclass__ = type
|
417 |
|
418 |
class E(A):
|
419 |
"old style"
|
420 |
|
421 |
class F:
|
422 |
"new style"
|
423 |
'''
|
424 |
mod_ast = builder.parse(data, __name__) |
425 |
if six.PY3:
|
426 |
self.assertTrue(mod_ast['A'].newstyle) |
427 |
self.assertTrue(mod_ast['B'].newstyle) |
428 |
self.assertTrue(mod_ast['E'].newstyle) |
429 |
else:
|
430 |
self.assertFalse(mod_ast['A'].newstyle) |
431 |
self.assertFalse(mod_ast['B'].newstyle) |
432 |
self.assertFalse(mod_ast['E'].newstyle) |
433 |
self.assertTrue(mod_ast['C'].newstyle) |
434 |
self.assertTrue(mod_ast['D'].newstyle) |
435 |
self.assertTrue(mod_ast['F'].newstyle) |
436 |
|
437 |
def test_globals(self): |
438 |
data = '''
|
439 |
CSTE = 1
|
440 |
|
441 |
def update_global():
|
442 |
global CSTE
|
443 |
CSTE += 1
|
444 |
|
445 |
def global_no_effect():
|
446 |
global CSTE2
|
447 |
print (CSTE)
|
448 |
'''
|
449 |
astroid = builder.parse(data, __name__) |
450 |
self.assertEqual(len(astroid.getattr('CSTE')), 2) |
451 |
self.assertIsInstance(astroid.getattr('CSTE')[0], nodes.AssignName) |
452 |
self.assertEqual(astroid.getattr('CSTE')[0].fromlineno, 2) |
453 |
self.assertEqual(astroid.getattr('CSTE')[1].fromlineno, 6) |
454 |
with self.assertRaises(exceptions.NotFoundError): |
455 |
astroid.getattr('CSTE2')
|
456 |
with self.assertRaises(exceptions.InferenceError): |
457 |
next(astroid['global_no_effect'].ilookup('CSTE2')) |
458 |
|
459 |
@unittest.skipIf(os.name == 'java', |
460 |
'This test is skipped on Jython, because the '
|
461 |
'socket object is patched later on with the '
|
462 |
'methods we are looking for. Since we do not '
|
463 |
'understand setattr in for loops yet, we skip this')
|
464 |
def test_socket_build(self): |
465 |
import socket |
466 |
astroid = self.builder.module_build(socket)
|
467 |
# XXX just check the first one. Actually 3 objects are inferred (look at
|
468 |
# the socket module) but the last one as those attributes dynamically
|
469 |
# set and astroid is missing this.
|
470 |
for fclass in astroid.igetattr('socket'): |
471 |
self.assertIn('connect', fclass) |
472 |
self.assertIn('send', fclass) |
473 |
self.assertIn('close', fclass) |
474 |
break
|
475 |
|
476 |
def test_gen_expr_var_scope(self): |
477 |
data = 'l = list(n for n in range(10))\n'
|
478 |
astroid = builder.parse(data, __name__) |
479 |
# n unavailable outside gen expr scope
|
480 |
self.assertNotIn('n', astroid) |
481 |
# test n is inferable anyway
|
482 |
n = test_utils.get_name_node(astroid, 'n')
|
483 |
self.assertIsNot(n.scope(), astroid)
|
484 |
self.assertEqual([i.__class__ for i in n.infer()], |
485 |
[util.YES.__class__]) |
486 |
|
487 |
def test_no_future_imports(self): |
488 |
mod = builder.parse("import sys")
|
489 |
self.assertEqual(set(), mod._future_imports) |
490 |
|
491 |
def test_future_imports(self): |
492 |
mod = builder.parse("from __future__ import print_function")
|
493 |
self.assertEqual(set(['print_function']), mod._future_imports) |
494 |
|
495 |
def test_two_future_imports(self): |
496 |
mod = builder.parse("""
|
497 |
from __future__ import print_function
|
498 |
from __future__ import absolute_import
|
499 |
""")
|
500 |
self.assertEqual(set(['print_function', 'absolute_import']), mod._future_imports) |
501 |
|
502 |
def test_inferred_build(self): |
503 |
code = '''
|
504 |
class A: pass
|
505 |
A.type = "class"
|
506 |
|
507 |
def A_assign_type(self):
|
508 |
print (self)
|
509 |
A.assign_type = A_assign_type
|
510 |
'''
|
511 |
astroid = builder.parse(code) |
512 |
lclass = list(astroid.igetattr('A')) |
513 |
self.assertEqual(len(lclass), 1) |
514 |
lclass = lclass[0]
|
515 |
self.assertIn('assign_type', lclass._locals) |
516 |
self.assertIn('type', lclass._locals) |
517 |
|
518 |
def test_augassign_attr(self): |
519 |
builder.parse("""
|
520 |
class Counter:
|
521 |
v = 0
|
522 |
def inc(self):
|
523 |
self.v += 1
|
524 |
""", __name__)
|
525 |
# TODO: Check self.v += 1 generate AugAssign(AssAttr(...)),
|
526 |
# not AugAssign(GetAttr(AssName...))
|
527 |
|
528 |
def test_inferred_dont_pollute(self): |
529 |
code = '''
|
530 |
def func(a=None):
|
531 |
a.custom_attr = 0
|
532 |
def func2(a={}):
|
533 |
a.custom_attr = 0
|
534 |
'''
|
535 |
builder.parse(code) |
536 |
nonetype = nodes.const_factory(None)
|
537 |
self.assertNotIn('custom_attr', nonetype._locals) |
538 |
self.assertNotIn('custom_attr', nonetype._instance_attrs) |
539 |
nonetype = nodes.const_factory({}) |
540 |
self.assertNotIn('custom_attr', nonetype._locals) |
541 |
self.assertNotIn('custom_attr', nonetype._instance_attrs) |
542 |
|
543 |
def test_asstuple(self): |
544 |
code = 'a, b = range(2)'
|
545 |
astroid = builder.parse(code) |
546 |
self.assertIn('b', astroid._locals) |
547 |
code = '''
|
548 |
def visit_if(self, node):
|
549 |
node.test, body = node.tests[0]
|
550 |
'''
|
551 |
astroid = builder.parse(code) |
552 |
self.assertIn('body', astroid['visit_if']._locals) |
553 |
|
554 |
def test_build_constants(self): |
555 |
'''test expected values of constants after rebuilding'''
|
556 |
code = '''
|
557 |
def func():
|
558 |
return None
|
559 |
return
|
560 |
return 'None'
|
561 |
'''
|
562 |
astroid = builder.parse(code) |
563 |
none, nothing, chain = [ret.value for ret in astroid.body[0].body] |
564 |
self.assertIsInstance(none, nodes.Const)
|
565 |
self.assertIsNone(none.value)
|
566 |
self.assertIsNone(nothing)
|
567 |
self.assertIsInstance(chain, nodes.Const)
|
568 |
self.assertEqual(chain.value, 'None') |
569 |
|
570 |
def test_not_implemented(self): |
571 |
node = test_utils.extract_node('''
|
572 |
NotImplemented #@
|
573 |
''')
|
574 |
inferred = next(node.infer())
|
575 |
self.assertIsInstance(inferred, nodes.Const)
|
576 |
self.assertEqual(inferred.value, NotImplemented) |
577 |
|
578 |
|
579 |
class FileBuildTest(unittest.TestCase): |
580 |
def setUp(self): |
581 |
self.module = resources.build_file('data/module.py', 'data.module') |
582 |
|
583 |
def test_module_base_props(self): |
584 |
"""test base properties and method of a astroid module"""
|
585 |
module = self.module
|
586 |
self.assertEqual(module.name, 'data.module') |
587 |
self.assertEqual(module.doc, "test module for astroid\n") |
588 |
self.assertEqual(module.fromlineno, 0) |
589 |
self.assertIsNone(module.parent)
|
590 |
self.assertEqual(module.frame(), module)
|
591 |
self.assertEqual(module.root(), module)
|
592 |
self.assertEqual(module.source_file, os.path.abspath(resources.find('data/module.py'))) |
593 |
self.assertEqual(module.pure_python, 1) |
594 |
self.assertEqual(module.package, 0) |
595 |
self.assertFalse(module.is_statement)
|
596 |
self.assertEqual(module.statement(), module)
|
597 |
self.assertEqual(module.statement(), module)
|
598 |
|
599 |
def test_module_locals(self): |
600 |
"""test the 'locals' dictionary of a astroid module"""
|
601 |
module = self.module
|
602 |
_locals = module._locals |
603 |
self.assertIs(_locals, module._globals)
|
604 |
keys = sorted(_locals.keys())
|
605 |
should = ['MY_DICT', 'NameNode', 'YO', 'YOUPI', |
606 |
'__revision__', 'global_access', 'modutils', 'four_args', |
607 |
'os', 'redirect'] |
608 |
should.sort() |
609 |
self.assertEqual(keys, sorted(should)) |
610 |
|
611 |
def test_function_base_props(self): |
612 |
"""test base properties and method of a astroid function"""
|
613 |
module = self.module
|
614 |
function = module['global_access']
|
615 |
self.assertEqual(function.name, 'global_access') |
616 |
self.assertEqual(function.doc, 'function test') |
617 |
self.assertEqual(function.fromlineno, 11) |
618 |
self.assertTrue(function.parent)
|
619 |
self.assertEqual(function.frame(), function)
|
620 |
self.assertEqual(function.parent.frame(), module)
|
621 |
self.assertEqual(function.root(), module)
|
622 |
self.assertEqual([n.name for n in function.args.args], ['key', 'val']) |
623 |
self.assertEqual(function.type, 'function') |
624 |
|
625 |
def test_function_locals(self): |
626 |
"""test the 'locals' dictionary of a astroid function"""
|
627 |
_locals = self.module['global_access']._locals |
628 |
self.assertEqual(len(_locals), 4) |
629 |
keys = sorted(_locals.keys())
|
630 |
self.assertEqual(keys, ['i', 'key', 'local', 'val']) |
631 |
|
632 |
def test_class_base_props(self): |
633 |
"""test base properties and method of a astroid class"""
|
634 |
module = self.module
|
635 |
klass = module['YO']
|
636 |
self.assertEqual(klass.name, 'YO') |
637 |
self.assertEqual(klass.doc, 'hehe') |
638 |
self.assertEqual(klass.fromlineno, 25) |
639 |
self.assertTrue(klass.parent)
|
640 |
self.assertEqual(klass.frame(), klass)
|
641 |
self.assertEqual(klass.parent.frame(), module)
|
642 |
self.assertEqual(klass.root(), module)
|
643 |
self.assertEqual(klass.basenames, [])
|
644 |
if six.PY3:
|
645 |
self.assertTrue(klass.newstyle)
|
646 |
else:
|
647 |
self.assertFalse(klass.newstyle)
|
648 |
|
649 |
def test_class_locals(self): |
650 |
"""test the 'locals' dictionary of a astroid class"""
|
651 |
module = self.module
|
652 |
klass1 = module['YO']
|
653 |
locals1 = klass1._locals |
654 |
keys = sorted(locals1.keys())
|
655 |
self.assertEqual(keys, ['__init__', 'a']) |
656 |
klass2 = module['YOUPI']
|
657 |
locals2 = klass2._locals |
658 |
keys = locals2.keys() |
659 |
self.assertEqual(sorted(keys), |
660 |
['__init__', 'class_attr', 'class_method', |
661 |
'method', 'static_method']) |
662 |
|
663 |
def test_class_instance_attrs(self): |
664 |
module = self.module
|
665 |
klass1 = module['YO']
|
666 |
klass2 = module['YOUPI']
|
667 |
self.assertEqual(list(klass1._instance_attrs.keys()), ['yo']) |
668 |
self.assertEqual(list(klass2._instance_attrs.keys()), ['member']) |
669 |
|
670 |
def test_class_basenames(self): |
671 |
module = self.module
|
672 |
klass1 = module['YO']
|
673 |
klass2 = module['YOUPI']
|
674 |
self.assertEqual(klass1.basenames, [])
|
675 |
self.assertEqual(klass2.basenames, ['YO']) |
676 |
|
677 |
def test_method_base_props(self): |
678 |
"""test base properties and method of a astroid method"""
|
679 |
klass2 = self.module['YOUPI'] |
680 |
# "normal" method
|
681 |
method = klass2['method']
|
682 |
self.assertEqual(method.name, 'method') |
683 |
self.assertEqual([n.name for n in method.args.args], ['self']) |
684 |
self.assertEqual(method.doc, 'method test') |
685 |
self.assertEqual(method.fromlineno, 47) |
686 |
self.assertEqual(method.type, 'method') |
687 |
# class method
|
688 |
method = klass2['class_method']
|
689 |
self.assertEqual([n.name for n in method.args.args], ['cls']) |
690 |
self.assertEqual(method.type, 'classmethod') |
691 |
# static method
|
692 |
method = klass2['static_method']
|
693 |
self.assertEqual(method.args.args, [])
|
694 |
self.assertEqual(method.type, 'staticmethod') |
695 |
|
696 |
def test_method_locals(self): |
697 |
"""test the 'locals' dictionary of a astroid method"""
|
698 |
method = self.module['YOUPI']['method'] |
699 |
_locals = method._locals |
700 |
keys = sorted(_locals)
|
701 |
if sys.version_info < (3, 0): |
702 |
self.assertEqual(len(_locals), 5) |
703 |
self.assertEqual(keys, ['a', 'autre', 'b', 'local', 'self']) |
704 |
else:# ListComp variables are no more accessible outside |
705 |
self.assertEqual(len(_locals), 3) |
706 |
self.assertEqual(keys, ['autre', 'local', 'self']) |
707 |
|
708 |
|
709 |
class ModuleBuildTest(resources.SysPathSetup, FileBuildTest): |
710 |
|
711 |
def setUp(self): |
712 |
super(ModuleBuildTest, self).setUp() |
713 |
abuilder = builder.AstroidBuilder() |
714 |
try:
|
715 |
import data.module |
716 |
except ImportError: |
717 |
# Make pylint happy.
|
718 |
self.skipTest('Unable to load data.module') |
719 |
else:
|
720 |
self.module = abuilder.module_build(data.module, 'data.module') |
721 |
|
722 |
@unittest.skipIf(six.PY3, "guess_encoding not used on Python 3") |
723 |
class TestGuessEncoding(unittest.TestCase): |
724 |
def setUp(self): |
725 |
self.guess_encoding = builder._guess_encoding
|
726 |
|
727 |
def testEmacs(self): |
728 |
e = self.guess_encoding('# -*- coding: UTF-8 -*-') |
729 |
self.assertEqual(e, 'UTF-8') |
730 |
e = self.guess_encoding('# -*- coding:UTF-8 -*-') |
731 |
self.assertEqual(e, 'UTF-8') |
732 |
e = self.guess_encoding(''' |
733 |
### -*- coding: ISO-8859-1 -*-
|
734 |
''')
|
735 |
self.assertEqual(e, 'ISO-8859-1') |
736 |
e = self.guess_encoding(''' |
737 |
|
738 |
### -*- coding: ISO-8859-1 -*-
|
739 |
''')
|
740 |
self.assertIsNone(e)
|
741 |
|
742 |
def testVim(self): |
743 |
e = self.guess_encoding('# vim:fileencoding=UTF-8') |
744 |
self.assertEqual(e, 'UTF-8') |
745 |
e = self.guess_encoding(''' |
746 |
### vim:fileencoding=ISO-8859-1
|
747 |
''')
|
748 |
self.assertEqual(e, 'ISO-8859-1') |
749 |
e = self.guess_encoding(''' |
750 |
|
751 |
### vim:fileencoding= ISO-8859-1
|
752 |
''')
|
753 |
self.assertIsNone(e)
|
754 |
|
755 |
def test_wrong_coding(self): |
756 |
# setting "coding" varaible
|
757 |
e = self.guess_encoding("coding = UTF-8") |
758 |
self.assertIsNone(e)
|
759 |
# setting a dictionnary entry
|
760 |
e = self.guess_encoding("coding:UTF-8") |
761 |
self.assertIsNone(e)
|
762 |
# setting an arguement
|
763 |
e = self.guess_encoding("def do_something(a_word_with_coding=None):") |
764 |
self.assertIsNone(e)
|
765 |
|
766 |
def testUTF8(self): |
767 |
e = self.guess_encoding('\xef\xbb\xbf any UTF-8 data') |
768 |
self.assertEqual(e, 'UTF-8') |
769 |
e = self.guess_encoding(' any UTF-8 data \xef\xbb\xbf') |
770 |
self.assertIsNone(e)
|
771 |
|
772 |
|
773 |
if __name__ == '__main__': |
774 |
unittest.main() |