5

テストを自動化して、Python 2.xコードの本体に文字列インスタンスが含まれていない(Unicodeインスタンスのみ)ことを強制するにはどうすればよいですか?

例えば。

コード内からそれを行うことはできますか?

この機能を備えた静的分析ツールはありますか?

編集:

Python 2.5のアプリケーションでこれが欲しかったのですが、次の理由でこれは実際には不可能であることがわかりました。

  1. 2.5はサポートしていませんunicode_literals
  2. kwargsディクショナリキーをUnicodeオブジェクトにすることはできず、文字列のみにすることができます

だから私はそれがさまざまな理由であるとしても、それは不可能であるという答えを受け入れています:)

4

3 に答える 3

1

正直なところのPythonパーサーでコードを解析する必要があるように思えます。次に、パーサーが生成する AST を掘り下げて、文字列リテラルが含まれているかどうかを確認する必要があります。

Python には、すぐに使用できるパーサーが付属しているようです。このドキュメントから、このコードサンプルが機能するようになりました:

import parser
from token import tok_name

def checkForNonUnicode(codeString):
    return checkForNonUnicodeHelper(parser.suite(codeString).tolist())

def checkForNonUnicodeHelper(lst):
    returnValue = True
    nodeType = lst[0]
    if nodeType in tok_name and tok_name[nodeType] == 'STRING':
        stringValue = lst[1]
        if stringValue[0] != "u": # Kind of hacky. Does this always work?
            print "%s is not unicode!" % stringValue
            returnValue = False

    else:
        for subNode in [lst[n] for n in range(1, len(lst))]:
            if isinstance(subNode, list):
                returnValue = returnValue and checkForNonUnicodeHelper(subNode)

    return returnValue

print checkForNonUnicode("""
def foo():
    a = 'This should blow up!'
""")
print checkForNonUnicode("""
def bar():
    b = u'although this is ok.'
""")

印刷する

'This should blow up!' is not unicode!
False
True

現在、doc 文字列はユニコードではありませんが、許可する必要がfrom symbol import sym_nameあるため、クラスと関数の定義に使用するノード タイプを検索できる場所など、より複雑なことを行う必要がある場合があります。次に、単純な文字列である最初のサブノード、つまり割り当てなどの一部ではない最初のサブノードは、Unicode ではないことを許可する必要があります。

良い質問!

編集

ただの補足コメントです。便利なことに、parser.suite実際には python コードを評価しません。これは、命名エラーやインポート エラーを心配することなく、Python ファイルに対してこのパーサーを実行できることを意味します。たとえば、次のものmyObscureUtilityFile.pyが含まれているとします。

from ..obscure.relative.path import whatever

あなたはできる

checkForNonUnicode(open('/whoah/softlink/myObscureUtilityFile.py').read())
于 2010-10-28T21:22:22.063 に答える
1

すべての文字列が Unicodeであることを強制することはできません。from __future__ import unicode_literalsモジュール内であっても、バイト文字列b'...'は Python 3 と同じように として記述できます。

グローバルと同じ効果を得るために使用できるオプションがありました: コマンドライン オプション. ただし、基本的にすべてのスクリプトを壊したため、2.x シリーズの初期に放棄されました。unicode_literals-U

これの目的は何ですか?バイト文字列を廃止することは望ましくありません。それらは「悪い」ものではなく、Unicode 文字列は普遍的に「優れている」わけではありません。それらは 2 つの別個の動物であり、両方が必要になります。バイナリ ファイルやネットワーク サービスと通信するには、バイト文字列が必ず必要になります。

Python 3 に移行する準備をしたい場合、最善の策は、b'...'実際にバイトであることを意味するすべての文字u'...'列と、本質的に Unicode である文字列を記述することです。デフォルトの文字列'...'形式は、他のすべて、気にしない場所、および/または Python 3 がデフォルトの文字列型を変更するかどうかに使用できます。

于 2010-10-28T21:26:29.823 に答える
0

当社のSD ソース コード検索エンジン (SCSE)は、この結果を直接提供できます。

SCSE は、言語構造の一部を使用して大規模なファイル セット全体を非常に高速に検索する方法を提供し、正確なクエリを可能にし、誤検知を最小限に抑えます。Python を含むさまざまな言語を同時に処理します。GUI には、検索ヒットと、選択したヒットを含むファイルからの実際のテキストのページが表示されます。

ソース言語からの語彙情報をクエリの基礎として使用します。これは、さまざまな言語キーワードと、さまざまなコンテンツの言語要素に一致するパターン トークンで構成されます。SCSE は、その言語で使用できる語彙素のタイプを認識しています。一般的な識別子 (クエリ トークン I を使用) または正規表現に一致する識別子を検索できます。同様に、一般的な文字列 (「あらゆる種類の文字列リテラル」に対してクエリ トークン "S" を使用) または特定の種類の文字列 ("UnicodeStrings"、非 Unicode 文字列などを含む Python の場合) を検索できます。 "S" を構成する Python のもののセット)。

だから検索:

 'for' ... I=ij*

接頭辞が「ij」である識別子の近く (「...」) のキーワード「for」を検索し、すべてのヒットを表示します。(改行やコメントを含む言語固有の空白は無視されます。

簡単な検索:

  S

すべての文字列リテラルを検索します。多くの場合、これはかなり大きなセットです:-}

検索

 UnicodeStrings

字句的に Unicode 文字列 (u"...") として定義されているすべての文字列リテラルを検索します

必要なのは、UnicodeStrings ではないすべての文字列です。SCSE は、別の種類のヒットと重複する 1 つの種類のヒットを減算する "減算" 演算子を提供します。したがって、「ユニコードではない文字列」という質問は、次のように簡潔に表現されます。

  S-UnicodeStrings

表示されるすべてのヒットは、正確な質問である Unicode 文字列ではない文字列になります。

SCSE は、ヒットを記録できるようにロギング機能を提供します。コマンド ラインから SCSE を実行して、回答に対するスクリプト クエリを有効にすることができます。これをコマンドスクリプトに入れると、ツールが答えを直接提供します。

于 2010-11-01T01:10:03.973 に答える