Ticket #37027

AttributeError: 'NoneType' object has no attribute 'label'

Date d'ouverture: 2017-02-27 13:08 Dernière mise à jour: 2017-03-06 09:24

Rapporteur:
Propriétaire:
État:
Ouvert [Owner assigned]
Composant:
(Aucun)
Jalon:
(Aucun)
Priorité:
5 - moyen
Sévérité:
5 - moyen
Résolution:
Aucun
Fichier:
2

Détails

TicketSubmitPolicy-0.13-py2.4に不具合と思われる事象発生のため起票いたします。 「チケット登録」や「チケットを見る」をクリックすると不定期で発生する。 apachectl gracefulを実施すると発生頻度が少なくなる。

ログは以下の通り

2017-02-27 12:48:04,978 Trac[main] ERROR: Internal Server Error:
Traceback (most recent call last):
  File "/usr/lib/python2.4/site-packages/trac/web/main.py", line 511, in _dispatch_request
    dispatcher.dispatch(req)
  File "/usr/lib/python2.4/site-packages/trac/web/main.py", line 258, in dispatch
    content_type)
  File "/usr/lib/python2.4/site-packages/trac/web/chrome.py", line 840, in render_template
    stream |= self._filter_stream(req, method, filename, stream, data)
  File "build/bdist.linux-i686/egg/genshi/core.py", line 132, in __or__
  File "/usr/lib/python2.4/site-packages/trac/web/chrome.py", line 991, in inner
    data)
  File "build/bdist.linux-i686/egg/ticketsubmitpolicy/ticketsubmitpolicy.py", line 167, in filter_stream
  File "build/bdist.linux-i686/egg/ticketsubmitpolicy/ticketsubmitpolicy.py", line 139, in parse
AttributeError: 'NoneType' object has no attribute 'label'

Ticket History (3/19 Histories)

2017-02-27 13:08 Updated by: kmtsnmy
  • New Ticket "Internal Server Error" created
2017-02-27 13:25 Updated by: jun66j5
  • Details Updated
Commentaire

trac.ini に設定している [ticket-submit-policy] の内容が正しくないように見えます。その内容も記述していただけますか?

2017-02-27 13:30 Updated by: kmtsnmy
Commentaire
(This comment has been deleted)
2017-02-27 13:32 Updated by: kmtsnmy
Commentaire

trac.iniは以下を設定しています。 これはtrac管理画面の「サブミットポリシー」で設定した結果、自動的にiniにセットされたようで直接編集したものではありません。

[ticket-submit-policy]
policy1.condition = status is accepted
policy1.readonly = summary, shokuban, shimei, s_assy, nozu, inflink, memo
policy2.condition = type is 報告
policy2.readonly = owner, description, type
policy2.requires = summary, shokuban, shimei, s_assy, nozu

2017-02-28 13:16 Updated by: jun66j5
Commentaire

何度か試してみましたが、再現しません。またコードから見えても再現しそうにありません。

https://trac-hacks.org/wiki/TicketSubmitPolicyPlugin を元に日本語化したものなのは確かですが、オリジナルのほうには該当部分にあたるコードはなく、また、日本語化の作業分のログが完全にないため、修正内容の意味がまったく追跡できません。

とりあえず、以下のように変更してみて、再発時に再度スタックトレースを送って頂けますか。

diff --git a/ticketsubmitpolicy/ticketsubmitpolicy.py b/ticketsubmitpolicy/ticketsubmitpolicy.py
index cbb1381ca..8f1a57ccd 100644
--- a/ticketsubmitpolicy/ticketsubmitpolicy.py
+++ b/ticketsubmitpolicy/ticketsubmitpolicy.py
@@ -136,7 +136,7 @@ class TicketSubmitPolicyPlugin(Component):
             if not policies[name].has_key('actions'):
                 policies[name]['actions'] = []
             args = parse_list(section[key])
-            policies[name]['actions'].append({'name': action, 'args': args, 'label': policy_dict.get(action).label()})
+            policies[name]['actions'].append({'name': action, 'args': args, 'label': policy_dict[action].label()})

         for policy in policies:
             # empty condition ==> true

もしくはこれを使う事自体を放棄して、オリジナル https://trac-hacks.org/wiki/TicketSubmitPolicyPlugin のほうを試してみるのが妥当かも知れません。

2017-02-28 14:05 Updated by: kmtsnmy
Commentaire

ticketsubmitpolicy.pyを指示通り変更、コンパイルして試してみましたがそもそものポリシーが適用されなくなりました。

具体的には、ステータスがacceptedの状態にもかかわらず入力項目が読み取り専用ではなくなります。

オリジナルも過去に試したのですが、上記と同様にポリシーが効かなくなるため0.13を利用させてもらったという経緯があります。

2017-02-28 14:34 Updated by: jun66j5
Commentaire

いまの修正だけで動かなくなるとは到底思えないのですが…。手元 (添付 20170228T143121.png) では summary が readonly になっています。

2017-02-28 14:45 Updated by: kmtsnmy
Commentaire

修正に間違いはないはずなのですが、こちらの環境ではどの項目もreadonlyとなりません。

            if not policies[name].has_key('actions'):
                policies[name]['actions'] = []
            args = parse_list(section[key])
#            policies[name]['actions'].append({'name': action, 'args': args, 'label': policy_dict.get(action).label()})
#2017.2.28
             policies[name]['actions'].append({'name': action, 'args': args, 'label': policy_dict[action].label()})


        for policy in policies:
            # empty condition ==> true
2017-02-28 15:42 Updated by: jun66j5
Commentaire
            if not policies[name].has_key('actions'):
                policies[name]['actions'] = []
            args = parse_list(section[key])
#            policies[name]['actions'].append({'name': action, 'args': args, 'label': policy_dict.get(action).label()})
#2017.2.28
             policies[name]['actions'].append({'name': action, 'args': args, 'label': policy_dict[action].label()})
            ^ インデントずれていますが、これだと syntax error が吐かれているはずです。ここに貼り付ける際のミスでしょうか

        for policy in policies:
            # empty condition ==> true

svn revert - R . を実行して変更を破棄したら、添付ファイルの r821.diff を使って patch -p1 < r821.diff を実行してください。適用したら svn diff で変更が妥当か確認してください。

2017-02-28 15:59 Updated by: kmtsnmy
Commentaire

申し訳ありません。

こちらのミスがありました。

この状態で動作させ、再現しましたら再度ログを記載いたします。

2017-03-02 13:25 Updated by: kmtsnmy
Commentaire

アドバイスいただいたソースに変更後、再現しました。

ログを添付します。(が、前と出力内容は同様です。)

2017-03-02 13:21:03,824 Trac[main] ERROR: Internal Server Error:
Traceback (most recent call last):
  File "/usr/lib/python2.4/site-packages/trac/web/main.py", line 511, in _dispatch_request
    dispatcher.dispatch(req)
  File "/usr/lib/python2.4/site-packages/trac/web/main.py", line 258, in dispatch
    content_type)
  File "/usr/lib/python2.4/site-packages/trac/web/chrome.py", line 840, in render_template
    stream |= self._filter_stream(req, method, filename, stream, data)
  File "build/bdist.linux-i686/egg/genshi/core.py", line 132, in __or__
  File "/usr/lib/python2.4/site-packages/trac/web/chrome.py", line 991, in inner
    data)
  File "build/bdist.linux-i686/egg/ticketsubmitpolicy/ticketsubmitpolicy.py", line 167, in filter_stream
  File "build/bdist.linux-i686/egg/ticketsubmitpolicy/ticketsubmitpolicy.py", line 139, in parse
AttributeError: 'NoneType' object has no attribute 'label'

2017-03-02 14:49 Updated by: jun66j5
Commentaire

パッチでは以下のように変更しました。

-policy_dict.get(action).label()
+policy_dict[action].label()
ここで相変わらず AttributeError が上がってくるということは policy_dict[action]None であるということなのですが、policy_dictself.policy_dict() の戻り値で、
 94         policies = {}
 95         policy_dict = self.policy_dict()
こういう実装になっています。dict に入っている値が None になっているかどうかで言えば、ここでは self.policies のリストから None が出てくる必要があります。しかし policy.name() をキーにしているので None であれば、そもそもここでエラーを吐くはずです。
 52     def policy_dict(self):
 53         retval = {}
 54         for policy in self.policies:
 55             retval[policy.name()] = policy
 56         return retval
要は、そのパッチを当てたソースはちゃんとインストールできていますか。

単に policy_dictaction の値が確認したいだけなので、以下のパッチに差し替えます。これで再現したら、その変数もログに出力されるはずですので、それも投稿してください。

適用できているかは、チケットページなどを参照した際に 2017-03-02 14:47:26 というログが出力されるはずですので、それでチェックしてください。

diff --git a/ticketsubmitpolicy/ticketsubmitpolicy.py b/ticketsubmitpolicy/ticketsubmitpolicy.py
index cbb1381ca..aaa22d2e8 100644
--- a/ticketsubmitpolicy/ticketsubmitpolicy.py
+++ b/ticketsubmitpolicy/ticketsubmitpolicy.py
@@ -53,6 +53,7 @@ class TicketSubmitPolicyPlugin(Component):
         retval = {}
         for policy in self.policies:
             retval[policy.name()] = policy
+        self.log.warning('policy_dict: %r', retval)
         return retval

     def save(self, policies):
@@ -85,6 +86,7 @@ class TicketSubmitPolicyPlugin(Component):
         """
         parse the [ticket-submit-policy] section of the config for policy rules
         """
+        self.log.warning('2017-03-02 14:47:26')

         section = dict([i for i in self.config.options('ticket-submit-policy')])

@@ -136,7 +138,8 @@ class TicketSubmitPolicyPlugin(Component):
             if not policies[name].has_key('actions'):
                 policies[name]['actions'] = []
             args = parse_list(section[key])
-            policies[name]['actions'].append({'name': action, 'args': args, 'label': policy_dict.get(action).label()})
+            self.log.warning('policy_dict: %r, action: %r', policy_dict, action)
+            policies[name]['actions'].append({'name': action, 'args': args, 'label': policy_dict[action].label()})

         for policy in policies:
             # empty condition ==> true

2017-03-03 10:29 Updated by: kmtsnmy
Commentaire

いただいた情報を適用し再現しました。以下にログを添付いたします。

「2017-03-02 14:47:26 」の情報が出力されているため間違いないかと思いますが、trac、pythonについてまだ勉強中で不慣れなもので 何か間違いあるようでしたら指摘よろしくお願いします。

2017-03-03 10:23:26,621 Trac[ticketsubmitpolicy] WARNING: 2017-03-02 14:47:26
2017-03-03 10:23:26,621 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.TicketExcludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'requires': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}
2017-03-03 10:23:26,621 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.TicketExcludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'requires': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}, action: u'readonly'
2017-03-03 10:23:26,622 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.TicketExcludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'requires': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}, action: u'readonly'
2017-03-03 10:23:26,622 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.Ticket
Excludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'require
s': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}, action: u'requires'
2017-03-03 10:23:31,152 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.Ticket
Excludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'require
s': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}
2017-03-03 10:23:31,153 Trac[ticketsubmitpolicy] WARNING: 2017-03-02 14:47:26
2017-03-03 10:23:31,153 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.Ticket
Excludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'require
s': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}
2017-03-03 10:23:31,153 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.Ticket
Excludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'require
s': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}, action: u'readonly'
2017-03-03 10:23:31,154 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.Ticket
Excludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'require
s': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}, action: u'readonly'
2017-03-03 10:23:31,154 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.Ticket
Excludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'require
s': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}, action: u'requires'
2017-03-03 10:23:32,947 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.Ticket
Excludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'require
s': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}
2017-03-03 10:23:32,947 Trac[ticketsubmitpolicy] WARNING: 2017-03-02 14:47:26
2017-03-03 10:23:32,948 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.Ticket
Excludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'require
s': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}
2017-03-03 10:23:32,948 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.Ticket
Excludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'require
s': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}, action: u'readonly'
2017-03-03 10:23:32,948 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.Ticket
Excludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'require
s': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}, action: u'readonly'
2017-03-03 10:23:32,948 Trac[ticketsubmitpolicy] WARNING: policy_dict: {'excludes': <ticketsubmitpolicy.policies.Ticket
Excludes object at 0x1172372c>, 'readonly': <ticketsubmitpolicy.policies.TicketReadOnly object at 0x117238cc>, 'require
s': <ticketsubmitpolicy.policies.TicketRequires object at 0x11723a4c>}, action: u'requires'
2017-03-03 10:23:59,335 Trac[main] ERROR: Internal Server Error:
Traceback (most recent call last):
  File "/usr/lib/python2.4/site-packages/trac/web/main.py", line 511, in _dispatch_request
    dispatcher.dispatch(req)
  File "/usr/lib/python2.4/site-packages/trac/web/main.py", line 258, in dispatch
    content_type)
  File "/usr/lib/python2.4/site-packages/trac/web/chrome.py", line 840, in render_template
    stream |= self._filter_stream(req, method, filename, stream, data)
  File "build/bdist.linux-i686/egg/genshi/core.py", line 132, in __or__
  File "/usr/lib/python2.4/site-packages/trac/web/chrome.py", line 991, in inner
    data)
  File "build/bdist.linux-i686/egg/ticketsubmitpolicy/ticketsubmitpolicy.py", line 167, in filter_stream
  File "build/bdist.linux-i686/egg/ticketsubmitpolicy/ticketsubmitpolicy.py", line 139, in parse
AttributeError: 'NoneType' object has no attribute 'label'
2017-03-03 12:07 Updated by: jun66j5
  • Summary Updated
  • Type Update from Bogues to Demande de soutien
Commentaire

例外が起きた場所よりも前の箇所にログ出力のコードを足したので同じ例外が起きた場合、その行数が変わるはずであるにも関わらず、変わっていません。

  File "build/bdist.linux-i686/egg/ticketsubmitpolicy/ticketsubmitpolicy.py", line 139, in parse
AttributeError: 'NoneType' object has no attribute 'label'
ログ追加したモジュールと件の例外を起こしているモジュールは別の場所にあり、別々にロードされていると考えます。 そもそも件の例外ではソースの一部が表示されていません。(139行目のコードが出力されるはずが見えない)

そもそもインストール手順が間違っているのではないでしょうか。

  • どのようにインストールしたのか教えてください。
  • インストールした TicketSubmitPolicy-0.13-py2.4.egg (/usr/lib/python2.4/site-packages/ 配下?) を完全に削除してください。
  • egg-cache 上に展開されているものがあれば、それも完全に捨ててください。
  • その上で再インストールしてください。ソースディレクトリ上にある build, dist ディレクトリはインストール実行前に削除してください。
  • インストール後、TRAC_ADMIN 権限ありのユーザで /about ページにアクセスして、「インストールしているプラグイン」にリストされているか、その場所は期待に沿っているかを確認してください。
2017-03-03 13:43 Updated by: kmtsnmy
Commentaire

お手数おかけして申し訳ありません。

インストールは以下のようにして実施しております。

・既存のプラグインをプロジェクトから削除 ・apachectl graceful

・ダウンロード svn co http://svn.sourceforge.jp/svnroot/shibuya-trac/plugins/ticketsubmitpolicy/trunk

・指示があった通りticketsubmitpolicy.pyを修正

・コンパイル python setup.py bdist_egg

・/var/trac/project/xxx/trac/plugins/配下にeggをコピー ※プロジェクト単位でプラグインを動作させています。

apachectl graceful

以下は具体的に教えていただいてよろしいでしょうか。 •egg-cache 上に展開されているものがあれば、それも完全に捨ててください。

2017-03-04 23:58 Updated by: jun66j5
Commentaire

/var/trac/project/xxx/trac/plugins/配下にeggをコピー ※プロジェクト単位でプラグインを動作させています。

ここがおかしいです。これはすべてのプロジェクトにコピーしているんでしょうか。

Apache の設定はどのようにしてありますか。mod_wsgi か mod_python で TRAC_ENV_PARENT_DIR または trac.env_parent_dir を設定して複数プロジェクトにアクセスできるようにしてあると推測しています。が、この場合に、Trac プロジェクトごとに python プロセスが生成されるのではないため、egg ファイルを投入したプロジェクト以外からもそのプラグインはロードされています。

複数の Trac プロジェクトの plugins ディレクトリに同じでないプラグインが配置してあると妙なことが起きるはずです。

こういう場合は、プロジェクトにある plugins ディレクトリは使わずに、プラグインを配置するディレクトリを用意して [inherit] plugins_dir オプションに指定するほうがよいです。([inherit] file を使っていれば、そのファイルにだけ指定するようにもできます)

これとは違う状況であれば、Apache の設定を教えてください。

p.s. 謝罪は不要です

2017-03-06 09:24 Updated by: kmtsnmy
Commentaire

ご推察の通りです。

trac.env_parent_dirを設定してプロジェクト単位にて設定しております。

が、pythonのプロセスは生成されないとのこと、今回のエラーはこちらの環境に依存して発生しているということですね。

プラグインディレクトリの配置変更を検討いたします。 ありがとうございました。

Attachment File List

Modifier

Please login to add comment to this ticket » Connexion