Как найти не-ascii байт в моем коде? - PullRequest
1 голос
/ 17 сентября 2011

При создании приложения App Engine я неожиданно столкнулся с ошибкой, которая показывает каждую пару запросов:

    run_wsgi_app(application)
  File "/home/ubuntu/Programs/google/google_appengine/google/appengine/ext/webapp/util.py", line 98, in run_wsgi_app
    run_bare_wsgi_app(add_wsgi_middleware(application))
  File "/home/ubuntu/Programs/google/google_appengine/google/appengine/ext/webapp/util.py", line 118, in run_bare_wsgi_app
    for data in result:
  File "/home/ubuntu/Programs/google/google_appengine/google/appengine/ext/appstats/recording.py", line 897, in appstats_wsgi_wrapper
    result = app(environ, appstats_start_response)
  File "/home/ubuntu/Programs/google/google_appengine/google/appengine/ext/webapp/_webapp25.py", line 717, in __call__
    handler.handle_exception(e, self.__debug)
  File "/home/ubuntu/Programs/google/google_appengine/google/appengine/ext/webapp/_webapp25.py", line 463, in handle_exception
    self.error(500)
  File "/home/ubuntu/Programs/google/google_appengine/google/appengine/ext/webapp/_webapp25.py", line 436, in error
    self.response.clear()
  File "/home/ubuntu/Programs/google/google_appengine/google/appengine/ext/webapp/_webapp25.py", line 288, in clear
    self.out.seek(0)
  File "/usr/lib/python2.7/StringIO.py", line 106, in seek
    self.buf += ''.join(self.buflist)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd7 in position 208: ordinal not in range(128)

Я действительно понятия не имею, где это может быть, это происходит только тогда, когда я использую определенную функцию, но невозможно отследить всю имеющуюся у меня строку. Возможно, этот байт является символом типа ' " [ ] и т. Д., Но только на другом языке

Как мне найти этот байт и, возможно, другие?

Я использую GAE с Python 2.7 в Ubuntu 11.04

Спасибо.

* ** обновлен 1014 *

Это код, который я использовал в итоге: из кодеков импорт BOM_UTF8 из os import listdir, путь p = "путь"

def loopPath(p, times=0):
    for fname in listdir(p):
        filePath = path.join(p, fname)
        if path.isdir(filePath):
            return loopPath(filePath, times+1)

        if fname.split('.', 1)[1] != 'py': continue

        f = open(filePath, 'r')
        ln = 0
        for line in f:
            #print line[:3] == BOM_UTF8
            if not ln and line[:3] == BOM_UTF8:
                line = line[4:]
            col = 0
            for c in list(line):
                if ord(c) > 128:
                    raise Exception('Found "'+line[c]+'" line %d column %d in %s' % (ln+1, col, filePath))
                col += 1
            ln += 1
        f.close()

loopPath(p)

Ответы [ 5 ]

4 голосов
/ 17 сентября 2011

Просто проходит через каждый символ в каждой строке кода.Примерно так:

# -*- coding: utf-8 -*-
import sys

data = open(sys.argv[1])
line = 0
for l in data:
    line += 1
    char = 0
    for s in list(unicode(l,'utf-8')):
        char += 1
        try:
            s.encode('ascii')
        except:
            print 'Non ASCII character at line:%s char:%s' % (line,char)
1 голос
/ 17 сентября 2011

Когда я перевел файлы UTF-8 на латиницу 1 LaTeX, у меня были похожие проблемы. Я хотел получить список всех злых символов Юникода в моих файлах.

Возможно, вам нужно еще больше, но я использовал это:

UNICODE_ERRORS = {}

def fortex(exc):
    import unicodedata, exceptions
    global UNICODE_ERRORS
    if not isinstance(exc, exceptions.UnicodeEncodeError):
        raise TypeError("don't know how to handle %r" % exc)
    l = []
    print >>sys.stderr, "   UNICODE:", repr(exc.object[max(0,exc.start-20):exc.end+20])
    for c in exc.object[exc.start:exc.end]:
        uname = unicodedata.name(c, u"0x%x" % ord(c))
        l.append(uname)
        key = repr(c)
        if not UNICODE_ERRORS.has_key(key): UNICODE_ERRORS[key] = [ 1, uname ]
        else: UNICODE_ERRORS[key][0] += 1
    return (u"\\gpTastatur{%s}" % u", ".join(l), exc.end)

def main():    
    codecs.register_error("fortex", fortex)
    ...
    fileout = codecs.open(filepath, 'w', DEFAULT_CHARSET, 'fortex')
    ...
    print UNICODE_ERROS

полезно

Вот соответствующая выдержка из документа Python:

codecs.register_error (имя, обработчик ошибок) Зарегистрируйте функцию обработки ошибок error_handler под именем name. error_handler будет вызываться во время кодирования и декодирования в случае ошибки, когда в качестве параметра ошибок указано имя.

Для кодирования error_handler будет вызываться с экземпляром UnicodeEncodeError, который содержит информацию о местонахождении ошибки. Обработчик ошибок должен либо вызвать это, либо другое исключение, либо вернуть кортеж с заменой на некодируемую часть ввода и позицию, в которой кодирование должно продолжаться. Кодировщик закодирует замену и продолжит кодирование исходного ввода в указанной позиции. Отрицательные значения позиции будут обрабатываться как относящиеся к концу входной строки. Если полученная позиция выходит за границы, будет возникать ошибка IndexError.

0 голосов
/ 12 ноября 2012

Этот скрипт Python выдает символ оскорбления и его индекс в тексте, когда этот текст рассматривается в виде одной строки:

[(index, char) for (index, char) in enumerate(open('myfile').read()) if ord(char) > 127]
0 голосов
/ 05 ноября 2012

Вы можете использовать команду:

grep --color='auto' -P -n "[\x80-\xFF]" file.xml

Это даст вам номер строки и выделит символы не-ascii красным цветом.

Скопировано из Как выполнить grep для всех не-ASCII символов в UNIX . Ответ Фредрика хороший, но не совсем правильный, поскольку он также находит символы ASCII, которые не являются буквенно-цифровыми.

0 голосов
/ 17 сентября 2011

Это должно перечислить оскорбительные строки:

grep -v [:alnum:] dodgy_file


$ cat test
/home/ubuntu/tmp/SO/c.awk

$ cat test2
/home/ubuntu/tmp/SO/c.awk
な

$ grep -v [:alnum:] test

$ grep -v [:alnum:] test2
な
...