summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain Th?nault <sylvain.thenault@logilab.fr>2013-04-11 12:28:32 +0200
committerSylvain Th?nault <sylvain.thenault@logilab.fr>2013-04-11 12:28:32 +0200
commite2a1f83980cb5c995454f48e80a021803a089f3c (patch)
tree2a2f9b9a94a9cc3fd286a0c75081f3c7efbbd1a0
parent8977153205a2cb4eac24f5eab4e15de9bfc8f915 (diff)
downloadastroid-e2a1f83980cb5c995454f48e80a021803a089f3c.tar.gz
enhanced generator support. Closes #124340
-rw-r--r--bases.py7
-rw-r--r--raw_building.py13
-rw-r--r--scoped_nodes.py4
-rw-r--r--test/unittest_lookup.py14
4 files changed, 22 insertions, 16 deletions
diff --git a/bases.py b/bases.py
index 2df440e..b4357ef 100644
--- a/bases.py
+++ b/bases.py
@@ -274,9 +274,12 @@ class BoundMethod(UnboundMethod):
class Generator(Instance):
- """a special node representing a generator"""
+ """a special node representing a generator.
+
+ Proxied class is set once for all in raw_building.
+ """
def callable(self):
- return True
+ return False
def pytype(self):
return '%s.generator' % BUILTINS
diff --git a/raw_building.py b/raw_building.py
index 96eafea..fb234ab 100644
--- a/raw_building.py
+++ b/raw_building.py
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-astng.
@@ -322,15 +322,15 @@ def astng_boot_strapping():
"""astng boot strapping the builtins module"""
# this boot strapping is necessary since we need the Const nodes to
# inspect_build builtins, and then we can proxy Const
- builder = InspectBuilder()
from logilab.common.compat import builtins
- astng_builtin = builder.inspect_build(builtins)
+ astng_builder = InspectBuilder()
+ astng_builtin = astng_builder.inspect_build(builtins)
for cls, node_cls in CONST_CLS.items():
if cls is type(None):
proxy = build_class('NoneType')
proxy.parent = astng_builtin
else:
- proxy = astng_builtin.getattr(cls.__name__)[0] # XXX
+ proxy = astng_builtin.getattr(cls.__name__)[0]
if cls in (dict, list, set, tuple):
node_cls._proxied = proxy
else:
@@ -345,6 +345,7 @@ def _set_proxied(const):
return _CONST_PROXY[const.value.__class__]
Const._proxied = property(_set_proxied)
-# FIXME : is it alright that Generator._proxied is not a astng node?
-Generator._proxied = MANAGER.infer_astng_from_something(type(a for a in ()))
+from types import GeneratorType
+Generator._proxied = Class(GeneratorType.__name__, GeneratorType.__doc__)
+ASTNG_BUILDER.object_build(Generator._proxied, GeneratorType)
diff --git a/scoped_nodes.py b/scoped_nodes.py
index 8ad8116..b53cf0c 100644
--- a/scoped_nodes.py
+++ b/scoped_nodes.py
@@ -1,4 +1,4 @@
-# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-astng.
@@ -612,7 +612,7 @@ class Function(Statement, Lambda):
def infer_call_result(self, caller, context=None):
"""infer what a function is returning when called"""
if self.is_generator():
- yield Generator(self)
+ yield Generator()
return
returns = self.nodes_of_class(Return, skip_klass=Function)
for returnnode in returns:
diff --git a/test/unittest_lookup.py b/test/unittest_lookup.py
index 8361aec..c82c2d3 100644
--- a/test/unittest_lookup.py
+++ b/test/unittest_lookup.py
@@ -1,4 +1,4 @@
-# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of logilab-astng.
@@ -24,7 +24,7 @@ from logilab.common.testlib import TestCase, unittest_main, require_version
from logilab.astng import builder, nodes, scoped_nodes, \
InferenceError, NotFoundError, UnresolvableName
-from logilab.astng.scoped_nodes import builtin_lookup
+from logilab.astng.scoped_nodes import builtin_lookup, Function
from logilab.astng.bases import YES
from unittest_inference import get_name_node
@@ -217,16 +217,18 @@ var
def test_generator_attributes(self):
tree = builder.string_build("""
def count():
- "ntesxt"
+ "test"
yield 0
iterer = count()
num = iterer.next()
""")
next = tree.body[2].value.func # Getattr
- gener = next.expr.infered()[0] # Genrator
- # XXX gener._proxied is a Function which has no instance_attr
- self.assertRaises(AttributeError, gener.getattr, 'next')
+ gener = next.expr.infered()[0] # Generator
+ self.assertIsInstance(gener.getattr('next')[0], Function)
+ self.assertIsInstance(gener.getattr('send')[0], Function)
+ self.assertIsInstance(gener.getattr('throw')[0], Function)
+ self.assertIsInstance(gener.getattr('close')[0], Function)
def test_explicit___name__(self):
code = '''