Configparser иногда возвращает пустой результат - PullRequest
4 голосов
/ 16 апреля 2020

Я читаю конфигурации из INI-файла, используя Python configparser. 95% времени работает отлично. Без каких-либо изменений в INI-файле (например, в середине регрессионного теста) configparser начнет возвращать пустые результаты, а затем, конечно, будет иметь ключевые ошибки при поиске вложенных конфигов.

Это говорит о том, что это не проблема с INI-файлом, так как он не меняется, а также потому, что это происходит иногда. Как только проблема возникает, она продолжает происходить во всех вызовах парсера конфигурации, пока я не убью программу и не перезапущу ее.

Я читаю конфигурацию так:

try:
    path = os.path.dirname(os.path.realpath(__file__))
    kml_ini = '/'.join([path, 'kml.ini'])
    config = configparser.ConfigParser()
    config.read(kml_ini)
    db_conn_returnable = config['database']['db_connection'].strip()
except Exception as e:
    print(e)        
    traceback.print_exc(file=sys.stdout)
    pprint.pprint(config.sections())
    pprint.pprint({section: dict(config.items(section)) for section in config.sections()})

Я получаю сообщение об ошибке: файл "/home/sahmed/anaconda3/envs/kml/lib/python3.6/configparser.py", строка 959, в getitem KeyError: 'database'

Мой INI-файл выглядит так:

[api]
server_debug=False
log_level=info
n_workers=10

[database]
db_connection=http://1.1.1.1:9191
user=admin
pass=whateverman

[cluster]
default_workers=3

Моя первоначальная мысль была проблемой с потоком, так как у меня 8 потоков, постоянно обращающихся к этому файлу конфигурации (хотя это не имеет смысла ... мы читаю только) так что я даже блок крепежа на чтение прочел, все равно не повезло. Что может вызвать такую ​​ситуацию?

Ответы [ 2 ]

2 голосов
/ 16 апреля 2020

Единственный способ, которым я мог бы воспроизвести проблему с предоставленным вами кодом, это если я принудительно изменил рабочий каталог во время кода.

Я собрал это, чтобы проверить проблему:

from time import sleep
import configparser
import os

def readINI():
    try:
        path = os.path.dirname(os.path.realpath(__file__))
        ini = '/'.join([path, "test.ini"])
        config = configparser.ConfigParser()
        config.read(ini)
        string = config["things"]["abc"]
        print(string)
    except Exception as e:
        print("Error: {}".format(e))

count = 0
while True:
    count +=1
    readINI()
    sleep(1)
    if count % 3 == 0:
        os.chdir("..")
    elif count > 1 and count % 3 == 1:
        os.chdir("./TestFolder")

test.ini очень просто, он состоит из двух строк:

[things]
abc=123

У меня есть оба файла в одной папке, и я перемещаюсь назад и вперед между папкой "root" и TestFolder, который содержит файлы Если вы raise исключение вместо того, чтобы просто распечатать его, вы получите то же сообщение об ошибке.

Убедитесь, что вы случайно не изменили рабочий каталог во время выполнения кода, и посмотрите, действительно ли это причина проблем.

1 голос
/ 22 апреля 2020

Я решил проблему. Регистратор Python вытягивал слишком много файловых дескрипторов, исчерпывающих максимальный предел (внутри часто вызываемой функции был getLogger (), а не глобально), поэтому весь процесс Python не смог открыть файл конфигурации.

Общий ответ здесь заключается в том, что ConfigParser, конечно, подвержен общим системным проблемам, когда он не может прочитать файл, который мог прочитать ранее. Не из-за самого файла, а из-за общих системных ограничений.

...