[Python-ideas] .pyu nicode syntax symbols (was Re: Empty set, Empty dict)

Andrew Barnert abarnert at yahoo.com
Tue Jul 1 11:00:29 CEST 2014


On , Andrew Barnert <abarnert at yahoo.com> wrote:
> On Mon, Jun 30, 2014 at 7:15 PM, Nick Coghlan <ncoghlan at gmail.com> 
> wrote:
>> Eugene Toder & Dave Malcolm have some interesting patches on the 
>> tracker to help enhance the compiler

[snip]
 
> Are you referring to Dave Malcolm's patch to adding a hook for an AST 
> optimizer (in Python) right before compiling the AST to code 
> (http://bugs.python.org/issue10399 and related)? 
> 
> If so, I don't think that would actually help here. Unless it's possible 
> to say "BUILD_SET 0" in AST, but in that case, we don't need any 
> new compiler hooks; just use an import hook the same way MacroPy does.

I should have just tested it before saying anything:

>>> e = ast.Expression(body=ast.Set(elts=[], ctx=ast.Load(),
...                                 lineno=1, col_offset=0))
>>> c = compile(e2, '<>', 'eval')
>>> dis.dis(c)
  1           0 BUILD_SET           0
              3 RETURN_VALUE

So… it is possible to say "BUILD_SET 0" in AST. Which means the easy way to do this is to wrap an import hook around this:

class FixEmptySet(ast.NodeTransformer):
    def visit_Name(self, node):
        if node.id == '_EMPTY_SET_LITERAL':
            return ast.copy_location(
                ast.Set(elts=[], ctx=ast.Load()),
                node)
        return node

def ecompile(src, fname):
    src = src.replace('∅', '_EMPTY_SET_LITERAL')
    tree = compile(src, fname, 'exec', flags=ast.PyCF_ONLY_AST)
    tree = FixEmptySet().visit(tree)
    return compile(tree, fname, 'exec')

code = ecompile('def f(): return ∅', '<>')
exec(code)
f()

That returns set(). And if you dis.dis(f), it's just BUILD_SET 0 and RETURN_VALUE.


More information about the Python-ideas mailing list