Formatting Bython code?
markus-wa opened this issue ยท 7 comments
I would like to enable auto-format-on-save for my IDE but can't find a way to format bython.
I thought by2py example.by && py2by example.py && rm example.py
would achieve what I'm looking for, but it generates some additional newlines etc.
py2by
also doesn't overwrite the existing example.by
so it would have to be done with rm example.by
between by2py
& py2by
. Deleting the file would probably mess up the IDE, 'in place' replacement would be preferable.
Input:
def print_message(num_of_times) {
for i in range(num_of_times) {
print("Bython is awesome!");
}
}
if __name__ == "__main__" {
print_message(10);
}
After by2py:
def print_message(num_of_times):
for i in range(num_of_times):
print("Bython is awesome!")
if __name__ == "__main__":
print_message(10)
After py2by:
def print_message(num_of_times){
for i in range(num_of_times){
print("Bython is awesome!")
}
}
if __name__ == "__main__"{
print_message(10)
}
Maybe cat example.by | by2py --stdin --stdout | py2by --stdin --stdout > example.by
will be what you want, provided that CLI has been changed that way.
Thanks @b1f6c1c4 , I didn't know about the --stdin
& --stdout
flags.
I think those should be mentioned in the --help
output?
So yeah if py2by were to generate nicely formatted output that could do it.
Actually, these flags seemingly haven't been implemented (nor planned) yet. ๐ Probably you can turn this issue into a feature request.
Ohhh, right, I missunderstood ๐
Both py2by
and bython -c
(which by2py
is an alias of) should overwrite files. Could it be your IDE messing things up? (by for example working on a local copy of the file).
For debugging, could you try this with no text editor open and diffing the results? I just did, and it is clear that by2py has overwritten the previous file:
$ cp test.by test2.by
$ by2py test.by && py2by test.py
$ diff test.by test2.by # this produces a non-empty result
Doing this however, will create some newlines. It will also place the closing braces on somewhat clunky positions, imho (because of how the python parser tokenizes the source file). I haven't looked into autmatic formatting of Bython code, something like black could be used for autoformatting the resulting Python code, but that's another issue. From your example I guess that you would like to fix indentation?
Maybe some --format
flag could be added to just fix indentation and such? ๐
@b1f6c1c4 I agree --stdin
and --stdout
options that should be added, feel free to open another issue on that ๐
I actually tried it outside of the IDE, I thought it didn't overwrite the files. I'll check again and post an update.
Actually, indentation seems correct. It's just the additional newlines (or missing ones between defs) that bother me.
+1 for --format
, maybe this could even become the default behavior at some point in the future? (if it doesn't add too much to transpilation time)
I've looked a bit more into this, and making a good code formatter is a lot of work, and very difficult work, and I have more faith in other peoples ability to do it than my own. Thus, I propose the following hacky method of auto-formatting Bython:
- Run
bython -c
on your source code - Run some Python formatter like yapf or black on the resulting Python code
- Run
py2by
to turn it back into Bython
Keep in mind that py2by
is still regarded as experimental, so be careful. I have not had too many issues though.
In the recent version of Bython (version 0.7), one of the updates is reworking where the py2by
translator places the closing brace. It is now much more logical, and more in-line with where a human would place it. It still produces some white spaces, but running a code formatter in-between solves this.
I've done some simple tests with yapf
, and the results seem quite nice:
Input:
def print_message(num_of_times) {
for i in range(num_of_times) {
print("Bython is awesome!");
}
}
if __name__ =="__main__" {
print_message(10);
}
After bython -c
:
def print_message(num_of_times):
for i in range(num_of_times):
print("Bython is awesome!")
if __name__ =="__main__":
print_message(10)
After yapf -i
:
def print_message(num_of_times):
for i in range(num_of_times):
print("Bython is awesome!")
if __name__ == "__main__":
print_message(10)
(notice how this also adds the space in if __name__ == "__main__"
, making the code prettier)
After py2by
:
def print_message(num_of_times) {
for i in range(num_of_times) {
print("Bython is awesome!")
}
}
if __name__ == "__main__" {
print_message(10)
}