codegen icon indicating copy to clipboard operation
codegen copied to clipboard

fails on `from x import y`

Open jonathaneunice opened this issue 13 years ago • 1 comments

$ python
Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

>>> import ast
>>> import codegen
>>> a = ast.parse('import stuf')
>>> print ast.dump(a)
Module(body=[Import(names=[alias(name='stuf', asname=None)])])
>>> print codegen.to_source(a)
import stuf
>>> # so far, so good!
... 

>>> b = ast.parse('from stuf import orderedstuf')
>>> print ast.dump(b)
Module(body=[ImportFrom(module='stuf', names=[alias(name='orderedstuf', asname=None)], level=0)])
>>> print codegen.to_source(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Python/2.7/site-packages/codegen.py", line 70, in to_source
    return ''.join(generator.result)
TypeError: sequence item 2: expected string, alias found
>>> # uh... something broke
... 
>>> 

In looking this over, codegen is based on a 2008 code release. I have not explored them yet, but have found several other forks / descendants of the same code: this refactoring and then an evolved derivative of that: astor. At least one, astor successfully handles this from x import y construction.

jonathaneunice avatar Nov 19 '12 18:11 jonathaneunice

I got the same problem, and fix it as fellow, before I found this issue:

    def visit_ImportFrom(self, node):
        self.newline(node)
        self.write('from %s%s import ' % ('.' * node.level, node.module))
        for idx, item in enumerate(node.names):
            if idx:
                self.write(', ')
            if type(item) is alias:
                self.write(item.name)
            else:
                self.write(item)

mojianhao avatar Apr 26 '17 11:04 mojianhao