рдкреЗрд╢ рд╣реИ рдкрд╛рдЗрдерди рдореЗрдВ рдкрд░реАрдХреНрд╖рдгред рднрд╛рдЧ 3

рджреЛрд╕реНрддреЛрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЖрдкрдХреЗ рд▓рд┐рдП рдмрдбрд╝реА рдЦреБрд╢рдЦрдмрд░реА рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕реВрд░рдЬ рдЕрдВрддрддрдГ рд╕рдбрд╝рдХ рдкрд░ рдЪрдордХ рд░рд╣рд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╡рд╕рдВрдд рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдкрдиреЗ рдЕрдзрд┐рдХрд╛рд░реЛрдВ рдХреЛ рд▓реЗрдиреЗ рд▓рдЧрд╛ рд╣реИред рджреВрд╕рд░реА рдЦрдмрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реИ - 20 рдорд╛рд░реНрдЪ рдХреЛ, рдкрд╣рд▓рд╛ рдкрд╛рда "рдкрд╛рдпрдерди рдбреЗрд╡рд▓рдкрд░" рдкрд╛рдареНрдпрдХреНрд░рдо рдкрд░ рдПрдХ рдирдП рд╕реВрддреНрд░ рдореЗрдВ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕ рд╕рдВрдмрдВрдз рдореЗрдВ рд╣рдо рд▓реЗрдЦ "рдкрд╛рдпрдерди рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдкрд░рд┐рдЪрдп" рдХреЗ рдЕрдВрддрд┐рдо рднрд╛рдЧ рдХреЛ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдкрд┐рдЫрд▓реЗ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдпрд╣рд╛рдВ рдФрд░ рдпрд╣рд╛рдВ рдкрдврд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред

рдХрдИ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдкрд░реАрдХреНрд╖рдг

рдЕрдм рддрдХ, рдЖрдк рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд╛рддрд╛рд╡рд░рдг рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рд╕рд╛рде рдЖрднрд╛рд╕реА рд╡рд╛рддрд╛рд╡рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд╛рдпрдерди рдХреЗ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╣рдореЗрд╢рд╛ рдкрд╛рдпрдерди рдХреЗ рдХрдИ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдпрд╛ рдкреИрдХреЗрдЬ рдХреЗ рдХрдИ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИред Tox рдПрдХ рдРрд╕рд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИ рдЬреЛ рдХрдИ рд╡рд╛рддрд╛рд╡рд░рдгреЛрдВ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред



рд╡рд┐рд╖рд╛рдХреНрдд рд╕реНрдерд╛рдкрдирд╛

рдкреЙрдХреНрд╕ рдкрд╛рдЗрдк рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреИрдХреЗрдЬ рдХреЗ рд░реВрдк рдореЗрдВ рдкреЙрдХреНрд╕ рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИ:

$ pip install tox 

рд╕реНрдерд╛рдкрдирд╛ рдХреЗ рдмрд╛рдж, рдЖрдк рдЯреЛрдХреНрд╕ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдЕрдкрдиреА рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╖рд╛рдХреНрдд рдмрдирд╛рдирд╛

рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ Tox рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:

  • рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдорд╛рдВрдб рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП;
  • рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдХреЛрдИ рднреА рдЕрддрд┐рд░рд┐рдХреНрдд рдкреИрдХреЗрдЬ;
  • рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдЪрдпрдирд┐рдд рдкрд╛рдпрдерди рдХреЗ рд▓рдХреНрд╖реНрдп рд╕рдВрд╕реНрдХрд░рдгред

рдЯреЙрдХреНрд╕ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╕реАрдЦрдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЖрдк рдПрдХ рдХреНрд╡рд┐рдХрд╕реНрдЯрд╛рд░реНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓реЙрдиреНрдЪ рдХрд░рдХреЗ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 $ tox-quickstart 

рдЯреЛрдХреНрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЙрдкрдХрд░рдг рдЖрдкрд╕реЗ рдкреНрд░рд╢реНрди рдкреВрдЫреЗрдЧрд╛ рдФрд░ tox.ini рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЗ рд╕рдорд╛рди рдПрдХ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛ tox.ini :

 [tox] envlist = py27, py36 [testenv] deps = commands = python -m unittest discover 

Tox рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░ рд▓реЗрдВ рдХрд┐ рдкреИрдХреЗрдЬ рдХреЗ рд▓рд┐рдП рдЗрдВрд╕реНрдЯрд╛рд▓реЗрд╢рди рд╕реНрдЯреЗрдкреНрд╕ рдХреЗ рд╕рд╛рде setup.py рдПрдкреНрд▓реАрдХреЗрд╢рди рдлреЛрд▓реНрдбрд░ рдореЗрдВ рд╣реИред рдпрджрд┐ рдирд╣реАрдВ, рддреЛ setup.py рд╕реГрд╖реНрдЯрд┐ рдЧрд╛рдЗрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ ред

рдФрд░ рдпрджрд┐ рдЖрдкрдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛ PyPl рдкрд░ рд╡рд┐рддрд░рдг рдХреЗ рд▓рд┐рдП рдЕрднрд┐рдкреНрд░реЗрдд рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк рдЗрд╕ рд╢реАрд░реНрд╖рдХ рдХреЛ рд╡рд┐рд╖реИрд▓реЗ рд╢реАрд░реНрд╖рдХ рдХреЗ рддрд╣рдд tox.ini рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдирд┐рдореНрди рдкрдВрдХреНрддрд┐ рдЬреЛрдбрд╝рдХрд░ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:

 [tox] envlist = py27, py36 skipsdist=True 

рдпрджрд┐ рдЖрдк setup.py рдирд╣реАрдВ рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдореЗрдВ PyPl рдкрд░ рдХреБрдЫ рдирд┐рд░реНрднрд░рддрд╛рдПрдБ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЙрдиреНрд╣реЗрдВ testenv рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Django рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:

 [testenv] deps = django 

рдЗрд╕ рдЪрд░рдг рдХреЗ рдЕрдВрдд рдореЗрдВ, рдЖрдк рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдЕрдм рдЖрдк рдЯреЛрдХреНрд╕ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рджреЛ рдЖрднрд╛рд╕реА рд╡рд╛рддрд╛рд╡рд░рдг рдмрдирд╛рдПрдЧрд╛: рдПрдХ рдкрд╛рдпрдерди 2.7 рдХреЗ рд▓рд┐рдП рдФрд░ рдПрдХ рдкрд╛рдпрдерди 3.6 рдХреЗ рд▓рд┐рдПред Tox рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЛ .tox/ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдЖрднрд╛рд╕реА рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рд▓рд┐рдП Tox -m unittest discover рдХрд░реЗрдЧрд╛ред

рдЖрдк рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рд╕реЗ рдЯреЛрдХреНрд╕ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 $ tox 

рдЯреЙрдХреНрд╕ рдкреНрд░рддреНрдпреЗрдХ рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░реЗрдЧрд╛ред рдЬрдм рдЖрдк рдкрд╣рд▓реА рдмрд╛рд░ Tox рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрднрд╛рд╕реА рд╡рд╛рддрд╛рд╡рд░рдг рдмрдирд╛рдиреЗ рдореЗрдВ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рдЖрдк рджреВрд╕рд░реА рдмрд╛рд░ Tox рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рддреЗрдЬреА рд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред
рдЯреЙрдХреНрд╕ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рд╡рд╛рддрд╛рд╡рд░рдг рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╕реНрдерд╛рдкрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдкрд░реАрдХреНрд╖рдг рдХрдорд╛рдВрдб рдЪрд▓рд╛рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдпрд╛рдж рд░рдЦрдиреЗ рд▓рд╛рдпрдХ рдХреБрдЫ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рд╡рд┐рдХрд▓реНрдк рд╣реИрдВред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХрд▓ рд╡рд╛рддрд╛рд╡рд░рдг рдЪрд▓рд╛рдирд╛, рдЕрдЬрдЧрд░ 3.6:

 $ tox -e py36 

рд╡рд░реНрдЪреБрдЕрд▓ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдирд╛ рдЬрдм рдирд┐рд░реНрднрд░рддрд╛ рдмрджрд▓ рдЬрд╛рддреА рд╣реИ рдпрд╛ рд╕рд╛рдЗрдб-рдкреИрдХреЗрдЬ рджреВрд╖рд┐рдд рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ:

 $ tox -r 

рдХрдо рд╡рд┐рд╕реНрддреГрдд рдирд┐рд╖реНрдХрд░реНрд╖реЛрдВ рдХреЗ рд╕рд╛рде рд░рдирд┐рдВрдЧ рдЯреЙрдХреНрд╕:

 $ tox -q 

рдЕрдзрд┐рдХ рдХреНрд░рд┐рдпрд╛ рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд╕рд╛рде рд░рдирд┐рдВрдЧ рдЯреЙрдХреНрд╕:

 $ tox -v 

рдЖрдк Tox рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдЕрдзрд┐рдХ Tox рдкреНрд░рд▓реЗрдЦрди рд╕рд╛рдЗрдЯ рдкрд░ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдкрд░реАрдХреНрд╖рдг рд╕реНрд╡рдЪрд╛рд▓рди

рдЕрдм рддрдХ, рдЖрдкрдиреЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХрдорд╛рдВрдб рдЪрд▓рд╛рдХрд░ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдП рд╣реИрдВред рд▓реЗрдХрд┐рди рдЬрдм рдкрд░рд┐рд╡рд░реНрддрди рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рддреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдХрд░рдг рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░рдгрд╛рд▓реА рдХреЗ рд╕рд╛рде рднрдВрдбрд╛рд░ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдмрджреНрдз рдХрд░рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЧрд┐рдЯред рдЯреЗрд╕реНрдЯ рдСрдЯреЛрдореЗрд╢рди рдЯреВрд▓реНрд╕ рдХреЛ рдЕрдХреНрд╕рд░ CI / CD рдЯреВрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ "рдирд┐рд░рдВрддрд░ рдПрдХреАрдХрд░рдг / рдирд┐рд░рдВрддрд░ рддреИрдирд╛рддреА"ред рд╡реЗ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрд╡реЗрджрди рд╕рдВрдХрд▓рд┐рдд рдФрд░ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЙрдиреНрд╣реЗрдВ рдЙрддреНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рднреА рддреИрдирд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдЯреНрд░реИрд╡рд┐рд╕ CI рдЙрдкрд▓рдмреНрдз рдХрдИ рд╕реАрдЖрдИ рд╕реЗрд╡рд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред

рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рдкрд╛рдпрдерди рдХреЗ рд╕рд╛рде рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЕрдм рдЖрдк рдХреНрд▓рд╛рдЙрдб рдореЗрдВ рд╕рднреА рдмрдирд╛рдП рдЧрдП рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ! рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рдЧрд┐рдЯрд╣рдм рдФрд░ рдЧрд┐рдЯрд▓реИрдм рдкрд░ рдХрд┐рд╕реА рднреА рдЦреБрд▓реЗ рд╕реНрд░реЛрдд рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рд╣реИ рдФрд░ рдирд┐рдЬреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╢реБрд▓реНрдХ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реИред

рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдкрдиреЗ GitHub рдпрд╛ GitLab рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓реЙрдЧ рдЗрди рдХрд░реЗрдВ рдФрд░ рдкреНрд░рдорд╛рдгрд┐рдд рдХрд░реЗрдВред рдЗрд╕рдХреЗ рдмрд╛рдж рдПрдХ рдлрд╛рдЗрд▓ рдмрдирд╛рдПрдВ рдЬрд┐рд╕рдХрд╛ рдирд╛рдо рд╣реИ .travis.yml :

 language: python python: - "2.7" - "3.7" install: - pip install -r requirements.txt script: - python -m unittest discover 

рдпрд╣ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирд┐рд░реНрджреЗрд╢ рджреЗрддрд╛ рд╣реИ:

  • рдкрд╛рдпрдерди 2.7 рдФрд░ 3.7 рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг (рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ, рдЖрдк рдЙрдиреНрд╣реЗрдВ рдХрд┐рд╕реА рдЕрдиреНрдп рдХреЗ рд╕рд╛рде рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред)
  • рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдореЗрдВ рд╕реВрдЪреАрдмрджреНрдз рд╕рднреА рдкреИрдХреЗрдЬреЛрдВ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ред Txt (рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреЛрдИ рдирд┐рд░реНрднрд░рддрд╛ рдирд╣реАрдВ рд╣реИ рддреЛ рдЖрдк рдЗрд╕ рдЕрдиреБрднрд╛рдЧ рдХреЛ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред)
  • рдЕрдЬрдЧрд░ рдЪрд▓рд╛рдирд╛ -m unittest рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдирд╛ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИред

рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдХрдорд┐рдЯ рдХрд░рдиреЗ рдФрд░ рдкреБрд╢ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рдЗрди рдХрдорд╛рдВрдбреНрд╕ рдХреЛ рд╣рд░ рдмрд╛рд░ рдЖрдкрдХреЗ рд░рд┐рдореЛрдЯ рдЧрд┐рдЯ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдзрдХреЗрд▓ рджреЗрдЧрд╛ред рдкрд░рд┐рдгрд╛рдо рдЙрдирдХреА рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдЖрдЧреЗ рдХреНрдпрд╛ рд╣реИ

рдЕрдм рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ, рдЙрдиреНрд╣реЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рднреА рдХрд░реЗрдВ, рдЗрд╕рд▓рд┐рдП рдЖрдк рдЙрдиреНрдирдд рддрд░реАрдХреЛрдВ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдкрд░реАрдХреНрд╖рдг рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдмрдврд╝рдиреЗ рдХреЗ рд╕рд╛рде рд╣реА рдХрд╛рдо рдореЗрдВ рдЖ рд╕рдХрддреЗ рд╣реИрдВред

рдЖрд╡реЗрджрди рдХреЗ рд▓рд┐рдП рд▓рд╛рдЗрдирд░ рдкрд░рд┐рдЪрдп

Tox рдФрд░ Travis CI рдореЗрдВ рдПрдХ рдЯреЗрд╕реНрдЯ рдЯреАрдо рд╕реЗрдЯрдЕрдк рд╣реИред рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдореЗрдВ, рд╣рдордиреЗ рдЯреЗрд╕реНрдЯ рдЯреАрдо рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рдпрдерди-рдПрдо рдЕрдирд┐рдЯреЗрд╕реНрдЯ рдбрд┐рд╕реНрдХрд╡рд░ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ред

рдЖрдк рдЗрди рдЙрдкрдХрд░рдгреЛрдВ рдореЗрдВ рдПрдХ рдпрд╛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдХрдорд╛рдВрдб рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рдЧреБрдгрд╡рддреНрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХреЗ рд▓рд┐рдП рдирдП рдЙрдкрдХрд░рдг рдЬреЛрдбрд╝ рджреЗрдЧрд╛ред

рдРрд╕рд╛ рд╣реА рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓рд┐рдВрдЯрд░ рд╣реИред рд╡рд╣ рдЖрдкрдХреЗ рдХреЛрдб рдХреЛ рджреЗрдЦреЗрдЧрд╛ рдФрд░ рдЯрд┐рдкреНрдкрдгреА рдЫреЛрдбрд╝ рджреЗрдЧрд╛ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╡рд╣ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдкрд░ рд╕рд▓рд╛рд╣ рджреЗ рд╕рдХрддрд╛ рд╣реИ, рдЕрдиреБрдЧрд╛рдореА рд░рд┐рдХреНрдд рд╕реНрдерд╛рди рдХреЛ рд╕рд╣реА рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╕рдВрднрд╛рд╡рд┐рдд рдмрдЧреЛрдВ рдХреА рдЖрд╢рд╛ рднреА рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рд▓рд┐рдВрдЯрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд╛рдпрдерди рдХреЛрдб рдХреНрд╡рд╛рд▓рд┐рдЯреА рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рджреЗрдЦреЗрдВ ред

Flake8 рдХреЗ рд╕рд╛рде рдирд┐рд╖реНрдХреНрд░рд┐рдп рдЕрд╕реНрддрд░

flake8 рдПрдХ рд▓реЛрдХрдкреНрд░рд┐рдп рд▓рд┐рдВрдЯрд░ рд╣реИ рдЬреЛ PEP 8 рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЖрдкрдХреЗ рдХреЛрдб рдХреА рд╢реИрд▓реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЯрд┐рдкреНрдкрдгреА рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИред

рдЖрдк flake8 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ flake8 рд╕реНрдерд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 $ pip install flake8 

рдлрд┐рд░ рдЖрдк рдХрд┐рд╕реА рдПрдХрд▓ рдлрд╝рд╛рдЗрд▓, рдлрд╝реЛрд▓реНрдбрд░ рдпрд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рд▓рд┐рдП flake8 рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ:

 $ flake8 test.py test.py:6:1: E302 expected 2 blank lines, found 1 test.py:23:1: E305 expected 2 blank lines after class or function definition, found 1 test.py:24:20: W292 no newline at end of file 

рдЖрдкрдХреЛ flake8 рджреНрд╡рд╛рд░рд╛ рдорд┐рд▓реЗ рдХреЛрдб рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдФрд░ рдЪреЗрддрд╛рд╡рдирд┐рдпреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рджрд┐рдЦрд╛рдИ flake8 ред
flake8 рдХреЛ рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдпрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдкрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдХреБрдЫ рдирд┐рдпрдореЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, E305, рдКрдкрд░ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдЖрдк рдЗрд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред flake8 рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ setup.cfg рдлрд╝рд╛рдЗрд▓ рдпрд╛ flake8 рдлрд╝рд╛рдЗрд▓ рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдЧрд╛ред рдпрджрд┐ рдЖрдк Tox рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк flake8 рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди flake8 рдХреЛ tox.ini рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣ рдЙрджрд╛рд╣рд░рдг .git рдФрд░ __pycache__ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ , рд╕рд╛рде рд╣реА E305 рдирд┐рдпрдо рдХреА рдЙрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рдЕрдзрд┐рдХрддрдо рд▓рдВрдмрд╛рдИ 80 рд╡рд░реНрдгреЛрдВ рд╕реЗ 90 рддрдХ рдмрдврд╝ рдЬрд╛рддреА рд╣реИред рдЖрдк рдХреБрдЫ рдмрд┐рдВрджреБ рдкрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВрдЧреЗ рдХрд┐ рдкреНрд░рддрд┐ рдкрдВрдХреНрддрд┐ 79 рд╡рд░реНрдгреЛрдВ рдХреА рдорд╛рдирдХ рд╕реАрдорд╛ рдЙрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИ рдЬрд┐рдирдореЗрдВ рд▓рдВрдмреА рд╡рд┐рдзрд┐ рдХреЗ рдирд╛рдо рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдкрд░реАрдХреНрд╖рдг рдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╢рд╛рдмреНрджрд┐рдХ рдФрд░ рдбреЗрдЯрд╛ рдХреЗ рдЕрдиреНрдп рд▓рдВрдмреЗ рдЯреБрдХрдбрд╝реЗред рдЖрдорддреМрд░ рдкрд░, рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рд▓рдВрдмрд╛рдИ 120 рд╡рд░реНрдгреЛрдВ рддрдХ рдмрдврд╝рд╛рдПрдВ:

 [flake8] ignore = E305 exclude = .git,__pycache__ max-line-length = 90 

рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ, рдЖрдк рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдкрд░ рдпреЗ рд╡рд┐рдХрд▓реНрдк рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 $ flake8 --ignore E305 --exclude .git,__pycache__ --max-line-length=90 

рдкреНрд░рд▓реЗрдЦрди рд╕рд╛рдЗрдЯ рдкрд░ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреА рдПрдХ рдкреВрд░реА рд╕реВрдЪреА рдкрд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИред
рдЕрдм рдЖрдк flake8 рдХреЛ рдЕрдкрдиреЗ CI рд╕реЗрдЯрдЕрдк рдореЗрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдЯреНрд░реИрд╡рд┐рд╕ рд╕реАрдЖрдИ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

 matrix: include: - python: "2.7" script: "flake8" 

рдЯреНрд░реИрд╡рд┐рд╕ .flake8 рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ .flake8 рдФрд░ рд▓рд┐рдВрдЯ рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╣реЛрдиреЗ рдкрд░ рдмрд┐рд▓реНрдб рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЖрдк requirements.txt рд▓рд┐рдП flake8 рдирд┐рд░реНрднрд░рддрд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред

рдХреЛрдб рдлреЙрд░реНрдореЗрдЯрд░ рдХреЗ рд╕рд╛рде рдЖрдХреНрд░рд╛рдордХ рд▓рд╛рдЗрдирд┐рдВрдЧ

flake8 рдПрдХ рдирд┐рд╖реНрдХреНрд░рд┐рдп рд▓рд┐рдВрдЯрд░ рд╣реИ рдЬреЛ рдХреЗрд╡рд▓ рд╕рдВрдкрд╛рджрди рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХрд░рддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдЙрдиреНрд╣реЗрдВ рдХреЛрдб рдореЗрдВ рд╕реНрд╡рдпрдВ рджрд░реНрдЬ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдХреЛрдб рдлреЙрд░реНрдореЗрдЯрд░ рдПрдХ рдЕрдзрд┐рдХ рдЖрдХреНрд░рд╛рдордХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИред рдпрд╣ рд╢реИрд▓рд┐рдпреЛрдВ рдФрд░ рд▓реЗрдЖрдЙрдЯ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХреЛрдб рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдмрджрд▓рддрд╛ рд╣реИред

black рдХрд╛ рдПрдХ рдмрд╣реБрдд рд╣реА рд╕реБрдВрджрд░ рд░реВрдк рд╣реИред рдЗрд╕рдХреА рдХреЛрдИ рд╕реЗрдЯрд┐рдВрдЧ рдирд╣реАрдВ рд╣реИ рдФрд░ рдпрд╣ рдмрд╣реБрдд рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рд╣реИред рдЬреЛ рдЗрд╕реЗ рдЖрдкрдХреЗ рдкрд░реАрдХреНрд╖рдг рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╣рд╛рди рдЙрдкрдХрд░рдг рдмрдирд╛рддрд╛ рд╣реИред

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ: рдХрд╛рд▓реЗ рд░рдВрдЧ рдХреЛ рдкрд╛рдпрдерди рд╕рдВрд╕реНрдХрд░рдг 3.6 рдФрд░ рдЙрдЪреНрдЪрддрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдЖрдк рдкрд╛рдЗрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ black рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 $ pip install black 

рдлрд┐рд░, рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрд╕ рдлрд╝рд╛рдЗрд▓ рдпрд╛ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ рдЬрд┐рд╕реЗ рдЖрдк рдкреНрд░рд╛рд░реВрдкрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:

 $ black test.py 

рдЯреЗрд╕реНрдЯ рдХреЛрдб рдХреЛ рд╕рд╛рдл рд░рдЦреЗрдВ

рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрддреЗ рд╕рдордп рдЖрдк рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рддреЗ рд╕рдордп рдХреЛрдб рдХреЗ рдЯреБрдХрдбрд╝реЗ рдХреЛ рдЕрдзрд┐рдХ рдмрд╛рд░ рдХреЙрдкреА-рдкреЗрд╕реНрдЯ рдХрд░реЗрдВрдЧреЗред рд╕рдордп-рд╕рдордп рдкрд░, рдкрд░реАрдХреНрд╖рдг рдмрд╣реБрдд рдиреАрд░рд╕ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдЧрд▓рдд рдФрд░ рдЦрдВрдбрд┐рдд рд░реВрдк рдореЗрдВ рдХреЛрдб рдХреЛ рдЫреЛрдбрд╝рдиреЗ рдХрд╛ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реИред

рд╕рдордп рдХреЗ рд╕рд╛рде, рддрдХрдиреАрдХреА рдЛрдг рдЖрдкрдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдореЗрдВ рдЬрдорд╛ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛрдб рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдирд╛ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдХрд╛рд░рдг рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрддреЗ рд╕рдордп, DRY рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ: рдЕрдкрдиреЗ рдЖрдк рдХреЛ рджреЛрд╣рд░рд╛рдПрдВ рдирд╣реАрдВред

рдЯреЗрд╕реНрдЯ рдЬреБрдбрд╝рдирд╛рд░ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХрд╛ рдПрдХ рд╢рд╛рдирджрд╛рд░ рддрд░реАрдХрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдмрдирд╛рдП рд░рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкрдврд╝рдиреЗ рдХреА рдЖрд╕рд╛рдиреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдордд рднреВрд▓рдирд╛ред рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдХреЛ flake8 рдЬреИрд╕реЗ flake8 рдЯреВрд▓ рддреИрдирд╛рдд рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:

 $ flake8 --max-line-length=120 tests/ 

рд╕рдВрдкрд╛рджрди рдХреЗ рдмреАрдЪ рдЙрддреНрдкрд╛рджрдХрддрд╛ рдШрдЯрдиреЗ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг

рдкрд╛рдпрдерди рдореЗрдВ рдХреЛрдб рдХреЛ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдХрд░рдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЗ рд╣реИрдВред рдорд╛рдирдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдПрдХ рдЯрд╛рдЗрдордЯрд╛рдЗрдо рдореЙрдбреНрдпреВрд▓ рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдХрдИ рдмрд╛рд░ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рд╡рд┐рддрд░рдг рджрд┐рдЦрд╛рддрд╛ рд╣реИред рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдкрд░реАрдХреНрд╖рдг () рдХреЛ 100 рдмрд╛рд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдлрд┐рд░ рдкреНрд░рд┐рдВрдЯ () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

 def test(): # ... your code if __name__ == '__main__': import timeit print(timeit.timeit("test()", setup="from __main__ import test", number=100)) 

рдпрджрд┐ рдЖрдк рдЯреЗрд╕реНрдЯ рд░рдирд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ-рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдкреНрд▓рдЧрдЗрди рджреЗрдЦреЗрдВред рдпрд╣ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдирд╛рдордХ рдПрдХ рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ рд╕реНрдерд┐рд░рддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдХрд┐рд╕реА рднреА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдмреЗрдВрдЪрдорд╛рд░реНрдХ () рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ рдкрд░рд┐рдгрд╛рдореЛрдВ рдореЗрдВ рдХреЙрд▓ рдХрд╛ рд╕рдордп рдкрд╛рд░ рдХрд░рддрд╛ рд╣реИред

рдЖрдк рдкрд╛рдЗрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ PyPl рд╕реЗ рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ-рдмреЗрдВрдЪрдорд╛рд░реНрдХ рд╕реНрдерд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 $ pip install pytest-benchmark 

рдлрд┐рд░ рдЖрдк рд╕реНрдерд┐рд░рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 def test_my_function(benchmark): result = benchmark(test) 

рд╕рдмрд╕реЗ рддреЗрдЬ рдЪрд▓рдиреЗ рд╕реЗ рдЖрдкрдХреЛ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓реЗрдВрдЧреЗ:



рдЖрдк рдкреНрд░рд▓реЗрдЦрди рд╕рд╛рдЗрдЯ рдкрд░ рдЕрдзрд┐рдХ рдЬрд╛рди рд╕рдХрддреЗ рд╣реИрдВред

рд╕реБрд░рдХреНрд╖рд╛ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдкрд╣рдЪрд╛рди рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг

рдПрдХ рдЕрдиреНрдп рдкрд░реАрдХреНрд╖рдг рдЬреЛ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдкрд░ рдЪрд▓рдирд╛ рдЪрд╛рд╣рд┐рдП, рд╡рд╣ рд╕рд╛рдорд╛рдиреНрдп рддреНрд░реБрдЯрд┐рдпреЛрдВ рдФрд░ рд╕реБрд░рдХреНрд╖рд╛ рдХрдордЬреЛрд░рд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХрд░ рд░рд╣рд╛ рд╣реИред

рдкрд╛рдЗрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ PyPl рд╕реЗ bandit рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:

 $ pip install bandit 

рддрдм рдЖрдк рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдирд╛рдо -r рдзреНрд╡рдЬ рдХреЗ рд╕рд╛рде рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 $ bandit -r my_sum [main] INFO profile include tests: None [main] INFO profile exclude tests: None [main] INFO cli include tests: None [main] INFO cli exclude tests: None [main] INFO running on Python 3.5.2 Run started:2018-10-08 00:35:02.669550 Test results: No issues identified. Code scanned: Total lines of code: 5 Total lines skipped (#nosec): 0 Run metrics: Total issues (by severity): Undefined: 0.0 Low: 0.0 Medium: 0.0 High: 0.0 Total issues (by confidence): Undefined: 0.0 Low: 0.0 Medium: 0.0 High: 0.0 Files skipped (0): 

flake8 рд╕рд╛рде, bandit рдлрд╝реНрд▓реИрдЧ bandit рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдЖрдк рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде setup.cfg рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдирд┐рдореНрди рдЯреБрдХрдбрд╝реЗ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:

 [bandit] exclude: /test tests: B101,B102,B301 

GitHub рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реАред

рдирд┐рд╖реНрдХрд░реНрд╖

рдкрд╛рдпрдерди рдиреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд╕рд╣реА рд╕рдВрдЪрд╛рд▓рди рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдХрдорд╛рдВрдб рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдЙрдкрд▓рдмреНрдз рдХрд░рд╛рдпрд╛ рд╣реИред рдкрд╛рдпрдерди рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рд╢реБрд░реВ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ: рдЖрдк рдХреЛрдб рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХрддрд░рдлрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЫреЛрдЯреЗ, рдЖрд╕рд╛рди рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рддрд░реАрдХреЗ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдХреЗ рдкрд░реАрдХреНрд╖рдг рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рдЙрдиреНрдирдд рдЙрдиреНрдирдд рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдПрдХ рдкрд░реАрдХреНрд╖рдг рдврд╛рдВрдЪреЗ рдореЗрдВ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред

рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдЕрдЬрдЧрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрд╕реНрдерд┐рд░ рднрд╡рд┐рд╖реНрдп рд╣реИ!

рдФрд░ рдЬреЛ рд▓реЛрдЧ рд▓реЗрдЦ рдкрдврд╝ рдЪреБрдХреЗ рд╣реИрдВ, рдЙрдирдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдФрд░ рдмрдбрд╝реА рдЦрдмрд░ рд╣реИред рдЕрднреА, рдЖрдк 10,000 рд░реВрдмрд▓ рдХреА рдЫреВрдЯ рдкрд░ рдкрд╛рдпрдерди рдбреЗрд╡рд▓рдкрд░ рдХреЛрд░реНрд╕ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ!

рдкрд╣рд▓рд╛ рднрд╛рдЧ
рджреВрд╕рд░рд╛ рднрд╛рдЧ

Source: https://habr.com/ru/post/hi444204/


All Articles