LINUX.ORG.RU

Калькулятор на питоне, без eval()

 


0

1

Чатгпт можно научить использовать функции когда надо, например когда человек спрашивает как посчитать что то он может вызвать функцию calc('"(1/5461512)**3 * (math.factorial(12856723)/(math.factorial(3)*math.factorial(12856723-3)))«')

и собственно проблема - если эта функция на питоне с eval(filtered expression) то вот это вот она будет считать бесконечно долго, пока сервер не лопнет или наступит тепловая смерть вселенной

надо как то ограничить это безобразие

★★

>>> math.factorial(2000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Exceeds the limit (4300 digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit

а в общем случае парсить выражение, находить операции с нелинейной вычислительной сложностью, ограничивать аргументы передаваемые. Т.е. чтобы 100! можно было посчитать, а 100500! уже нет

cobold ★★★★★
()

ДО calc/eval выражение можно упрощать. В питоне наверняка где-то есть пакеты символьных вычислений. Или внешний вычислятор-упрощатор можно зацепить, например maxima

MKuznetsov ★★★★★
()

надо как то ограничить это безобразие

вспомнилось - есть же ресурсы и лимиты. Только в питоне с ними сложность, они вроде как сразу на весь процесс там ставятся. Это в тикле можно сделать дочерний interp, задать лимит 5 сек и запустить в нём eval.

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

Так в питоне никто не мешает запустить второй питон с таймаутом, а в нём eval.

P. S. В первом комментарии уже написали.

monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от monk

Так в питоне никто не мешает запустить второй питон с таймаутом, а в нём eval.

P. S. В первом комментарии уже написали.

там про запуск отдельного системного процесса. Я имел в виду отдельный интерпретатор (это ближе к грин-тред). Вещи схожие, но слегка разные :-) Даже и сомневаюсь что в питоне такое есть.

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

Я имел в виду отдельный интерпретатор

Есть еще с девяностых годов, но ЕМНИП нельзя управлять мульти-интерпретатором из питоньего кода, только из сишных либ

https://peps.python.org/pep-0554/

На практике вам это не надо, есть https://www.programiz.com/python-programming/methods/built-in/exec и мультипроцессинг

FishHook
()
Ответ на: комментарий от ei-grad

вот тут немного странное - https://github.com/ei-grad/kill-timeout/blob/master/kill_timeout.py#L45-L51 (но не критичное)

наверное надо просто после kill ещё раз код завершения спросить, хоть через os.waitpid если Process не позволит сделать это нормально

PRs are welcome - https://github.com/ei-grad/kill-timeout/issues/4

ei-grad ★★★★★
()
Последнее исправление: ei-grad (всего исправлений: 3)
Ответ на: комментарий от theurs

func_timeout не может остановить eval() по таймауту.

Ну так перепиши, чтоб запускал в отдельном процессе и килял, если сам не завершить я через эн секунд, 10 строчек кода же

pihter ★★★★★
()