For Leptonica 1.79+ use leptSetStderrHandler

Lock free and considerably less dangerous to stderr messages.
This commit is contained in:
James R. Barlow
2020-07-19 03:40:33 -07:00
parent 4ea9cffebd
commit 5cbbff8472
4 changed files with 81 additions and 15 deletions
+59 -1
View File
@@ -24,7 +24,9 @@ import argparse
import logging
import os
import sys
import threading
import warnings
from collections import deque
from collections.abc import Sequence
from contextlib import suppress
from ctypes.util import find_library
@@ -75,7 +77,7 @@ except ffi.error as e:
) from e
class _LeptonicaErrorTrap:
class _LeptonicaErrorTrap_Redirect:
"""
Context manager to trap errors reported by Leptonica.
@@ -155,6 +157,62 @@ class _LeptonicaErrorTrap:
return False
tls = threading.local()
tls.trap = None
@ffi.callback("void(char *)")
def _stderr_handler(cstr):
msg = ffi.string(cstr).decode(errors='replace')
if msg.startswith("Error"):
logger.error(msg)
elif msg.startswith("Warning"):
logger.warning(msg)
else:
logger.debug(msg)
if tls.trap is not None:
tls.trap.append(msg)
return
class _LeptonicaErrorTrap_Queue:
def __init__(self):
self.queue = deque()
def __enter__(self):
self.queue.clear()
tls.trap = self.queue
def __exit__(self, exc_type, exc_value, traceback):
tls.trap = None
output = ''.join(self.queue)
self.queue.clear()
# If there are Python errors, record them
if exc_type:
logger.warning(output)
if 'Error' in output:
if 'image file not found' in output:
raise FileNotFoundError()
if 'pixWrite: stream not opened' in output:
raise LeptonicaIOError()
if 'index not valid' in output:
raise IndexError()
raise LeptonicaError(output)
return False
try:
lept.leptSetStderrHandler(_stderr_handler)
except ffi.error:
# Pre-1.79 Leptonica does not have leptSetStderrHandler
_LeptonicaErrorTrap = _LeptonicaErrorTrap_Redirect
else:
# 1.79 have this new symbol
_LeptonicaErrorTrap = _LeptonicaErrorTrap_Queue
class LeptonicaError(Exception):
pass
File diff suppressed because one or more lines are too long
+2
View File
@@ -509,6 +509,8 @@ void selDestroy ( SEL **psel );
l_int32
setMsgSeverity(l_int32 newsev);
void
leptSetStderrHandler(void (*handler)(const char *));
"""
)