Status of the Python 3.14 / uv modernization and what is still open.
- The translator runs on Python 3.14+, packaged with uv (
pyproject.toml,uv_build).setup.pyis gone. - ANTLR 3.1.3 Python runtime vendored and ported to Python 3 in
java2python/lang/antlr3/. - Generated code targets Python 3.14+:
python3shebang, no__future__imports,class X:,super(),ABCinterfaces,intforlong,0ooctal literals, Java integer division via an inlinedjdiv()helper. - The full
cd test && makesuite has been run against a JDK: all 107test/*.javaprograms compile, translate, and run, with the Python output diffing clean against the Java output.make selectorspasses (11 tests). - CLI fixes: a directory walk now writes under the output directory instead
of beside the input (
path.joindiscards it for absolute names), each file of a walk gets its own config list instead of accumulating the previous files' configs, and unreadable or unparseable input reports an error and an exit code instead of a traceback (JavaSyntaxErrorfrombuildAST). - A Claude Code plugin lives in
plugin/; see CLAUDE.md. - Labeled
breakandcontinueare translated. A jump a bare keyword can express still emits one; the rest raise a generated per-label exception that the labeled statement catches (java2python/compiler/visitor.py,basic.maybeLabelClasses). Covered bytest/Break2-4.java,test/Continue3-5.javaandtest/ForEach1.java.
- Java
%semantics. Java%truncates toward zero, while Python%floors, so the results differ when an operand is negative. Consider ajmod()helper alongsidejdiv()(java2python/compiler/visitor.py,java2python/mod/include/). - Division readability. Every
/becomesjdiv(a, b), even for floats, because types aren't tracked. Possible improvements: emit plain/when an operand is a float literal or a float/double cast, or track declared local variable types. - Parser regeneration. The
java2python/lang/Makefileflow (ANTLR 3.1.3 tool, then rewriting the imports to the vendored runtime) is untested. Regenerating would also bring back the__main__blocks that importantlr3.main, which isn't vendored. test/configs/defaults.py. It definesoutputSubs, but the code readsmoduleOutputSubs, so those substitutions probably never apply. Rename it and check that the tests still pass.- Generated-code style. Possible cleanups: emit f-strings instead of
.format()forString.formatand drop redundantint()/str()casts on literals (flagged byruff --select UPon the test output).@classmethodfor static methods could become@staticmethodwhenclsisn't used. - Optional dependency on zope.interface. It is only needed by
test/configs/defaults.pyand thezope*handlers inmod/basic.py. Consider dropping those handlers. - Tooling. Add ruff configuration and CI (GitHub Actions with
astral-sh/setup-uv, a JDK, andmake -C test). Possibly port the Makefile harness to pytest. - Docs.
doc/usage.md,doc/translation.md, anddoc/customization.mdstill show Python 2-era output in places, and the links still point at the upstreamnatural/java2pythonrepository.