Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect if code is python 3 compatible

Tags:

python

I'm doing static code analysis using openstack/bandit. Do have a lot of repositories, some of those are in python 2 other in python 3. How can I detect if code is syntactically compatible with python 3 without running the code.

like image 694
aisbaa Avatar asked Nov 30 '16 10:11

aisbaa


People also ask

Are Python 2 and 3 compatible with each other?

Python 3 is not backward compatible with Python 2. Python 2 was mostly used to become a DevOps Engineer. It is no longer in use after 2020. Python 3 is used in a lot of fields like Software Engineering, Data Science, etc.

How do I convert Python 2 to Python 3 code?

We can convert Python2 scripts to Python3 scripts by using 2to3 module. It changes Python2 syntax to Python3 syntax. We can change all the files in a particular folder from python2 to python3.

Is code written in Python 3 is backward-compatible with Python 2?

The simple and straight-forward answer is “No”.

What is the difference between Python 2 and Python3?

Python 3 is more in-demand and includes a typing system. Python 2 is outdated and uses an older syntax for the print function. While Python 2 is still in use for configuration management in DevOps, Python 3 is the current standard. Python (the code, not the snake) is a popular coding language to learn for beginners.


2 Answers

Basic validation would be if the 2to3 tool prints any diffs (s. https://docs.python.org/3/library/2to3.html for basic usage)

on a simple file like a.py:

import urllib2  print "printing something" 

you'd get:

> 2to3 a.py

RefactoringTool: Skipping optional fixer: buffer RefactoringTool: Skipping optional fixer: idioms RefactoringTool: Skipping optional fixer: set_literal RefactoringTool: Skipping optional fixer: ws_comma RefactoringTool: Refactored a.py --- a.py    (original) +++ a.py    (refactored) @@ -1,4 +1,4 @@ -import urllib2 +import urllib.request, urllib.error, urllib.parse  -print "printing something" +print("printing something")  RefactoringTool: Files that need to be modified: RefactoringTool: a.py 
like image 84
Jann Avatar answered Sep 19 '22 15:09

Jann


Here's one thing you might want to do. I think it's the easiest way you can know if code is compatible at least syntaxically.

Have a python3 program load the python modules (without executing them). If the code is compatible, it will load the module, if it isn't... it will raise a syntax error.

Use the ast module.

import ast  def test_source_code_compatible(code_data):     try:         return ast.parse(code_data)     except SyntaxError as exc:         return False  ast_tree = test_source_code_compatible(open('file.py', 'rb').read()) if not ast_tree:     print("File couldn't get loaded") 

If the code can't be loaded it will raise a SyntaxError error.

Documentation of the Ast Module

If the abstract syntax tree can't be loaded, then you may have to check for python2 methods that don't exists in python3 or methods that changed their behaviour.

For example the division in python3 and python2 works differently. In python2, the division divide in integers so the result of a division will be different if you don't use the same division scheme. In that case, you'll have to look if the module is importing from __future__ import division to have the same behaviour in python2 and python3.

Here's an exhaustive list of things that you might want to handle:

http://python-future.org/compatible_idioms.html

Loading the ast of the module will give you right away things that absolutely can't work.. but knowing if code that can be parsed will work in python3 is subject to many false positive. It's hard even impossible to accurately detect if code will actually work 100% in python2 and 3 without actually running it and comparing the results.

like image 42
Loïc Faure-Lacroix Avatar answered Sep 18 '22 15:09

Loïc Faure-Lacroix