diff options
author | Sylvain Th?nault <sylvain.thenault@logilab.fr> | 2013-06-18 17:42:00 +0200 |
---|---|---|
committer | Sylvain Th?nault <sylvain.thenault@logilab.fr> | 2013-06-18 17:42:00 +0200 |
commit | 603897f04b9f5c702e7fbe877207b1ff1dee25b3 (patch) | |
tree | fac019483682417a7ecbf5df5e3ef6f3b8ac4e2c /brain | |
parent | e36d4c0989c849fc51a8d04a687dfeadef0cefce (diff) | |
download | astroid-603897f04b9f5c702e7fbe877207b1ff1dee25b3.tar.gz |
namedtuple support using extended transformation function features. Closes #8766
Diffstat (limited to 'brain')
-rw-r--r-- | brain/py2stdlib.py | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/brain/py2stdlib.py b/brain/py2stdlib.py index b3da2a5..cea3a79 100644 --- a/brain/py2stdlib.py +++ b/brain/py2stdlib.py @@ -5,7 +5,8 @@ Currently help understanding of : * hashlib.md5 and hashlib.sha1 """ -from astroid import MANAGER, nodes +from astroid import MANAGER, AsStringRegexpPredicate, UseInferenceDefault, inference_tip +from astroid import nodes from astroid.builder import AstroidBuilder MODULE_TRANSFORMS = {} @@ -13,6 +14,17 @@ MODULE_TRANSFORMS = {} # module specific transformation functions ##################################### +def transform(module): + try: + tr = MODULE_TRANSFORMS[module.name] + except KeyError: + pass + else: + tr(module) +MANAGER.register_transform(nodes.Module, transform) + +# module specific transformation functions ##################################### + def hashlib_transform(module): fake = AstroidBuilder(MANAGER).string_build(''' @@ -170,16 +182,38 @@ MODULE_TRANSFORMS['pkg_resources'] = pkg_resources_transform MODULE_TRANSFORMS['urlparse'] = urlparse_transform MODULE_TRANSFORMS['subprocess'] = subprocess_transform - -def transform(module): +# namedtuple support ########################################################### + +def infer_named_tuple(node, context=None): + """Specific inference function for namedtuple CallFunc node""" + # node is a CallFunc node, class name as first argument and generated class + # attributes as second argument + if len(node.args) != 2: + # something weird here, go back to class implementation + raise UseInferenceDefault() + # namedtuple list of attributes can be a list of strings or a + # whitespace-separate string try: - tr = MODULE_TRANSFORMS[module.name] - except KeyError: - pass - else: - tr(module) - -from astroid import MANAGER -MANAGER.register_transform(nodes.Module, transform) + name = node.args[0].value + try: + attributes = node.args[1].value.split() + except AttributeError: + attributes = [const.value for const in node.args[1].elts] + except AttributeError: + raise UseInferenceDefault() + # we want to return a Class node instance with proper attributes set + class_node = nodes.Class(name, 'docstring') + # set base class=tuple + class_node.bases.append(nodes.Tuple) + # XXX add __init__(*attributes) method + for attr in attributes: + fake_node = nodes.EmptyNode() + fake_node.parent = class_node + class_node.instance_attrs[attr] = [fake_node] + # we use UseInferenceDefault, we can't be a generator so return an iterator + return iter([class_node]) + +MANAGER.register_transform(nodes.CallFunc, inference_tip(infer_named_tuple), + AsStringRegexpPredicate('namedtuple', 'func')) |