Allow reserved key words as methods in CPython

189 views Asked by At

It looks like Python has a list of reserved key words that cannot be used as method names. For instance,

class A:
   def finally(self):
       return 0

returns a SyntaxError: invalid syntax. There is a way around it with getattr/setattr,

  class A:
      pass
  

  setattr(A, 'finally', lambda self: 0)
  
  a = A()
  print(getattr(a, "finally")())

works fine. However, a.finally() still produces a SyntaxError: invalid syntax.

Is there a way to avoid it? More specifically, are there some settings when compiling CPython 3.8 from sources (or a code patch) that would allow avoiding this error?

Note that the same error happens in PyPy 3.

The context is that in Pyodide, that builds CPython to WebAssembly, one can pass Javascripts objects to Python. And because of the present limitation, currently, Python code like Promise.new(...).then(...).finally(...) would error with a syntax error (cf GH-pyodide#769)

2

There are 2 answers

1
sam On BEST ANSWER

I'm not aware of any such flags but I imagine it would be a Herculean feat seeing as how the reserved keywords are baked into the very grammar of Python. You'd have to make some structural changes to allow keywords to be used as method names. It could be easy, but one would have to have knowledge about Python's grammar and how it translates to C. You can start by looking into the Tools section, particularly the peg_generator and parser projects.

Hopefully someone more knowledgeable than I am can give a more satisfying answer.

2
kaya3 On

This is not possible in Python. The standard way around this is to append an underscore if the name would be reserved (e.g. finally_). Otherwise you can just choose a different name.

In your specific case, what you have is JavaScript code, so it's not clear why you would want it to also be valid Python code. If it's not something you need to execute in Python-land then it should probably be in a string instead of raw code; there may be a way to tell the cross-compiler to emit JavaScript code provided as a string. If you do need to execute it in Python-land, then getattr(promise, 'finally') will retrieve it; it may be convenient to define a helper function for dealing with JavaScript promises in Python so you don't have to write getattr everywhere.