I used to use perl -c programfile
to check the syntax of a Perl program and then exit without executing it. Is there an equivalent way to do this for a Python script?
2 gold badges28 silver badges41 bronze badges
asked Nov 26, 2010 at 10:12
Eugene Yarmash
39 gold badges319 silver badges372 bronze badges
You can check the syntax by compiling it:
python -m py_compile script.py
answered Dec 8, 2011 at 20:57
Mark Johnson
4 gold badges28 silver badges34 bronze badges
import sys
filename = sys.argv[1]
source = open(filename, 'r').read() + '\n'
compile(source, filename, 'exec')
Save this as checker.py and run python checker.py yourpyfile.py
.
11 gold badges51 silver badges73 bronze badges
answered Nov 26, 2010 at 10:39
Rosh Oxymoron
6 gold badges41 silver badges43 bronze badges
Here’s another solution, using the ast
module:
python -c "import ast; ast.parse(open('programfile').read())"
To do it cleanly from within a Python script:
import ast, traceback
filename = 'programfile'
with open(filename) as f:
source = f.read()
valid = True
try:
ast.parse(source)
except SyntaxError:
valid = False
traceback.print_exc() # Remove to silence any errros
print(valid)
answered Aug 15, 2019 at 11:15
Pyflakes does what you ask, it just checks the syntax. From the docs:
Pyflakes makes a simple promise: it will never complain about style, and it will try very, very hard to never emit false positives.
Pyflakes is also faster than Pylint or Pychecker. This is largely because Pyflakes only examines the syntax tree of each file individually.
To install and use:
$ pip install pyflakes
$ pyflakes yourPyFile.py
answered Jan 8, 2020 at 19:52
Brian C.
3 gold badges30 silver badges42 bronze badges
python -m compileall -q .
Will compile everything under current directory recursively, and print only errors.
$ python -m compileall --help
usage: compileall.py [-h] [-l] [-r RECURSION] [-f] [-q] [-b] [-d DESTDIR] [-x REGEXP] [-i FILE] [-j WORKERS] [--invalidation-mode {checked-hash,timestamp,unchecked-hash}] [FILE|DIR [FILE|DIR ...]]
Utilities to support installing Python libraries.
positional arguments:
FILE|DIR zero or more file and directory names to compile; if no arguments given, defaults to the equivalent of -l sys.path
optional arguments:
-h, --help show this help message and exit
-l don't recurse into subdirectories
-r RECURSION control the maximum recursion level. if `-l` and `-r` options are specified, then `-r` takes precedence.
-f force rebuild even if timestamps are up to date
-q output only error messages; -qq will suppress the error messages as well.
-b use legacy (pre-PEP3147) compiled file locations
-d DESTDIR directory to prepend to file paths for use in compile-time tracebacks and in runtime tracebacks in cases where the source file is unavailable
-x REGEXP skip files matching the regular expression; the regexp is searched for in the full path of each file considered for compilation
-i FILE add all the files and directories listed in FILE to the list considered for compilation; if "-", names are read from stdin
-j WORKERS, --workers WORKERS
Run compileall concurrently
--invalidation-mode {checked-hash,timestamp,unchecked-hash}
set .pyc invalidation mode; defaults to "checked-hash" if the SOURCE_DATE_EPOCH environment variable is set, and "timestamp" otherwise.
Exit value is 1 when syntax errors have been found.
answered Apr 19, 2021 at 8:25
3 gold badges71 silver badges63 bronze badges
Perhaps useful online checker PEP8 : http://pep8online.com/
answered Sep 10, 2015 at 9:22
1 gold badge13 silver badges12 bronze badges
import sys
import glob, os
os.chdir(sys.argv[1])
for file in glob.glob("*.py"):
source = open(file, 'r').read() + '\n'
compile(source, file, 'exec')
Save this as checker.py and run python checker.py ~/YOURDirectoryTOCHECK
answered Sep 10, 2020 at 20:19
10 silver badges16 bronze badges
# ---------------------------------------------------------
# check the python synax for all the *.py files under the
# <<product_version_dir/sfw/python
# ---------------------------------------------------------
doCheckPythonSyntax(){
doLog "DEBUG START doCheckPythonSyntax"
test -z "$sleep_interval" || sleep "$sleep_interval"
cd $product_version_dir/sfw/python
# python3 -m compileall "$product_version_dir/sfw/python"
# foreach *.py file ...
while read -r f ; do \
py_name_ext=$(basename $f)
py_name=${py_name_ext%.*}
doLog "python3 -c \"import $py_name\""
# doLog "python3 -m py_compile $f"
python3 -c "import $py_name"
# python3 -m py_compile "$f"
test $! -ne 0 && sleep 5
done < <(find "$product_version_dir/sfw/python" -type f -name "*.py")
doLog "DEBUG STOP doCheckPythonSyntax"
}
# eof func doCheckPythonSyntax
answered Dec 27, 2016 at 11:04
Yordan Georgiev
1 gold badge54 silver badges53 bronze badges
Проверять код на валидность можно без print’ов и без IDE’шных инструментов отладки.
Для этого существуют модуль time и отладочная функция assert. Остановимся на них поподробней.
Модуль time
Модуль time очень обширен, но подробно рассматривать его для наших целей я не вижу смысла, ибо полагаю, что нам интересно только узнать время выполнения программы в секундах.
Чтобы узнать это, достаточно импортировать модуль и запомнить время старта программы с помощью функции time.time()
import time
t = time.time() # запоминаем время на момент начала работы программы
print(t)
Теперь переменная t хранит в себе время в секундах с начала нашей эры от момента начала программы.
Чтобы узнать как долго происходило выполнение программы нам нужно вновь обратиться к time.time() и вычесть из этого значения наше значение t:
import time
t = time.time() # запоминаем время на момент начала работы программы
# блоки кода
print('Время выполнения', time.time() - t, 'cек')
Но не забывайте, что конфигурация влияет на время выполнения, поэтому одно значение у вас может отличаться от значения на другой машине. Чтобы снизить разницу я рекомендую пройти курсы по алгоритам.
Assert
Assert это такая отладочная штука, которая проверяет условие на истинность, и если условие истинно, то код работает дальше, а если ложно, то assert возбуждает исключение типа AssertionError.
Как с этим работать? Очень просто. Нужно предположить как будет вести себя код, какими будут значения в той или иной строке и для проверки выставить assert с условиями на истинность этих предположений.
Например, давайте сделаем список из int значений, элементы которого будут нацело делиться на 2:
lst = [int(x) for x in range(0, 101, 2)]
Мы хотим вывести наши значения и предполагаем, что они:
- нацело делятся на 2
- имеют тип int
Перебираем список и перед тем как вывести значения расставляем наши assert’ы
for x in lst:
assert x % 2 == 0 # проверяем, что число делится без остатка на 2
assert type(x) == int # что его тип - int
assert x % 2 == 0 and type(x) == int # можно строить более длинные и сложные конструкции
# assert x % 2 == 0 and type(x) == float # а это мы уже не пройдём, потому что тип int
print(x) # наконец выводим значение
Пример со всем сразу
Допустим у нас есть файл с логами перемещения в формате x y z
. Иными словами, файл с координатами.
Мы импортируем модуль time и random (он нам понадобится) и сохраняем время начала работы программы.
import time, random
t = time.time()
Создадим файл, который будем читать:
# создаём файл
file = open('coordinates.log', 'w')
for x in range(10000):
x = random.uniform(-100, 100)
y = random.uniform(-100, 100)
z = random.uniform(-100, 100)
file.write(str(x) + ' ' + str(y) + ' ' + str(z) + '\n')
file.close()
Затем открываем файл с логами и читаем его:
with open('coordinates.log', 'r') as f:
lines = f.readlines()
for line in lines:
line = line.strip()
# line = line.split() # разбиение не проводим
assert len(line) == 3 and type(line) == list # и поэтому тут получаем ошибку
Давайте исправим ошибку и добавим split(), а также добавим в код некоторый функционал
import time, random
t = time.time()
prev_coor = [0, 0, 0] # переменная, хранящая предыдущие координаты
# по моей задумке, изначально это нулевые координаты
# создаём файл
file = open('coordinates.log', 'w')
# будем генерировать случайные float числа от -100 до 100
for x in range(10000):
x = random.uniform(-100, 100)
y = random.uniform(-100, 100)
z = random.uniform(-100, 100)
file.write(str(x) + ' ' + str(y) + ' ' + str(z) + '\n')
file.close()
# открываем созданный файл и файл для вывода
with open('coordinates.log', 'r') as f, open('coor_difference.txt', 'w') as d:
lines = f.readlines()
for line in lines:
line = line.strip()
line = line.split() # добавляем split() и исправляем нашу ошибку
assert len(line) == 3 and type(line) == list # и код проходит проверку
# а если не проходит
# значит файл с bad data
try:
line = [float(x) for x in line] # приводим каждый элемент строки к числу
except ValueError:
raise Exception ('Bad data') # не получилось? - райзим Exception Bad data
# по поводу блока try-except хотелось бы сказать, что если бы мы не использовали данный блок,
# а просто делали приведение типа, и данные были бы плохие, то
# исключение было бы возбуждено само собой, но мне хотелось показать, что исключения
# можно не только отлавливать, но также и возбуждать их с помощью raise
for x in line:
assert type(x) == float # проверяем, что мы привели каждый элемент к типу float
# ну и, к примеру выводим разницу между текущими и предыдущими координатами в файл, открытый для вывода
d.write(str([round(curr - prev, 2) for curr, prev in zip(line, prev_coor)]) + '\n')
prev_coor = line
# не забываем про то, что нам интересно сколько было затрачено времени
print('Время выполнения', time.time() - t, 'cек')
Более интересный пример
Например, мы создаём какой-либо функционал в классе. В нашем случае это простейший калькулятор. Как проверить, что функционал реализован верно? Мы запустим определённое количество проверок, в которых будем инициализировать экземпляры класса с определёнными значениями и будем проверять, сходятся ли наши ответы.
В данном случае функционал встроен в пайтон, поэтому правильны ли ответы, мы будем смотреть путём идентичных операций.
class Calculator(object):
def __init__ (self, l, r):
self.l = l
self.r = r
def plus(self):
return self.l + self.r
def min(self):
return self.l - self.r
def div(self):
return self.l / self.r
def mul(self):
return self.l * self.r
def get_items(self):
return (self.l, self.r)
for x in range(100):
a = random.randint(-100, 100)
b = random.randint(-100, 100)
calc = Calculator(a, b)
assert calc.plus() == a + b # верно ли реализована оперция сложения
assert calc.min() == a - b # верно ли реализована операция вычитания
assert calc.div() == a / b # верно ли реализована операция деления
assert calc.mul() == a * b # верно ли реализована операция умножения
# также выводим результаты в файл
c = open('calc_output.txt', 'a') # ключ a открывает файл на дозапись
c.write(str(calc.get_items()) + ' операция +; результат - ' + str(calc.plus()) + '\n')
c.write(str(calc.get_items()) + ' операция -; результат - ' + str(calc.min()) + '\n')
c.write(str(calc.get_items()) + ' операция /; результат - ' + str(calc.div()) + '\n')
c.write(str(calc.get_items()) + ' операция *; результат - ' + str(calc.mul()) + '\n')
c.close()
In this post , we will explore – How to Check Syntax Errors in Python Code.
You can use various options to check for any syntax errors in Python without executing the script .
Try the below options –
Option 1 – Using Compilation Script
- Using Python basic compilation . Use the code below and save it as any .py file e.g pythonSyntaxChecker.py
import sys your_python_script_name = sys.argv[1] source = open(your_python_script_name, 'r').read() + '\n' compile(source, your_python_script_name, 'exec')
- Next run your Python script(say yourPythonScript.py) against the above script
python3 pythonSyntaxChecker.py yourPythonScript.py OR python pythonSyntaxChecker.py yourPythonScript.py
Option 2 – Using Direct Compilation
- You can directly compile your Python script
- Note the below poinst –
- python returns a non-zero exit code if the compilation fails.
- Also type errors are not detected — those are only detected at runtime
python -m py_compile yourPythonScript.py
Option 3 – Using Pychecker
- You can use PyChecker to syntax check your python code. Use code below from the command line:
pychecker [options] YOUR_PYTHON_SCRIPT.py
- The [options] provides below features –
- –only –> only warn about files passed on the command line
- -#, –limit –> the maximum number of warnings to be displayed
- –no-shadowbuiltin –> check if a variable shadows a builtin
- -q, –stdlib –> ignore warnings from files under standard library
- -T, –argsused –> unused method/function arguments
- If you want to syntax check multiple Python scripts at one go ,
pychecker <YOUR_DIR>/*.py
Sample how pychecker shows the syntax errors –
script1.py:5: Imported module (string) not used script1.py:6: Instantiating an object with arguments, but no constructor script1.py:7: Object (useless) has no attribute (valeu) script1.py:8: No local variable (var1) script1.py:9: self is not first method argument
Option 4 – Using Pyflakes
- Another worthy option to try – https://github.com/PyCQA/pyflakes
pyflakes yourPythonScript.py
Option 5 – Using “ast” module
- The ast module helps to process trees of the Python abstract syntax grammar – basically ast helps to find out the current grammar appearance.
- More here – https://docs.python.org/3/library/ast.html
- Using CLI
python -c "import ast; ast.parse(open('yourPythonScript.py').read())"
- Check syntax of any block of code
import ast tree = ast.parse("print ('This is Great')") ast.dump(tree) "Module(body=[Expr(value=Call(func=Name(id='print', ctx=Load()), args=[Str(s='This is Great')], keywords=[]))])"
- Alternatively use as a python script
import ast, traceback g = '<YOUR PYTHON SCRIPT NAME>' with open(g) as f: source = f.read() valid = True try: ast.parse(source) except SyntaxError: valid = False traceback.print_exc() finally: print(valid) ast.dump(source)
Hope this write up was helpful.
Other Interesting Reads –
python syntax check, python syntax, invalid syntax python, python for loop syntax, python if syntax, python, pycharm, django, matplotlib, python online, python programming, python list, learn python, python syntax checker,How do I check Python syntax, How do I check Python syntax online, What is Python basic syntax, What Is syntax check,check python script online,python code tester,how to find error in python code ,pep8 checker,python 3.5 syntax checker,python syntax error,python check function,bug checker python, python syntax checker command line, python 3.5 syntax checker, python syntax error fixer,syntaxerror: invalid syntax python 3,invalid syntax python print,how to resolve name error in python,invalid syntax python def,pylint syntax error,how to find error in python code,file <stdin>”, line 1 syntaxerror: invalid syntax,online python compiler, python find syntax error,How to find syntax error in python,How to solve the python syntax error,What is a syntax error in python,How does Python handle syntax errors,python syntax error,how to find error in python code,python compiler invalid syntax python ,check python script online,python code tester,occurs when a syntax error is raised for a module
Рассмотрим популярные инструменты для анализа кода Python и подробно расскажем об их специфике и основных принципах работы.
Автор: Валерий Шагур, teacher assistance на курсе Программирование на Python
Высокая стоимость ошибок в программных продуктах предъявляет повышенные
требования к качеству кода. Каким критериям должен соответствовать хороший код?
Отсутствие ошибок, расширяемость, поддерживаемость, читаемость и наличие документации. Недостаточное внимание к любому из этих критериев может привести к появлению новых ошибок или снизить вероятность обнаружения уже существующих. Небрежно написанный или чересчур запутанный код, отсутствие документации напрямую влияют на время исправления найденного бага, ведь разработчику приходится заново вникать в код. Даже такие, казалось бы, незначительные вещи как неправильные имена переменных или отсутствие форматирования могут сильно влиять на читаемость и понимание кода.
Командная работа над проектом еще больше повышает требования к качеству кода, поэтому важным условием продуктивной работы команды становится описание формальных требований к написанию кода. Это могут быть соглашения, принятые в языке программирования, на котором ведется разработка, или собственное (внутрикорпоративное) руководство по стилю. Выработанные требования к оформлению кода не исключают появления “разночтений” среди разработчиков и временных затрат на их обсуждение. Кроме этого, соблюдение выработанных требований ложится на плечи программистов в виде дополнительной нагрузки. Все это привело к появлению инструментов для проверки кода на наличие стилистических и логических ошибок. О таких инструментах для языка программирования Python мы и поговорим в этой статье.
Анализаторы и автоматическое форматирование кода
Весь инструментарий, доступный разработчикам Python, можно условно разделить на две группы по способу реагирования на ошибки. Первая группа сообщает о найденных ошибках, перекладывая задачу по их исправлению на программиста. Вторая — предлагает пользователю вариант исправленного кода или автоматически вносит изменения.
И первая, и вторая группы включают в себя как простые утилиты командной строки для решения узкоспециализированных задач (например, проверка docstring или сортировка импортов), так и богатые по возможностям библиотеки, объединяющие в себе более простые утилиты. Средства анализа кода из первой группы принято называть линтерами (linter). Название происходит от lint — статического анализатора для языка программирования Си и со временем ставшего нарицательным. Программы второй группы называют форматировщиками (formatter).
Даже при поверхностном сравнении этих групп видны особенности работы с ними. При применении линтеров программисту, во-первых, необходимо писать код с оглядкой, дабы позже не исправлять найденные ошибки. И во вторых, принимать решение по поводу обнаруженных ошибок — какие требуют исправления, а какие можно проигнорировать. Форматировщики, напротив, автоматизируют процесс исправления ошибок, оставляя программисту возможность осуществлять контроль.
Часть 1
Часть 2
Соглашения принятые в статье и общие замечания
Прежде чем приступить к обзору программ, мы хотели бы обратить ваше внимание на несколько важных моментов.
Версия Python: во всех примерах, приведенных в статье, будет использоваться третья версия языка программирования Python.
Установка всех программ в обзоре практически однотипна и сводится к использованию пакетного менеджера pip.
$ python3.6 -m pip install --upgrade <package_name>
Некоторые из библиотек имеют готовые бинарные пакеты в репозиториях дистрибутивов linux или возможность установки с использованием git. Тем не менее для большей определенности и возможности повторения примеров из статьи, установка будет производится с помощью pip.
Об ошибках: стоит упомянуть, что говоря об ошибках, обнаруживаемых анализаторами кода, как правило, имеют в виду два типа ошибок. К первому относятся ошибки стиля (неправильные отступы, длинные строки), ко второму — ошибки в логике программы и ошибки синтаксиса языка программирования (опечатки при написании названий стандартных функций, неиспользуемые импорты, дублирование кода). Существуют и другие виды ошибок, например — оставленные в коде пароли или высокая цикломатическая сложность.
Тестовый скрипт: для примеров использования программ мы создали простенький по содержанию файл example.py. Мы сознательно не стали делать его более разнообразным по наличию в нем ошибок. Во-первых, добавление листингов с выводом некоторых анализаторов в таком случае сильно “раздуло” бы статью. Во-вторых, у нас не было цели детально показать различия в “отлове” тех или иных ошибок для каждой из утилит.
Содержание файла example.py:
import os import notexistmodule def Function(num,num_two): return num class MyClass: """class MyClass """ def __init__(self,var): self.var=var def out(var): print(var) if __name__ == "__main__": my_class = MyClass("var") my_class.out("var") notexistmodule.func(5)
В коде допущено несколько ошибок:
- импорт неиспользуемого модуля os,
- импорт не существующего модуля notexistmodule,
- имя функции начинается с заглавной буквы,
- лишние аргументы в определении функции,
- отсутствие self первым аргументом в методе класса,
- неверное форматирование.
Руководства по стилям: для тех, кто впервые сталкивается с темой оформления кода, в качестве знакомства предлагаем прочитать официальные руководства по стилю для языка Python PEP8 и PEP257. В качестве примера внутрикорпоративных соглашений можно рассмотреть Google Python Style Guide — https://github.com/google/styleguide/blob/gh-pages/pyguide.md
Pycodestyle
Pycodestyle — простая консольная утилита для анализа кода Python, а именно для проверки кода на соответствие PEP8. Один из старейших анализаторов кода, до 2016 года носил название pep8, но был переименован по просьбе создателя языка Python Гвидо ван Россума.
Запустим проверку на нашем коде:
$ python3 -m pycodestyle example.py example.py:4:1: E302 expected 2 blank lines, found 1 example.py:4:17: E231 missing whitespace after ',' example.py:7:1: E302 expected 2 blank lines, found 1 example.py:10:22: E231 missing whitespace after ',' example.py:11:17: E225 missing whitespace around operator
Лаконичный вывод показывает нам строки, в которых, по мнению анализатора, есть нарушение соглашений PEP8. Формат вывода прост и содержит только необходимую информацию:
<имя файла>: <номер строки> :<положение символа>: <код и короткая расшифровка ошибки>
Возможности программы по проверке соглашений ограничены: нет проверок на правильность именования, проверка документации сводится к проверки длины docstring. Тем не менее функционал программы нельзя назвать “спартанским”, он позволяет настроить необходимый уровень проверок и получить различную информацию о результатах анализа. Запуск с ключом –statistics -qq выводит статистику по ошибкам:
$ python3 -m pycodestyle --statistics -qq example.py 1 E225 missing whitespace around operator 2 E231 missing whitespace after ',' 2 E302 expected 2 blank lines, found 1
Более наглядный вывод можно получить при использовании ключа –show-source. После каждого сообщения об ошибке будет выведена строка исходного кода, в которой содержится ошибка.
$ python3 -m pycodestyle --show-source example.py example.py:4:1: E302 expected 2 blank lines, found 1 def Function(num,num_two): ^ example.py:4:17: E231 missing whitespace after ',' def Function(num,num_two): ^ example.py:7:1: E302 expected 2 blank lines, found 1 class MyClass: ^ example.py:10:22: E231 missing whitespace after ',' def __init__(self,var): ^ example.py:11:17: E225 missing whitespace around operator self.var=var ^
Если есть необходимость посмотреть, какие из соглашений PEP8 были нарушены, используйте ключ — show-pep8. Программа выведет список всех проверок с выдержками из PEP8 для случаев нарушений. При обработке файлов внутри директорий предусмотрена возможность фильтрации по шаблону. Pycodestyle позволяет сохранять настройки поиска в конфигурационных файлах как глобально, так и на уровне проекта.
Pydocstyle
Утилиту pydocstyle мы уже упоминали в статье Работа с документацией в Python: поиск информации и соглашения. Pydocstyle проверяет наличие docstring у модулей, классов, функций и их соответствие официальному соглашению PEP257.
$ python3 -m pydocstyle example.py example.py:1 at module level: D100: Missing docstring in public module example.py:4 in public function `Function`: D103: Missing docstring in public function example.py:7 in public class `MyClass`: D400: First line should end with a period (not 's') example.py:7 in public class `MyClass`: D210: No whitespaces allowed surrounding docstring text example.py:10 in public method `__init__`: D107: Missing docstring in __init__ example.py:13 in public method `out`: D102: Missing docstring in public method
Как мы видим из листинга, программа указала нам на отсутствие документации в определениях функции, методов класса и ошибки оформления в docstring класса. Вывод можно сделать более информативным, если использовать ключи –explain и –source при вызове программы. Функционал pydocstyle практически идентичен описанному выше для pycodestyle, различия касаются лишь названий ключей.
Pyflakes
В отличие от уже рассмотренных инструментов для анализа кода Python pyflakes не делает проверок стиля. Цель этого анализатора кода — поиск логических и синтаксических ошибок. Разработчики pyflakes сделали упор на скорость работы программы, безопасность и простоту. Несмотря на то, что данная утилита не импортирует проверяемый файл, она прекрасно справляется c поиском синтаксических ошибок и делает это быстро. С другой стороны, такой подход сильно сужает область проверок.
Функциональность pyflakes — “нулевая”, все что он умеет делать — это выводить результаты анализа в консоль:
$ python3 -m pyflakes example.py example.py:1: 'os' imported but unused
В нашем тестовом скрипте, он нашел только импорт не используемого модуля os. Вы можете самостоятельно поэкспериментировать с запуском программы и передачей ей в качестве параметра командной строки Python файла, содержащего синтаксические ошибки. Данная утилита имеет еще одну особенность — если вы используете обе версии Python, вам придется установить отдельные утилиты для каждой из версий.
Pylint
До сих пор мы рассматривали утилиты, которые проводили проверки на наличие либо стилистических, либо логических ошибок. Следующий в обзоре статический инструмент для анализа кода Python — Pylint, который совместил в себе обе возможности. Этот мощный, гибко настраиваемый инструмент для анализа кода Python отличается большим количеством проверок и разнообразием отчетов. Это один из самых “придирчивых” и “многословных” анализаторов кода. Анализ нашего тестового скрипта выдает весьма обширный отчет, состоящий из списка найденных в ходе анализа недочетов, статистических отчетов, представленных в виде таблиц, и общей оценки кода:
$ python3.6 -m pylint --reports=y text example.py ************* Module text /home/ququshka77/.local/lib/python3.6/site-packages/pylint/reporters/text.py:79:22: W0212: Access to a protected member _splitstrip of a client class (protected-access) ************* Module example example.py:4:16: C0326: Exactly one space required after comma def Function(num,num_two): ^ (bad-whitespace) example.py:10:21: C0326: Exactly one space required after comma def __init__(self,var): ^ (bad-whitespace) example.py:11:16: C0326: Exactly one space required around assignment self.var=var ^ (bad-whitespace) example.py:1:0: C0111: Missing module docstring (missing-docstring) example.py:2:0: E0401: Unable to import 'notexistmodule' (import-error) example.py:4:0: C0103: Function name "Function" doesn't conform to snake_case naming style (invalid-name) example.py:4:0: C0111: Missing function docstring (missing-docstring) example.py:4:17: W0613: Unused argument 'num_two' (unused-argument) example.py:13:4: C0111: Missing method docstring (missing-docstring) example.py:13:4: E0213: Method should have "self" as first argument (no-self-argument) example.py:7:0: R0903: Too few public methods (1/2) (too-few-public-methods) example.py:18:4: C0103: Constant name "my_class" doesn't conform to UPPER_CASE naming style (invalid-name) example.py:19:4: E1121: Too many positional arguments for method call (too-many-function-args) example.py:1:0: W0611: Unused import os (unused-import) Report ====== 112 statements analysed. Statistics by type +----------+----------+---------------+-------------+-------------------+---------------+ |type |number |old number |difference |%documented |%badname | +======+======+========+========+===========+========+ |module |2 |2 |= |50.00 |0.00 | +-----------+----------+---------------+-------------+-------------------+---------------+ |class |5 |5 |= |100.00 |0.00 | +-----------+----------+---------------+-------------+-------------------+---------------+ |method |11 |11 |= |90.91 |0.00 | +-----------+----------+---------------+-------------+-------------------+---------------+ |function |4 |4 |= |75.00 |25.00 | +-----------+----------+---------------+-------------+-------------------+---------------+ External dependencies :: pylint \-interfaces (text) \-reporters (text) | \-ureports | \-text_writer (text) \-utils (text) Raw metrics +-------------+----------+-------+-----------+-------------+ |type |number |% |previous |difference | +=======+======+=====+=====+========+ |code |128 |48.30 |128 |= | +-------------+----------+--------+-----------+------------+ |docstring |84 |31.70 |84 |= | +-------------+----------+--------+-----------+------------+ |comment |16 |6.04 |16 |= | +-------------+----------+--------+-----------+------------+ |empty |37 |13.96 |37 |= | +-------------+----------+--------+-----------+------------+ Duplication +-------------------------------+------+------------+-------------+ | |now |previous |difference | +=================+=====+======+========+ |nb duplicated lines |0 |0 |= | +-------------------------------+-------+------------+------------+ |percent duplicated lines |0.000 |0.000 |= | +-------------------------------+-------+------------+------------+ Messages by category +--------------+----------+-----------+-------------+ |type |number |previous |difference | +========+======+======+========+ |convention |8 |8 |= | +--------------+----------+-----------+-------------+ |refactor |1 |1 |= | +--------------+-----------+----------+-------------+ |warning |3 |3 |= | +--------------+-----------+----------+-------------+ |error |3 |3 |= | +--------------+-----------+----------+-------------+ % errors / warnings by module +-----------+--------+-----------+----------+--------------+ |module |error |warning |refactor |convention | +======+=====+======+======+========+ |example |100.00 |66.67 |100.00 |100.00 | +-----------+---------+----------+-----------+-------------+ |text |0.00 |33.33 |0.00 |0.00 | +-----------+---------+----------+-----------+-------------+ Messages +-----------------------------+----------------+ |message id |occurrences | +=================+=========+ |missing-docstring |3 | +-----------------------------+----------------+ |bad-whitespace |3 | +------------------------------+---------------+ |invalid-name |2 | +------------------------------+---------------+ |unused-import |1 | +------------------------------+---------------+ |unused-argument |1 | +------------------------------+---------------+ |too-many-function-args |1 | +------------------------------+---------------+ |too-few-public-methods |1 | +------------------------------+---------------+ |protected-access |1 | +------------------------------+---------------+ |no-self-argument |1 | +------------------------------+---------------+ |import-error |1 | +------------------------------+---------------+ ------------------------------------------------------------------------------------------ Your code has been rated at 7.59/10 (previous run: 7.59/10, +0.00)
Программа имеет свою внутреннюю маркировку проблемных мест в коде:
Для вывода подробного отчета мы использовали ключ командной строки –reports=y.
Более гибко настроить вывод команды позволяют разнообразные ключи командной строки. Настройки можно сохранять в файле настроек rcfile. Мы не будем приводить подробное описание ключей и настроек, для этого есть официальная документация — https://pylint.readthedocs.io/en/latest/index.html#, остановимся лишь на наиболее интересных, с нашей точки зрения, возможностях утилиты:
— Генерация файла настроек (–generate-rcfile). Позволяет не писать конфигурационный файл с нуля. В созданном rcfile содержатся все текущие настройки с подробными комментариями к ним, вам остается только отредактировать его под собственные требования.
# pylint: disable=unused-argument
и запустим pylint. Из результатов проверки “исчезло” сообщение:
example.py:4:17: W0613: Unused argument 'num_two' (unused-argument)
— Создание отчетов в формате json (–output-format=json). Полезно, если необходимо сохранение или дальнейшая обработка результатов работы линтера. Вы также можете создать собственный формат вывода данных.
— Параллельный запуск (-j 4). Запуск в нескольких параллельных потоках на многоядерных процессорах сокращает время проверки.
— Встроенная документация. Вызов программы с ключом –help-msg=<key> выведет справку по ключевому слову key. В качестве ключевого слова может быть код сообщения (например: E0401) или символическое имя сообщения (например: import-error). Ниже приведен листинг получения справки по ключу import-error:
$ python3.6 -m pylint --help-msg=import-error :import-error (E0401): *Unable to import %s* Used when pylint has been unable to import a module. This message belongs to the imports checker.
— Система оценки сохраняет последний результат и при последующих запусках показывает изменения, что позволяет количественно оценить прогресс исправлений.
— Плагины — отличная возможность изменять поведение pylint. Их применение может оказаться полезным в случаях, когда pylint неправильно обрабатывает код и есть “ложные” срабатывания, или когда требуется отличный от стандартного формат вывода результатов.
Vulture
Vulture — небольшая утилита для поиска “мертвого” кода в программах Python. Она использует модуль ast стандартной библиотеки и создает абстрактные синтаксические деревья для всех файлов исходного кода в проекте. Далее осуществляется поиск всех объектов, которые были определены, но не используются. Vulture полезно применять для очистки и нахождения ошибок в больших базовых кодах.
Продолжение следует
Во второй части мы продолжим разговор об инструментах для анализа кода Python. Будут рассмотрены линтеры, представляющие собой наборы утилит. Также мы посмотрим, какие программы можно использовать для автоматического форматирования кода.
Еще статьи по Python
Популярные инструменты для анализа кода Python делают плоды вашего труда лучше и эффективнее. Как? Рассказываем в статье.
Автор: Валерий Шагур, teacher assistance на курсе Программирование на Python
Продолжаем разговор об инструментах для анализа кода Python, начатый нами в первой части статьи.
Flake8
Flake8 — первая программа в этом обзоре, представляющая собой “комбайн”, обвязку к входящим в нее утилитам — pyflakes, pycodestyle, mccabe. В начале работы с ней нас ждал один неприятный сюрприз. Дело в том, что текущая версия flake8-3.2.1 не заработала с текущей версией pycodestyle-2.4.0 и мы были вынуждены откатить pycodestyle до 2.3.1. Этот момент стоит учитывать, если вы в дальнейшем планируете использовать flake8 в своей работе или захотите поэкспериментировать с ней.
Flake8 имеет схожий с pylint основной функционал. Однако она имеет ряд отличий и особенностей:
— Возможности статистических отчетов ограничены подсчетом количества каждой из ошибок (–statistics) и их общим количеством (–count). Пример запуска flake8 на тестовом скрипте:
$ python3.6 -m flake8 --statistics --count example.py example.py:1:1: F401 'os' imported but unused example.py:4:1: E302 expected 2 blank lines, found 1 example.py:4:5: N802 function name 'Function' should be lowercase example.py:4:17: E231 missing whitespace after ',' example.py:7:1: E302 expected 2 blank lines, found 1 example.py:10:22: E231 missing whitespace after ',' example.py:11:17: E225 missing whitespace around operator example.py:13:9: N805 first argument of a method should be named 'self' 1 E225 missing whitespace around operator 2 E231 missing whitespace after ',' 2 E302 expected 2 blank lines, found 1 1 F401 'os' imported but unused 1 N802 function name 'Function' should be lowercase 1 N805 first argument of a method should be named 'self' 8
— Для запуска в несколько потоков (–jobs=<num>) используется модуль multiprocessing, по этой причине многопоточность не будет работать на Windows системах.
— Отсутствует возможность генерации отчетов в формате json, при вызове с ключом –bug-report создается только заголовок для отчета с указанием платформы и версий входящих утилит.
— Во время редактирования для подавления отдельных ошибок “на лету” можно перечислить исключаемые ошибки в ключе –extend-ignore=<errors>
— Проверка синтаксиса в строках doctest (–doctests).
Следующие возможности Flake8 можно отнести к его достоинствам. Наличие их сделало Flake8 весьма популярным инструментом среди разработчиков:
— Наличие Version Control Hooks. Интеграция с системами контроля версий происходит буквально с помощью двух команд (поддерживаются git и mercurial). Приведем пример для git. Настройка hook позволяет не допускать создания коммита при нарушении каких-либо правил оформления. Подробнее о механизме git-hook вы можете узнать в документации git.
Инициализируем новый репозиторий в директории с файлом example.py и сделаем первый коммит:
$ git init Инициализирован пустой репозиторий Git в /home/test/.git/ $ git add example.py $ git commit -m "first commit" [master (корневой коммит) d1f25d0] first commit 1 file changed, 20 insertions(+) create mode 100644 example.py
Установим git pre-commit hook:
$ python3.6 -m flake8 --install-hook git git pre-commit hook installed, for configuration options see http://flake8.pycqa.org/en/latest/user/using-hooks.html $ git config --bool flake8.strict true
$ echo "# new comment" >> example.py
Попробуем теперь зафиксировать изменения в ветке:
$ git add example.py $ git commit -m "second commit" example.py:1:1: F401 'os' imported but unused example.py:4:1: E302 expected 2 blank lines, found 1 example.py:4:5: N802 function name 'Function' should be lowercase example.py:4:17: E231 missing whitespace after ',' example.py:7:1: E302 expected 2 blank lines, found 1 example.py:10:22: E231 missing whitespace after ',' example.py:11:17: E225 missing whitespace around operator example.py:13:9: N805 first argument of a method should be named 'self'
Вывод содержит только информацию о найденных ошибках, сообщения о зафиксированных изменениях нет. В том, что коммит не был сделан, можно убедиться с помощью команды git status:
$ git status На ветке master Изменения, которые будут включены в коммит: (используйте «git reset HEAD <файл>…», чтобы убрать из индекса) изменено: example.py
— Расширяемость. Flake8 для анализа кода Python позволяет создавать и использовать плагины. С помощью плагинов в Flake8 можно: добавить дополнительные проверки, использовать другие форматы отчетов или автоматически исправлять найденные ошибки. На PyPi можно найти большое количество open-source плагинов.
— В состав Flake8 входит mccabe — инструмент для проверки цикломатической сложности кода.
Prospector
Prospector — это инструмент для анализа кода Python. Объединяет функциональность других инструментов анализа Python, таких как pylint, pep8, mccabe, Pyflakes, Dodgy, pydocstyle (экспериментально, возможны ошибки). Дополнительно можно подключить mypy, pyroma, vulture. Главной особенностью prospector является наличие предустановленных профилей, которые содержат настройки входящих в него утилит, призванных подавить наиболее придирчивые предупреждения и оставить только важные сообщения. Это позволяет начать работу с prospector без длительной настройки. Часть профилей отличаются уровнем “строгости” к требованиям. Из коробки доступно пять таких профилей: verylow, low, medium, high и veryhigh. Для указания этих профилей при запуске анализатора предназначен ключ –strictness:
$ python3.6 -m prospector --strictness veryhigh Messages ======== example.py Line: 1 pylint: unused-import / Unused import os Line: 2 pylint: import-error / Unable to import 'notexistmodule' Line: 4 pep8: N802 / function name 'Function' should be lowercase (col 5) pep8: E302 / expected 2 blank lines, found 1 (col 1) pylint: unused-argument / Unused argument 'num_two' (col 17) pep8: E231 / missing whitespace after ',' (col 17) pylint: invalid-name / Function name "Function" doesn't conform to snake_case naming style Line: 7 pep8: E302 / expected 2 blank lines, found 1 (col 1) pylint: too-few-public-methods / Too few public methods (1/2) Line: 10 pep8: E231 / missing whitespace after ',' (col 22) Line: 11 pep8: E225 / missing whitespace around operator (col 17) Line: 13 pep8: N805 / first argument of a method should be named 'self' (col 9) pylint: no-self-argument / Method should have "self" as first argument (col 4) Line: 18 pylint: invalid-name / Constant name "my_class" doesn't conform to UPPER_CASE naming style (col 4) Line: 19 pylint: too-many-function-args / Too many positional arguments for method call (col 4) Check Information ================= Started: 2018-10-01 22:52:45.294446 Finished: 2018-10-01 22:52:45.567646 Time Taken: 0.27 seconds Formatter: grouped Profiles: default, strictness_veryhigh, no_doc_warnings, no_test_warnings, no_member_warnings Strictness: veryhigh Libraries Used: Tools Run: dodgy, mccabe, pep8, profile-validator, pyflakes, pylint Messages Found: 15
Оставшиеся профили касаются стилистики исходного кода. Полный список можно посмотреть здесь.
Пользователям предоставляется возможность создать профиль под собственные требования. Для хранения настроек профиля используется yaml-файл, что позволяет очень гибко настроить Prospector. Например, определить какие инструменты и с какими настройками использовать, выбрать формат вывода (yaml, text, json, xunit, pylint) и так далее.
В набор утилит Prospector входят три утилиты для анализа кода Python, с которыми мы еще не встречались:
Мы не будем останавливаться на них, так как они выходят за рамки рассматриваемой темы.
Еще одной важной особенностью Prospector, является определение зависимостей. Программа попытается установить, какие библиотеки использует ваш проект и, обнаружив зависимости, автоматически включит поддержку требуемых библиотек.
Pylama
Pylama — инструмент аудита кода для Python и JavaScript. Служит оберткой на такими утилитами как: pydocstyle, pycodestyle, pyflakes, mccabe, pylint, radon (инструмент для сбора и вычисления различных метрик из исходного кода). Для работы с работы с JavaScript кодом используется gjslint.
Из доступных настроек стоит выделить возможность запускаться в асинхронном режиме интеграцию с pytest (пакет автоматически регистрируется как плагин pytest во время установки). Запуск pylama из pytest:
$ python3.6 -m pytest --pylama . ====================== test session starts ================================= platform linux -- Python 3.6.6, pytest-3.8.1, py-1.6.0, pluggy-0.7.1 rootdir: /home/test, inifile: plugins: pylama-7.4.3 collected 1 item example.py F [100%] ======================== FAILURES ====================================== ___________________________________________________________________________ example.py:1:1: W0611 'os' imported but unused [pyflakes] example.py:4:1: E302 expected 2 blank lines, found 1 [pycodestyle] example.py:4:17: E231 missing whitespace after ',' [pycodestyle] example.py:7:1: E302 expected 2 blank lines, found 1 [pycodestyle] example.py:10:22: E231 missing whitespace after ',' [pycodestyle] example.py:11:17: E225 missing whitespace around operator [pycodestyle] -------------------------------------------- Captured stdout call ----------------------------------------------------- example.py:1:1: W0611 'os' imported but unused [pyflakes] example.py:4:1: E302 expected 2 blank lines, found 1 [pycodestyle] example.py:4:17: E231 missing whitespace after ',' [pycodestyle] example.py:7:1: E302 expected 2 blank lines, found 1 [pycodestyle] example.py:10:22: E231 missing whitespace after ',' [pycodestyle] example.py:11:17: E225 missing whitespace around operator [pycodestyle] =========================== 1 failed in 0.20 seconds =========================
autopep8
Рассмотрение форматировщиков в этом обзоре мы начнем с autopep8. Он модифицирует код, не совместимый с PEP8. Проверка соответствия соглашениям осуществляется с помощью утилиты pycodestyle. В autopep8 есть поддержка многопоточности, рекурсивного обхода каталогов, возможность сохранения настроек в файле, задание диапазона строк для исправления, фильтрация ошибок и непосредственное изменение проверяемого файла. По умолчанию программа выводит исправленный код в виде текста на консоль. При использовании ключа –diff выводятся только различия:
$ python3.6 -m autopep8 --diff example.py --- original/example.py +++ fixed/example.py @@ -1,14 +1,16 @@ import os import notexistmodule -def Function(num,num_two): + +def Function(num, num_two): return num + class MyClass: """class MyClass """ - def __init__(self,var): - self.var=var + def __init__(self, var): + self.var = var def out(var): print(var)
autopep8 отлично справляется задачей форматирования, следя за несоблюдением PEP8. Однако невозможность подключения собственных стилей ограничивает круг его применения.
yapf
Код этой утилиты для анализа кода Python принадлежит компании Google. Прежде чем устанавливать этот форматировщик у себя на компьютере, вы можете опробовать yapf в действии с помощью онлайн демонстратора.
black
По утверждению разработчиков, black — это бескомпромиссный форматировщик, который работает быстро и экономит время и умственную энергию программистов для более важных вопросов. Демонстрацию работы black вы можете посмотреть на сайте. При установке программы на компьютер необходимо учитывать, что для запуска black требуется Python версии 3.6 и выше. Также к особенностям данного инструмента можно отнести:
- игнорирование не модифицированных файлов, программа запоминает, какие файлы она изменяла и при следующем запуске форматирует только файлы с внесенными изменениями;
- возможность запретить изменение отдельных блоков в коде, для этого используются комментарии: # fmt: off и # fmt: on, обозначающие начало и конец блока;
- длина строки по умолчанию является 88 символов, что не соответствует официальному соглашению PEP8;
- дополнительно можно установить HTTP сервер blackd, который позволяет избежать накладных расходов на создание процесса каждый раз, когда мы хотим отформатировать файл. Исходный код передается в теле POST запроса, а флаги управления форматированием в заголовках (флаги идентичны ключам командной строки, используемых при запуске black).
Заключение
Мы рассмотрели наиболее известные инструменты для анализа и автоматического форматирования кода. Многие из них давно интегрированы в современные IDE (SiblimeText, PyCharm, VisualStudio) и текстовые редакторы (Vim, Emacs). На основе некоторых построены онлайн-сервисы:
Существуют и другие инструменты для работы с кодом. Например, утилита для сортировки импорта по алфавиту и автоматического разделения на разделы — isort или библиотека ciocheck. Формат статьи не позволяет включить их все в обзор. Тем не менее мы уверены, что использования даже некоторых из рассмотренных выше инструментов достаточно для того, чтобы повысить качество кода в вашем проекте, сделать более комфортным совместную работу и в некоторых случаях избежать ошибок.
Регулярные выражения проверяются с помощью специальных сервисов. Такие сайты совмещают тестирование, подсказки и оптимизацию.
Популярный ресурс, понятный даже новичку. Тестит регулярные выражения PHP, JavaScript, Golang и Python. Проверка регулярных выражений сопровождается цветными пометками, которые разделяют символы на группы. Есть отладчик, сохранение и генератор кода с поддержкой C#, Java регулярок, Ruby, Rust, Perl.
Больше языков, но хуже интерфейс. Если начинающий кодер захочет протестировать регулярные выражения PHP онлайн и забредет на этот сайт, то, скорее всего, тут же выйдет. Для опытных же программистов RegexPlanet – это сервис-находка с поддержкой сразу десятка языков. Можно «скармливать» регулярные выражения JS, Ruby, Haskell и многое другое.
Неплохая проверка регулярных выражений онлайн, да еще и российский сервис. Страница информационного и практического характера. Если с английским не заладилось, это подходящий ресурс. Поддерживаются только регулярки JScript, но познавательная статья для новичков и удобство калькулятора заслуживают места в перечне.
Сайт с хорошей визуализацией и удобным интерфейсом. Поддерживается проверка регулярных выражений Python, JavaScript и PCRE. Если нажать «View Cheatsheet», внизу выскочат подсказки в виде распространенных регулярок для выбранного языка. Правда, сервис не поддерживает глобальный поиск, поэтому найти подходящую под шаблон строку можно лишь раз.
Отличный ресурс для проверки регулярных выражений онлайн на языке Ruby. Он на ходу отмечает подстроки, соответствующие шаблону. Также можно сохранить результат, а линк на него переслать. Визуально приятный и доступный для понимания интерфейс. Внизу разместился «Regex quick reference», он же перечень регулярок.
Другие статьи по теме:
Это команда pep8, которую можно запустить в бесплатном хостинг-провайдере OnWorks, используя одну из наших многочисленных бесплатных онлайн-рабочих станций, таких как Ubuntu Online, Fedora Online, онлайн-эмулятор Windows или онлайн-эмулятор MAC OS.
ПРОГРАММА:
ИМЯ
pep8 – инструмент для проверки вашего кода Python на соответствие некоторым стилевым соглашениям в PEP 8.
СИНТАКСИС
опционы
вход
ОПЦИИ
–версия
показать номер версии программы и выйти
-h, –Помогите
показать это справочное сообщение и выйти
-v, –подробный
распечатать сообщения о состоянии или выполнить отладку с помощью -вв
-q, –тихий
сообщать только имена файлов или ничего с -qq
описания
исключить файлы или каталоги, соответствующие этим шаблонам, разделенным запятыми (по умолчанию:
.svn, CVS, .bzr, .hg, .git, __ pycache__)
описания
при разборе каталогов проверяйте только имена файлов, соответствующие этим разделенным запятыми
шаблоны (по умолчанию: * .py)
Ошибки
выберите ошибки и предупреждения (например, E, W6)
Ошибки
пропускать ошибки и предупреждения (например, E4, W)
–первый
показать первое появление каждой ошибки
-r, –повторить
(устарело) показать все вхождения одной и той же ошибки
–show-источник
показать исходный код для каждой ошибки
–show-pep8
показывать текст PEP 8 для каждой ошибки (подразумевает –first)
–статистика
подсчитывать ошибки и предупреждения
–считать
вывести общее количество ошибок и предупреждений как стандартную ошибку и установить код выхода равным 1
если сумма не равна нулю
–максимальная длина строки=
n
установить максимально допустимую длину строки (по умолчанию: 79)
– закрывающийся
повесить закрывающую скобку вместо совпадающего отступа строки открывающей скобки
формат
–diff сообщать только строки, измененные в соответствии с унифицированной разницей, полученной на STDIN
– тест
измерить скорость обработки
путь
расположение файла конфигурации пользователя (по умолчанию: $ HOME / .config / pep8)
Отобразите, как часто обнаруживалась каждая ошибка:
% pep8 –statistics -qq пример / lib /
Показать исходный код и более подробное объяснение из PEP 8:
% pep8 –show-source –show-pep8 foo.py
Используйте pep8 онлайн с помощью сервисов onworks.net
Checking a syntax while coding is a crucial feature designed to test the validity of the ladder program during its development. Therefore, when the Syntax Check is run, all programs within the project are checked in succession.
Python has commands and tools to help you write better, bug-free, error-free, refactored-reusable code. But, first, let’s explore syntax checking in Python in detail.
Python is a server-side scripting programming language. However, it can also be employed as a general-purpose programming language.
Python error-checker tool lets you detect mistakes in syntax ( lint). In addition, you can check code in Python programming online from your browser.
If a syntax mistake is identified, the error line is highlighted and will jump to it to help reduce the time (no need to go through for the lines).
To check Python code syntax without executing it, use the Python -m py_compile script.py command.
For better syntax checking in Python, use one of these tools:
- PyChecker: It is a tool for finding errors in Python source code.
- Pyflakes: It is a simple program that checks source files for errors in Python.
- Pylint: It is a static code analysis tool that looks for programming errors helps enforce a coding standard.
Python syntax checker tool
PyChecker is similar to lint. PyChecker tool works in a variety of ways. First, it imports each module. If there is an import error, the module cannot be processed.
To use PyChecker, pass options, and the python source files (or packages), you want to check on the command line:
first_file.py.py,
Python syntax checker program
python3 -m pip install pyflakes
Python linter for syntax check
Pylint is a Python static code analysis tool that looks for programming errors, helps implement a coding standard, gasps for code smells, and offers simple, highly usable code refactoring suggestions.
python3 -m pip install pylint
That’s it for this tutorial.
See also
Python elapsed time
Python null coalesce