1

For some projects, I'd like to stop supporting Python 2.7 (see http://python3statement.org/) to use only Python > 3.6 (or rather 3.5 + f-string, like Pypy v6.0).

A first step could be to modify the setup.py file to get an explicit error if one try to use the package with a Python version without f-string.

But then there is a lot of work to switch to pure Python 3.6 syntax and remove all the

  • from __future__ import ...,

  • try related to Python 2.7 support,

  • future and/or six code

and to replace in many places

  • class MyClass(object) -> class MyClass:
  • super(MyClass, self) -> super()
  • "{}".format(foo) -> f"{foo}"

I did this work for a code basically manually (actually I also automate some steps by processing the code with a Python script) and I really see the difference. The code is much less verbose now and globally much nicer.

I'm sure that I forget many other nice simplifications that could be done, for example I now use a lot from pathlib import Path but these changes are much less direct.

How would you transform a Python 2.7/3.6 compatible code to a clean Python 3.6 code? How can you avoid to do this boring work manually?

Edit after the first answer

I think a hypothetical internalization (which in many cases won't append) should not stop us from using f-strings, which are just cleaner (and slightly faster).

I still think the modifications that I mentioned are reasonable.

wim
  • 338,267
  • 99
  • 616
  • 750
paugier
  • 1,838
  • 2
  • 20
  • 39
  • 2
    StackOverflow has a rule against asking for recommendations for libraries, which sometimes feels silly, but it does protect from a lot of spam. If you edit your answer to ask for a way to transform code to Python 3.6 code (rather than a tool), then I could see this question being re-opened. – Flimm Sep 20 '18 at 11:28
  • Thank you. I removed the world "tool". – paugier Sep 20 '18 at 11:54
  • What do I have to do to have this question reopened? – paugier Sep 20 '18 at 13:10
  • Enough people have to vote to re-open the question. It looks like this question was re-opened. – Flimm Sep 21 '18 at 09:00

2 Answers2

2

If your goal is to stop your code from running on pre-Python-3.6, then explicitly check for that:

import sys
if sys.version_info < (3, 6):
    raise RuntimeError('my_thing requires a Python version of at least 3.6.')

If you just no longer care about pre-Python-3.6 support, then you don't need to do anything. Your code is already perfectly valid Python 3.6.


Trying to go through your whole codebase and transform it all to use techniques that don't work on prior versions would merely cause a ton of unnecessary code churn and risk introducing bugs for no real gain. The new techniques aren't even unconditional upgrades over the old; for example, if you go through and switch all your string formatting to f-strings, you may find yourself having to go through and switch everything back again anyway to support internationalization, because it's impossible to internationalize f-string formatting.

Instead, when you have a specific reason to change some part of your code, you should feel free to use techniques that are incompatible with pre-3.6 Python releases when making those changes.


Remember, the new things in new Python releases aren't just simple things like 0-argument super. If you want to stuff your code full of as many shiny new language features as possible for some reason, there's stuff like

and that's before even considering Python 3-only dependencies you now have access to. Many of these things will require careful design work to incorporate into your program. Incorporating them in a way that produces actually good code isn't something an automatic tool or a mindless, quick manual pass over your code can handle. Trying to tell you how to incorporate all these things into your program is far too broad for a Stack Overflow answer; there's just too much new stuff.

Also, even the Python standard library itself makes no effort to purge use of patterns compatible with old versions. A quick grep through the current CPython master branch shows hundreds of classes still inheriting from object and over a thousand uses of str.format that could be replaced with f-strings.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • I'm sorry but you don't answer to the question and the tone of your answer is inappropriate. I asked specifically for Python 3.5 + f-string and you write a check which won't work with Pypy 6.0. Then you tell me "change nothing" when I ask "how to change things". You don't cover the `__future__`, `try` and `future` code. And then you switch to fancy things with inappropriate wording ("stuff your code full of as many shiny new language features as possible"). Note that `pathlib` is not a "shiny new language feature" ([pep-428](https://www.python.org/dev/peps/pep-0428/) was created in 2012). – paugier Sep 21 '18 at 07:44
  • @paugier: You asked a question about how to drop support for old versions. I answered that question, and treated the "change everything" as the Y in your [XY problem](http://xyproblem.info/). This is the *charitable* interpretation of your question, because the other interpretation is that there are far too many new, incompatible features and your question is way too broad. If you want to narrow things down to a specific language feature ("how can I auto-convert my string formatting to f-strings", for example), that would be a properly-scoped, answerable question. – user2357112 Sep 21 '18 at 17:01
  • user2357112: now I feel really bad because of you. Stackoverflow has became a place bad for people. I really need to stop using it and asking questions, since they are so silly. – paugier Sep 22 '18 at 20:54
1

I found a great tool which does what I needed : pyupgrade.

There is an option --py36-plus which trigger the replacement of most "{}".format(var) by f"{var}" (much cleaner and clearer).

With the Unix command find -name "*.py" | xargs pyupgrade --py36-plus it produces such commits:

https://bitbucket.org/fluiddyn/fluidsim/pull-requests/78/pyupgrade-py36-plus

Now, the code is much cleaner and clearer and shows the coding style that we want today.

It's really very useful for projects that dropped Python 2.7 support (see http://python3statement.org/).

paugier
  • 1,838
  • 2
  • 20
  • 39