Mercurial > master > logilab > astng
changeset 705:1ee2ec866741
fix #20464: raises “TypeError: '_Yes' object is not iterable” on list inference
| author | Sylvain Thénault <sylvain.thenault@logilab.fr> |
|---|---|
| date | Tue, 23 Mar 2010 09:47:19 +0100 |
| parents | 89ad40f83a7b |
| children | d31d479ed4a1 |
| files | ChangeLog protocols.py test/unittest_inference.py |
| diffstat | 3 files changed, 43 insertions(+), 3 deletions(-) [+] |
line diff
1.1 --- a/ChangeLog Mon Mar 22 18:23:24 2010 +0100 1.2 +++ b/ChangeLog Tue Mar 23 09:47:19 2010 +0100 1.3 @@ -4,6 +4,8 @@ 1.4 -- 1.5 1.6 2010-03-22 -- 0.20.0 1.7 + * fix #20464: raises “TypeError: '_Yes' object is not iterable” on list inference 1.8 + 1.9 * fix #19882: pylint hangs 1.10 1.11 * fix #20759: crash on pyreverse UNARY_OP_METHOD KeyError '~' 1.12 @@ -22,8 +24,10 @@ 1.13 * Ned Batchelder patch to properly import eggs with Windows line 1.14 endings. This fixes a problem with pylint not being able to 1.15 import setuptools. 1.16 + 1.17 * Winfried Plapper patches fixing .op attribute value for AugAssign nodes, 1.18 visit_ifexp in nodes_as_string 1.19 + 1.20 * Edward K. Ream / Tom Fleck patch closes #19641 (maximum recursion depth 1.21 exceeded" messages w/ python 2.6), see https://bugs.launchpad.net/pylint/+bug/456870 1.22
2.1 --- a/protocols.py Mon Mar 22 18:23:24 2010 +0100 2.2 +++ b/protocols.py Tue Mar 23 09:47:19 2010 +0100 2.3 @@ -107,13 +107,16 @@ 2.4 for other in other.infer(context): 2.5 if isinstance(other, self.__class__) and operator == '+': 2.6 node = self.__class__() 2.7 - elts = [n for elt in self.elts for n in elt.infer(context)] 2.8 - elts += [n for elt in other.elts for n in elt.infer(context)] 2.9 + elts = [n for elt in self.elts for n in elt.infer(context) 2.10 + if not n is YES] 2.11 + elts += [n for elt in other.elts for n in elt.infer(context) 2.12 + if not n is YES] 2.13 node.elts = elts 2.14 yield node 2.15 elif isinstance(other, nodes.Const) and operator == '*': 2.16 node = self.__class__() 2.17 - elts = [n for elt in self.elts for n in elt.infer(context)] * other.value 2.18 + elts = [n for elt in self.elts for n in elt.infer(context) 2.19 + if not n is YES] * other.value 2.20 node.elts = elts 2.21 yield node 2.22 elif isinstance(other, Instance) and not isinstance(other, nodes.Const):
3.1 --- a/test/unittest_inference.py Mon Mar 22 18:23:24 2010 +0100 3.2 +++ b/test/unittest_inference.py Tue Mar 23 09:47:19 2010 +0100 3.3 @@ -1056,5 +1056,38 @@ 3.4 break 3.5 else: 3.6 self.fail('expected to find an instance of Application in %s' % infered) 3.7 + 3.8 + def test_list_inference(self): 3.9 + """#20464""" 3.10 + code = ''' 3.11 +import optparse 3.12 + 3.13 +A = [] 3.14 +B = [] 3.15 + 3.16 +def test(): 3.17 + xyz = [ 3.18 + "foobar=%s" % options.ca, 3.19 + ] + A + B 3.20 + 3.21 + if options.bind is not None: 3.22 + xyz.append("bind=%s" % options.bind) 3.23 + return xyz 3.24 + 3.25 +def main(): 3.26 + global options 3.27 + 3.28 + parser = optparse.OptionParser() 3.29 + (options, args) = parser.parse_args() 3.30 + 3.31 +Z = test() 3.32 + ''' 3.33 + astng = builder.string_build(code, __name__, __file__) 3.34 + infered = list(astng['Z'].infer()) 3.35 + self.assertEquals(len(infered), 1, infered) 3.36 + self.assertIsInstance(infered[0], Instance) 3.37 + self.assertIsInstance(infered[0]._proxied, nodes.Class) 3.38 + self.assertEquals(infered[0]._proxied.name, 'list') 3.39 + 3.40 if __name__ == '__main__': 3.41 unittest_main()
