Python 2 will retire in about one month. Given many organizations continued reliance on it, you may be asking “Now What?” What does this change mean for a company that heavily relies on a deprecated language?

Many times, the Python 2 deployed in an organization still generates a lot of value. Yet as this code continues to age, you expose ourselves to potential security vulnerabilities with fewer avenues to address them. To continue running Python 2 and safely address this challenge, you have three options:

  • Rewrite. For services that deliver value today, and will deliver even more value in the future, it may be worth rewriting.
  • Migrate. Convert the code from Python 2 to Python 3.
  • Mitigate. Stick with Python 2, but patch/refactor as critical vulnerabilities are discovered.

Rewrite

For any services that still provide customer value, you should take a hard look at rewriting that service. This new service can be written using Go, Java, Kotlin, or Python 3 — whatever you like as long as it is not Python 2!

However, you can’t — and probably don’t want to — rewrite everything. There are legacy use cases that some customers still depend on, and there are other use cases you may not be ready to support before the Python 2 End of Life. In these cases, you have the option of migrating code to Python 3, or mitigating your risk by patching the code as vulnerabilities are discovered. Let’s consider migration first.

Migrate

There has been a spat of recent blog posts from tech savvy companies detailing their journey from Python 2 to 3. These journeys have been smooth for some, and time consuming for others. For example, Facebook started by rewriting their first service to Python 3 in 2014, Instagram took about a year to migrate all of their code, while Dropbox took three years to migrate roughly one million lines of Python code.

Instagram’s approach is illustrative (emphasis mine):

The decision at that time was, do we invest in a version of the language that was mature, but wasn’t going anywhere — or the language that was the next version and had great and growing community support? It made sense that, if we were going to stay on Python for the next ten years, we should invest in the latest version of the language.

Hui Ding — Instagram Engineer

Before Instagram undertook a migration effort, they first looked at how Python was used, and the trajectory of Python at the company. Then they decided to put forth the effort toward a migration. You owe it to yourselves to take a similar approach. If you look at it honestly, this may be one area where the juice may not be worth the squeeze — migrating an application from Python 2 to Python 3 presents a significant short-term downside, and only a modest to low long-term upside. Migration simply may not be worth the effort.

Even if it was straightforward to port from Python 2 to 3, the transition of language represents only a fraction of the problem. You may interact with libraries and dependencies with no clear replacement, requiring you to update to new APIs or dependencies.

If migrating isn’t a palatable option for you, maybe mitigating is?

Mitigate

How about just leaving leaving things alone? This means accepting Python 2 applications as-is, acknowledging that there is some risk with this approach, and mitigating that risk where possible by patching or refactoring as critical vulnerabilities are discovered. But how do you patch or refactor an unsupported language? What options do you have?

Just because Python 2 is reaching End of Life doesn’t mean companies will stop using it overnight. For example, many large organizations like airlines and banks still run some variation of FORTRAN or COBOL under the covers, and — for the most part — customers are happy with that. For many large organizations, migrating from Python 2 does not make economic sense and they will continue to run large Python 2 installations for the foreseeable future. You can take advantage of that. For example, Google’s App Engine team will continue to support the Python 2 version of their runtime with security fixes or risk losing their FedRamp status. In addition, alternative Python runtimes like PyPy will continue to support Python 2 indefinitely. Expect continued support for Python 2 to come from community efforts.

Companies like ActiveState are already providing commercial support for Python 2 installations. This support includes security and vulnerability fixes for the Python 2 core language, support for any third-party Python 2 packages, libraries and modules you use, back-porting of core language and third-party library security fixes to Python 2, and migration and rewrite support if you want it. A commercial support option may help you mitigate most — if not all — of the risk associated with Python 2.

You also need to acknowledge your role. Support and maintenance work on Python 2 may continue for the foreseeable future, and any particularly high risk items need to be brought forward for proper prioritization and scoping.

Acceptance — An Honest Look at the New Reality

I’m not writing this post to minimize the effort required to continue to support Python 2 — there will always be more that can be done. Rather, I’m arguing that accepting Python 2 and acknowledging the risk that comes with it is The Right Thing to Do™ given a reasoned examination of the situation. However, accepting risk doesn’t mean ignoring it — there are a few things you can do:

  • Stop the bleeding — any new Python code must be Python 3 or Python 3 compatible.
  • Fully understand which Python 2 services you still rely on and the plans and timelines to rewrite alternative implementations where appropriate.
  • Know the third-party libraries and dependencies are in Python 2, and how to update them should vulnerabilities be discovered.
  • Realistically evaluate commercial support offerings for Python 2.

This will require effort, and it will require time, and it won’t really feel good knowing you have services running in a deprecated language. Yet while the Python 2 End of Life would have you fear for the worst, the sky is not falling.