Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-tesserocr for 
openSUSE:Factory checked in at 2026-09-23 14:34:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-tesserocr (Old)
 and      /work/SRC/openSUSE:Factory/.python-tesserocr.new.383539 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-tesserocr"

Wed Sep 23 14:34:39 2026 rev:28 rq:1379774 version:2.11.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-tesserocr/python-tesserocr.changes        
2026-02-18 17:07:09.554042518 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-tesserocr.new.383539/python-tesserocr.changes
    2026-09-23 14:36:16.183618903 +0200
@@ -1,0 +2,9 @@
+Wed Sep 23 01:26:48 UTC 2026 - Steve Kowalik <[email protected]>
+
+- Update to 2.11.0:
+  * Catch exception in get_languages()
+  * fix _pix_to_image memory leak
+  * place long running API calls in cysignals blocks
+- Build with Cython 3.
+
+-------------------------------------------------------------------

Old:
----
  tesserocr-2.9.2.tar.gz

New:
----
  tesserocr-2.11.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-tesserocr.spec ++++++
--- /var/tmp/diff_new_pack.svV5Bt/_old  2026-09-23 14:36:17.005652893 +0200
+++ /var/tmp/diff_new_pack.svV5Bt/_new  2026-09-23 14:36:17.008653017 +0200
@@ -18,14 +18,15 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-tesserocr
-Version:        2.9.2
+Version:        2.11.0
 Release:        0
 Summary:        A Python wrapper around tesseract-ocr
 License:        MIT
 URL:            https://github.com/sirfz/tesserocr
 Source:         
https://files.pythonhosted.org/packages/source/t/tesserocr/tesserocr-%{version}.tar.gz
-BuildRequires:  %{python_module Cython0}
+BuildRequires:  %{python_module Cython}
 BuildRequires:  %{python_module Pillow}
+BuildRequires:  %{python_module cysignals}
 BuildRequires:  %{python_module devel}
 BuildRequires:  %{python_module pip}
 BuildRequires:  %{python_module pytest}
@@ -39,6 +40,7 @@
 BuildRequires:  tesseract-ocr-traineddata-orientation_and_script_detection
 BuildRequires:  pkgconfig(libcurl)
 BuildRequires:  pkgconfig(tesseract)
+Requires:       python-cysignals
 Requires:       tesseract-ocr-traineddata-english
 Requires:       tesseract-ocr-traineddata-orientation_and_script_detection
 Recommends:     python-Pillow

++++++ tesserocr-2.9.2.tar.gz -> tesserocr-2.11.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tesserocr-2.9.2/.eggs/cysignals-1.12.5-py3.9-linux-x86_64.egg/cysignals/macros.h
 
new/tesserocr-2.11.0/.eggs/cysignals-1.12.5-py3.9-linux-x86_64.egg/cysignals/macros.h
--- 
old/tesserocr-2.9.2/.eggs/cysignals-1.12.5-py3.9-linux-x86_64.egg/cysignals/macros.h
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/tesserocr-2.11.0/.eggs/cysignals-1.12.5-py3.9-linux-x86_64.egg/cysignals/macros.h
       2026-08-04 13:59:53.000000000 +0200
@@ -0,0 +1,320 @@
+/*
+Interrupt and signal handling for Cython.
+
+This code distinguishes between two kinds of signals:
+
+(1) interrupt-like signals: SIGINT, SIGALRM, SIGHUP.  The word
+"interrupt" refers to any of these signals.  These need not be handled
+immediately, we might handle them at a suitable later time, outside of
+sig_block() and with the Python GIL acquired.  SIGINT raises a
+KeyboardInterrupt (as usual in Python), SIGALRM raises AlarmInterrupt
+(a custom exception inheriting from KeyboardInterrupt), while SIGHUP
+raises SystemExit, causing Python to exit.  The latter signal also
+redirects stdin from /dev/null, to cause interactive sessions to exit.
+
+(2) critical signals: SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGBUS, SIGSEGV.
+These are critical because they cannot be ignored.  If they happen
+outside of sig_on(), we can only exit Python with the dreaded
+"unhandled SIG..." message.  Inside of sig_on(), they can be handled
+and raise various exceptions (see cysignals/signals.pyx).  SIGQUIT
+will never be handled and always causes Python to exit.
+
+*/
+
+/*****************************************************************************
+ *       Copyright (C) 2006 William Stein <[email protected]>
+ *                     2006 Martin Albrecht 
<[email protected]>
+ *                     2010-2016 Jeroen Demeyer <[email protected]>
+ *
+ * cysignals is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * cysignals is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with cysignals.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ****************************************************************************/
+
+
+#ifndef CYSIGNALS_MACROS_H
+#define CYSIGNALS_MACROS_H
+
+#include <setjmp.h>
+#include <signal.h>
+#include "struct_signals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**********************************************************************
+ * HELPER FUNCTIONS                                                   *
+ **********************************************************************/
+
+/* Send a signal to the calling process. The POSIX raise() function
+ * sends a signal to the calling thread, while kill() typically sends
+ * a signal to the main thread (although this is not guaranteed by the
+ * POSIX standard) */
+#if HAVE_KILL
+#define proc_raise(sig)  kill(getpid(), sig)
+#else
+/* On Windows, raise() actually signals the process */
+#define proc_raise(sig)  raise(sig)
+#endif
+
+/**********************************************************************
+ * IMPLEMENTATION OF SIG_ON/SIG_OFF                                   *
+ **********************************************************************/
+
+/*
+ * Implementation of sig_on().  Applications should not use this
+ * directly, use sig_on() or sig_str() instead.
+ *
+ * _sig_on_(message) is a macro which pretends to be a function.
+ * Since this is declared as "cdef except 0", Cython will know that an
+ * exception occurred if the value of _sig_on_() is 0 (false).
+ *
+ * INPUT:
+ *
+ *  - message -- a string to be displayed as error message when the code
+ *    between sig_on() and sig_off() fails and raises an exception.
+ *
+ * OUTPUT: zero if an exception occurred, non-zero otherwise.
+ *
+ * The function cysetjmp() in the _sig_on_() macro can return:
+ *  - zero: this happens in the actual sig_on() call. cysetjmp() sets
+ *    up the address for the signal handler to jump to.  The
+ *    program continues normally.
+ *  - a signal number (e.g. 2 for SIGINT), assumed to be strictly
+ *    positive: the cysignals signal handler handled a signal.  Since
+ *    _sig_on_() will return 0 in this case, the Exception (raised by
+ *    cysigs_signal_handler) will be detected by Cython.
+ *  - a negative number: this is assumed to come from sig_retry().  In
+ *    this case, the program continues as if nothing happened between
+ *    sig_on() and sig_retry().
+ *
+ * We cannot simply put cysetjmp() in a function, because when that
+ * function returns, we would lose the stack frame to cylongjmp() to.
+ * That's why we need this hackish macro.  We use the fact that || is
+ * a short-circuiting operator (the second argument is only evaluated
+ * if the first returns 0).
+ */
+
+#define _sig_on_(message) ( unlikely(_sig_on_prejmp(message, __FILE__, 
__LINE__)) || _sig_on_postjmp(cysetjmp(cysigs.env)) )
+
+/*
+ * Set message, return 0 if we need to cysetjmp(), return 1 otherwise.
+ */
+static inline int _sig_on_prejmp(const char* message, CYTHON_UNUSED const 
char* file, CYTHON_UNUSED int line)
+{
+    cysigs.s = message;
+#if ENABLE_DEBUG_CYSIGNALS
+    if (cysigs.debug_level >= 4)
+    {
+        fprintf(stderr, "sig_on (count = %i) at %s:%i\n",
+                (int)cysigs.sig_on_count+1, file, line);
+        fflush(stderr);
+    }
+    if (cysigs.block_sigint && cysigs.sig_on_count <= 0)
+    {
+        fprintf(stderr, "\n*** ERROR *** sig_on() with sig_on_count = %i, 
block_sigint = %i\n",
+                (int)cysigs.sig_on_count, (int)cysigs.block_sigint);
+        print_backtrace();
+    }
+#endif
+    if (cysigs.sig_on_count > 0)
+    {
+        cysigs.sig_on_count++;
+        return 1;
+    }
+
+    /* At this point, cysigs.sig_on_count == 0 */
+    return 0;
+}
+
+
+/*
+ * Process the return value of cysetjmp().
+ * Return 0 if there was an exception, 1 otherwise.
+ */
+static inline int _sig_on_postjmp(int jmpret)
+{
+    if (unlikely(jmpret > 0))
+    {
+        /* An exception occurred */
+        _sig_on_recover();
+        return 0;
+    }
+
+    /* When we are here, it's either the original sig_on() call or we
+     * got here after sig_retry(). */
+    cysigs.sig_on_count = 1;
+
+    /* Check whether we received an interrupt before this point.
+     * cysigs.interrupt_received can only be set by the interrupt
+     * handler if cysigs.sig_on_count is zero.  Because of that and
+     * because cysigs.sig_on_count and cysigs.interrupt_received are
+     * volatile, we can safely evaluate cysigs.interrupt_received here
+     * without race conditions. */
+    if (unlikely(cysigs.interrupt_received))
+    {
+        _sig_on_interrupt_received();
+        return 0;
+    }
+
+    return 1;
+}
+
+
+/*
+ * Implementation of sig_off().  Applications should not use this
+ * directly, use sig_off() instead.
+ */
+static inline void _sig_off_(const char* file, int line)
+{
+#if ENABLE_DEBUG_CYSIGNALS
+    if (cysigs.debug_level >= 4)
+    {
+        fprintf(stderr, "sig_off (count = %i) at %s:%i\n",
+                (int)cysigs.sig_on_count, file, line);
+        fflush(stderr);
+    }
+#endif
+    if (unlikely(cysigs.sig_on_count <= 0))
+    {
+        _sig_off_warning(file, line);
+    }
+    else
+    {
+        --cysigs.sig_on_count;
+    }
+}
+
+
+/**********************************************************************
+ * USER MACROS/FUNCTIONS                                              *
+ **********************************************************************/
+
+/* The actual macros which should be used in a program. */
+#define sig_on()           _sig_on_(NULL)
+#define sig_str(message)   _sig_on_(message)
+#define sig_off()          _sig_off_(__FILE__, __LINE__)
+
+/* sig_check() should be functionally equivalent to sig_on(); sig_off();
+ * but much faster.  Essentially, it checks whether we missed any
+ * interrupts.
+ *
+ * OUTPUT: zero if an interrupt occurred, non-zero otherwise.
+ */
+static inline int sig_check(void)
+{
+    if (unlikely(cysigs.interrupt_received) && cysigs.sig_on_count == 0)
+    {
+        _sig_on_interrupt_received();
+        return 0;
+    }
+
+    return 1;
+}
+
+
+/*
+ * Temporarily block interrupts from happening inside sig_on().  This
+ * is meant to wrap malloc() for example.  sig_unblock() checks whether
+ * an interrupt happened in the mean time.  If yes, the interrupt is
+ * re-raised.
+ *
+ * NOTES:
+ * - This only works inside sig_on()/sig_off().  Outside of sig_on(),
+ *   interrupts behave as usual.  This is because we can't propagate
+ *   Python exceptions from low-level C code.
+ * - Despite the above note, it is still legal to use sig_block()
+ *   outside of sig_on().
+ * - Other signals still go through, because we can't really ignore
+ *   SIGSEGV for example.
+ * - It is NOT allowed to have an outer call of sig_on() inside
+ *   sig_block().
+ *   A deeper nesting (sig_on(); sig_block(); sig_on();) is OK.
+ */
+static inline void sig_block(void)
+{
+    /* This increment may not be atomic. However, that's not an issue
+     * because our signal handlers do not change this value. The value
+     * of block_sigint is set to 0 in _sig_on_recover, but that only
+     * happens after a longjmp(). */
+    ++cysigs.block_sigint;
+}
+
+static inline void sig_unblock(void)
+{
+#if ENABLE_DEBUG_CYSIGNALS
+    if (cysigs.block_sigint < 1)
+    {
+        fprintf(stderr, "\n*** ERROR *** sig_unblock() with sig_on_count = %i, 
block_sigint = %i\n",
+                (int)cysigs.sig_on_count, (int)cysigs.block_sigint);
+        print_backtrace();
+    }
+#endif
+    --cysigs.block_sigint;
+
+    if (unlikely(cysigs.interrupt_received))
+        /* Re-raise the signal if we can handle it now */
+        if (cysigs.sig_on_count > 0 && cysigs.block_sigint == 0)
+            proc_raise(cysigs.interrupt_received);
+}
+
+
+/*
+ * Retry a failed computation starting from sig_on().
+ */
+static inline void sig_retry(void)
+{
+    /* If we're outside of sig_on(), we can't jump, so we can only bail
+     * out */
+    if (unlikely(cysigs.sig_on_count <= 0))
+    {
+        fprintf(stderr, "sig_retry() without sig_on()\n");
+        proc_raise(SIGABRT);
+    }
+    cylongjmp(cysigs.env, -1);
+}
+
+/* Used in error callbacks from C code (in particular NTL and PARI).
+ * This should be used after an exception has been raised to jump back
+ * to sig_on() where the exception will be seen. */
+static inline void sig_error(void)
+{
+    if (unlikely(cysigs.sig_on_count <= 0))
+    {
+        fprintf(stderr, "sig_error() without sig_on()\n");
+    }
+    proc_raise(SIGABRT);
+}
+
+
+static inline int _set_debug_level(int level)
+{
+#if ENABLE_DEBUG_CYSIGNALS
+    int old = cysigs.debug_level;
+    cysigs.debug_level = level;
+    return old;
+#else
+    if (level == 0)
+        return 0;    /* 0 is the only valid debug level */
+    else
+        return -1;   /* Error */
+#endif
+}
+
+#ifdef __cplusplus
+}  /* extern "C" */
+#endif
+
+#endif  /* ifndef CYSIGNALS_MACROS_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/tesserocr-2.9.2/.eggs/cysignals-1.12.5-py3.9-linux-x86_64.egg/cysignals/struct_signals.h
 
new/tesserocr-2.11.0/.eggs/cysignals-1.12.5-py3.9-linux-x86_64.egg/cysignals/struct_signals.h
--- 
old/tesserocr-2.9.2/.eggs/cysignals-1.12.5-py3.9-linux-x86_64.egg/cysignals/struct_signals.h
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/tesserocr-2.11.0/.eggs/cysignals-1.12.5-py3.9-linux-x86_64.egg/cysignals/struct_signals.h
       2026-08-04 13:59:53.000000000 +0200
@@ -0,0 +1,109 @@
+/*****************************************************************************
+ *       Copyright (C) 2006 William Stein <[email protected]>
+ *                     2006 Martin Albrecht 
<[email protected]>
+ *                     2010-2016 Jeroen Demeyer <[email protected]>
+ *
+ * cysignals is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * cysignals is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with cysignals.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ****************************************************************************/
+
+#ifndef CYSIGNALS_STRUCT_SIGNALS_H
+#define CYSIGNALS_STRUCT_SIGNALS_H
+
+
+#include "cysignals_config.h"
+#include <setjmp.h>
+#include <signal.h>
+#include <Python.h>
+
+
+/* Choose sigjmp/longjmp variant */
+#if CYSIGNALS_USE_SIGSETJMP
+#define cyjmp_buf sigjmp_buf
+#define cysetjmp(env) sigsetjmp(env, 0)
+#define cylongjmp(env, val) siglongjmp(env, val)
+#else
+#define cyjmp_buf jmp_buf
+#define cysetjmp(env) setjmp(env)
+#define cylongjmp(env, val) longjmp(env, val)
+#endif
+
+
+/* Define a cy_atomic_int type for atomic operations */
+#if __cplusplus
+#if CYSIGNALS_STD_ATOMIC
+#include <atomic>
+typedef volatile std::atomic<int> cy_atomic_int;
+#elif CYSIGNALS_CXX_ATOMIC
+typedef volatile _Atomic int cy_atomic_int;
+#else
+/* The type sig_atomic_t is not really atomic, but it's the best we have */
+typedef volatile sig_atomic_t cy_atomic_int;
+#endif
+#else
+#if CYSIGNALS_C_ATOMIC
+typedef volatile _Atomic int cy_atomic_int;
+#else
+/* The type sig_atomic_t is not really atomic, but it's the best we have */
+typedef volatile sig_atomic_t cy_atomic_int;
+#endif
+#endif
+
+
+/* All the state of the signal handler is in this struct. */
+typedef struct
+{
+    /* Reference counter for sig_on().
+     * If this is strictly positive, we are inside a sig_on(). */
+    cy_atomic_int sig_on_count;
+
+    /* If this is nonzero, it is a signal number of a non-critical
+     * signal (e.g. SIGINT) which happened during a time when it could
+     * not be handled.  This may be set when an interrupt occurs either
+     * outside of sig_on() or inside sig_block().  To avoid race
+     * conditions, this value may only be changed when all
+     * interrupt-like signals are masked. */
+    cy_atomic_int interrupt_received;
+
+    /* Are we currently handling a signal inside cysigs_signal_handler()?
+     * This is set to 1 on entry in cysigs_signal_handler (not in
+     * cysigs_interrupt_handler) and 0 in _sig_on_postjmp.  This is
+     * needed to check for signals raised within the signal handler. */
+    cy_atomic_int inside_signal_handler;
+
+    /* Non-zero if we currently are in a function such as malloc()
+     * which blocks interrupts, zero normally.
+     * See sig_block(), sig_unblock(). */
+    cy_atomic_int block_sigint;
+
+    /* A jump buffer holding where to cylongjmp() after a signal has
+     * been received. This is set by sig_on(). */
+    cyjmp_buf env;
+
+    /* An optional string (in UTF-8 encoding) to be used as text for
+     * the exception raised by sig_raise_exception(). If this is NULL,
+     * use some default string depending on the type of signal. This can
+     * be set using sig_str() instead of sig_on(). */
+    const char* s;
+
+    /* Reference to the exception object that we raised (NULL if none).
+     * This is used by the sig_occurred function. */
+    PyObject* exc_value;
+
+#if ENABLE_DEBUG_CYSIGNALS
+    int debug_level;
+#endif
+} cysigs_t;
+
+#endif  /* ifndef CYSIGNALS_STRUCT_SIGNALS_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tesserocr-2.9.2/MANIFEST.in 
new/tesserocr-2.11.0/MANIFEST.in
--- old/tesserocr-2.9.2/MANIFEST.in     2025-12-18 09:51:29.000000000 +0100
+++ new/tesserocr-2.11.0/MANIFEST.in    2026-08-04 13:59:43.000000000 +0200
@@ -3,7 +3,7 @@
 include tesserocr/*.pyx
 include tesserocr/*.pxd
 include tesserocr/*.pyi
-include tests/*.py tests/*.png
+include tests/*.py tests/*.png tests/*.train
 exclude tesserocr/*.cpp
 exclude tesserocr/*.so
 exclude *.so
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tesserocr-2.9.2/PKG-INFO 
new/tesserocr-2.11.0/PKG-INFO
--- old/tesserocr-2.9.2/PKG-INFO        2025-12-18 09:51:35.032224200 +0100
+++ new/tesserocr-2.11.0/PKG-INFO       2026-08-04 13:59:55.400774200 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: tesserocr
-Version: 2.9.2
+Version: 2.11.0
 Summary: A simple, Pillow-friendly, Python wrapper around tesseract-ocr API 
using Cython
 Home-page: https://github.com/sirfz/tesserocr
 Author: Fayez Zouheiry
@@ -12,7 +12,6 @@
 Classifier: Topic :: Multimedia :: Graphics :: Capture :: Scanners
 Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
 Classifier: Topic :: Scientific/Engineering :: Image Recognition
-Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: POSIX
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.9
@@ -27,6 +26,7 @@
 Requires-Python: >=3.9
 Description-Content-Type: text/x-rst
 License-File: LICENSE
+Requires-Dist: cysignals
 Dynamic: author
 Dynamic: author-email
 Dynamic: classifier
@@ -36,6 +36,7 @@
 Dynamic: keywords
 Dynamic: license
 Dynamic: license-file
+Dynamic: requires-dist
 Dynamic: requires-python
 Dynamic: summary
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tesserocr-2.9.2/setup.py 
new/tesserocr-2.11.0/setup.py
--- old/tesserocr-2.9.2/setup.py        2025-12-18 09:51:29.000000000 +0100
+++ new/tesserocr-2.11.0/setup.py       2026-08-04 13:59:43.000000000 +0200
@@ -1,4 +1,3 @@
-import codecs
 import errno
 import glob
 import itertools
@@ -39,7 +38,7 @@
 
 
 def read(*parts):
-    with codecs.open(pjoin(here, *parts), "r", encoding="utf-8") as f:
+    with open(pjoin(here, *parts), "r", encoding="utf-8") as f:
         return f.read()
 
 
@@ -301,7 +300,6 @@
         "Topic :: Multimedia :: Graphics :: Capture :: Scanners",
         "Topic :: Multimedia :: Graphics :: Graphics Conversion",
         "Topic :: Scientific/Engineering :: Image Recognition",
-        "License :: OSI Approved :: MIT License",
         "Operating System :: POSIX",
         "Programming Language :: Python :: 3",
         "Programming Language :: Python :: 3.9",
@@ -318,7 +316,8 @@
     cmdclass={"build_ext": my_build_ext},
     ext_modules=[make_extension()],
     test_suite="tests",
-    setup_requires=["Cython>=3.0.0,<3.2.0"],
+    setup_requires=["Cython>=3.0.0,<3.2.0", "cysignals"],
+    install_requires=["cysignals"],
     packages=["tesserocr"],
     package_dir={"tesserocr": "tesserocr"},
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tesserocr-2.9.2/tesserocr/tesseract5.pxd 
new/tesserocr-2.11.0/tesserocr/tesseract5.pxd
--- old/tesserocr-2.9.2/tesserocr/tesseract5.pxd        2025-12-18 
09:51:29.000000000 +0100
+++ new/tesserocr-2.11.0/tesserocr/tesseract5.pxd       2026-08-04 
13:59:43.000000000 +0200
@@ -282,7 +282,7 @@
             int Init(cchar_t *, cchar_t *)
             cchar_t *GetInitLanguagesAsString() const
             void GetLoadedLanguagesAsVector(vector[string] *) const
-            void GetAvailableLanguagesAsVector(vector[string] *) const
+            void GetAvailableLanguagesAsVector(vector[string] *) except +
             void InitForAnalysePage()
             void ReadConfigFile(cchar_t *)
             void SetPageSegMode(PageSegMode)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tesserocr-2.9.2/tesserocr/tesserocr.pyx 
new/tesserocr-2.11.0/tesserocr/tesserocr.pyx
--- old/tesserocr-2.9.2/tesserocr/tesserocr.pyx 2025-12-18 09:51:29.000000000 
+0100
+++ new/tesserocr-2.11.0/tesserocr/tesserocr.pyx        2026-08-04 
13:59:43.000000000 +0200
@@ -18,7 +18,7 @@
  ['eng', 'osd', 'equ'])
 """
 
-__version__ = '2.9.2'
+__version__ = '2.11.0'
 
 import os
 import logging
@@ -39,6 +39,7 @@
 from libcpp.vector cimport vector
 from cython.operator cimport preincrement as inc, dereference as deref
 from cpython.version cimport PY_MAJOR_VERSION
+from cysignals.signals cimport sig_on, sig_off
 
 
 _LOGGER = logging.getLogger("tesserocr")
@@ -375,9 +376,11 @@
         size_t size
         int result
         int fmt = pix.informat
+        Pix *converted_pix = NULL
     if pix.d == 1:
         # prevent catastrophic 8-bit conversion
-        pix = pixConvertTo8(pix, 0)
+        converted_pix = pixConvertTo8(pix, 0)
+        pix = converted_pix
     if fmt > 0:
         result = pixWriteMem(&buff, &size, pix, fmt)
     else:
@@ -392,6 +395,8 @@
             image.load()
     finally:
         free(buff)
+        if converted_pix != NULL:
+            pixDestroy(&converted_pix)
 
     return image
 
@@ -2073,8 +2078,11 @@
             blockids_addr = NULL
         if not paraids:
             paraids_addr = NULL
-        boxa = self._baseapi.GetComponentImages(level, text_only, raw_image, 
raw_padding,
-                                                &pixa, blockids_addr, 
paraids_addr)
+        with nogil:
+            sig_on()
+            boxa = self._baseapi.GetComponentImages(level, text_only, 
raw_image, raw_padding,
+                                                    &pixa, blockids_addr, 
paraids_addr)
+            sig_off()
         if boxa == NULL:
             # no components found
             return []
@@ -2122,7 +2130,9 @@
         """
         cdef PageIterator *piter
         with nogil:
+            sig_on()
             piter = self._baseapi.AnalyseLayout(merge_similar_words)
+            sig_off()
         if piter == NULL:
             return None
         return PyPageIterator.createPageIterator(piter)
@@ -2145,6 +2155,7 @@
             ETEXT_DESC monitor
             int res
         with nogil:
+            sig_on()
             if timeout > 0:
                 monitor.cancel = NULL
                 monitor.cancel_this = NULL
@@ -2152,6 +2163,7 @@
                 res = self._baseapi.Recognize(&monitor)
             else:
                 res = self._baseapi.Recognize(NULL)
+            sig_off()
         return res == 0
 
     """Methods to retrieve information after :meth:`SetImage`,
@@ -2164,6 +2176,7 @@
                 ETEXT_DESC monitor
                 int res
             with nogil:
+                sig_on()
                 if timeout > 0:
                     monitor.cancel = NULL
                     monitor.cancel_this = NULL
@@ -2171,6 +2184,7 @@
                     res = self._baseapi.RecognizeForChopTest(&monitor)
                 else:
                     res = self._baseapi.RecognizeForChopTest(NULL)
+                sig_off()
             return res == 0
 
     cdef TessResultRenderer *_get_renderer(self, cchar_t *outputbase):
@@ -2370,7 +2384,9 @@
         """Return the recognized text coded as UTF-8 from the image."""
         cdef char *text
         with nogil:
+            sig_on()
             text = self._baseapi.GetUTF8Text()
+            sig_off()
             self._destroy_pix()
             if text == NULL:
                 with gil:
@@ -2710,7 +2726,9 @@
         if pix == NULL:
             with gil:
                 raise RuntimeError('Failed to read picture')
+        sig_on()
         text = _image_to_text(pix, clang, psm, cpath, oem)
+        sig_off()
         if text == NULL:
             with gil:
                 raise RuntimeError(f'Failed to init API, possibly an invalid 
tessdata path: {path}')
@@ -2755,7 +2773,9 @@
         if pix == NULL:
             with gil:
                 raise RuntimeError('Failed to read picture')
+        sig_on()
         text = _image_to_text(pix, clang, psm, cpath, oem)
+        sig_off()
         if text == NULL:
             with gil:
                 raise RuntimeError(f'Failed to init API, possibly an invalid 
tessdata path: {path}')
@@ -2799,7 +2819,11 @@
             int i
     baseapi.Init(py_path, NULL)
     path = baseapi.GetDatapath()
-    baseapi.GetAvailableLanguagesAsVector(&v)
+    try:
+        baseapi.GetAvailableLanguagesAsVector(&v)
+    except RuntimeError:
+        baseapi.End()
+        raise
     langs = [v[i].c_str() for i in range(v.size())]
     baseapi.End()
     return path, langs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tesserocr-2.9.2/tesserocr.egg-info/PKG-INFO 
new/tesserocr-2.11.0/tesserocr.egg-info/PKG-INFO
--- old/tesserocr-2.9.2/tesserocr.egg-info/PKG-INFO     2025-12-18 
09:51:33.000000000 +0100
+++ new/tesserocr-2.11.0/tesserocr.egg-info/PKG-INFO    2026-08-04 
13:59:54.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: tesserocr
-Version: 2.9.2
+Version: 2.11.0
 Summary: A simple, Pillow-friendly, Python wrapper around tesseract-ocr API 
using Cython
 Home-page: https://github.com/sirfz/tesserocr
 Author: Fayez Zouheiry
@@ -12,7 +12,6 @@
 Classifier: Topic :: Multimedia :: Graphics :: Capture :: Scanners
 Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
 Classifier: Topic :: Scientific/Engineering :: Image Recognition
-Classifier: License :: OSI Approved :: MIT License
 Classifier: Operating System :: POSIX
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.9
@@ -27,6 +26,7 @@
 Requires-Python: >=3.9
 Description-Content-Type: text/x-rst
 License-File: LICENSE
+Requires-Dist: cysignals
 Dynamic: author
 Dynamic: author-email
 Dynamic: classifier
@@ -36,6 +36,7 @@
 Dynamic: keywords
 Dynamic: license
 Dynamic: license-file
+Dynamic: requires-dist
 Dynamic: requires-python
 Dynamic: summary
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tesserocr-2.9.2/tesserocr.egg-info/SOURCES.txt 
new/tesserocr-2.11.0/tesserocr.egg-info/SOURCES.txt
--- old/tesserocr-2.9.2/tesserocr.egg-info/SOURCES.txt  2025-12-18 
09:51:35.000000000 +0100
+++ new/tesserocr-2.11.0/tesserocr.egg-info/SOURCES.txt 2026-08-04 
13:59:55.000000000 +0200
@@ -3,6 +3,8 @@
 README.rst
 pyproject.toml
 setup.py
+.eggs/cysignals-1.12.5-py3.9-linux-x86_64.egg/cysignals/macros.h
+.eggs/cysignals-1.12.5-py3.9-linux-x86_64.egg/cysignals/struct_signals.h
 tesserocr/__init__.py
 tesserocr/__init__.pyi
 tesserocr/tesseract.pxd
@@ -11,7 +13,9 @@
 tesserocr.egg-info/PKG-INFO
 tesserocr.egg-info/SOURCES.txt
 tesserocr.egg-info/dependency_links.txt
+tesserocr.egg-info/requires.txt
 tesserocr.egg-info/top_level.txt
 tests/__init__.py
+tests/box.train
 tests/eurotext.png
 tests/test_api.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tesserocr-2.9.2/tesserocr.egg-info/requires.txt 
new/tesserocr-2.11.0/tesserocr.egg-info/requires.txt
--- old/tesserocr-2.9.2/tesserocr.egg-info/requires.txt 1970-01-01 
01:00:00.000000000 +0100
+++ new/tesserocr-2.11.0/tesserocr.egg-info/requires.txt        2026-08-04 
13:59:54.000000000 +0200
@@ -0,0 +1 @@
+cysignals
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tesserocr-2.9.2/tests/box.train 
new/tesserocr-2.11.0/tests/box.train
--- old/tesserocr-2.9.2/tests/box.train 1970-01-01 01:00:00.000000000 +0100
+++ new/tesserocr-2.11.0/tests/box.train        2026-08-04 13:59:43.000000000 
+0200
@@ -0,0 +1,12 @@
+disable_character_fragments T
+file_type                   .bl
+textord_fast_pitch_test        T
+tessedit_zero_rejection T
+tessedit_minimal_rejection F
+tessedit_write_rep_codes F
+edges_children_fix F
+edges_childarea 0.65
+edges_boxarea 0.9
+tessedit_resegment_from_boxes T
+tessedit_train_from_boxes T
+textord_no_rejects T
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tesserocr-2.9.2/tests/test_api.py 
new/tesserocr-2.11.0/tests/test_api.py
--- old/tesserocr-2.9.2/tests/test_api.py       2025-12-18 09:51:29.000000000 
+0100
+++ new/tesserocr-2.11.0/tests/test_api.py      2026-08-04 13:59:43.000000000 
+0200
@@ -48,6 +48,7 @@
 class TestTessBaseApi(unittest.TestCase):
 
     _test_dir = os.path.abspath(os.path.dirname(__file__))
+    _config_file = os.path.join(_test_dir, "box.train")
     _image_file = os.path.join(_test_dir, "eurotext.png")
 
     def setUp(self):
@@ -77,13 +78,13 @@
         self.assertEqual(self._api.GetVariableAsString("file_type"), ".tif")
         self.assertEqual(self._api.GetVariableAsString("edges_childarea"), 
"0.5")
         # use box.train config variables
-        configs = ["box.train"]
+        configs = [self._config_file]
         # change edges_childarea
         vars_ = {"edges_childarea": "0.7"}
         self._api.End()
         self._api.InitFull(configs=configs, variables=vars_)
         # assert file_type from box.train and custom edges_childarea
-        self.assertEqual(self._api.GetVariableAsString("file_type"), ".tif")
+        self.assertEqual(self._api.GetVariableAsString("file_type"), ".bl")
         self.assertEqual(self._api.GetVariableAsString("edges_childarea"), 
"0.7")
         # reset back to default
         self._api.End()

Reply via email to