Support for Python 2 ends in 2019, and it’s high time for developers to take action

Support for Python 2 ends in 2019, and it's high time for developers to take action
Support for Python 2 ends in 2019, and it's high time for developers to take action

After a long time, the time has come: The support of Python 2 is discontinued. On December 3, 2008, Python 3 saw the light of day. The coexistence of the incompatible versions Python 2 and Python 3 existed for a good ten years. This unfortunate intermediate state is coming to an end: As announced in 2015, support for Python 2 ends on December 31, 2019.

Read More Stories: Guido blames social media for his decision to abandon the supervision of Python

Python 2 or Python 3, that’s the question

The years of dual support for both versions of Python raises the question of which strategies have evolved to deal with the intermediate state. In short, all conceivable strategies were used. Many simply continued existing projects in Python 2. Some developers even started new projects in Python 2. There were many reasons for this: On the one hand they spoke fluently Python 2, on the other hand necessary libraries were not yet ported to Python 3. Additionally, customers have requested Python 2 code. Some teams just split the codebase in Python 2 and Python 3 and had to maintain both versions.

Read More Stories: Chandrayaan-2: Second Indian lunar mission to be launched this July

Although Python 2 and Python 3 are incompatible, it is possible to rewrite Python code to work with both Python 2 and Python 3. The scripts futurize and modernize help with this step . The latter is more conservative than the former when changing the Python code. For the modification, projects must have two prerequisites: a test coverage and code that has been migrated to Python 2.7.

The Cheat Sheet “Writing Python 2-3 compatible code ” cheat sheet describes in detail what syntactical differences exist between Python 2 and Python 3 and how to write Python code that both Python 2 and Python 3 support.

Read More Stories: The cold war between the US and China shakes the technological market

Migration from Python 2 to Python 3

Porting Python 2 code to Python 3 has a well-defined path (see Figure 1), with developers having to test code and troubleshoot every step of the way.

Migration from Python 2 to Python 3 Figure 1
Migration from Python 2 to Python 3 Figure 1

The following lines of code serve as an example for the migration from Python 2 to 3. All lines in the example use Python functional components because some changes have occurred in these built-in functions.

Read More Stories: The Swedish Prosecutor’s Office requests the arrest of Julian Assange for rape

print "sum of the integers:", 
  apply (lambda a, b, c: a + b + c, (2, 3, 4)) 

print "factorial of 10:", 
  reduce (lambda x, y: x * y , range (1,1 1)) 

print "titles in text:", filter (lambda word: word.istitle (), 
                                  "This is a long Test" .split ()) 

print "titles in text:", 
[word for word in "This is a long test" .split () 
  if word.istitle ()]

The first function calculates the sum of the three numbers 2, 3, and 4 by applying the arguments to the lambda function. The built-in reduce () function gradually reduces the list of all numbers from 1 through 10 inclusive by multiplying the result of the last multiplication by the next number from the sequence. The last two functions filter out of the string all words starting with a capital letter. The code already works under Python 2.6, so only steps 3 and 4 have to be done for porting.

Read More Stories: Technology companies plummet on Wall Street after Google veto Huawei

Calling the Python 2.7 interpreter with option -3 shows the incompatibilities with version 3 (see Figure 2): Both apply () and reduce () are no longer built-in functions in Python 3.

Figure 2

Read More Stories: Autosubsync, a tool to synchronize subtitles automatically on Mac and Linux

The code is quickly repaired to avoid deprecation warnings:

print "sum of the integers:", 
  (lambda a, b, c: a + b + c) (* (2, 3, 4)) 

import functools 

print "factorial of 10:", 
  functools.reduce (lambda x, y: x * y, range (1, 11)) 

print "titles in text:", 
  filter (lambda word: word.istitle (), 
          "This is a long Test" .split ()) 

print "titles in text: ", 
  [word for word in this is a long test" .plit () 
   if word.istitle ()]

The script (see Figure 3) proves useful when correcting the Python 2 code because it automatically generates code for Python 3 in the last step.

Read More Stories: Beyond Android: this may affect the US blockade of Huawei on their computers

Read More Stories: Pokémon Go: Raid week and new monsters

The direct way is to override the source file : python <path to> -w . The result is the source code ported to Python 3. Interestingly, the code generator has replaced the filter ()expression with an equivalent list comprehension:

print ("sum of the integers:", 
  (lambda a, b, c: a + b + c) (* (2,3,4))) 

import functools 

print ("factorial of 10:", 
  functools.reduce ( lambda x, y: x * y, list (range (1,11)))) 

print ("titles in text:", 
  [word for word in "This is a long Test" .split () 
   if word.istitle () )]) 

print ("titles in text:", 
  [word for word in "This is a long Test" .split () 
   if word.istitle ()])

Python 3: The new features

Of course, the migration from Python 2 to Python 3 has pitfalls and weaknesses. As part of the porting developers should familiarize themselves with the new features of Python 3.

Read More Stories: Meme Factory, a decentralized meme market based on Ethereum’s smart contracts

print is a function with Python 3. The new syntax is generally the following:

print (* args, sep = "", 
      end = "\ n", 
      file = sys.stdout, 
      flush = true)

Where args denotes the arguments, sep the separator between them, end the end-of-line character, file the output medium and flush the buffer. The following table compares the syntactic changes to the print function, including their default values.

Read More Stories: OGUsers, the forum of hackers who stole Instagram credentials, hacked by other hackers

The following table shows the differences for print in Python 2 and Python 3:

example Python 2.x Python 3.x
General form print “x =”, 5 print (“x =”, 5)
wordwrap print print ()
Subdue the line break print x, print (x, end = “”)
Suppress the line break without spaces print (1, 2, 3, 4, 5, sep = “”)
Redirection of the output print >> sys.stderr, “error” print (“error”, file = sys.stderr)

The advantage of the new version reveals itself only at second glance, because the printfunction is now overloaded: The listing shows a print function that writes both in the standard output as well as in a log file. For this purpose, it exploits the built-in function __builtins __. Print .

import sys 

def print (* args, sep = "", end = "\ n", 
          file = sys.stdout, flush = True): 
  __builtins __. print (* args, sep = sep, end = end, 
                     file = file, flush = flush) 
  __builtins __. print (* args, sep = sep, end = end, 
                     file = open ("log.txt", "a"))

The biggest difference between Python 2 and Python 3 can be found in the strings. If programmers in Python had to explicitly declare 2 strings as Unicode ( u “unicode string” ), strings in Python 3 automatically consist of Unicode characters ( “unicode string” ). Python 3 knows text and (binary) data instead of Unicode strings and 8-bit strings. Binary data in Python 3 is explicitly defined by “binary data” . Text is Unicode, while encoded Unicode stands for binary data. The data type that contains text is “str” , the data type that contains data is “bytes”.

Read More Stories: Linux 5.2 Tied: New ARM Driver and Case Insensitivity for Ext4 File System

The exact details about strings in Python 2 and Python 3 can be found in the Unicode How-to.

To convert data types, the functions str.encode () and bytes.decode () exist. The transformers will need developers in Python 3 if they use both types of data because there is no implicit type conversion.

With so-called Function Annotations, the metadata in Python 3 can be bound to a function. In the second step , the latter can also be provided with decorators , which automatically generate documentation from the metadata or check the types at runtime. The equivalent functions sumOrig () and sumMeta () show the function declaration with and without metadata. The latter can be found in the second function for the signature and the return value. The metadata can be referenced using the function attribute __annotations__ .

Read More Stories: Chaos Engineering: Would your servers in the cloud withstand the attack of an army of crazy monkeys?

Necessary cleanup

Not only does Python 3 bring new features, it also cleans up Python 2 altogether. The adjustments affect libraries that

  • were removed
  • be written in lowercase according to the Python Style Guide,
  • newly packed in packages or
  • coexist in a C and a Python implementation.

The well-known Python idiom of importing the fast C implementation of a module and using the Python implementation in case of an error is no longer necessary. Python takes care of it automatically.

    import cPickle as pickle 
except ImportError: 
    import pickle

More details on the changes to the standard library can be found in an overview of the new features.

There are other things that make writing code in Python 3 easier. For co-operative super calls, developers no longer have to name the instance of the class and the class name. Python 3 only knows New Style classes, so the annoying deriving of object is no longer necessary to address the newer features of Python.

Read More Stories: “Boycott Apple” movement threatens Apple’s China business

The automatic evaluation of the input with the input ()command is superfluous, as the input in Python 3 is available as a string. This has closed a big security hole in Python. Consequently, raw_input () is now called input () .

The purpose of Python 2.7 is to simplify the transition to version 3. Therefore, the project has backported many features from Python 3.0 to Python 2.7.

Read More Stories: This is Internet in 2019: 4,000 million users, and pages four times heavier than 10 years ago

Backports on Python 2

The Context Manager with with is an important new feature available with Python 2.6. A resource such as a file, socket, or mutex automatically binds Python when it enters the withblock and releases it when it exits. C ++ programmers may remember the idiom of Resource Acquisition Is Initialization (RAII).

The with statement behaves from a user perspective as a try … finally , since both the tryblock and the finally block always be executed. However, this happens without explicit exception handling.

Read More Stories: Sophie Turner: “After ‘Game of Thrones’ I am learning to find myself”

In an with block you can use any object that offers the context management protocol and thus has the internal methods __enter () __ and __exit () __ . When entering the with block, Python calls __enter () __ – and exits _exit () __ method. The file object brings with it the appropriate methods.

Resource management can also be implemented by hand using the methods __enter () __and __exit () __ . If manual writing is too much work, you can use the decorator contextmanager from the contextlib library to benefit from context management. Further use cases can be found in the Python Enhancement Proposal (PEP) 0343.

with open ('/ etc / passwd', 'r') as file: 
    for line in file: 
    print line, 
# file is automatically closed

Probably the largest syntactic extension takes place in Python 2.6 with the introduction of abstract base classes. Whether an object can be used in a context depends on the characteristics of the object and not on its formal interface specification.

Read More Stories: We were ten years ahead, but the community did not let us do it, says Mark Shuttleworth

The idiom is called Duck-Typing – free after the poem by James Whitcomb Riley: “When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck”.

Once a class has an abstract method, it becomes an abstract base class and can not be instantiated. Derived classes can only be generated if they implement the abstract methods. Abstract base classes in Python behave similarly as in C ++, in particular, abstract methods may contain an implementation.

Read More Stories: Mac & i: Kernel extensions for macOS now need Apple authentication

In addition, Python also knows abstract properties. Python 3 uses abstract base classes in the numbers and collections modules.

The answer to the question still arises as to how a class becomes an abstract class: it needs the metaclass ABCMeta . Then the methods can be declared as @abstractmethod or properties as @abstractproperty with the respective decorators. The use of abstract base classes also means that the static typing feeds into the dynamically typed language.

Parallel work

Python’s answer to multiprocessor architectures is the new multiprocessing library. It imitates the well-known Python module threading , but instead of a thread creates a process – platform independent. The multiprocessing module was necessary because in the standard implementation CPython only one thread can run in the interpreter. The behavior is due to the so-called Global Interpreter Lock (GIL).

Read More Stories: Dementia: Two effective tricks to enhance memory


The Python community has described workflows and provided tools to greatly simplify the transition from Python 2 to Python 3. The typical migration strategy should begin with a test coverage, as summarized in Figure 1, and end with automatic code migration, using the 2to3 tool.

Anyone planning and consistently implementing the migration strategy throughout the year should not encounter any obstacles in the process of migrating from Python 2 to Python 3. As of 2020, Python 2 is history and only Python 3 is allowed.

Read More Stories: How many coffees are doing bad in our hearts