
Show HN: Python-to-Python compiler for some 3.6 features in older versions - nvbn
https://github.com/nvbn/py-backwards
======
sly010
Imho this is a much better solution than 2to3. If python3 adoption is the
goal, python3 should be the input and not the output.

~~~
masklinn
> Imho this is a much better solution than 2to3.

That's nonsensical since it solves a completely unrelated problem.

2to3 was conceived of as a one-shot migration tool for Python 2 codebases. Not
as a way to build cross-version Python, and not as something to use repeatedly
(which it why it is relatively simplistic and fallible), just as a way to take
an existing codebase and handle the first 90% of migrating to Python 3,
leaving you with the second 90%.

~~~
sitkack
You are not being charitable.

2to3 was _conceived_ of as migration tool, as if evolutionary lineages just
all stopped, changed their genome and restarted. Except it only refactored
some easy stuff and let the rest fall on the floor.

Six has had way more impact than 2to3. It was only because core Python said
running a single 2/3 codebase was UnPythonic that people didn't embrace it
sooner. Running a single codebases across both 2 and 3 is now the defacto
technique.

Writing in 3 and "compiling down" to 2 gets people _writing_ 3 which is the
point, even if they can't run CPython3.

~~~
masklinn
> You are not being charitable.

There's nothing to be charitable about, GP's comment is rather clear and
stands for itself.

> 2to3 was _conceived_ of as migration tool

And it still is one, so far as I know, which is actually part of the issues
with it.

> Except it only refactored some easy stuff and let the rest fall on the
> floor.

I'm rather well aware of that, which you'd have noted if you'd actually read
my comment.

> Six has had way more impact than 2to3. […] Running a single codebases across
> both 2 and 3 is now the defacto technique.

Sure, but again that has nothing whatsoever to do with the inanity of ranking
2to3 and backwards.

> Writing in 3 and "compiling down" to 2 gets people writing 3 which is the
> point, even if they can't run CPython3.

You do realise that's _complementary_ to 2to3 right? A big issue of 2to3 is
that once you've converted your P2 codebase to pure-3 ( _not_ a common subset
of 2 and 3) you either have to maintain two different branches making
packaging and backporting difficult or you just leave your P2 users out in the
cold.

Once again, the purpose of 2to3 is not to regularly run 2to3 to generate a
Python3 release from a Python2 source.

------
wbond
Ever since mypy started gaining attention, I’ve been looking for a way to
write using Python 3 annotations and strip the annotations for release so that
the code can run on Python 2.

I never was able to find anyone talking about that goal with mypy, but it
looks like this tool may be a solution.

~~~
sametmax
Use the comment syntax for type annotations. They are compatible with both
versions.

~~~
wbond
I didn’t like the idea of moving the annotations out-of-band with the
parameter names. Aesthetically you also loose syntax highlighting.

------
tyingq
Great idea.

A writeup on how you handled mapping bytes, bytearrays, unicode, etc, to 2.7
constructs would be interesting.

In code that supports both 2 and 3, I end up with ugly stuff testing
sys.hexversion to deal with 3rd party libraries, like pyserial, that expect
str in v2, bytearrays in v3.

~~~
benhoyt
I've scanned the source code and it doesn't look like it handles the
bytes/unicode thing. Which, while the project is cool, will mean it won't work
for a ton of Python 3 code.

~~~
nas
The implicit coercion between bytes and unicode was one of the biggest hurtles
I ran into when porting a relatively large (30k+ lines) code base from Python
2 to 3. Also challenging was the change in comparisons (None no longer smaller
than all types, TypeError when trying to order disjoint types). While this
looks like an interesting hack, I can't see anyone seriously using it to
backport code to Python 2.7.

As I mentioned elsewhere, I created "ppython" to handle these two porting
problems. The source code is on github:
[https://github.com/nascheme/ppython](https://github.com/nascheme/ppython) .
If someone needs a Windows binary, I could build it if you ask politely. ;-)
For my project, it has been a useful tool to speed up porting.

Porting code is not trivial and there is huge amount of Python 2 out there. I
wish more effort had been spent building tools to help porting of code. Even
simple things like disallowing the 'u' prefix on strings in Python 3 was a big
mistake. Mostly those things have been corrected but it is still going to take
a very long time to move the majority of the community to Python 3. There will
be Python 2 running for the next 50 years easily, I'm sure, maybe 100 years.
At least Python is open source and you will not be stranded like VB developers
where when MS drastically changed Visual Basic.

~~~
sitkack
You probably fixed lots of bugs in the process. How long did it take?

------
dbcurtis
Serious question: Why would anyone still be doing anything with Python 2.7
except porting the last remnants of their code base to 3.X?

~~~
Marat_Dukhan
Because Python 2.7 is, IMO, a better language than Python 3+, e.g.:

\- I like lambda a, b: a + b syntax better than lambda a_b: a_b[0] + a_b[1]

\- I prefer map/reduce/filter to return lists rather than iterable

\- I prefer dict.keys/values/items to return sets/lists rather than iterables,
unless I call dict.iter[keys/values/items]

~~~
filmor
Your first point is incorrect, lambda works with the first syntax for both
python 2 and 3. What /has/ changed, however, is the implicit destructuring:

    
    
        l = lambda (a, b): a + b
        l((1, 2))
    

I suspect there are very good reasons not to allow something like this.

With regard to the second point, I also would have liked a more "gradual" step
there, I find myself (especially in REPL environments) often doing
`list(map(sth, sth))`. A `mapi`, `filteri` or something like this would
probably not be zenny enough.

Both don't pose very strong points for python 2 > 3.

~~~
rhaps0dy
PEP 3113 -- Removal of Tuple Parameter Unpacking
[http://legacy.python.org/dev/peps/pep-3113/](http://legacy.python.org/dev/peps/pep-3113/)

These seem like OK reasons, but I find myself continuously needing the
destructuring idiom in lambdas, while these introspection and documentation
concerns are just not there for me.

However tuple-parameters being an exception to rules (such as args and kwargs
not being usable with them) is more compelling. And allowing destructuring
only in lambdas would be weird, because they wouldn't be normal function
objects any more.

Unless the destructuring was only syntactic sugar for the translation in the
PEP? But that's again inconsistent.

------
jwilk
I'm confused with the way the "Supported features" section is divided.

Does it mean I can only use f''-strings if the target version is 3.5? Why such
a limitation?

~~~
linux2647
I think it means that you tell the compiler what version of Python the
original source code is in, so it knows how to compile it. So, if your
codebase has f''-strings then the compiler needs to know.

That's my guess, anyway.

------
forgottenacc57
If you need python 3 features that badly then you have made the case for
upgrading your entire system to use the real python 3.

Python 2 is near end if life anyway.

------
sametmax
Please don't. The transpiler route ended very badly for JS. Let's not open
this pandora box for Python.

~~~
pekk
We've already had tools like 2to3, but they weren't all that popular, and this
won't be either. Most things are ported to Python 3 now and most new projects
just use Python 3. Never fear.

~~~
masklinn
2to3 is not a tool with which you generate releases with, it's a one-shot
porting aid.

------
awinter-py
huzzah -- now that guy who complained python 3 wasn't turing complete can
sleep at night

------
sigjuice
I am not a Python developer, but thanks for not using the unnecessary term
"transpiler".

~~~
castis
But isn't that what this is? I was under the impression that a compiler turns
source code into machine code whereas a transpiler turns source code into
differnet source code?

~~~
daeken
All compilers turn one form of code into another. Whether that's C to assembly
(to machine code), or JavaScript to bytecode to machine code, or Python to
Python. Transpiler is just a term referring to a compiler taking one high-
level language to another. It's unnecessary because a Coffeescript to
JavaScript compiler _is_ a transpiler already; saying "transpiler" there tells
you nothing you don't already know.

~~~
omaranto
The phrase "an A to B compiler" might not gain anything from changing compiler
to transpiler, but the phrase "an A compiler" does.

------
dangayle
Quick! Someone inform Zed Shaw!

~~~
pekk
Pigs fly - he already has a draft of LPTHW for Python 3

------
nas
Interesting but I wonder when you would need a tool like that. I have
something related, a fork of Python 3.6 that adds a bunch of backwards
compatible behaviour so 2.7 code runs more easily,
[https://github.com/nascheme/ppython](https://github.com/nascheme/ppython) .

~~~
antman
Link broken

~~~
leejoramo
[https://github.com/nascheme/ppython](https://github.com/nascheme/ppython)

