Fixing threading._RLock exception on Python 3.6

Issue was the usual business: objects that cross process boundaries need
to be picklable and Python 3.6 is more strict about this. The logger
object in particular interfered, so now we suppress it and rebuild it
in process.
This commit is contained in:
James R. Barlow
2019-05-17 14:24:47 -07:00
parent 56067b590b
commit cfd67ab6aa
2 changed files with 42 additions and 20 deletions
+38 -12
View File
@@ -22,10 +22,29 @@ import os
from contextlib import suppress
class PDFContext:
class PicklableLoggerMixin:
def __init__(self):
self._log = None
@property
def log(self):
if not self._log:
self._log = self.get_logger()
return self._log
def __getstate__(self):
log = self._log
self._log = None
state = self.__dict__
self._log = log
return state
class PDFContext(PicklableLoggerMixin):
"""Holds our context for a particular run of the pipeline"""
def __init__(self, options, work_folder, origin, pdfinfo):
PicklableLoggerMixin.__init__(self)
self.options = options
self.work_folder = work_folder
self.origin = origin
@@ -36,7 +55,9 @@ class PDFContext:
self.name = 'origin.pdf'
if self.name == '-':
self.name = 'stdin'
self.log = get_logger(options, filename=self.name)
def get_logger(self):
return make_logger(self.options, filename=self.name)
def get_path(self, name):
return os.path.join(self.work_folder, name)
@@ -47,22 +68,27 @@ class PDFContext:
yield PageContext(self, n)
class PageContext:
"""Holds our context for a page"""
class PageContext(PicklableLoggerMixin):
"""Holds our context for a page
Must be pickable, so only store intrinsic/simple data elements
"""
def __init__(self, pdf_context, pageno):
self.pdf_context = pdf_context
PicklableLoggerMixin.__init__(self)
self.work_folder = pdf_context.work_folder
self.origin = pdf_context.origin
self.options = pdf_context.options
self.name = pdf_context.name
self.pageno = pageno
self.pageinfo = pdf_context.pdfinfo[pageno]
self.log = get_logger(
pdf_context.options, filename=self.pdf_context.name, page=(self.pageno + 1)
)
self._log = None
def get_logger(self):
return make_logger(self.options, filename=self.name, page=self.pageno + 1)
def get_path(self, name):
return os.path.join(
self.pdf_context.work_folder, "%06d_%s" % (self.pageno + 1, name)
)
return os.path.join(self.work_folder, "%06d_%s" % (self.pageno + 1, name))
def cleanup_working_files(work_folder, options):
@@ -88,7 +114,7 @@ class LogNamePageAdapter(logging.LoggerAdapter):
)
def get_logger(options=None, prefix='ocrmypdf', filename=None, page=None):
def make_logger(options=None, prefix='ocrmypdf', filename=None, page=None):
log = logging.getLogger(prefix)
if filename and page:
adapter = LogNamePageAdapter(log, dict(filename=filename, page=page))
+4 -8
View File
@@ -29,7 +29,7 @@ from tempfile import mkdtemp
from tqdm import tqdm
from . import VERSION
from ._jobcontext import PDFContext, cleanup_working_files, get_logger
from ._jobcontext import PDFContext, cleanup_working_files, make_logger
from ._pipeline import (
convert_to_pdfa,
copy_final,
@@ -83,17 +83,13 @@ def exec_page_sync(page_context):
if is_ocr_required(page_context):
if options.rotate_pages:
# Rasterize
rasterize_preview_out = rasterize_preview(
page_context.pdf_context.origin, page_context
)
rasterize_preview_out = rasterize_preview(page_context.origin, page_context)
orientation_correction = get_orientation_correction(
rasterize_preview_out, page_context
)
rasterize_out = rasterize(
page_context.pdf_context.origin,
page_context,
correction=orientation_correction,
page_context.origin, page_context, correction=orientation_correction
)
preprocess_out = rasterize_out
@@ -240,7 +236,7 @@ def exec_concurrent(context):
def run_pipeline(options):
log = get_logger(options, __name__)
log = make_logger(options, __name__)
log.debug('ocrmypdf ' + VERSION)
result = check_options(options)