Pylint-työkalu

Pylint on työkalu, joka antaa palautetta Python-koodin ohjelmointityylistä. Työkalun avulla on kätevää etsiä omasta koodista korjattavia asioita.

Esimerkiksi seuraava komento tarkastaa tiedoston test.py sisällön:

$ pylint test.py

Esimerkki

Kokeillaan testimielessä, millaista palautetta Pylint antaa kurssin esimerkkisovelluksesta. Tässä tapauksessa on kätevää antaa parametriksi *.py, jolloin saadaan palaute kaikista hakemiston Python-tiedostoista.

$ pylint *.py
************* Module app
app.py:1:0: C0114: Missing module docstring (missing-module-docstring)
app.py:1:0: E0401: Unable to import 'flask' (import-error)
app.py:7:0: C0413: Import "import routes" should be placed at the top of the module (wrong-import-position)
app.py:7:0: W0611: Unused import routes (unused-import)
app.py:2:0: C0411: standard import "from os import getenv" should be placed before "from flask import Flask" (wrong-import-order)
************* Module db
db.py:1:0: C0114: Missing module docstring (missing-module-docstring)
db.py:2:0: E0401: Unable to import 'flask_sqlalchemy' (import-error)
db.py:3:0: C0411: standard import "from os import getenv" should be placed before "from app import app" (wrong-import-order)
************* Module decks
decks.py:72:0: C0301: Line too long (101/100) (line-too-long)
decks.py:1:0: C0114: Missing module docstring (missing-module-docstring)
decks.py:4:0: C0116: Missing function or method docstring (missing-function-docstring)
decks.py:8:0: C0116: Missing function or method docstring (missing-function-docstring)
decks.py:13:0: C0116: Missing function or method docstring (missing-function-docstring)
decks.py:17:0: C0116: Missing function or method docstring (missing-function-docstring)
decks.py:22:0: C0116: Missing function or method docstring (missing-function-docstring)
decks.py:39:0: C0116: Missing function or method docstring (missing-function-docstring)
decks.py:44:0: C0116: Missing function or method docstring (missing-function-docstring)
decks.py:50:0: C0116: Missing function or method docstring (missing-function-docstring)
decks.py:54:0: C0116: Missing function or method docstring (missing-function-docstring)
decks.py:64:0: C0116: Missing function or method docstring (missing-function-docstring)
decks.py:69:0: C0116: Missing function or method docstring (missing-function-docstring)
decks.py:2:0: C0411: standard import "from random import randint" should be placed before "from db import db" (wrong-import-order)
************* Module routes
routes.py:56:0: C0301: Line too long (135/100) (line-too-long)
routes.py:98:0: C0301: Line too long (110/100) (line-too-long)
routes.py:1:0: C0114: Missing module docstring (missing-module-docstring)
routes.py:2:0: E0401: Unable to import 'flask' (import-error)
routes.py:3:0: C0410: Multiple imports on one line (decks, stats, users) (multiple-imports)
routes.py:6:0: C0116: Missing function or method docstring (missing-function-docstring)
routes.py:10:0: C0116: Missing function or method docstring (missing-function-docstring)
routes.py:10:0: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)
routes.py:35:8: W0622: Redefining built-in 'list' (redefined-builtin)
routes.py:42:12: W0621: Redefining name 'deck' from outer scope (line 48) (redefined-outer-name)
routes.py:31:0: C0116: Missing function or method docstring (missing-function-docstring)
routes.py:31:0: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)
routes.py:48:9: W0622: Redefining built-in 'id' (redefined-builtin)
routes.py:48:0: C0103: Argument name "id" doesn't conform to snake_case naming style (invalid-name)
routes.py:48:0: C0116: Missing function or method docstring (missing-function-docstring)
routes.py:59:0: C0116: Missing function or method docstring (missing-function-docstring)
routes.py:80:9: W0622: Redefining built-in 'id' (redefined-builtin)
routes.py:80:0: C0103: Argument name "id" doesn't conform to snake_case naming style (invalid-name)
routes.py:80:0: C0116: Missing function or method docstring (missing-function-docstring)
routes.py:87:0: C0116: Missing function or method docstring (missing-function-docstring)
routes.py:101:0: C0116: Missing function or method docstring (missing-function-docstring)
routes.py:109:8: R1705: Unnecessary "else" after "return" (no-else-return)
routes.py:101:0: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)
routes.py:115:0: C0116: Missing function or method docstring (missing-function-docstring)
routes.py:120:0: C0116: Missing function or method docstring (missing-function-docstring)
routes.py:137:11: R1714: Consider merging these comparisons with "in" to "role not in ('1', '2')" (consider-using-in)
routes.py:140:8: R1705: Unnecessary "else" after "return" (no-else-return)
routes.py:120:0: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)
routes.py:120:0: R0911: Too many return statements (7/6) (too-many-return-statements)
routes.py:146:0: C0116: Missing function or method docstring (missing-function-docstring)
************* Module stats
stats.py:1:0: C0114: Missing module docstring (missing-module-docstring)
stats.py:3:0: C0116: Missing function or method docstring (missing-function-docstring)
stats.py:8:0: C0116: Missing function or method docstring (missing-function-docstring)
************* Module users
users.py:1:0: C0114: Missing module docstring (missing-module-docstring)
users.py:2:0: E0401: Unable to import 'flask' (import-error)
users.py:3:0: E0401: Unable to import 'werkzeug.security' (import-error)
users.py:6:0: C0116: Missing function or method docstring (missing-function-docstring)
users.py:10:4: R1705: Unnecessary "else" after "return" (no-else-return)
users.py:13:8: R1705: Unnecessary "else" after "return" (no-else-return)
users.py:22:0: C0116: Missing function or method docstring (missing-function-docstring)
users.py:27:0: C0116: Missing function or method docstring (missing-function-docstring)
users.py:34:4: W0702: No exception type(s) specified (bare-except)
users.py:38:0: C0116: Missing function or method docstring (missing-function-docstring)
users.py:41:0: C0116: Missing function or method docstring (missing-function-docstring)
users.py:45:0: C0116: Missing function or method docstring (missing-function-docstring)
users.py:4:0: C0411: standard import "import os" should be placed before "from db import db" (wrong-import-order)
users.py:1:0: R0401: Cyclic import (app -> routes) (cyclic-import)
users.py:1:0: R0401: Cyclic import (app -> routes -> decks -> db) (cyclic-import)
users.py:1:0: R0401: Cyclic import (app -> routes -> stats -> db) (cyclic-import)
users.py:1:0: R0401: Cyclic import (app -> routes -> users -> db) (cyclic-import)

------------------------------------------------------------------
Your code has been rated at 5.62/10

Pylint antaa palautteen jokaisesta tiedostosta ja lopuksi arvion koodin laadusta. Tässä tapauksessa Pylint antaa koodille arvion 5.62/10.

Raportin tulkinta

Pylintin antama raportti kannattaa lukea huolellisesti ja miettiä, miten koodin laatua voi parantaa sen avulla. Tässä projektissa Pylint huomauttaa mm. seuraavista asioista:

Huomaa kuitenkin, että raportin tulkinnassa kannattaa käyttää omaa harkintaa. Vaikka Pylint huomauttaa jostain asiasta, se ei välttämättä vaadi korjaamista. Esimerkiksi tämän kurssin projektissa moduuleja ja funktioita ei tarvitse dokumentoida.

Raportin asetukset

Pylintin raportissa joka rivin perässä on tunnus, joka ilmaisee palautteen aiheen. Tiedoston .pylintrc avulla voi määrittää, että tiettyjä asioita ei käsitellä raportissa.

Esimerkiksi tämän kurssin projektissa tiedoston sisältö voisi olla seuraava:

.pylintrc

[MESSAGES CONTROL]

disable=missing-module-docstring,
        missing-function-docstring,
        import-error,
        cyclic-import

Tämän seurauksena raportti lyhenee selvästi ja siitä näkee paremmin tämän projektin kannalta hyödyllistä palautetta:

$ pylint *.py
************* Module app
app.py:7:0: C0413: Import "import routes" should be placed at the top of the module (wrong-import-position)
app.py:7:0: W0611: Unused import routes (unused-import)
app.py:2:0: C0411: standard import "from os import getenv" should be placed before "from flask import Flask" (wrong-import-order)
************* Module db
db.py:3:0: C0411: standard import "from os import getenv" should be placed before "from app import app" (wrong-import-order)
************* Module decks
decks.py:72:0: C0301: Line too long (101/100) (line-too-long)
decks.py:2:0: C0411: standard import "from random import randint" should be placed before "from db import db" (wrong-import-order)
************* Module routes
routes.py:56:0: C0301: Line too long (135/100) (line-too-long)
routes.py:98:0: C0301: Line too long (110/100) (line-too-long)
routes.py:3:0: C0410: Multiple imports on one line (decks, stats, users) (multiple-imports)
routes.py:10:0: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)
routes.py:35:8: W0622: Redefining built-in 'list' (redefined-builtin)
routes.py:42:12: W0621: Redefining name 'deck' from outer scope (line 48) (redefined-outer-name)
routes.py:31:0: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)
routes.py:48:9: W0622: Redefining built-in 'id' (redefined-builtin)
routes.py:48:0: C0103: Argument name "id" doesn't conform to snake_case naming style (invalid-name)
routes.py:80:9: W0622: Redefining built-in 'id' (redefined-builtin)
routes.py:80:0: C0103: Argument name "id" doesn't conform to snake_case naming style (invalid-name)
routes.py:109:8: R1705: Unnecessary "else" after "return" (no-else-return)
routes.py:101:0: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)
routes.py:137:11: R1714: Consider merging these comparisons with "in" to "role not in ('1', '2')" (consider-using-in)
routes.py:140:8: R1705: Unnecessary "else" after "return" (no-else-return)
routes.py:120:0: R1710: Either all return statements in a function should return an expression, or none of them should. (inconsistent-return-statements)
routes.py:120:0: R0911: Too many return statements (7/6) (too-many-return-statements)
************* Module users
users.py:10:4: R1705: Unnecessary "else" after "return" (no-else-return)
users.py:13:8: R1705: Unnecessary "else" after "return" (no-else-return)
users.py:34:4: W0702: No exception type(s) specified (bare-except)
users.py:4:0: C0411: standard import "import os" should be placed before "from db import db" (wrong-import-order)

------------------------------------------------------------------
Your code has been rated at 8.71/10

Nyt koodi saa arvion 8.71/10, mutta koodissa olisi vielä monenlaista parannettavaa.