Публикувани са резултатите от изследване на податливостта на кода на Python на грешки, свързани с неправилна употреба на запетаи в кода. Проблемите възникват, тъй като по време на изброявания Python автоматично обединява елементите в списъка, ако не са разделени със запетаи, и също така обработва стойността като кортеж, ако след стойността има запетая. Проведен е автоматизиран анализ на 666 GitHub хранилища с код на Python, при който изследователите установиха възможни проблеми с запетаи в 5% от разглежданите проекти.
По-нататъшната ръчна проверка показа, че реалните грешки присъстват само в 24 хранилища (3.6%), а останалите 1.4% са фалшиви сработвания (например, запетая може да е пропусната умишлено между елементите, за да се обединят разбити на няколко реда файлови пътища, дълги хешове, HTML блокове или SQL изрази). Интересен факт е, че между 24-те хранилища с реални грешки се намират и големи проекти като Tensorflow, Google V8, Sentry, Pydata xarray, rapidpro, django-colorfield и django-helpdesk. В същото време проблемите със запетаите не са специфични за Python и често се появяват в проекти на C/C++ (пример за последни поправки — LLVM, Mono, Tensorflow).
Основни видове изучени грешки:
- Случайно пропусната запетая в списъци, кортежи и множества, водеща до обединяване на елементите вместо тяхното интерпретиране като отделни стойности. Например, в Sentry в един от тестовете е била пропусната запета между елементите 'releases' и 'discover' в списъка, което е довело до проверка на несъществуващ обработчик '/releasesdiscover', вместо отделна проверка на '/releases' и '/discover'.

Друг пример — пропуснатата запета в rapidpro води до обединяване на две различни правила на ред 572:

- Пропусната запета в края на определението на кортеж с един елемент, което води до присвояване на нормален тип вместо кортеж. Например, изразът 'values = (1,)' ще присвои на променливата кортеж с един елемент, но 'values = (1)' ще присвои цялостен тип. Скобите в посочените присвоявания не влияят на определението на типа и са незадължителни, а наличието на кортежа се определя от парсера единствено на базата на наличието на запетаи. REST_FRAMEWORK = { ‘DEFAULT_PERMISSION_CLASSES’: ( ‘rest_framework.permissions.IsAuthenticated’ # вместо кортежа ще бъде присвоена строка. ) }
- Обратната ситуация е излишни запетаи при присвояването. Ако в края на присвояването случайно е оставена запетая, тогава вместо обикновен тип ще бъде присвоен кортеж (например, ако вместо „value = 1“ е записано „value = 1,“).
Източник: opennet.ru


