回答編集履歴

2

追記と真実

2017/03/05 17:29

投稿

sharow
sharow

スコア1149

test CHANGED
@@ -9,3 +9,57 @@
9
9
  ```
10
10
 
11
11
  のようにするとか
12
+
13
+
14
+
15
+ ----
16
+
17
+ 追記:
18
+
19
+ 質問タイトルから乖離した回答だったので、補足です。この方法はflake8の警告を消す方法ではなくて、文字列リテラルを避ける方法です。以下の理由は私個人のもので、一般的ではありません。
20
+
21
+
22
+
23
+ ### 文字列リテラルを避けたい
24
+
25
+ どんな言語でも文字列リテラルの中身が正しいかどうかは検証できないので、もし簡単に文字列リテラルの使用を避けられるのなら避ける、というのが私個人のやり方です。名前空間をもつオブジェクトが文字列リテラルでなくて`__name__`で参照されれば、flake8でも検証できます。ただ、flake8で警告が抑止されるのは結果であって、そのために文字列リテラルを避けてるのではありません。flake8を使わなくとも文字列リテラルはなるべく避ける、それだけです(例えば可能な場合はdictよりもnamedtupleを使う、など)。
26
+
27
+
28
+
29
+ ### importに対するnoqaを避けたい
30
+
31
+ もう一つの理由はF401を抑止する#noqaがイケてないと思っているからです。他の#noqaはその行に対する警告を抑止します。抑止したい警告はその行にあるので、もしその行を編集して、警告が出ない状態になれば#noqaコメントを消します。#noqaが抑止している警告はその行に依存してる、と言うことができます。視覚的にはとても近いので普通は気付けます。
32
+
33
+
34
+
35
+ 一方、importのF401に対する#noqaはソースコードのその行以下全部に依存しています。ソースコードに変更が入ってF401警告が出ない状態になったときに、import部分まで戻って#noqaを消す、という手順になります。これは視覚の範囲外であることが多いので、編集している人の頭に頼ったやりかたです。時間が空いたり、チームで作業していたりしてこれを忘れると、1.不要になった#noqaを消し忘れる、2.本当に使っていないのに#noqaで抑止されている、の2つケースに陥ります。
36
+
37
+
38
+
39
+ そもそも、importに対する#noqaをやらなければこんなことは考えなくていい、そしてimportに対する#noqaが必要になる理由は、文字列リテラルを列挙する形で`__all__`を定義しているからだ、というのが私の回答の背景でした(過去形)。
40
+
41
+
42
+
43
+
44
+
45
+ ## 真実
46
+
47
+ ここまで書いておいて、**こんな結末はないだろ**という感じもしますが、質問者さんの`__all__`の値は「文字列のタプル」ではなくてただの「文字列」になっています。
48
+
49
+
50
+
51
+ ```python
52
+
53
+ __all__ = ("ModuleA") # -> == "ABC" 誤
54
+
55
+ __all__ = ("ModuleA",) # -> 正
56
+
57
+ ```
58
+
59
+
60
+
61
+ ちゃんとタプルかリストにすればflake8(ver 3.3.0)はimportされたものが使われている、と認識してくれるようです。
62
+
63
+
64
+
65
+ これを最初に指摘できなくてごめんなさい・・・。

1

修正

2017/03/05 17:29

投稿

sharow
sharow

スコア1149

test CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ```python
6
6
 
7
- __all__ = (ModuleA.__name__)
7
+ __all__ = [ModuleA.__name__]
8
8
 
9
9
  ```
10
10