2016-11-30 2 views
4

Я занимаюсь анализом статического кода с использованием openstack/bandit. У вас много репозиториев, некоторые из них находятся в python 2 в python 3. Как я могу определить, синтаксически совместим ли код с python 3 без запуска кода.Как определить, совместим ли код с python 3

ответ

2

Вот одна вещь, которую вы migh я хочу сделать. Я думаю, что это самый простой способ узнать, совместим ли код по крайней мере синтаксически.

Попросите программу python3 загрузить модули python (без их выполнения). Если код совместим, он загрузит модуль, если он не ... он поднимет синтаксическую ошибку.

Используйте модуль 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').read()) 
if not ast_tree: 
    print("File couldn't get loaded") 

Если код не может быть загружен он поднимет ошибку SyntaxError.

Документации Ast Module

Если абстрактное дерево синтаксиса не может быть загружено, то вам, возможно, придется проверить методы python2, не существует в Python3 или методах, которые изменили свое поведение.

Например, деление на python3 и python2 работает по-разному. В python2 деление делится на целые числа, поэтому результат деления будет другим, если вы не используете одну и ту же схему разделения. В этом случае вам нужно будет посмотреть, импортирует ли модуль from __future__ import division, чтобы иметь такое же поведение в python2 и python3.

Вот исчерпывающий список вещей, которые вы можете обращаться:

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

Загрузка AST модуля даст вам сразу то, что совершенно не может работать .. но зная код который может быть проанализирован, будет работать в python3, подлежит множеству ложных срабатываний. Трудно даже точно определить, действительно ли код будет работать на 100% в python2 и 3 без фактического запуска и сравнения результатов.

+0

Если код совместим, он загрузит модуль и выполнит весь код верхнего уровня в этот модуль. – vaultah

+0

@vaultah это смешно. Разве я не писал _ без их выполнения? –

+2

Возможно, вам стоит написать, как вы их загрузите. –

8

Базовая проверка будет, если инструмент 2to3 печатает любой Diffs

на простой файл как a.py (S https://docs.python.org/3/library/2to3.html для основного использования.):

import urllib2 

print "printing something" 

вы получите:

> 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 
+0

;-) Такая же идея, я просто не могу публиковать ответы по какой-то причине. : D +1 – derM

+4

Я думаю, что это дало бы много ложных ответов при кормлении кода Python 3. Например, я просто попробовал, и он хочет заменить 'print (42)' на 'print ((42))', ouch. Итак, вы увидите diff и подумаете, что это Python 2? –

+0

@StefanPochmann просто проверил, что, кажется, интерпретирует его (ошибочно) как кортеж.'' 'print (" testing ")' '' не изменяется – Jann

2

Для этого можно использовать Pycharm IDE. Просто откройте файлы python в редакторе pycharm, он покажет предупреждения, если код не совместим с Python2 или Python3.

Вот скриншот, на котором отображается предупреждение синтаксиса команды печати. enter image description here

+1

Минимальная индивидуальная стоимость составляет 89 долларов США в год. – SDsolar

+0

@SDsolar это будущее [поддерживается в издании сообщества] (https://www.jetbrains.com/pycharm/features/editions_comparison_matrix.html) –

Смежные вопросы