スクリプトのお勉強 技術

整形/文法チェック ツール インストールまとめ

投稿日:2019年5月7日 更新日:

1.はじめに

最近、仕事で複数スクリプトを組み合わせてコーディングすることが多くなりました。
それだと、各スクリプトの癖を忘れたり、そもそもどう書くのか忘れたりと、不良を作りこむ可能性が多くなります。

なので、スクリプトの整形/文法チェック(lint)する環境を整える必要があると考えました。

主に使用するスクリプトは以下としました。

  • perl(5.26,1)
  • python(3.5.2)

IDEを使う方式もありますが、今回はコマンドで起動する方式にします。

以降で各スクリプトの整形/lintツールのインストール方法を書いていきます。

2.perl

2.1 インストール

perltidyとPerl::Criticは以下でインストールします。

$ cpanm Perl::Tidy
$ cpanm Perl::Critic
$ cpanm Test::Perl::Critic

2.2 整形ツール(perltidy)

整形は perltidy というコマンドを使用します。例として、s3.pl(ファイル名)にperltidyをかけると、s3.pl.tdyというファイルを生成します。

$HOME/.perltidyrcに以下のように書いておきます。

-l=78   # Max line width is 78 cols
-i=4    # Indent level is 4 cols
-ci=4   # Continuation indent is 4 cols
-se     # Errors to STDERR
-vt=2   # Maximal vertical tightness
-cti=0  # No extra indentation for closing brackets
-pt=1   # Medium parenthesis tightness
-bt=1   # Medium brace tightness
-sbt=1  # Medium square brace tightness
-bbt=1  # Medium block brace tightness
-nsfs   # No space before semicolons
-nolq   # Don't outdent long quoted strings
-wbb="% + - * / x != == >= <= =~ !~ < > | & >= < = **= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x="
# Break before all operators

実行例は以下の通りです。

$ vi s3.pl
#!/usr/bin/perl

package TEST;

use strict;
use warnings;

use Smart::Comments;

foo();

sub foo {


  bar();

}

sub bar {
  baz();
}

sub baz {

    ### <here>
    print "loooooooooooooooooonggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg";
}
$ perltidy s3.pl
$ ls -l s3.pl.tdy
s3.pl.tdy
$ cat s3.pl.tdy
#!/usr/bin/perl

package TEST;

use strict;
use warnings;

use Smart::Comments;

foo();

sub foo {

    bar();

}

sub bar {
    baz();
}

sub baz {

    ### <here>
    print
        "loooooooooooooooooonggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg";
}

ソースを直接編集するなら-bをつけます。

$ perltidy -b s3.pl

2.3 文法チェック(Perl::Critic)

文法チェックには、 Perl::Critic を使用します。以下でs3.plをチェックします。
ディレクトリを指定すれば、ディレクトリ下のソースを再帰してチェックします。

$ perlcritic --profile-proto > t/perlcriticrc
$ vi t/99.-perlcritic.t
use strict;
use Test::More;

eval { require Test::Perl::Critic; Test::Perl::Critic->import(-profile => "t/perlcriticrc") };
plan skip_all => "Test::Perl::Critic is not installed." if $@;

all_critic_ok("s3.pl");

手元のコードを確認してみると、以下のようになります。

$ perl t/99-perlcritic.t
ok - Test::Perl::Critic for "s3.pl"
1..1

3.python

pythonのバージョンは3.5を仮定しています。

3.1 インストール

autopep8flake8は以下のようにインストールします。

$ pip install autopep8
$ pip install flake8

3.2 整形ツール(autopep8)

整形ツールには、autopep8が使えます。その他に[yapf]
というのもありますが、今回はautopep8で整形してみます。

以下のようにインストールします。

以下のようなテストコードを書いてみます。

vi hw.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from bottle import route, run

a = ['', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa','bb','cc','dd','ee','ff']

b = {'aa': 1,'bb':2, 'ccccccccccccccccccccccccccccccccccccccccc': 3333333333333333, 'ddd': 'bbbb'}

#テスト用コード
@route('/hello')
def hello():
    """ テスト実装
    """
  print(a)
  print(b)
    return "Hello World!"

#テスト用起動
run(host='0.0.0.0', port=8080, debug=True, reloader=True)

以下で起動します。「-i」はそのファイルを直接修正します。「-a」はaggressiveの意味で、より見やすく修正されるようなのでつけて起動しています。

$ autopep8 -i -a -a hw.py

autopep8を通した結果、以下になりました。コメントの位置がちょっと納得いきませんが、PEP8に準拠するとこうなることになりますので、問題ないようです。

vi hw.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from bottle import route, run

a = [
    '',
    'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
    'bb',
    'cc',
    'dd',
    'ee',
    'ff']

b = {
    'aa': 1,
    'bb': 2,
    'ccccccccccccccccccccccccccccccccccccccccc': 3333333333333333,
    'ddd': 'bbbb'}

# テスト用コード


@route('/hello')
def hello():
    """ テスト実装
    """
    print(a)
    print(b)
    return "Hello World!"


# テスト用起動
run(host='0.0.0.0', port=8080, debug=True, reloader=True)

3.3 文法チェック(flake8/tox)

flake8は複数のLintコマンドを統合したツールです。

修正前のhw.pyを通したところ、以下のように言われました。

$ flake8 hw.py
hw2.py:1:1: E902 IndentationError: unindent does not match any outer indentation level
hw2.py:5:75: E231 missing whitespace after ','
hw2.py:5:80: E501 line too long (100 > 79 characters)
hw2.py:5:80: E231 missing whitespace after ','
hw2.py:5:85: E231 missing whitespace after ','
hw2.py:5:90: E231 missing whitespace after ','
hw2.py:5:95: E231 missing whitespace after ','
hw2.py:7:13: E231 missing whitespace after ','
hw2.py:7:18: E231 missing whitespace after ':'
hw2.py:7:80: E501 line too long (98 > 79 characters)
hw2.py:9:1: E265 block comment should start with '# '
hw2.py:10:1: E302 expected 2 blank lines, found 1
hw2.py:13:1: W191 indentation contains tabs
hw2.py:14:10: E999 IndentationError: unindent does not match any outer indentation level

flake8をtox経由起動することもできます。以下がtoxを起動した際の出力です。

$ tox -e flake8
flake8 installed: flake8==3.5.0,flake8-colors==0.1.6,flake8-docstrings==1.3.0,flake8-import-order==0.17.1,flake8-polyfill==1.0.2,mccabe==0.6.1,pep8-naming==0.5.0,pycodestyle==2.3.1,pydocstyle==2.1.1,pyflakes==1.6.0,six==1.11.0,snowballstemmer==1.2.1
flake8 runtests: PYTHONHASHSEED='1882794980'
flake8 runtests: commands[0] | flake8 .
./hw.py:1:1: D100 Missing docstring in public module
./hw.py:22:1: E302 expected 2 blank lines, found 1
./hw.py:23:1: D400 First line should end with a period
./hw.py:23:1: D210 No whitespaces allowed surrounding docstring text
./hw.py:23:1: D200 One-line docstring should fit on one line with quotes

tox.iniは、

https://github.com/KenichiTanino/practice_the_script/blob/master/lint/tox.ini

に置いてあります。

4. 終わりに

開発には必須ですが、どうしても後回しにしがちなので、調べておきました。
有効に活用していきたいと思います。

-スクリプトのお勉強, 技術

執筆者:

関連記事

fastapi + SQLAlchemy で CRUDアプリケーションを作ってみる

概要 勉強用に、PythonでPostgresqlを制御しようと思います。の続きです。 前回でPostgreSQLと、データベース/テーブルまでは用意したので、今回はAPIを作成しようと思います。 実 …

Pythonからsvnしてみる

SVN: レガシーシステムの一つ。。 私の関わってるシステムでは、いまだにsvnレポジトリがあります。pythonで処理する必要性が生じましたが、そういえばどう処理していいもんか、完全に忘れました。 …

「Python3 メモ」 独自例外クラスからの値取得/変数の内容取得

忙しい。。 この時期でなぜか忙しく、ブログ書いてる暇ない。。のでメモ書き程度。そして、内容をよく忘れるやつ。。 python3の独自例外クラス 例外クラスからの値取得方法をいつも忘れます。ある関数or …

悪いほうが良い? でも限度があるよね。。

自分のその時の状態によって結論が変わる https://tech.nikkeibp.co.jp/atcl/nxt/column/18/00620/040900010/を見て書こうと思いました。 今やっ …

Djangoのurls.pyにはまった。。

けっこうハマった。。 Django 2.2.4の話。以下のエラーを修正するのに、とっても時間がかかった。 django.urls.exceptions.NoReverseMatch: Reverse …

google オプトアウト Click here to opt-out.