Frage

Wie kann ich einen Test automatisieren, um durchzusetzen, dass ein Python 2.x -Code keine String -Instanzen (nur Unicode -Instanzen) enthält?

Z.B.

Kann ich es aus dem Code aus tun?

Gibt es ein statisches Analyse -Tool mit dieser Funktion?

Bearbeiten:

Ich wollte dies für eine Anwendung in Python 2.5, aber es stellt sich heraus, dass dies nicht wirklich möglich ist, weil:

  1. 2.5 unterstützt nicht unicode_literals
  2. KWARGS -Wörterbuchschlüssel können keine Unicode -Objekte sein, nur Zeichenfolgen

Ich akzeptiere die Antwort, die besagt, dass sie nicht möglich ist, obwohl sie aus verschiedenen Gründen ist :)

War es hilfreich?

Lösung

Das können Sie nicht durchsetzen alle Saiten sind Unicode; sogar mit from __future__ import unicode_literals In einem Modul können Byte -Saiten als geschrieben werden b'...', wie sie können in Python 3.

Dort war eine Option, die verwendet werden könnte, um den gleichen Effekt zu erzielen wie unicode_literals Weltweit: Die Befehlszeilenoption -U. Es wurde jedoch früh in der 2.x -Serie aufgegeben, weil es im Grunde jedes Drehbuch gebrochen wurde.

Was ist Ihr Zweck dafür? Es ist nicht wünschenswert, Byte -Saiten abzuschaffen. Sie sind nicht „schlecht“ und Unicode -Saiten sind nicht allgemein „besser“; Es sind zwei getrennte Tiere und Sie werden beide brauchen. BYTE Saiten werden sicherlich benötigt, um mit Binärdateien und Netzwerkdiensten zu sprechen.

Wenn Sie bereit sein möchten, zu Python 3 überzugehen, ist das beste Schreiben am besten zu schreiben b'...' Für alle Saiten, die du wirklich Bytes sein willst, und u'...' für die von Natur aus unikde sind. Die Standardzeichenfolge '...' Das Format kann für alles andere verwendet werden, Orte, an denen Sie sich nicht interessieren und/oder ob Python 3 den Standard -Zeichenfolge -Typ ändert.

Andere Tipps

Es scheint mir, als müssten Sie den Code wirklich mit einem ehrlichen Python -Parser analysieren. Anschließend müssen Sie durch das AST -Erstellen Ihres Parsers graben, um festzustellen, ob er String -Literale enthält.

Es sieht so aus, als ob Python mit einem Parser aus der Schachtel kommt. Davon Dokumentation Ich habe dieses Code -Beispiel funktioniert:

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.'
""")

das druckt aus

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

Jetzt sind DOC -Zeichenfolgen nicht ein Unicode, sollten aber erlaubt sein, also müssen Sie möglicherweise etwas komplizierteres tun wie from symbol import sym_name Wo Sie nachschlagen können, welche Knotentypen für Klassen- und Funktionsdefinitionen sind. Dann sollte der erste Unterknoten, der einfach eine Zeichenfolge ist, dh nicht Teil einer Aufgabe oder was auch immer, nicht ein Unicode sein dürfen.

Gute Frage!

Bearbeiten

Nur ein Follow -up -Kommentar. Bequem für Ihre Zwecke, parser.suite Bewertet Ihren Python -Code nicht wirklich. Dies bedeutet, dass Sie diesen Parser über Ihre Python -Dateien ausführen können, ohne sich Sorgen um Benennung oder Importfehler zu machen. Nehmen wir zum Beispiel an, Sie haben myObscureUtilityFile.py das beinhaltet

from ..obscure.relative.path import whatever

Du kannst

checkForNonUnicode(open('/whoah/softlink/myObscureUtilityFile.py').read())

Unser SD -Quellcode -Suchmaschine (SCSE) kann dieses Ergebnis direkt liefern.

Der SCSE bietet eine Möglichkeit, um in großen Dateien, die einige der Sprachstruktur unter Verwendung eines Teils der Sprachstruktur, extrem schnell suchen, um präzise Abfragen zu ermöglichen und falsch positive Ergebnisse zu minimieren. Es behandelt eine Vielzahl von Sprachen, auch gleichzeitig, einschließlich Python. Eine GUI zeigt Suchhits und eine Seite des tatsächlichen Textes aus der Datei mit einem ausgewählten Hit.

Es verwendet lexikalische Informationen aus den Quellsprachen als Grundlage für Abfragen, die aus verschiedenen Langauge -Schlüsselwörtern und Muster -Token bestehen, die unterschiedliche Inhalte Langauge -Elemente entsprechen. SCSE kennt die Arten von Lexemen, die in der Langauge verfügbar sind. Man kann nach einer generischen Kennung (mit Abfrage -Token I) oder einem Kennung suchen, der ein Regulatr -Ausdruck entspricht. Ähnlich kann bei der Suche nach einer generischen Zeichenfolge (unter Verwendung von Abfragen-Token "S" nach "jede Art von String-Literal") oder für eine bestimmte Art von String (für Python einschließlich "Unicodestrings", Nicht-Unicode-Zeichenfolgen usw. Die Set von Python -Dingen, die "s" umfassen).

Also eine Suche:

 'for' ... I=ij*

Findet das Schlüsselwort 'für' in der Nähe ("...") eine Kennung, deren Präfix "ij" ist und zeigt dir alle Treffer. (Sprachspezifische Whitespace einschließlich Zeilenpausen und Kommentare werden ignoriert.

Eine triviale Suche:

  S

Findet alle String -Literale. Dies ist oft ein ziemlich großes Set:-}

Eine Suche

 UnicodeStrings

Findet alle String -Literale, die lexikalisch als Unicode -Saiten definiert sind (u "...")

Was Sie wollen, sind alles Strings, die keine Unikodestringe sind. Der SCSE liefert einen "Subtrahieren" -Operator, der Hits einer Art subtrahiert, die Treffer einer anderen überlappen. Ihre Frage "Was Strings ist nicht unicode", wird präzise ausgedrückt als:

  S-UnicodeStrings

Alle gezeigten Treffer sind die Zeichenfolgen, die keine Unicode -Zeichenfolgen sind, Ihre genaue Frage.

Die SCSE bietet Protokollierungseinrichtungen, damit Sie Treffer aufnehmen können. Sie können SCSE aus einer Befehlszeile ausführen und eine Skriptabfrage für Ihre Antwort aktivieren. Wenn Sie dies in ein Befehlskript einfügen, wird Ihre Antwort direkt angeben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top