This project is the inverse of my JavaPy project. It allows you to write Python code using semicolons and braces instead of indentation, like Java.
Call the program with java -jar pyjava.jar <filename> and it will output a file
called the same thing except with a .py extension.
You can use pyjavaconfig.json to configure parsing options.
The program tries to format the file to be human-readable but may not be quite right in places. Use your own formatter as necessary.
The parser does not always check for semantically invalid syntax, such as duplicate/missing variable names, duplicate functions, etc.
The configuration file, if present, has the format
{
"requireSemicolons"?: boolean = false,
"allowColonSimpleBlocks"?: boolean = true,
"allowNoColonSimpleBlocks"?: boolean = true,
"forceParensInStatements"?: boolean = false,
"forceParensInReturnYieldRaise"?: boolean = false,
"files"?: {
"include"?: string[] = ["**.pyj"],
"exclude"?: string[] = []
}
}Simply put, if this is true then semicolons will be required at the end of statements, as opposed to the default method which is similar to JavaScript's semicolon auto-insertion.
Defaults to false.
Input:
if (condition)
return
getValue();Output when requireSemicolons is false:
if (condition):
return
getValue()Output when requireSemicolons is true:
if (condition):
return getValue()This allows you to have blocks consisting of a colon followed by a single statement, such as
if condition: return TrueDefaults to true.
This allows you to have blocks consisting of a single statement, such as
if condition
return TrueDefaults to true.
This option, when true, requires conditions in if, while, for and other statements to be surrounded by parenthesis.
if (condition) { ... }
while (condition) { ... }
for (elem in values) { ... }Defaults to false.
This option, when true, requires the values of return, yield, assert, raise, and basically any other statement which accepts an expression immediately following its keyword, to be enclosed by parenthesis.
return (value)
raise (Exception)
yield (element)
assert (condition, "message")
del (x.y, z[0])Defaults to false.
This object allows you to specify a list of files/folder globs to include and exclude from compilation.
include defaults to ["**.pyj"].
exclude defaults to [].
Non-compound statements must now end with a semicolon unless the --optional-semicolons flag is provided.
A block of code is now enclosed in curly brackets { }.
You can also do a colon : followed by a single statement.
Examples:
Normal Python:
class Example:
def __init__(self, x, y):
self.x = x
self.y = yPyJava:
class Example {
def __init__(self, x, y) {
self.x = x;
self.y = y;
}
}A nice pro of not caring about whitespace is that you can now make mutli-line lambdas (anonymous functions).
Example:
filter(lambda x {
if not isinstance(x, str):
return False;
if x.isspace():
return False;
return True;
}, args)You can also add type annotations to lambdas. Adding type annotations to the parameters requires enclosing the parameters in parenthesis. Adding a return type annotation is as simple as following the parameter list with a -> and the annotation expression.
Example:
lambda (x: int, y: int) -> int {
if x + y < 10 {
return 3;
} else {
return x - y;
}
}You can now do anonymous classes. The syntax is this:
class [superclass arguments] <arguments> <brace-enclosed class body>
If superclass arguments are provided, the hidden name of the class will try to be similar to the first superclass defined. Otherwise, it will be similar to 'object'.
Example:
class Animal(ABC) {
@abstractmethod
def speak(self) {}
}
dog = class(Animal)() {
def speak(self) {
print("woof!");
}
};- The walrus operator
:=, new in Python 3.8, is supported. - The positional parameter syntax
/, new in Python 3.8, is supported. - The match statement, new in Python 3.10, is supported.