Python 3 エンジニア認定実践試験対策 (5) - Flake8



### Flake8とは
- **目的**: Flake8は、Pythonコードの静的解析を行うコマンドラインツールで、PEP8スタイルガイドに基づいてコードの品質をチェックします。文法エラーや潜在的なバグ、コードの複雑さを検出します。

- **構成**: Flake8は以下の3つのツールで構成されています。
  - **pycodestyle**: PEP8に準拠しているかをチェックします。
  - **Pyflakes**: 潜在的なバグを検出します（フレーク＝小さな塊＝不具合箇所の意）。
  - **McCabe**: コードの複雑さを測定します
    - 複雑度を表すマッケイブ指標が由来。
    - デフォルトでは無効化されているため、複雑度を指定するオプションを指定すると有効化されます。

### Flake8のインストール
```bash
$ pip install flake8
```

### 静的コードチェックの実行
```bash
$ flake8 <チェック対象ファイル名>
```

### エラーコードの確認
Flake8が出力するエラーコードの詳細は、公式ドキュメントで確認できます。
- [Flake8エラーコード一覧](https://flake8.pycqa.org/en/latest/user/error-codes.html)

エラーコードの先頭文字で、どのツールがエラーを検出したかを判別できます。
- `E/W`: pycodestyle
- `F`: Pyflakes
- `C`: McCabe

### チェック対象からの除外
特定のエラーを無視したい場合、以下の2つの方法があります。
1. ソースコード内にインラインコメントを追加する:
   ```python
   # noqa: E501
   ```
   `noqa`は「No Quality Assurance」の略です。
   
2. Flake8実行時に`--ignore`オプションを使用する:
   ※次項を参照

### 静的コードチェックのカスタマイズ
Flake8のチェック内容は、コマンドラインオプションや設定ファイルを使用してカスタマイズできます。主なオプションは以下の通りです。
- `ignore`: 特定のエラーを無視する
- `exclude`: チェック対象から特定のファイルやディレクトリを除外する
- `max-line-length`: 1行の最大文字数を設定する
- `max-complexity`: コードの複雑度の閾値を設定する

#### コマンドラインでのオプション指定例
- 特定のエラーを無視する:
  フルコード指定だけでなく、前方一致方式での文字列検索でヒットさせることも可能です。
  ```bash
  $ flake8 --ignore=E203,E501
  ```
- 除外するファイルやディレクトリを指定する:
  ```bash
  $ flake8 --exclude=.env,build
  ```
- 1行の最大文字数を変更する:
  ```bash
  $ flake8 --max-line-length=100
  ```
- 複雑度の閾値を変更する:
  閾値10以上だと複雑度が高いと見なされます。
  ```bash
  $ flake8 --max-complexity=10
  ```

#### 設定ファイルの使用
設定ファイルにオプションを定義することもできます。以下は設定ファイルの例です。
```
[flake8]
ignore = E203, E501
exclude = .venv, build
max-line-length = 88
max-complexity = 10
```
設定ファイルはプロジェクトディレクトリ直下に以下のいずれかの名前で配置します。
- `setup.cfg`
- `tox.ini`
- `.flake8`
設定ファイルとコマンドラインでオプションが重複する場合、コマンドラインオプションが優先されます。

### Flake8のプラグイン
Flake8にプラグインを追加することで、チェック機能を拡張できます。主なプラグインには以下があります。
- **flake8-import-order**: import文の順序をチェック
- **pep8-naming**: PEP8命名規約に準拠しているかをチェック
- **flake8-commas**: カンマの位置をチェック
- **flake8-quotes**: クォートの使用をチェック
- **flake8-docstrings**: docstringの有無や書式をチェック
- **flake8-print**: テスト用のprint()関数の不適切な使用をチェック

# Python コーディング規約 (Flake8) - 確認問題


1. Flake8の主な目的は何ですか？
   a) Pythonのバージョン管理  
   b) Pythonコードの静的解析  
   c) Pythonプログラムの実行  
   d) Pythonのパッケージ管理  

2. Flake8はどのようなツールで構成されていますか？
   a) 1つのツールのみ  
   b) 2つのツール  
   c) 3つのツール  
   d) 4つのツール  

3. `pycodestyle`はFlake8のどの機能を担当していますか？
   a) コードの複雑さを測定する  
   b) PEP8準拠のチェック  
   c) 潜在的なバグの検出  
   d) コードの実行速度を測定  

4. Flake8をインストールするためのコマンドは何ですか？
   a) `pip install flake8`  
   b) `pip install flake`  
   c) `install flake8`  
   d) `pip get flake8`  

5. Flake8のエラーコードの先頭文字が`F`の場合、どのツールがエラーを検出したことを示していますか？
   a) pycodestyle  
   b) Pyflakes  
   c) McCabe  
   d) None  

6. 特定のエラーを無視するために、ソースコード内に追加するコメントは何ですか？
   a) `# ignore: E501`  
   b) `# skip: E501`  
   c) `# noqa: E501`  
   d) `# exclude: E501`  

7. Flake8の実行時に特定のファイルやディレクトリを除外するためのオプションは何ですか？
   a) `--ignore`  
   b) `--exclude`  
   c) `--skip`  
   d) `--omit`  

8. Flake8の設定ファイルにおいて、1行の最大文字数を設定するオプションは何ですか？
   a) `max-length`  
   b) `max-line-length`  
   c) `line-length`  
   d) `max-line`  

9. Flake8の複雑度を測定するツールは何ですか？
   a) pycodestyle  
   b) Pyflakes  
   c) McCabe  
   d) None  

10. Flake8の設定ファイルをプロジェクトディレクトリに配置する際のファイル名として正しいものはどれですか？
    a) `flake8.cfg`  
    b) `setup.cfg`  
    c) `config.ini`  
    d) `flake8.ini`  

11. Flake8のプラグインを追加することで何が可能になりますか？
    a) コードの実行速度を向上させる  
    b) チェック機能を拡張する  
    c) コードの自動生成を行う  
    d) バージョン管理を行う  

12. `--max-complexity`オプションを使用する目的は何ですか？
    a) コードの行数を制限する  
    b) コードの複雑度の閾値を設定する  
    c) エラーを無視する  
    d) 特定のファイルを除外する  

13. Flake8のエラーコードの先頭文字が`C`の場合、どのツールがエラーを検出したことを示していますか？
    a) pycodestyle  
    b) Pyflakes  
    c) McCabe  
    d) None  

14. Flake8の実行時に、特定のエラーを無視するためのコマンドはどれですか？
    a) `$ flake8 --exclude=E501`  
    b) `$ flake8 --ignore=E501`  
    c) `$ flake8 --skip=E501`  
    d) `$ flake8 --omit=E501`  

15. Flake8のプラグインの一例として、どれが正しいですか？
    a) flake8-formatter  
    b) flake8-import-order  
    c) flake8-optimizer  
    d) flake8-analyzer  

解答:
1. b  
2. c  
3. b  
4. a  
5. b  
6. c  
7. b  
8. b  
9. c  
10. b  
11. b  
12. b  
13. c  
14. b  
15. b