You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While working through the implementation of the reverse bridge for the upcoming J2NI backend, we uncovered an old behavior regarding how Java method names that conflict with Python keywords are handled. Currently, a Java method named exec() is exposed in Python as exec_().
The reason for this is that JPype still respects the keyword list from Python 2, where exec and print were reserved language statements. In modern Python 3, these are standard built-in functions, meaning obj.exec() and obj.print() are perfectly valid syntax and no longer cause syntax errors.
While carrying over these trailing-underscore workarounds is relatively harmless, it is surprising to modern Python developers and leaves legacy "scar tissue" in the API.
As we march toward JPype 2.0, we have a rare, limited window to clean up legacy behaviors like this. Removing the Python 2 keyword protections would be a breaking change for codebases relying on the trailing underscore, but it would bring JPype in line with modern Python expectations.
Proposed Change
For JPype 2.0, we are proposing to update the keyword mangling list to strictly reflect modern Python 3 keywords (e.g., True, False, None, async, await).
What changes: Java methods like exec() or print() will map directly to obj.exec() and obj.print() in Python.
What stays mangled: Methods matching actual Python 3 keywords (like import(), def(), class(), or pass()) will continue to be appended with a trailing underscore (e.g., import_()).
We Want Your Feedback
Because this is a breaking change for anyone currently invoking exec_(), we want to gauge how the community feels about cleaning up the past:
Do you have codebases actively relying on the Python 2-specific mangled names like exec_() or print_()?
Do you support dropping Python 2 keyword mangling entirely for the 2.0 release to achieve a cleaner, modern API?
Are there any other legacy/Python 2 holdovers in JPype that you feel we should drop or keep while we have the hood open for a major release?
This discussion was converted from issue #1376 on June 30, 2026 16:48.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
While working through the implementation of the reverse bridge for the upcoming J2NI backend, we uncovered an old behavior regarding how Java method names that conflict with Python keywords are handled. Currently, a Java method named
exec()is exposed in Python asexec_().The reason for this is that JPype still respects the keyword list from Python 2, where
execandprintwere reserved language statements. In modern Python 3, these are standard built-in functions, meaningobj.exec()andobj.print()are perfectly valid syntax and no longer cause syntax errors.While carrying over these trailing-underscore workarounds is relatively harmless, it is surprising to modern Python developers and leaves legacy "scar tissue" in the API.
As we march toward JPype 2.0, we have a rare, limited window to clean up legacy behaviors like this. Removing the Python 2 keyword protections would be a breaking change for codebases relying on the trailing underscore, but it would bring JPype in line with modern Python expectations.
Proposed Change
For JPype 2.0, we are proposing to update the keyword mangling list to strictly reflect modern Python 3 keywords (e.g.,
True,False,None,async,await).exec()orprint()will map directly toobj.exec()andobj.print()in Python.import(),def(),class(), orpass()) will continue to be appended with a trailing underscore (e.g.,import_()).We Want Your Feedback
Because this is a breaking change for anyone currently invoking
exec_(), we want to gauge how the community feels about cleaning up the past:exec_()orprint_()?Please drop your thoughts and use cases below!
All reactions