スクリプトのお勉強 技術

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

投稿日: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. 終わりに

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

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

執筆者:

関連記事

Python(prophet)で体重予測

最近ダイエットしていて、少しだけ成果が出たので、グラフ表示しようと思ってました。そのついでにこれからの予測もしてみようということで、過去のデータを集め、グラフ表示してみます。 google Colab …

Python Django REST Framework(REST API)の作成

1.はじめに 今回は、pythonの「Django」というWebアプリケーションフレームワークを使用し、REST APIを作成します。作成するREST APIは、これから作るであろう、Nuxt.jsか …

Python3/ある日付から日付までの月/日/時間ごとの時刻を算出する

小ネタです。 要するに、時刻A と 時刻B を指定したときの、各時間間隔での時刻取得したかったです。 当初はdateutilを使う方法でなく、自前で実装しようと思ったのですが、面倒なことに気づきました …

seaborn + Pandas + Python によるグラフ描画(その1: 準備編)

グラフ描画してみよう 今現在の仕事で、グラフ描画する可能性があるので、少し練習してみようと思います。 題材について 突然ですが、私は確定拠出型年金に加入しています。証券会社はSBI証券 にしています。 …

Nuxt.js – CRUDアプリケーションのフォーム/一覧を作成する

前回で作ったAPIのフロントエンドアプリケーションを作ろうと思います。 どういうアプリ? サンプルとして作ったAPIが住所録的だったので、住所録を作りました。 以下の機能があります。 登録(確認付き) …