New Upstream Release - python-libzim

Ready changes

Summary

Merged new upstream version: 3.0.0+ds (was: 2.1.0+ds).

Diff

diff --git a/PKG-INFO b/PKG-INFO
index 3f8b6dc..2443ae6 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: libzim
-Version: 2.1.0
+Version: 3.0.0
 Summary: A python-facing API for creating and interacting with ZIM files
 Home-page: https://github.com/openzim/python-libzim
 Author: Monadical Inc.
@@ -42,11 +42,11 @@ interface on top of the [C++ `libzim` library](https://github.com/openzim/libzim
 
 It is primarily used in [openZIM](https://github.com/openzim/) scrapers like [`sotoki`](https://github.com/openzim/sotoki) or [`youtube2zim`](https://github.com/openzim/youtube).
 
-[![Build Status](https://github.com/openzim/python-libzim/workflows/test/badge.svg?query=branch%3Amaster)](https://github.com/openzim/python-libzim/actions?query=branch%3Amaster)
+[![Build Status](https://github.com/openzim/python-libzim/workflows/test/badge.svg?query=branch%3Amain)](https://github.com/openzim/python-libzim/actions?query=branch%3Amain)
 [![CodeFactor](https://www.codefactor.io/repository/github/openzim/python-libzim/badge)](https://www.codefactor.io/repository/github/openzim/python-libzim)
 [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
 [![PyPI version shields.io](https://img.shields.io/pypi/v/libzim.svg)](https://pypi.org/project/libzim/)
-[![codecov](https://codecov.io/gh/openzim/python-libzim/branch/master/graph/badge.svg)](https://codecov.io/gh/openzim/python-libzim)
+[![codecov](https://codecov.io/gh/openzim/python-libzim/branch/main/graph/badge.svg)](https://codecov.io/gh/openzim/python-libzim)
 
 ## Installation
 
diff --git a/README.md b/README.md
index 6e4f945..27fbb37 100644
--- a/README.md
+++ b/README.md
@@ -6,11 +6,11 @@ interface on top of the [C++ `libzim` library](https://github.com/openzim/libzim
 
 It is primarily used in [openZIM](https://github.com/openzim/) scrapers like [`sotoki`](https://github.com/openzim/sotoki) or [`youtube2zim`](https://github.com/openzim/youtube).
 
-[![Build Status](https://github.com/openzim/python-libzim/workflows/test/badge.svg?query=branch%3Amaster)](https://github.com/openzim/python-libzim/actions?query=branch%3Amaster)
+[![Build Status](https://github.com/openzim/python-libzim/workflows/test/badge.svg?query=branch%3Amain)](https://github.com/openzim/python-libzim/actions?query=branch%3Amain)
 [![CodeFactor](https://www.codefactor.io/repository/github/openzim/python-libzim/badge)](https://www.codefactor.io/repository/github/openzim/python-libzim)
 [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
 [![PyPI version shields.io](https://img.shields.io/pypi/v/libzim.svg)](https://pypi.org/project/libzim/)
-[![codecov](https://codecov.io/gh/openzim/python-libzim/branch/master/graph/badge.svg)](https://codecov.io/gh/openzim/python-libzim)
+[![codecov](https://codecov.io/gh/openzim/python-libzim/branch/main/graph/badge.svg)](https://codecov.io/gh/openzim/python-libzim)
 
 ## Installation
 
diff --git a/debian/changelog b/debian/changelog
index d490302..e061f30 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+python-libzim (3.0.0+ds-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Fri, 31 Mar 2023 00:12:55 -0000
+
 python-libzim (2.1.0+ds-1) unstable; urgency=medium
 
   * New upstream version 2.1.0
diff --git a/debian/patches/0001-Skip-tests-that-need-internet-access.patch b/debian/patches/0001-Skip-tests-that-need-internet-access.patch
index 55ddd39..548b0ef 100644
--- a/debian/patches/0001-Skip-tests-that-need-internet-access.patch
+++ b/debian/patches/0001-Skip-tests-that-need-internet-access.patch
@@ -6,11 +6,11 @@ Subject: Skip tests that need internet access
  tests/test_libzim_reader.py | 1 +
  1 file changed, 1 insertion(+)
 
-diff --git a/tests/test_libzim_reader.py b/tests/test_libzim_reader.py
-index 0516c35..3f29f0a 100644
---- a/tests/test_libzim_reader.py
-+++ b/tests/test_libzim_reader.py
-@@ -277,6 +277,7 @@ def all_zims(tmpdir_factory):
+Index: python-libzim.git/tests/test_libzim_reader.py
+===================================================================
+--- python-libzim.git.orig/tests/test_libzim_reader.py
++++ python-libzim.git/tests/test_libzim_reader.py
+@@ -272,6 +272,7 @@ def all_zims(tmpdir_factory):
  
      # download libzim tests
      for url in libzim_urls:
diff --git a/libzim.egg-info/SOURCES.txt b/libzim.egg-info/SOURCES.txt
index 009977c..671ef54 100644
--- a/libzim.egg-info/SOURCES.txt
+++ b/libzim.egg-info/SOURCES.txt
@@ -15,4 +15,5 @@ libzim/libzim.pyx
 libzim/libzim_api.h
 libzim/zim.pxd
 tests/test_libzim_creator.py
-tests/test_libzim_reader.py
\ No newline at end of file
+tests/test_libzim_reader.py
+tests/test_libzim_version.py
\ No newline at end of file
diff --git a/libzim/libzim.cpp b/libzim/libzim.cpp
index 284dcd4..9461d57 100644
--- a/libzim/libzim.cpp
+++ b/libzim/libzim.cpp
@@ -1,4 +1,4 @@
-/* Generated by Cython 0.29.32 */
+/* Generated by Cython 0.29.33 */
 
 /* BEGIN: Cython Metadata
 {
@@ -39,8 +39,8 @@ END: Cython Metadata */
 #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
     #error Cython requires Python 2.6+ or Python 3.3+.
 #else
-#define CYTHON_ABI "0_29_32"
-#define CYTHON_HEX_VERSION 0x001D20F0
+#define CYTHON_ABI "0_29_33"
+#define CYTHON_HEX_VERSION 0x001D21F0
 #define CYTHON_FUTURE_DIVISION 1
 #include <stddef.h>
 #ifndef offsetof
@@ -117,7 +117,7 @@ END: Cython Metadata */
   #undef CYTHON_USE_EXC_INFO_STACK
   #define CYTHON_USE_EXC_INFO_STACK 0
   #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC
-    #define CYTHON_UPDATE_DESCRIPTOR_DOC (PYPY_VERSION_HEX >= 0x07030900)
+    #define CYTHON_UPDATE_DESCRIPTOR_DOC 0
   #endif
 #elif defined(PYSTON_VERSION)
   #define CYTHON_COMPILING_IN_PYPY 0
@@ -596,11 +596,11 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) {
 #endif
 #if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
   #define CYTHON_PEP393_ENABLED 1
-  #if defined(PyUnicode_IS_READY)
-  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ?\
-                                              0 : _PyUnicode_Ready((PyObject *)(op)))
+  #if PY_VERSION_HEX >= 0x030C0000
+    #define __Pyx_PyUnicode_READY(op)       (0)
   #else
-  #define __Pyx_PyUnicode_READY(op)       (0)
+    #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ?\
+                                                0 : _PyUnicode_Ready((PyObject *)(op)))
   #endif
   #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
   #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
@@ -609,14 +609,14 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) {
   #define __Pyx_PyUnicode_DATA(u)         PyUnicode_DATA(u)
   #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
   #define __Pyx_PyUnicode_WRITE(k, d, i, ch)  PyUnicode_WRITE(k, d, i, ch)
-  #if defined(PyUnicode_IS_READY) && defined(PyUnicode_GET_SIZE)
-  #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000
-  #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length))
-  #else
-  #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u)))
-  #endif
+  #if PY_VERSION_HEX >= 0x030C0000
+    #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != PyUnicode_GET_LENGTH(u))
   #else
-  #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != PyUnicode_GET_LENGTH(u))
+    #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000
+    #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length))
+    #else
+    #define __Pyx_PyUnicode_IS_TRUE(u)      (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u)))
+    #endif
   #endif
 #else
   #define CYTHON_PEP393_ENABLED 0
@@ -817,6 +817,7 @@ static CYTHON_INLINE float __PYX_NAN() {
 #include "zim/search.h"
 #include "zim/search_iterator.h"
 #include "libwrapper.h"
+#include "zim/version.h"
 #ifdef _OPENMP
 #include <omp.h>
 #endif /* _OPENMP */
@@ -1062,7 +1063,7 @@ struct __pyx_obj_6libzim___pyx_scope_struct_1_gen_blob;
 struct __pyx_obj_6libzim___pyx_scope_struct_2___iter__;
 struct __pyx_obj_6libzim___pyx_scope_struct_3___iter__;
 
-/* "libzim.pyx":206
+/* "libzim.pyx":207
  * writer_module_name = f"{__name__}.writer"
  * 
  * cdef class WritingBlob:             # <<<<<<<<<<<<<<
@@ -1076,7 +1077,7 @@ struct __pyx_obj_6libzim_WritingBlob {
 };
 
 
-/* "libzim.pyx":239
+/* "libzim.pyx":240
  * 
  * 
  * cdef class _Creator:             # <<<<<<<<<<<<<<
@@ -1091,7 +1092,7 @@ struct __pyx_obj_6libzim__Creator {
 };
 
 
-/* "libzim.pyx":615
+/* "libzim.pyx":607
  * cdef Py_ssize_t itemsize = 1
  * 
  * cdef class ReadingBlob:             # <<<<<<<<<<<<<<
@@ -1107,7 +1108,7 @@ struct __pyx_obj_6libzim_ReadingBlob {
 };
 
 
-/* "libzim.pyx":665
+/* "libzim.pyx":657
  * 
  * 
  * cdef class Entry:             # <<<<<<<<<<<<<<
@@ -1121,7 +1122,7 @@ struct __pyx_obj_6libzim_Entry {
 };
 
 
-/* "libzim.pyx":722
+/* "libzim.pyx":714
  *         return f"{self.__class__.__name__}(url={self.path}, title={self.title})"
  * 
  * cdef class Item:             # <<<<<<<<<<<<<<
@@ -1137,7 +1138,7 @@ struct __pyx_obj_6libzim_Item {
 };
 
 
-/* "libzim.pyx":783
+/* "libzim.pyx":775
  * 
  * 
  * cdef class Archive:             # <<<<<<<<<<<<<<
@@ -1151,7 +1152,7 @@ struct __pyx_obj_6libzim_Archive {
 };
 
 
-/* "libzim.pyx":1045
+/* "libzim.pyx":1037
  * search_module_name = f"{__name__}.search"
  * 
  * cdef class Query:             # <<<<<<<<<<<<<<
@@ -1164,7 +1165,7 @@ struct __pyx_obj_6libzim_Query {
 };
 
 
-/* "libzim.pyx":1055
+/* "libzim.pyx":1047
  * 
  * 
  * cdef class SearchResultSet:             # <<<<<<<<<<<<<<
@@ -1178,7 +1179,7 @@ struct __pyx_obj_6libzim_SearchResultSet {
 };
 
 
-/* "libzim.pyx":1074
+/* "libzim.pyx":1066
  *             preincrement(current)
  * 
  * cdef class Search:             # <<<<<<<<<<<<<<
@@ -1192,7 +1193,7 @@ struct __pyx_obj_6libzim_Search {
 };
 
 
-/* "libzim.pyx":1105
+/* "libzim.pyx":1097
  * 
  * 
  * cdef class Searcher:             # <<<<<<<<<<<<<<
@@ -1205,7 +1206,7 @@ struct __pyx_obj_6libzim_Searcher {
 };
 
 
-/* "libzim.pyx":1156
+/* "libzim.pyx":1148
  * suggestion_module_name = f"{__name__}.suggestion"
  * 
  * cdef class SuggestionResultSet:             # <<<<<<<<<<<<<<
@@ -1219,7 +1220,7 @@ struct __pyx_obj_6libzim_SuggestionResultSet {
 };
 
 
-/* "libzim.pyx":1175
+/* "libzim.pyx":1167
  *             preincrement(current)
  * 
  * cdef class SuggestionSearch:             # <<<<<<<<<<<<<<
@@ -1233,7 +1234,7 @@ struct __pyx_obj_6libzim_SuggestionSearch {
 };
 
 
-/* "libzim.pyx":1205
+/* "libzim.pyx":1197
  * 
  * 
  * cdef class SuggestionSearcher:             # <<<<<<<<<<<<<<
@@ -1246,7 +1247,7 @@ struct __pyx_obj_6libzim_SuggestionSearcher {
 };
 
 
-/* "libzim.pyx":455
+/* "libzim.pyx":456
  *         return len(self.content)
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
@@ -1259,7 +1260,7 @@ struct __pyx_obj_6libzim___pyx_scope_struct__gen_blob {
 };
 
 
-/* "libzim.pyx":470
+/* "libzim.pyx":471
  *         return self.size
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
@@ -1279,7 +1280,7 @@ struct __pyx_obj_6libzim___pyx_scope_struct_1_gen_blob {
 };
 
 
-/* "libzim.pyx":1066
+/* "libzim.pyx":1058
  *         return resultset
  * 
  *     def __iter__(self) -> Iterator[str]:             # <<<<<<<<<<<<<<
@@ -1294,7 +1295,7 @@ struct __pyx_obj_6libzim___pyx_scope_struct_2___iter__ {
 };
 
 
-/* "libzim.pyx":1167
+/* "libzim.pyx":1159
  *         return resultset
  * 
  *     def __iter__(self) -> Iterator[str]:             # <<<<<<<<<<<<<<
@@ -1310,7 +1311,7 @@ struct __pyx_obj_6libzim___pyx_scope_struct_3___iter__ {
 
 
 
-/* "libzim.pyx":615
+/* "libzim.pyx":607
  * cdef Py_ssize_t itemsize = 1
  * 
  * cdef class ReadingBlob:             # <<<<<<<<<<<<<<
@@ -1324,7 +1325,7 @@ struct __pyx_vtabstruct_6libzim_ReadingBlob {
 static struct __pyx_vtabstruct_6libzim_ReadingBlob *__pyx_vtabptr_6libzim_ReadingBlob;
 
 
-/* "libzim.pyx":665
+/* "libzim.pyx":657
  * 
  * 
  * cdef class Entry:             # <<<<<<<<<<<<<<
@@ -1338,7 +1339,7 @@ struct __pyx_vtabstruct_6libzim_Entry {
 static struct __pyx_vtabstruct_6libzim_Entry *__pyx_vtabptr_6libzim_Entry;
 
 
-/* "libzim.pyx":722
+/* "libzim.pyx":714
  *         return f"{self.__class__.__name__}(url={self.path}, title={self.title})"
  * 
  * cdef class Item:             # <<<<<<<<<<<<<<
@@ -1352,7 +1353,7 @@ struct __pyx_vtabstruct_6libzim_Item {
 static struct __pyx_vtabstruct_6libzim_Item *__pyx_vtabptr_6libzim_Item;
 
 
-/* "libzim.pyx":1055
+/* "libzim.pyx":1047
  * 
  * 
  * cdef class SearchResultSet:             # <<<<<<<<<<<<<<
@@ -1366,7 +1367,7 @@ struct __pyx_vtabstruct_6libzim_SearchResultSet {
 static struct __pyx_vtabstruct_6libzim_SearchResultSet *__pyx_vtabptr_6libzim_SearchResultSet;
 
 
-/* "libzim.pyx":1074
+/* "libzim.pyx":1066
  *             preincrement(current)
  * 
  * cdef class Search:             # <<<<<<<<<<<<<<
@@ -1380,7 +1381,7 @@ struct __pyx_vtabstruct_6libzim_Search {
 static struct __pyx_vtabstruct_6libzim_Search *__pyx_vtabptr_6libzim_Search;
 
 
-/* "libzim.pyx":1156
+/* "libzim.pyx":1148
  * suggestion_module_name = f"{__name__}.suggestion"
  * 
  * cdef class SuggestionResultSet:             # <<<<<<<<<<<<<<
@@ -1394,7 +1395,7 @@ struct __pyx_vtabstruct_6libzim_SuggestionResultSet {
 static struct __pyx_vtabstruct_6libzim_SuggestionResultSet *__pyx_vtabptr_6libzim_SuggestionResultSet;
 
 
-/* "libzim.pyx":1175
+/* "libzim.pyx":1167
  *             preincrement(current)
  * 
  * cdef class SuggestionSearch:             # <<<<<<<<<<<<<<
@@ -1521,18 +1522,18 @@ static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UIN
 
 /* GetModuleGlobalName.proto */
 #if CYTHON_USE_DICT_VERSIONS
-#define __Pyx_GetModuleGlobalName(var, name)  {\
+#define __Pyx_GetModuleGlobalName(var, name)  do {\
     static PY_UINT64_T __pyx_dict_version = 0;\
     static PyObject *__pyx_dict_cached_value = NULL;\
     (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_d))) ?\
         (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\
         __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\
-}
-#define __Pyx_GetModuleGlobalNameUncached(var, name)  {\
+} while(0)
+#define __Pyx_GetModuleGlobalNameUncached(var, name)  do {\
     PY_UINT64_T __pyx_dict_version;\
     PyObject *__pyx_dict_cached_value;\
     (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\
-}
+} while(0)
 static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value);
 #else
 #define __Pyx_GetModuleGlobalName(var, name)  (var) = __Pyx__GetModuleGlobalName(name)
@@ -1912,6 +1913,20 @@ static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
 #define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
 #endif
 
+/* PyUnicode_Unicode.proto */
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Unicode(PyObject *obj);
+
+/* DictGetItem.proto */
+#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY
+static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key);
+#define __Pyx_PyObject_Dict_GetItem(obj, name)\
+    (likely(PyDict_CheckExact(obj)) ?\
+     __Pyx_PyDict_GetItem(obj, name) : PyObject_GetItem(obj, name))
+#else
+#define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
+#define __Pyx_PyObject_Dict_GetItem(obj, name)  PyObject_GetItem(obj, name)
+#endif
+
 /* dict_getitem_default.proto */
 static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObject* default_value);
 
@@ -2316,6 +2331,8 @@ static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
 
 /* Module declarations from 'libcpp.memory' */
 
+/* Module declarations from 'libcpp.pair' */
+
 /* Module declarations from 'libcpp.set' */
 
 /* Module declarations from 'libcpp.string' */
@@ -2364,6 +2381,7 @@ static CYTHON_INLINE PyObject *__pyx_convert_PyBytes_string_to_py_std__in_string
 static CYTHON_INLINE PyObject *__pyx_convert_PyByteArray_string_to_py_std__in_string(std::string const &); /*proto*/
 static std::string __pyx_convert_string_from_py_std__in_string(PyObject *); /*proto*/
 static PyObject *__pyx_convert_set_to_py_unsigned_int(std::set<unsigned int>  const &); /*proto*/
+static PyObject *__pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string(std::pair<std::string,std::string>  const &); /*proto*/
 #define __Pyx_MODULE_NAME "libzim"
 extern int __pyx_module_is_main_libzim;
 int __pyx_module_is_main_libzim = 0;
@@ -2379,13 +2397,15 @@ static PyObject *__pyx_builtin_super;
 static PyObject *__pyx_builtin_open;
 static PyObject *__pyx_builtin_BufferError;
 static PyObject *__pyx_builtin_KeyError;
+static PyObject *__pyx_builtin_print;
 static const char __pyx_k_[] = "";
 static const char __pyx_k_fh[] = "fh";
 static const char __pyx_k_os[] = "os";
 static const char __pyx_k_rb[] = "rb";
 static const char __pyx_k_Set[] = "Set";
 static const char __pyx_k__24[] = ")";
-static const char __pyx_k__25[] = "_";
+static const char __pyx_k__50[] = "+ ";
+static const char __pyx_k__51[] = " ";
 static const char __pyx_k_abc[] = "abc";
 static const char __pyx_k_all[] = "__all__";
 static const char __pyx_k_doc[] = "doc";
@@ -2394,6 +2414,7 @@ static const char __pyx_k_hex[] = "hex";
 static const char __pyx_k_int[] = "int";
 static const char __pyx_k_mro[] = "mro";
 static const char __pyx_k_obj[] = "obj";
+static const char __pyx_k_out[] = "out";
 static const char __pyx_k_res[] = "res";
 static const char __pyx_k_sys[] = "sys";
 static const char __pyx_k_url[] = "(url=";
@@ -2404,6 +2425,7 @@ static const char __pyx_k_Enum[] = "Enum";
 static const char __pyx_k_Hint[] = "Hint";
 static const char __pyx_k_Item[] = "Item";
 static const char __pyx_k_List[] = "List";
+static const char __pyx_k_None[] = "None";
 static const char __pyx_k_Path[] = "Path";
 static const char __pyx_k_UUID[] = "UUID";
 static const char __pyx_k_W_OK[] = "W_OK";
@@ -2414,6 +2436,7 @@ static const char __pyx_k_date[] = "date";
 static const char __pyx_k_enum[] = "enum";
 static const char __pyx_k_exit[] = "__exit__";
 static const char __pyx_k_feed[] = "feed";
+static const char __pyx_k_file[] = "file";
 static const char __pyx_k_init[] = "__init__";
 static const char __pyx_k_iter[] = "__iter__";
 static const char __pyx_k_main[] = "__main__";
@@ -2447,8 +2470,8 @@ static const char __pyx_k_enter[] = "__enter__";
 static const char __pyx_k_hints[] = "hints";
 static const char __pyx_k_items[] = "items";
 static const char __pyx_k_lower[] = "lower";
+static const char __pyx_k_print[] = "print";
 static const char __pyx_k_pyint[] = "pyint";
-static const char __pyx_k_split[] = "split";
 static const char __pyx_k_start[] = "start";
 static const char __pyx_k_super[] = "super";
 static const char __pyx_k_throw[] = "throw";
@@ -2458,6 +2481,7 @@ static const char __pyx_k_value[] = "value";
 static const char __pyx_k_Loader[] = "Loader";
 static const char __pyx_k_Search[] = "Search";
 static const char __pyx_k_access[] = "access";
+static const char __pyx_k_decode[] = "decode";
 static const char __pyx_k_encode[] = "encode";
 static const char __pyx_k_exc_tb[] = "exc_tb";
 static const char __pyx_k_import[] = "__import__";
@@ -2468,11 +2492,13 @@ static const char __pyx_k_name_2[] = "__name__";
 static const char __pyx_k_parent[] = "parent";
 static const char __pyx_k_path_2[] = "(path=";
 static const char __pyx_k_path_3[] = "__path__";
+static const char __pyx_k_prefix[] = "prefix";
 static const char __pyx_k_pybool[] = "pybool";
 static const char __pyx_k_reader[] = "reader";
 static const char __pyx_k_reduce[] = "__reduce__";
 static const char __pyx_k_return[] = "return";
 static const char __pyx_k_search[] = "search";
+static const char __pyx_k_stdout[] = "stdout";
 static const char __pyx_k_target[] = "target";
 static const char __pyx_k_typing[] = "typing";
 static const char __pyx_k_writer[] = "writer";
@@ -2483,7 +2509,7 @@ static const char __pyx_k_archive[] = "archive";
 static const char __pyx_k_content[] = "content";
 static const char __pyx_k_exc_val[] = "exc_val";
 static const char __pyx_k_getsize[] = "getsize";
-static const char __pyx_k_keyword[] = "keyword";
+static const char __pyx_k_library[] = "library";
 static const char __pyx_k_members[] = "members";
 static const char __pyx_k_modules[] = "modules";
 static const char __pyx_k_pathlib[] = "pathlib";
@@ -2491,6 +2517,7 @@ static const char __pyx_k_prepare[] = "__prepare__";
 static const char __pyx_k_resolve[] = "resolve";
 static const char __pyx_k_title_2[] = ", title=";
 static const char __pyx_k_unicode[] = "unicode";
+static const char __pyx_k_version[] = "version";
 static const char __pyx_k_COMPRESS[] = "COMPRESS";
 static const char __pyx_k_Iterator[] = "Iterator";
 static const char __pyx_k_KeyError[] = "KeyError";
@@ -2515,6 +2542,7 @@ static const char __pyx_k_reader_2[] = ".reader";
 static const char __pyx_k_search_2[] = ".search";
 static const char __pyx_k_setstate[] = "__setstate__";
 static const char __pyx_k_strftime[] = "strftime";
+static const char __pyx_k_versions[] = "versions";
 static const char __pyx_k_writer_2[] = ".writer";
 static const char __pyx_k_Creator_2[] = "Creator";
 static const char __pyx_k_Generator[] = "Generator";
@@ -2528,9 +2556,9 @@ static const char __pyx_k_importlib[] = "importlib";
 static const char __pyx_k_machinery[] = "machinery";
 static const char __pyx_k_meta_path[] = "meta_path";
 static const char __pyx_k_metaclass[] = "__metaclass__";
-static const char __pyx_k_pascalize[] = "pascalize";
 static const char __pyx_k_reduce_ex[] = "__reduce_ex__";
 static const char __pyx_k_traceback[] = "traceback";
+static const char __pyx_k_version_2[] = ".version";
 static const char __pyx_k_ModuleSpec[] = "ModuleSpec";
 static const char __pyx_k_ModuleType[] = "ModuleType";
 static const char __pyx_k_expanduser[] = "expanduser";
@@ -2543,8 +2571,10 @@ static const char __pyx_k_suggestion[] = "suggestion";
 static const char __pyx_k_targetPath[] = "targetPath";
 static const char __pyx_k_BufferError[] = "BufferError";
 static const char __pyx_k_Compression[] = "Compression";
+static const char __pyx_k_OrderedDict[] = "OrderedDict";
 static const char __pyx_k_ReadingBlob[] = "ReadingBlob";
 static const char __pyx_k_WritingBlob[] = "WritingBlob";
+static const char __pyx_k_collections[] = "collections";
 static const char __pyx_k_compression[] = "compression";
 static const char __pyx_k_exec_module[] = "exec_module";
 static const char __pyx_k_get_content[] = "get_content";
@@ -2556,6 +2586,7 @@ static const char __pyx_k_RuntimeError[] = "RuntimeError";
 static const char __pyx_k_add_metadata[] = "add_metadata";
 static const char __pyx_k_get_keywords[] = "get_keywords";
 static const char __pyx_k_get_mimetype[] = "get_mimetype";
+static const char __pyx_k_get_versions[] = "get_versions";
 static const char __pyx_k_staticmethod[] = "staticmethod";
 static const char __pyx_k_suggestion_2[] = ".suggestion";
 static const char __pyx_k_FRONT_ARTICLE[] = "FRONT_ARTICLE";
@@ -2573,6 +2604,8 @@ static const char __pyx_k_Blob_has_views[] = "Blob has views";
 static const char __pyx_k_Creator___repr[] = "Creator.__repr__";
 static const char __pyx_k_MetaPathFinder[] = "MetaPathFinder";
 static const char __pyx_k_StringProvider[] = "StringProvider";
+static const char __pyx_k_libzim_version[] = "libzim.version";
+static const char __pyx_k_print_versions[] = "print_versions";
 static const char __pyx_k_BaseWritingItem[] = "BaseWritingItem";
 static const char __pyx_k_ContentProvider[] = "ContentProvider";
 static const char __pyx_k_Creator_started[] = "Creator started";
@@ -2589,8 +2622,10 @@ static const char __pyx_k_writer_module_doc[] = "writer_module_doc";
 static const char __pyx_k_SuggestionSearcher[] = "SuggestionSearcher";
 static const char __pyx_k_cline_in_traceback[] = "cline_in_traceback";
 static const char __pyx_k_config_compression[] = "config_compression";
+static const char __pyx_k_get_libzim_version[] = "get_libzim_version";
 static const char __pyx_k_reader_module_name[] = "reader_module_name";
 static const char __pyx_k_search_module_name[] = "search_module_name";
+static const char __pyx_k_version_module_doc[] = "version_module_doc";
 static const char __pyx_k_writer_module_name[] = "writer_module_name";
 static const char __pyx_k_Creator_not_started[] = "Creator not started";
 static const char __pyx_k_FileProvider___init[] = "FileProvider.__init__";
@@ -2598,6 +2633,7 @@ static const char __pyx_k_IndexData_get_title[] = "IndexData.get_title";
 static const char __pyx_k_NotImplementedError[] = "NotImplementedError";
 static const char __pyx_k_SuggestionResultSet[] = "SuggestionResultSet";
 static const char __pyx_k_get_contentprovider[] = "get_contentprovider";
+static const char __pyx_k_version_module_name[] = "version_module_name";
 static const char __pyx_k_ContentProvider_feed[] = "ContentProvider.feed";
 static const char __pyx_k_Creator_add_metadata[] = "Creator.add_metadata";
 static const char __pyx_k_FileProvider_gen_blob[] = "FileProvider.gen_blob";
@@ -2616,6 +2652,7 @@ static const char __pyx_k_ModuleFinder_find_spec[] = "ModuleFinder.find_spec";
 static const char __pyx_k_SearchResultSet___iter[] = "SearchResultSet.__iter__";
 static const char __pyx_k_suggestion_module_name[] = "suggestion_module_name";
 static const char __pyx_k_supports_effective_ids[] = "supports_effective_ids";
+static const char __pyx_k_version_public_objects[] = "version_public_objects";
 static const char __pyx_k_ContentProvider_is_None[] = "ContentProvider is None";
 static const char __pyx_k_IndexData_get_wordcount[] = "IndexData.get_wordcount";
 static const char __pyx_k_IndexData_has_indexdata[] = "IndexData.has_indexdata";
@@ -2658,6 +2695,7 @@ static const char __pyx_k_get_mimetype_must_be_implemented[] = "get_mimetype mus
 static const char __pyx_k_get_wordcount_must_be_implemente[] = "get_wordcount must be implemented.";
 static const char __pyx_k_libzim_search_module_Query_to_pr[] = "libzim search module\n\n- Query to prepare a query from a string\n- Searcher to perform a search over a libzim.reader.Archive\n\nUsage:\n\narchive = libzim.reader.Archive(fpath)\nsearcher = Searcher(archive)\nquery = Query().setQuery(\"foo\")\nsearch = searcher.search(query)\nfor path in search.getResult(10, 10) # get result from 10 to 20 (10 results)\n    print(path, archive.get_entry_by_path(path).title)";
 static const char __pyx_k_libzim_suggestion_module_Suggest[] = "libzim suggestion module\n\n- SuggestionSearcher to perform a suggestion search over a libzim.reader.Archive\n\nUsage:\n\narchive = Archive(fpath)\nsuggestion_searcher = SuggestionSearcher(archive)\nsuggestions = suggestion_searcher.suggest(\"foo\")\nfor path in suggestion.getResult(10, 10) # get result from 10 to 20 (10 results)\n    print(path, archive.get_entry_by_path(path).title)";
+static const char __pyx_k_libzim_version_module_Get_versio[] = "libzim version module\n- Get version of libzim and its dependencies\n- Print version of libzim and its dependencies\n- Get libzim version\n\nUsage:\n    from libzim.version import get_libzim_version, get_versions, print_versions\n    major, minor, patch = get_libzim_version().split(\".\", 2)\n\n    for dependency, version in get_versions().items():\n        print(f\"- {dependency}={version}\")\n\n    print_versions()";
 static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__";
 static const char __pyx_k_openZIM_s_file_format_library_bi[] = "openZIM's file format library binding\n\n- libzim.writer to create ZIM file with Creator\n- libzim.reader to open ZIM file as Archive\n- libzim.search to search on an Archive\n- libzim.suggestion to retrieve suggestions on an Archive\n\nhttps://openzim.org";
 static const char __pyx_k_self_c_entry_cannot_be_converted[] = "self.c_entry cannot be converted to a Python object for pickling";
@@ -2734,8 +2772,10 @@ static PyObject *__pyx_n_s_ModuleLoader_create_module;
 static PyObject *__pyx_n_s_ModuleLoader_exec_module;
 static PyObject *__pyx_n_s_ModuleSpec;
 static PyObject *__pyx_n_s_ModuleType;
+static PyObject *__pyx_kp_u_None;
 static PyObject *__pyx_n_s_NotImplementedError;
 static PyObject *__pyx_n_s_Optional;
+static PyObject *__pyx_n_s_OrderedDict;
 static PyObject *__pyx_n_s_Path;
 static PyObject *__pyx_n_s_Query;
 static PyObject *__pyx_n_s_ReadingBlob;
@@ -2765,7 +2805,8 @@ static PyObject *__pyx_n_s_WritingBlob;
 static PyObject *__pyx_n_u_WritingBlob;
 static PyObject *__pyx_kp_u_Y_m_d;
 static PyObject *__pyx_kp_u__24;
-static PyObject *__pyx_n_u__25;
+static PyObject *__pyx_kp_u__50;
+static PyObject *__pyx_kp_u__51;
 static PyObject *__pyx_n_s_abc;
 static PyObject *__pyx_n_s_access;
 static PyObject *__pyx_n_s_add_metadata;
@@ -2779,6 +2820,7 @@ static PyObject *__pyx_n_s_bsize;
 static PyObject *__pyx_n_s_class;
 static PyObject *__pyx_n_s_cline_in_traceback;
 static PyObject *__pyx_n_s_close;
+static PyObject *__pyx_n_s_collections;
 static PyObject *__pyx_n_s_compression;
 static PyObject *__pyx_n_s_config_compression;
 static PyObject *__pyx_n_s_content;
@@ -2786,6 +2828,7 @@ static PyObject *__pyx_n_s_count;
 static PyObject *__pyx_n_s_create_module;
 static PyObject *__pyx_n_s_date;
 static PyObject *__pyx_n_s_datetime;
+static PyObject *__pyx_n_s_decode;
 static PyObject *__pyx_n_s_doc;
 static PyObject *__pyx_n_s_doc_2;
 static PyObject *__pyx_n_s_effective_ids;
@@ -2800,6 +2843,7 @@ static PyObject *__pyx_n_s_exit;
 static PyObject *__pyx_n_s_expanduser;
 static PyObject *__pyx_n_s_feed;
 static PyObject *__pyx_n_s_fh;
+static PyObject *__pyx_n_s_file;
 static PyObject *__pyx_n_s_filename;
 static PyObject *__pyx_kp_u_filename_2;
 static PyObject *__pyx_n_s_filepath;
@@ -2819,6 +2863,7 @@ static PyObject *__pyx_n_s_get_hints;
 static PyObject *__pyx_kp_u_get_hints_must_be_implemented;
 static PyObject *__pyx_n_s_get_keywords;
 static PyObject *__pyx_kp_u_get_keywords_must_be_implemented;
+static PyObject *__pyx_n_s_get_libzim_version;
 static PyObject *__pyx_n_s_get_mimetype;
 static PyObject *__pyx_kp_u_get_mimetype_must_be_implemented;
 static PyObject *__pyx_n_s_get_path;
@@ -2827,6 +2872,7 @@ static PyObject *__pyx_n_s_get_size;
 static PyObject *__pyx_kp_u_get_size_must_be_implemented;
 static PyObject *__pyx_n_s_get_title;
 static PyObject *__pyx_kp_u_get_title_must_be_implemented;
+static PyObject *__pyx_n_s_get_versions;
 static PyObject *__pyx_n_s_get_wordcount;
 static PyObject *__pyx_kp_u_get_wordcount_must_be_implemente;
 static PyObject *__pyx_n_s_getsize;
@@ -2843,9 +2889,10 @@ static PyObject *__pyx_n_s_insert;
 static PyObject *__pyx_n_u_int;
 static PyObject *__pyx_n_s_items;
 static PyObject *__pyx_n_s_iter;
-static PyObject *__pyx_n_s_keyword;
 static PyObject *__pyx_n_s_language;
+static PyObject *__pyx_n_s_library;
 static PyObject *__pyx_n_s_libzim;
+static PyObject *__pyx_n_u_libzim;
 static PyObject *__pyx_kp_u_libzim_2;
 static PyObject *__pyx_kp_s_libzim_libzim_pyx;
 static PyObject *__pyx_kp_u_libzim_reader;
@@ -2854,6 +2901,8 @@ static PyObject *__pyx_kp_u_libzim_search;
 static PyObject *__pyx_kp_u_libzim_search_module_Query_to_pr;
 static PyObject *__pyx_kp_u_libzim_suggestion;
 static PyObject *__pyx_kp_u_libzim_suggestion_module_Suggest;
+static PyObject *__pyx_kp_u_libzim_version;
+static PyObject *__pyx_kp_u_libzim_version_module_Get_versio;
 static PyObject *__pyx_kp_u_libzim_writer;
 static PyObject *__pyx_kp_u_libzim_writer_module_Creator_to;
 static PyObject *__pyx_n_s_lower;
@@ -2876,13 +2925,16 @@ static PyObject *__pyx_n_s_none;
 static PyObject *__pyx_n_s_obj;
 static PyObject *__pyx_n_s_open;
 static PyObject *__pyx_n_s_os;
+static PyObject *__pyx_n_s_out;
 static PyObject *__pyx_n_s_parent;
-static PyObject *__pyx_n_s_pascalize;
 static PyObject *__pyx_n_s_path;
 static PyObject *__pyx_kp_u_path_2;
 static PyObject *__pyx_n_s_path_3;
 static PyObject *__pyx_n_s_pathlib;
+static PyObject *__pyx_n_s_prefix;
 static PyObject *__pyx_n_s_prepare;
+static PyObject *__pyx_n_s_print;
+static PyObject *__pyx_n_s_print_versions;
 static PyObject *__pyx_n_s_pybool;
 static PyObject *__pyx_n_s_pyint;
 static PyObject *__pyx_n_s_pyx_vtable;
@@ -2920,10 +2972,10 @@ static PyObject *__pyx_n_s_setstate;
 static PyObject *__pyx_n_s_setstate_cython;
 static PyObject *__pyx_n_s_size;
 static PyObject *__pyx_n_s_spec;
-static PyObject *__pyx_n_s_split;
 static PyObject *__pyx_n_s_start;
 static PyObject *__pyx_n_s_startswith;
 static PyObject *__pyx_n_s_staticmethod;
+static PyObject *__pyx_n_s_stdout;
 static PyObject *__pyx_n_s_strftime;
 static PyObject *__pyx_n_s_suggestion;
 static PyObject *__pyx_n_u_suggestion;
@@ -2948,6 +3000,13 @@ static PyObject *__pyx_n_u_unicode;
 static PyObject *__pyx_kp_u_url;
 static PyObject *__pyx_n_s_uuid;
 static PyObject *__pyx_n_s_value;
+static PyObject *__pyx_n_s_version;
+static PyObject *__pyx_n_u_version;
+static PyObject *__pyx_kp_u_version_2;
+static PyObject *__pyx_n_s_version_module_doc;
+static PyObject *__pyx_n_s_version_module_name;
+static PyObject *__pyx_n_s_version_public_objects;
+static PyObject *__pyx_n_s_versions;
 static PyObject *__pyx_n_s_writer;
 static PyObject *__pyx_n_u_writer;
 static PyObject *__pyx_kp_u_writer_2;
@@ -3000,7 +3059,6 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_6get_mimetype(CYTHON_UNUSED
 static PyObject *__pyx_pf_6libzim_15BaseWritingItem_8get_contentprovider(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_6libzim_15BaseWritingItem_10get_hints(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_6libzim_15BaseWritingItem_12__repr__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_6libzim_2pascalize(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_keyword); /* proto */
 static PyObject *__pyx_pf_6libzim_7Creator_config_compression(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_compression); /* proto */
 static PyObject *__pyx_pf_6libzim_7Creator_2add_metadata(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_name, PyObject *__pyx_v_content, PyObject *__pyx_v_mimetype); /* proto */
 static PyObject *__pyx_pf_6libzim_7Creator_4__repr__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
@@ -3084,6 +3142,9 @@ static int __pyx_pf_6libzim_18SuggestionSearcher___cinit__(struct __pyx_obj_6lib
 static struct __pyx_obj_6libzim_SuggestionSearch *__pyx_pf_6libzim_18SuggestionSearcher_2suggest(struct __pyx_obj_6libzim_SuggestionSearcher *__pyx_v_self, PyObject *__pyx_v_query); /* proto */
 static PyObject *__pyx_pf_6libzim_18SuggestionSearcher_4__reduce_cython__(CYTHON_UNUSED struct __pyx_obj_6libzim_SuggestionSearcher *__pyx_v_self); /* proto */
 static PyObject *__pyx_pf_6libzim_18SuggestionSearcher_6__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_6libzim_SuggestionSearcher *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state); /* proto */
+static PyObject *__pyx_pf_6libzim_2print_versions(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_out); /* proto */
+static PyObject *__pyx_pf_6libzim_4get_versions(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_6libzim_6get_libzim_version(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
 static PyObject *__pyx_pf_6libzim_12ModuleLoader_create_module(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_spec); /* proto */
 static PyObject *__pyx_pf_6libzim_12ModuleLoader_2exec_module(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_module); /* proto */
 static PyObject *__pyx_pf_6libzim_12ModuleFinder_find_spec(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_fullname, CYTHON_UNUSED PyObject *__pyx_v_path, CYTHON_UNUSED PyObject *__pyx_v_target); /* proto */
@@ -3107,6 +3168,7 @@ static PyObject *__pyx_tp_new_6libzim___pyx_scope_struct_3___iter__(PyTypeObject
 static __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_get = {0, &__pyx_n_s_get, 0, 0, 0};
 static PyObject *__pyx_int_0;
 static PyObject *__pyx_int_1;
+static PyObject *__pyx_k__49;
 static PyObject *__pyx_tuple__2;
 static PyObject *__pyx_tuple__3;
 static PyObject *__pyx_tuple__4;
@@ -3127,6 +3189,7 @@ static PyObject *__pyx_tuple__20;
 static PyObject *__pyx_tuple__21;
 static PyObject *__pyx_tuple__22;
 static PyObject *__pyx_tuple__23;
+static PyObject *__pyx_tuple__25;
 static PyObject *__pyx_tuple__26;
 static PyObject *__pyx_tuple__27;
 static PyObject *__pyx_tuple__28;
@@ -3150,8 +3213,6 @@ static PyObject *__pyx_tuple__45;
 static PyObject *__pyx_tuple__46;
 static PyObject *__pyx_tuple__47;
 static PyObject *__pyx_tuple__48;
-static PyObject *__pyx_tuple__49;
-static PyObject *__pyx_tuple__50;
 static PyObject *__pyx_tuple__52;
 static PyObject *__pyx_tuple__54;
 static PyObject *__pyx_tuple__56;
@@ -3159,10 +3220,10 @@ static PyObject *__pyx_tuple__58;
 static PyObject *__pyx_tuple__60;
 static PyObject *__pyx_tuple__62;
 static PyObject *__pyx_tuple__64;
-static PyObject *__pyx_tuple__65;
+static PyObject *__pyx_tuple__66;
 static PyObject *__pyx_tuple__67;
 static PyObject *__pyx_tuple__69;
-static PyObject *__pyx_tuple__70;
+static PyObject *__pyx_tuple__71;
 static PyObject *__pyx_tuple__72;
 static PyObject *__pyx_tuple__74;
 static PyObject *__pyx_tuple__76;
@@ -3182,20 +3243,21 @@ static PyObject *__pyx_tuple__102;
 static PyObject *__pyx_tuple__103;
 static PyObject *__pyx_tuple__105;
 static PyObject *__pyx_tuple__107;
-static PyObject *__pyx_tuple__109;
-static PyObject *__pyx_tuple__111;
+static PyObject *__pyx_tuple__110;
+static PyObject *__pyx_tuple__112;
+static PyObject *__pyx_tuple__114;
+static PyObject *__pyx_tuple__116;
 static PyObject *__pyx_codeobj__13;
 static PyObject *__pyx_codeobj__14;
-static PyObject *__pyx_codeobj__51;
 static PyObject *__pyx_codeobj__53;
 static PyObject *__pyx_codeobj__55;
 static PyObject *__pyx_codeobj__57;
 static PyObject *__pyx_codeobj__59;
 static PyObject *__pyx_codeobj__61;
 static PyObject *__pyx_codeobj__63;
-static PyObject *__pyx_codeobj__66;
+static PyObject *__pyx_codeobj__65;
 static PyObject *__pyx_codeobj__68;
-static PyObject *__pyx_codeobj__71;
+static PyObject *__pyx_codeobj__70;
 static PyObject *__pyx_codeobj__73;
 static PyObject *__pyx_codeobj__75;
 static PyObject *__pyx_codeobj__77;
@@ -3214,10 +3276,13 @@ static PyObject *__pyx_codeobj__101;
 static PyObject *__pyx_codeobj__104;
 static PyObject *__pyx_codeobj__106;
 static PyObject *__pyx_codeobj__108;
-static PyObject *__pyx_codeobj__110;
+static PyObject *__pyx_codeobj__109;
+static PyObject *__pyx_codeobj__111;
+static PyObject *__pyx_codeobj__113;
+static PyObject *__pyx_codeobj__115;
 /* Late includes */
 
-/* "libzim.pyx":61
+/* "libzim.pyx":62
  * pyint = type(1)
  * 
  * def create_module(name, doc, members):             # <<<<<<<<<<<<<<
@@ -3264,17 +3329,17 @@ static PyObject *__pyx_pw_6libzim_1create_module(PyObject *__pyx_self, PyObject
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_doc)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("create_module", 1, 3, 3, 1); __PYX_ERR(0, 61, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("create_module", 1, 3, 3, 1); __PYX_ERR(0, 62, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
         if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_members)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("create_module", 1, 3, 3, 2); __PYX_ERR(0, 61, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("create_module", 1, 3, 3, 2); __PYX_ERR(0, 62, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "create_module") < 0)) __PYX_ERR(0, 61, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "create_module") < 0)) __PYX_ERR(0, 62, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -3289,7 +3354,7 @@ static PyObject *__pyx_pw_6libzim_1create_module(PyObject *__pyx_self, PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("create_module", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 61, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("create_module", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 62, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.create_module", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -3324,14 +3389,14 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
   __Pyx_RefNannySetupContext("create_module", 0);
   __Pyx_INCREF(__pyx_v_name);
 
-  /* "libzim.pyx":63
+  /* "libzim.pyx":64
  * def create_module(name, doc, members):
  *     """Create/define a module for name and docstring, populated by members"""
  *     module = ModuleType(name, doc)             # <<<<<<<<<<<<<<
  *     _all = []
  *     for obj in members:
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_ModuleType); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 63, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_ModuleType); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 64, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_t_3 = NULL;
   __pyx_t_4 = 0;
@@ -3348,7 +3413,7 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
   #if CYTHON_FAST_PYCALL
   if (PyFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_3, __pyx_v_name, __pyx_v_doc};
-    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_4, 2+__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 63, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_4, 2+__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 64, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_GOTREF(__pyx_t_1);
   } else
@@ -3356,13 +3421,13 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
   #if CYTHON_FAST_PYCCALL
   if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
     PyObject *__pyx_temp[3] = {__pyx_t_3, __pyx_v_name, __pyx_v_doc};
-    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_4, 2+__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 63, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_4, 2+__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 64, __pyx_L1_error)
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_GOTREF(__pyx_t_1);
   } else
   #endif
   {
-    __pyx_t_5 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 63, __pyx_L1_error)
+    __pyx_t_5 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 64, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     if (__pyx_t_3) {
       __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __pyx_t_3 = NULL;
@@ -3373,7 +3438,7 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
     __Pyx_INCREF(__pyx_v_doc);
     __Pyx_GIVEREF(__pyx_v_doc);
     PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, __pyx_v_doc);
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 63, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 64, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   }
@@ -3381,19 +3446,19 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
   __pyx_v_module = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "libzim.pyx":64
+  /* "libzim.pyx":65
  *     """Create/define a module for name and docstring, populated by members"""
  *     module = ModuleType(name, doc)
  *     _all = []             # <<<<<<<<<<<<<<
  *     for obj in members:
  *         if isinstance(obj, tuple):
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 64, __pyx_L1_error)
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 65, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v__all = ((PyObject*)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "libzim.pyx":65
+  /* "libzim.pyx":66
  *     module = ModuleType(name, doc)
  *     _all = []
  *     for obj in members:             # <<<<<<<<<<<<<<
@@ -3404,26 +3469,26 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
     __pyx_t_1 = __pyx_v_members; __Pyx_INCREF(__pyx_t_1); __pyx_t_6 = 0;
     __pyx_t_7 = NULL;
   } else {
-    __pyx_t_6 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_members); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 65, __pyx_L1_error)
+    __pyx_t_6 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_members); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 66, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_7 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 65, __pyx_L1_error)
+    __pyx_t_7 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 66, __pyx_L1_error)
   }
   for (;;) {
     if (likely(!__pyx_t_7)) {
       if (likely(PyList_CheckExact(__pyx_t_1))) {
         if (__pyx_t_6 >= PyList_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely(0 < 0)) __PYX_ERR(0, 65, __pyx_L1_error)
+        __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely(0 < 0)) __PYX_ERR(0, 66, __pyx_L1_error)
         #else
-        __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 65, __pyx_L1_error)
+        __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 66, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         #endif
       } else {
         if (__pyx_t_6 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
         #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
-        __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely(0 < 0)) __PYX_ERR(0, 65, __pyx_L1_error)
+        __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_2); __pyx_t_6++; if (unlikely(0 < 0)) __PYX_ERR(0, 66, __pyx_L1_error)
         #else
-        __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 65, __pyx_L1_error)
+        __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 66, __pyx_L1_error)
         __Pyx_GOTREF(__pyx_t_2);
         #endif
       }
@@ -3433,7 +3498,7 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
         PyObject* exc_type = PyErr_Occurred();
         if (exc_type) {
           if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
-          else __PYX_ERR(0, 65, __pyx_L1_error)
+          else __PYX_ERR(0, 66, __pyx_L1_error)
         }
         break;
       }
@@ -3442,7 +3507,7 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
     __Pyx_XDECREF_SET(__pyx_v_obj, __pyx_t_2);
     __pyx_t_2 = 0;
 
-    /* "libzim.pyx":66
+    /* "libzim.pyx":67
  *     _all = []
  *     for obj in members:
  *         if isinstance(obj, tuple):             # <<<<<<<<<<<<<<
@@ -3453,31 +3518,31 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
     __pyx_t_9 = (__pyx_t_8 != 0);
     if (__pyx_t_9) {
 
-      /* "libzim.pyx":67
+      /* "libzim.pyx":68
  *     for obj in members:
  *         if isinstance(obj, tuple):
  *             name = obj[0]             # <<<<<<<<<<<<<<
  *             obj = obj[1]
  *         else:
  */
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_obj, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 67, __pyx_L1_error)
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_obj, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 68, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF_SET(__pyx_v_name, __pyx_t_2);
       __pyx_t_2 = 0;
 
-      /* "libzim.pyx":68
+      /* "libzim.pyx":69
  *         if isinstance(obj, tuple):
  *             name = obj[0]
  *             obj = obj[1]             # <<<<<<<<<<<<<<
  *         else:
  *             name = obj.__name__
  */
-      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_obj, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 68, __pyx_L1_error)
+      __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_obj, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 69, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_2);
       __pyx_t_2 = 0;
 
-      /* "libzim.pyx":66
+      /* "libzim.pyx":67
  *     _all = []
  *     for obj in members:
  *         if isinstance(obj, tuple):             # <<<<<<<<<<<<<<
@@ -3487,7 +3552,7 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
       goto __pyx_L5;
     }
 
-    /* "libzim.pyx":70
+    /* "libzim.pyx":71
  *             obj = obj[1]
  *         else:
  *             name = obj.__name__             # <<<<<<<<<<<<<<
@@ -3495,32 +3560,32 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
  *         _all.append(name)
  */
     /*else*/ {
-      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_obj, __pyx_n_s_name_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 70, __pyx_L1_error)
+      __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_obj, __pyx_n_s_name_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 71, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF_SET(__pyx_v_name, __pyx_t_2);
       __pyx_t_2 = 0;
     }
     __pyx_L5:;
 
-    /* "libzim.pyx":71
+    /* "libzim.pyx":72
  *         else:
  *             name = obj.__name__
  *         setattr(module, name, obj)             # <<<<<<<<<<<<<<
  *         _all.append(name)
  *     module.__all__ = _all
  */
-    __pyx_t_10 = PyObject_SetAttr(__pyx_v_module, __pyx_v_name, __pyx_v_obj); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 71, __pyx_L1_error)
+    __pyx_t_10 = PyObject_SetAttr(__pyx_v_module, __pyx_v_name, __pyx_v_obj); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 72, __pyx_L1_error)
 
-    /* "libzim.pyx":72
+    /* "libzim.pyx":73
  *             name = obj.__name__
  *         setattr(module, name, obj)
  *         _all.append(name)             # <<<<<<<<<<<<<<
  *     module.__all__ = _all
  *     sys.modules[name] = module
  */
-    __pyx_t_10 = __Pyx_PyList_Append(__pyx_v__all, __pyx_v_name); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 72, __pyx_L1_error)
+    __pyx_t_10 = __Pyx_PyList_Append(__pyx_v__all, __pyx_v_name); if (unlikely(__pyx_t_10 == ((int)-1))) __PYX_ERR(0, 73, __pyx_L1_error)
 
-    /* "libzim.pyx":65
+    /* "libzim.pyx":66
  *     module = ModuleType(name, doc)
  *     _all = []
  *     for obj in members:             # <<<<<<<<<<<<<<
@@ -3530,31 +3595,31 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":73
+  /* "libzim.pyx":74
  *         setattr(module, name, obj)
  *         _all.append(name)
  *     module.__all__ = _all             # <<<<<<<<<<<<<<
  *     sys.modules[name] = module
  *     return module
  */
-  if (__Pyx_PyObject_SetAttrStr(__pyx_v_module, __pyx_n_s_all, __pyx_v__all) < 0) __PYX_ERR(0, 73, __pyx_L1_error)
+  if (__Pyx_PyObject_SetAttrStr(__pyx_v_module, __pyx_n_s_all, __pyx_v__all) < 0) __PYX_ERR(0, 74, __pyx_L1_error)
 
-  /* "libzim.pyx":74
+  /* "libzim.pyx":75
  *         _all.append(name)
  *     module.__all__ = _all
  *     sys.modules[name] = module             # <<<<<<<<<<<<<<
  *     return module
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_sys); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 74, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_sys); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 75, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_modules); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 74, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_modules); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 75, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (unlikely(PyObject_SetItem(__pyx_t_2, __pyx_v_name, __pyx_v_module) < 0)) __PYX_ERR(0, 74, __pyx_L1_error)
+  if (unlikely(PyObject_SetItem(__pyx_t_2, __pyx_v_name, __pyx_v_module) < 0)) __PYX_ERR(0, 75, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":75
+  /* "libzim.pyx":76
  *     module.__all__ = _all
  *     sys.modules[name] = module
  *     return module             # <<<<<<<<<<<<<<
@@ -3566,7 +3631,7 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
   __pyx_r = __pyx_v_module;
   goto __pyx_L0;
 
-  /* "libzim.pyx":61
+  /* "libzim.pyx":62
  * pyint = type(1)
  * 
  * def create_module(name, doc, members):             # <<<<<<<<<<<<<<
@@ -3592,7 +3657,7 @@ static PyObject *__pyx_pf_6libzim_create_module(CYTHON_UNUSED PyObject *__pyx_se
   return __pyx_r;
 }
 
-/* "libzim.pyx":82
+/* "libzim.pyx":83
  * 
  * # This calls a python method and returns a python object.
  * cdef object call_method(object obj, string method):             # <<<<<<<<<<<<<<
@@ -3612,22 +3677,22 @@ static PyObject *__pyx_f_6libzim_call_method(PyObject *__pyx_v_obj, std::string
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("call_method", 0);
 
-  /* "libzim.pyx":83
+  /* "libzim.pyx":84
  * # This calls a python method and returns a python object.
  * cdef object call_method(object obj, string method):
  *     func = getattr(obj, method.decode('UTF-8'))             # <<<<<<<<<<<<<<
  *     return func()
  * 
  */
-  __pyx_t_1 = __Pyx_decode_cpp_string(__pyx_v_method, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 83, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_decode_cpp_string(__pyx_v_method, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 84, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_GetAttr(__pyx_v_obj, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 83, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_GetAttr(__pyx_v_obj, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 84, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_v_func = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "libzim.pyx":84
+  /* "libzim.pyx":85
  * cdef object call_method(object obj, string method):
  *     func = getattr(obj, method.decode('UTF-8'))
  *     return func()             # <<<<<<<<<<<<<<
@@ -3648,14 +3713,14 @@ static PyObject *__pyx_f_6libzim_call_method(PyObject *__pyx_v_obj, std::string
   }
   __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 84, __pyx_L1_error)
+  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 85, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":82
+  /* "libzim.pyx":83
  * 
  * # This calls a python method and returns a python object.
  * cdef object call_method(object obj, string method):             # <<<<<<<<<<<<<<
@@ -3677,7 +3742,7 @@ static PyObject *__pyx_f_6libzim_call_method(PyObject *__pyx_v_obj, std::string
   return __pyx_r;
 }
 
-/* "libzim.pyx":90
+/* "libzim.pyx":91
  * # Will be used by cpp side to call python method.
  * cdef public api:
  *     bool obj_has_attribute(object obj, string attribute) with gil:             # <<<<<<<<<<<<<<
@@ -3699,21 +3764,21 @@ bool obj_has_attribute(PyObject *__pyx_v_obj, std::string __pyx_v_attribute) {
   __Pyx_RefNannySetupContext("obj_has_attribute", 0);
   __Pyx_INCREF(__pyx_v_obj);
 
-  /* "libzim.pyx":92
+  /* "libzim.pyx":93
  *     bool obj_has_attribute(object obj, string attribute) with gil:
  *         """Check if a object has a given attribute"""
  *         return hasattr(obj, attribute.decode('UTF-8'))             # <<<<<<<<<<<<<<
  * 
  *     string string_cy_call_fct(object obj, string method, string *error) with gil:
  */
-  __pyx_t_1 = __Pyx_decode_cpp_string(__pyx_v_attribute, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 92, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_decode_cpp_string(__pyx_v_attribute, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_HasAttr(__pyx_v_obj, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 92, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_HasAttr(__pyx_v_obj, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 93, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_2;
   goto __pyx_L0;
 
-  /* "libzim.pyx":90
+  /* "libzim.pyx":91
  * # Will be used by cpp side to call python method.
  * cdef public api:
  *     bool obj_has_attribute(object obj, string attribute) with gil:             # <<<<<<<<<<<<<<
@@ -3735,7 +3800,7 @@ bool obj_has_attribute(PyObject *__pyx_v_obj, std::string __pyx_v_attribute) {
   return __pyx_r;
 }
 
-/* "libzim.pyx":94
+/* "libzim.pyx":95
  *         return hasattr(obj, attribute.decode('UTF-8'))
  * 
  *     string string_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -3777,7 +3842,7 @@ std::string string_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
   __Pyx_RefNannySetupContext("string_cy_call_fct", 0);
   __Pyx_INCREF(__pyx_v_obj);
 
-  /* "libzim.pyx":96
+  /* "libzim.pyx":97
  *     string string_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a string"""
  *         try:             # <<<<<<<<<<<<<<
@@ -3793,26 +3858,26 @@ std::string string_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "libzim.pyx":97
+      /* "libzim.pyx":98
  *         """Lookup and execute a pure virtual method on object returning a string"""
  *         try:
  *             ret_str = call_method(obj, method)             # <<<<<<<<<<<<<<
  *             return ret_str.encode('UTF-8')
  *         except Exception as e:
  */
-      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 97, __pyx_L3_error)
+      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 98, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_v_ret_str = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "libzim.pyx":98
+      /* "libzim.pyx":99
  *         try:
  *             ret_str = call_method(obj, method)
  *             return ret_str.encode('UTF-8')             # <<<<<<<<<<<<<<
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')
  */
-      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_ret_str, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 98, __pyx_L3_error)
+      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_ret_str, __pyx_n_s_encode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 99, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_5);
       __pyx_t_6 = NULL;
       if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -3826,15 +3891,15 @@ std::string string_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
       }
       __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_kp_u_UTF_8);
       __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 98, __pyx_L3_error)
+      if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 99, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_7 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 98, __pyx_L3_error)
+      __pyx_t_7 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 99, __pyx_L3_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_r = __pyx_t_7;
       goto __pyx_L7_try_return;
 
-      /* "libzim.pyx":96
+      /* "libzim.pyx":97
  *     string string_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a string"""
  *         try:             # <<<<<<<<<<<<<<
@@ -3847,7 +3912,7 @@ std::string string_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-    /* "libzim.pyx":99
+    /* "libzim.pyx":100
  *             ret_str = call_method(obj, method)
  *             return ret_str.encode('UTF-8')
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -3857,7 +3922,7 @@ std::string string_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
     __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_8) {
       __Pyx_AddTraceback("libzim.string_cy_call_fct", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6) < 0) __PYX_ERR(0, 99, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6) < 0) __PYX_ERR(0, 100, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_GOTREF(__pyx_t_6);
@@ -3865,16 +3930,16 @@ std::string string_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
       __pyx_v_e = __pyx_t_5;
       /*try:*/ {
 
-        /* "libzim.pyx":100
+        /* "libzim.pyx":101
  *             return ret_str.encode('UTF-8')
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')             # <<<<<<<<<<<<<<
  *         return b""
  * 
  */
-        __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_traceback); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 100, __pyx_L14_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_traceback); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 101, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 100, __pyx_L14_error)
+        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 101, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         __pyx_t_11 = NULL;
@@ -3889,10 +3954,10 @@ std::string string_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
         }
         __pyx_t_10 = (__pyx_t_11) ? __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_t_11) : __Pyx_PyObject_CallNoArg(__pyx_t_12);
         __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
-        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 100, __pyx_L14_error)
+        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 101, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_encode); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 100, __pyx_L14_error)
+        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_encode); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 101, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         __pyx_t_10 = NULL;
@@ -3907,15 +3972,15 @@ std::string string_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
         }
         __pyx_t_9 = (__pyx_t_10) ? __Pyx_PyObject_Call2Args(__pyx_t_12, __pyx_t_10, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_kp_u_UTF_8);
         __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
-        if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 100, __pyx_L14_error)
+        if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 101, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-        __pyx_t_7 = __pyx_convert_string_from_py_std__in_string(__pyx_t_9); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 100, __pyx_L14_error)
+        __pyx_t_7 = __pyx_convert_string_from_py_std__in_string(__pyx_t_9); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 101, __pyx_L14_error)
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         (__pyx_v_error[0]) = __pyx_t_7;
       }
 
-      /* "libzim.pyx":99
+      /* "libzim.pyx":100
  *             ret_str = call_method(obj, method)
  *             return ret_str.encode('UTF-8')
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -3974,7 +4039,7 @@ std::string string_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "libzim.pyx":96
+    /* "libzim.pyx":97
  *     string string_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a string"""
  *         try:             # <<<<<<<<<<<<<<
@@ -3999,18 +4064,18 @@ std::string string_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
     __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
   }
 
-  /* "libzim.pyx":101
+  /* "libzim.pyx":102
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')
  *         return b""             # <<<<<<<<<<<<<<
  * 
  *     zim.Blob blob_cy_call_fct(object obj, string method, string *error) with gil:
  */
-  __pyx_t_7 = __pyx_convert_string_from_py_std__in_string(__pyx_kp_b_); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 101, __pyx_L1_error)
+  __pyx_t_7 = __pyx_convert_string_from_py_std__in_string(__pyx_kp_b_); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 102, __pyx_L1_error)
   __pyx_r = __pyx_t_7;
   goto __pyx_L0;
 
-  /* "libzim.pyx":94
+  /* "libzim.pyx":95
  *         return hasattr(obj, attribute.decode('UTF-8'))
  * 
  *     string string_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -4040,7 +4105,7 @@ std::string string_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
   return __pyx_r;
 }
 
-/* "libzim.pyx":103
+/* "libzim.pyx":104
  *         return b""
  * 
  *     zim.Blob blob_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -4085,7 +4150,7 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
   __Pyx_RefNannySetupContext("blob_cy_call_fct", 0);
   __Pyx_INCREF(__pyx_v_obj);
 
-  /* "libzim.pyx":107
+  /* "libzim.pyx":108
  *         cdef WritingBlob blob
  * 
  *         try:             # <<<<<<<<<<<<<<
@@ -4101,20 +4166,20 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "libzim.pyx":108
+      /* "libzim.pyx":109
  * 
  *         try:
  *             blob = call_method(obj, method)             # <<<<<<<<<<<<<<
  *             if blob is None:
  *                 raise RuntimeError("Blob is none")
  */
-      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 108, __pyx_L3_error)
+      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 109, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
-      if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_6libzim_WritingBlob))))) __PYX_ERR(0, 108, __pyx_L3_error)
+      if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_6libzim_WritingBlob))))) __PYX_ERR(0, 109, __pyx_L3_error)
       __pyx_v_blob = ((struct __pyx_obj_6libzim_WritingBlob *)__pyx_t_4);
       __pyx_t_4 = 0;
 
-      /* "libzim.pyx":109
+      /* "libzim.pyx":110
  *         try:
  *             blob = call_method(obj, method)
  *             if blob is None:             # <<<<<<<<<<<<<<
@@ -4125,20 +4190,20 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
       __pyx_t_6 = (__pyx_t_5 != 0);
       if (unlikely(__pyx_t_6)) {
 
-        /* "libzim.pyx":110
+        /* "libzim.pyx":111
  *             blob = call_method(obj, method)
  *             if blob is None:
  *                 raise RuntimeError("Blob is none")             # <<<<<<<<<<<<<<
  *             return move(blob.c_blob)
  *         except Exception as e:
  */
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 110, __pyx_L3_error)
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 111, __pyx_L3_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_Raise(__pyx_t_4, 0, 0, 0);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __PYX_ERR(0, 110, __pyx_L3_error)
+        __PYX_ERR(0, 111, __pyx_L3_error)
 
-        /* "libzim.pyx":109
+        /* "libzim.pyx":110
  *         try:
  *             blob = call_method(obj, method)
  *             if blob is None:             # <<<<<<<<<<<<<<
@@ -4147,7 +4212,7 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
  */
       }
 
-      /* "libzim.pyx":111
+      /* "libzim.pyx":112
  *             if blob is None:
  *                 raise RuntimeError("Blob is none")
  *             return move(blob.c_blob)             # <<<<<<<<<<<<<<
@@ -4157,7 +4222,7 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
       __pyx_r = cython_std::move<wrapper::Blob>(__pyx_v_blob->c_blob);
       goto __pyx_L7_try_return;
 
-      /* "libzim.pyx":107
+      /* "libzim.pyx":108
  *         cdef WritingBlob blob
  * 
  *         try:             # <<<<<<<<<<<<<<
@@ -4168,7 +4233,7 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "libzim.pyx":112
+    /* "libzim.pyx":113
  *                 raise RuntimeError("Blob is none")
  *             return move(blob.c_blob)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -4178,7 +4243,7 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
     __pyx_t_7 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_7) {
       __Pyx_AddTraceback("libzim.blob_cy_call_fct", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_8, &__pyx_t_9) < 0) __PYX_ERR(0, 112, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_8, &__pyx_t_9) < 0) __PYX_ERR(0, 113, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_GOTREF(__pyx_t_9);
@@ -4186,16 +4251,16 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
       __pyx_v_e = __pyx_t_8;
       /*try:*/ {
 
-        /* "libzim.pyx":113
+        /* "libzim.pyx":114
  *             return move(blob.c_blob)
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')             # <<<<<<<<<<<<<<
  * 
  *         return move(zim.Blob())
  */
-        __Pyx_GetModuleGlobalName(__pyx_t_12, __pyx_n_s_traceback); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 113, __pyx_L15_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_12, __pyx_n_s_traceback); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 114, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_12);
-        __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 113, __pyx_L15_error)
+        __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 114, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_13);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
         __pyx_t_12 = NULL;
@@ -4210,10 +4275,10 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
         }
         __pyx_t_11 = (__pyx_t_12) ? __Pyx_PyObject_CallOneArg(__pyx_t_13, __pyx_t_12) : __Pyx_PyObject_CallNoArg(__pyx_t_13);
         __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
-        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 113, __pyx_L15_error)
+        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 114, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_11);
         __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-        __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_encode); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 113, __pyx_L15_error)
+        __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_encode); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 114, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_13);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         __pyx_t_11 = NULL;
@@ -4228,15 +4293,15 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
         }
         __pyx_t_10 = (__pyx_t_11) ? __Pyx_PyObject_Call2Args(__pyx_t_13, __pyx_t_11, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_13, __pyx_kp_u_UTF_8);
         __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
-        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 113, __pyx_L15_error)
+        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 114, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
-        __pyx_t_14 = __pyx_convert_string_from_py_std__in_string(__pyx_t_10); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 113, __pyx_L15_error)
+        __pyx_t_14 = __pyx_convert_string_from_py_std__in_string(__pyx_t_10); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 114, __pyx_L15_error)
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         (__pyx_v_error[0]) = __pyx_t_14;
       }
 
-      /* "libzim.pyx":112
+      /* "libzim.pyx":113
  *                 raise RuntimeError("Blob is none")
  *             return move(blob.c_blob)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -4295,7 +4360,7 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "libzim.pyx":107
+    /* "libzim.pyx":108
  *         cdef WritingBlob blob
  * 
  *         try:             # <<<<<<<<<<<<<<
@@ -4320,7 +4385,7 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
     __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
   }
 
-  /* "libzim.pyx":115
+  /* "libzim.pyx":116
  *             error[0] = traceback.format_exc().encode('UTF-8')
  * 
  *         return move(zim.Blob())             # <<<<<<<<<<<<<<
@@ -4331,12 +4396,12 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
     __pyx_t_23 = wrapper::Blob();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 115, __pyx_L1_error)
+    __PYX_ERR(0, 116, __pyx_L1_error)
   }
   __pyx_r = cython_std::move<wrapper::Blob>(__pyx_t_23);
   goto __pyx_L0;
 
-  /* "libzim.pyx":103
+  /* "libzim.pyx":104
  *         return b""
  * 
  *     zim.Blob blob_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -4366,7 +4431,7 @@ wrapper::Blob blob_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method
   return __pyx_r;
 }
 
-/* "libzim.pyx":117
+/* "libzim.pyx":118
  *         return move(zim.Blob())
  * 
  *     zim.ContentProvider* contentprovider_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -4411,7 +4476,7 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
   __Pyx_RefNannySetupContext("contentprovider_cy_call_fct", 0);
   __Pyx_INCREF(__pyx_v_obj);
 
-  /* "libzim.pyx":119
+  /* "libzim.pyx":120
  *     zim.ContentProvider* contentprovider_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a ContentProvider"""
  *         try:             # <<<<<<<<<<<<<<
@@ -4427,43 +4492,43 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "libzim.pyx":120
+      /* "libzim.pyx":121
  *         """Lookup and execute a pure virtual method on object returning a ContentProvider"""
  *         try:
  *             contentProvider = call_method(obj, method)             # <<<<<<<<<<<<<<
  *             if not contentProvider:
  *                 raise RuntimeError("ContentProvider is None")
  */
-      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 120, __pyx_L3_error)
+      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 121, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_v_contentProvider = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "libzim.pyx":121
+      /* "libzim.pyx":122
  *         try:
  *             contentProvider = call_method(obj, method)
  *             if not contentProvider:             # <<<<<<<<<<<<<<
  *                 raise RuntimeError("ContentProvider is None")
  *             return new zim.ContentProviderWrapper(<PyObject*>contentProvider)
  */
-      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_contentProvider); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 121, __pyx_L3_error)
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_contentProvider); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 122, __pyx_L3_error)
       __pyx_t_6 = ((!__pyx_t_5) != 0);
       if (unlikely(__pyx_t_6)) {
 
-        /* "libzim.pyx":122
+        /* "libzim.pyx":123
  *             contentProvider = call_method(obj, method)
  *             if not contentProvider:
  *                 raise RuntimeError("ContentProvider is None")             # <<<<<<<<<<<<<<
  *             return new zim.ContentProviderWrapper(<PyObject*>contentProvider)
  *         except Exception as e:
  */
-        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 122, __pyx_L3_error)
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 123, __pyx_L3_error)
         __Pyx_GOTREF(__pyx_t_4);
         __Pyx_Raise(__pyx_t_4, 0, 0, 0);
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __PYX_ERR(0, 122, __pyx_L3_error)
+        __PYX_ERR(0, 123, __pyx_L3_error)
 
-        /* "libzim.pyx":121
+        /* "libzim.pyx":122
  *         try:
  *             contentProvider = call_method(obj, method)
  *             if not contentProvider:             # <<<<<<<<<<<<<<
@@ -4472,7 +4537,7 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
  */
       }
 
-      /* "libzim.pyx":123
+      /* "libzim.pyx":124
  *             if not contentProvider:
  *                 raise RuntimeError("ContentProvider is None")
  *             return new zim.ContentProviderWrapper(<PyObject*>contentProvider)             # <<<<<<<<<<<<<<
@@ -4483,12 +4548,12 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
         __pyx_t_7 = new ContentProviderWrapper(((PyObject *)__pyx_v_contentProvider));
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 123, __pyx_L3_error)
+        __PYX_ERR(0, 124, __pyx_L3_error)
       }
       __pyx_r = __pyx_t_7;
       goto __pyx_L7_try_return;
 
-      /* "libzim.pyx":119
+      /* "libzim.pyx":120
  *     zim.ContentProvider* contentprovider_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a ContentProvider"""
  *         try:             # <<<<<<<<<<<<<<
@@ -4499,7 +4564,7 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "libzim.pyx":124
+    /* "libzim.pyx":125
  *                 raise RuntimeError("ContentProvider is None")
  *             return new zim.ContentProviderWrapper(<PyObject*>contentProvider)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -4509,7 +4574,7 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
     __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_8) {
       __Pyx_AddTraceback("libzim.contentprovider_cy_call_fct", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_9, &__pyx_t_10) < 0) __PYX_ERR(0, 124, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_9, &__pyx_t_10) < 0) __PYX_ERR(0, 125, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_GOTREF(__pyx_t_10);
@@ -4517,16 +4582,16 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
       __pyx_v_e = __pyx_t_9;
       /*try:*/ {
 
-        /* "libzim.pyx":125
+        /* "libzim.pyx":126
  *             return new zim.ContentProviderWrapper(<PyObject*>contentProvider)
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')             # <<<<<<<<<<<<<<
  * 
  *         return NULL
  */
-        __Pyx_GetModuleGlobalName(__pyx_t_13, __pyx_n_s_traceback); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 125, __pyx_L15_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_13, __pyx_n_s_traceback); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 126, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_13);
-        __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_13, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 125, __pyx_L15_error)
+        __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_13, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 126, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_14);
         __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
         __pyx_t_13 = NULL;
@@ -4541,10 +4606,10 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
         }
         __pyx_t_12 = (__pyx_t_13) ? __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_t_13) : __Pyx_PyObject_CallNoArg(__pyx_t_14);
         __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
-        if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 125, __pyx_L15_error)
+        if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 126, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-        __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_n_s_encode); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 125, __pyx_L15_error)
+        __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_n_s_encode); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 126, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_14);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
         __pyx_t_12 = NULL;
@@ -4559,15 +4624,15 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
         }
         __pyx_t_11 = (__pyx_t_12) ? __Pyx_PyObject_Call2Args(__pyx_t_14, __pyx_t_12, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_kp_u_UTF_8);
         __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
-        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 125, __pyx_L15_error)
+        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 126, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_11);
         __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-        __pyx_t_15 = __pyx_convert_string_from_py_std__in_string(__pyx_t_11); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 125, __pyx_L15_error)
+        __pyx_t_15 = __pyx_convert_string_from_py_std__in_string(__pyx_t_11); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 126, __pyx_L15_error)
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         (__pyx_v_error[0]) = __pyx_t_15;
       }
 
-      /* "libzim.pyx":124
+      /* "libzim.pyx":125
  *                 raise RuntimeError("ContentProvider is None")
  *             return new zim.ContentProviderWrapper(<PyObject*>contentProvider)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -4626,7 +4691,7 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "libzim.pyx":119
+    /* "libzim.pyx":120
  *     zim.ContentProvider* contentprovider_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a ContentProvider"""
  *         try:             # <<<<<<<<<<<<<<
@@ -4651,7 +4716,7 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
     __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
   }
 
-  /* "libzim.pyx":127
+  /* "libzim.pyx":128
  *             error[0] = traceback.format_exc().encode('UTF-8')
  * 
  *         return NULL             # <<<<<<<<<<<<<<
@@ -4661,7 +4726,7 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
   __pyx_r = NULL;
   goto __pyx_L0;
 
-  /* "libzim.pyx":117
+  /* "libzim.pyx":118
  *         return move(zim.Blob())
  * 
  *     zim.ContentProvider* contentprovider_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -4691,7 +4756,7 @@ zim::writer::ContentProvider *contentprovider_cy_call_fct(PyObject *__pyx_v_obj,
   return __pyx_r;
 }
 
-/* "libzim.pyx":129
+/* "libzim.pyx":130
  *         return NULL
  * 
  *     zim.IndexData* indexdata_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -4736,7 +4801,7 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
   __Pyx_RefNannySetupContext("indexdata_cy_call_fct", 0);
   __Pyx_INCREF(__pyx_v_obj);
 
-  /* "libzim.pyx":131
+  /* "libzim.pyx":132
  *     zim.IndexData* indexdata_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a IndexData"""
  *         try:             # <<<<<<<<<<<<<<
@@ -4752,30 +4817,30 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "libzim.pyx":132
+      /* "libzim.pyx":133
  *         """Lookup and execute a pure virtual method on object returning a IndexData"""
  *         try:
  *             indexData = call_method(obj, method)             # <<<<<<<<<<<<<<
  *             if not indexData:
  *                 # indexData is none
  */
-      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 132, __pyx_L3_error)
+      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 133, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_v_indexData = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "libzim.pyx":133
+      /* "libzim.pyx":134
  *         try:
  *             indexData = call_method(obj, method)
  *             if not indexData:             # <<<<<<<<<<<<<<
  *                 # indexData is none
  *                 return NULL;
  */
-      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_indexData); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 133, __pyx_L3_error)
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_indexData); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 134, __pyx_L3_error)
       __pyx_t_6 = ((!__pyx_t_5) != 0);
       if (__pyx_t_6) {
 
-        /* "libzim.pyx":135
+        /* "libzim.pyx":136
  *             if not indexData:
  *                 # indexData is none
  *                 return NULL;             # <<<<<<<<<<<<<<
@@ -4785,7 +4850,7 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
         __pyx_r = NULL;
         goto __pyx_L7_try_return;
 
-        /* "libzim.pyx":133
+        /* "libzim.pyx":134
  *         try:
  *             indexData = call_method(obj, method)
  *             if not indexData:             # <<<<<<<<<<<<<<
@@ -4794,7 +4859,7 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
  */
       }
 
-      /* "libzim.pyx":136
+      /* "libzim.pyx":137
  *                 # indexData is none
  *                 return NULL;
  *             return new zim.IndexDataWrapper(<PyObject*>indexData)             # <<<<<<<<<<<<<<
@@ -4805,12 +4870,12 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
         __pyx_t_7 = new IndexDataWrapper(((PyObject *)__pyx_v_indexData));
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 136, __pyx_L3_error)
+        __PYX_ERR(0, 137, __pyx_L3_error)
       }
       __pyx_r = __pyx_t_7;
       goto __pyx_L7_try_return;
 
-      /* "libzim.pyx":131
+      /* "libzim.pyx":132
  *     zim.IndexData* indexdata_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a IndexData"""
  *         try:             # <<<<<<<<<<<<<<
@@ -4821,7 +4886,7 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "libzim.pyx":137
+    /* "libzim.pyx":138
  *                 return NULL;
  *             return new zim.IndexDataWrapper(<PyObject*>indexData)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -4831,7 +4896,7 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
     __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_8) {
       __Pyx_AddTraceback("libzim.indexdata_cy_call_fct", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_9, &__pyx_t_10) < 0) __PYX_ERR(0, 137, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_9, &__pyx_t_10) < 0) __PYX_ERR(0, 138, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_GOTREF(__pyx_t_10);
@@ -4839,16 +4904,16 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
       __pyx_v_e = __pyx_t_9;
       /*try:*/ {
 
-        /* "libzim.pyx":138
+        /* "libzim.pyx":139
  *             return new zim.IndexDataWrapper(<PyObject*>indexData)
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')             # <<<<<<<<<<<<<<
  * 
  *         return NULL
  */
-        __Pyx_GetModuleGlobalName(__pyx_t_13, __pyx_n_s_traceback); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 138, __pyx_L15_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_13, __pyx_n_s_traceback); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 139, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_13);
-        __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_13, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 138, __pyx_L15_error)
+        __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_13, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 139, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_14);
         __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
         __pyx_t_13 = NULL;
@@ -4863,10 +4928,10 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
         }
         __pyx_t_12 = (__pyx_t_13) ? __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_t_13) : __Pyx_PyObject_CallNoArg(__pyx_t_14);
         __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
-        if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 138, __pyx_L15_error)
+        if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 139, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-        __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_n_s_encode); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 138, __pyx_L15_error)
+        __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_n_s_encode); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 139, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_14);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
         __pyx_t_12 = NULL;
@@ -4881,15 +4946,15 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
         }
         __pyx_t_11 = (__pyx_t_12) ? __Pyx_PyObject_Call2Args(__pyx_t_14, __pyx_t_12, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_kp_u_UTF_8);
         __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
-        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 138, __pyx_L15_error)
+        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 139, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_11);
         __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-        __pyx_t_15 = __pyx_convert_string_from_py_std__in_string(__pyx_t_11); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 138, __pyx_L15_error)
+        __pyx_t_15 = __pyx_convert_string_from_py_std__in_string(__pyx_t_11); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 139, __pyx_L15_error)
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         (__pyx_v_error[0]) = __pyx_t_15;
       }
 
-      /* "libzim.pyx":137
+      /* "libzim.pyx":138
  *                 return NULL;
  *             return new zim.IndexDataWrapper(<PyObject*>indexData)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -4948,7 +5013,7 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "libzim.pyx":131
+    /* "libzim.pyx":132
  *     zim.IndexData* indexdata_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a IndexData"""
  *         try:             # <<<<<<<<<<<<<<
@@ -4973,7 +5038,7 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
     __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
   }
 
-  /* "libzim.pyx":140
+  /* "libzim.pyx":141
  *             error[0] = traceback.format_exc().encode('UTF-8')
  * 
  *         return NULL             # <<<<<<<<<<<<<<
@@ -4983,7 +5048,7 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
   __pyx_r = NULL;
   goto __pyx_L0;
 
-  /* "libzim.pyx":129
+  /* "libzim.pyx":130
  *         return NULL
  * 
  *     zim.IndexData* indexdata_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -5013,7 +5078,7 @@ zim::writer::IndexData *indexdata_cy_call_fct(PyObject *__pyx_v_obj, std::string
   return __pyx_r;
 }
 
-/* "libzim.pyx":142
+/* "libzim.pyx":143
  *         return NULL
  * 
  *     bool bool_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -5055,7 +5120,7 @@ bool bool_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, std::st
   __Pyx_RefNannySetupContext("bool_cy_call_fct", 0);
   __Pyx_INCREF(__pyx_v_obj);
 
-  /* "libzim.pyx":144
+  /* "libzim.pyx":145
  *     bool bool_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a bool"""
  *         try:             # <<<<<<<<<<<<<<
@@ -5071,21 +5136,21 @@ bool bool_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, std::st
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "libzim.pyx":145
+      /* "libzim.pyx":146
  *         """Lookup and execute a pure virtual method on object returning a bool"""
  *         try:
  *             return call_method(obj, method)             # <<<<<<<<<<<<<<
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')
  */
-      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 145, __pyx_L3_error)
+      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 146, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 145, __pyx_L3_error)
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely((__pyx_t_5 == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 146, __pyx_L3_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_r = __pyx_t_5;
       goto __pyx_L7_try_return;
 
-      /* "libzim.pyx":144
+      /* "libzim.pyx":145
  *     bool bool_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a bool"""
  *         try:             # <<<<<<<<<<<<<<
@@ -5096,7 +5161,7 @@ bool bool_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, std::st
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "libzim.pyx":146
+    /* "libzim.pyx":147
  *         try:
  *             return call_method(obj, method)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -5106,7 +5171,7 @@ bool bool_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, std::st
     __pyx_t_6 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_6) {
       __Pyx_AddTraceback("libzim.bool_cy_call_fct", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(0, 146, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(0, 147, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GOTREF(__pyx_t_8);
@@ -5114,16 +5179,16 @@ bool bool_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, std::st
       __pyx_v_e = __pyx_t_7;
       /*try:*/ {
 
-        /* "libzim.pyx":147
+        /* "libzim.pyx":148
  *             return call_method(obj, method)
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')             # <<<<<<<<<<<<<<
  * 
  *         return False
  */
-        __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_traceback); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 147, __pyx_L14_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_traceback); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 148, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 147, __pyx_L14_error)
+        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 148, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         __pyx_t_11 = NULL;
@@ -5138,10 +5203,10 @@ bool bool_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, std::st
         }
         __pyx_t_10 = (__pyx_t_11) ? __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_t_11) : __Pyx_PyObject_CallNoArg(__pyx_t_12);
         __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
-        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 147, __pyx_L14_error)
+        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 148, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_encode); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 147, __pyx_L14_error)
+        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_encode); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 148, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         __pyx_t_10 = NULL;
@@ -5156,15 +5221,15 @@ bool bool_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, std::st
         }
         __pyx_t_9 = (__pyx_t_10) ? __Pyx_PyObject_Call2Args(__pyx_t_12, __pyx_t_10, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_kp_u_UTF_8);
         __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
-        if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 147, __pyx_L14_error)
+        if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 148, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-        __pyx_t_13 = __pyx_convert_string_from_py_std__in_string(__pyx_t_9); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 147, __pyx_L14_error)
+        __pyx_t_13 = __pyx_convert_string_from_py_std__in_string(__pyx_t_9); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 148, __pyx_L14_error)
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         (__pyx_v_error[0]) = __pyx_t_13;
       }
 
-      /* "libzim.pyx":146
+      /* "libzim.pyx":147
  *         try:
  *             return call_method(obj, method)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -5223,7 +5288,7 @@ bool bool_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, std::st
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "libzim.pyx":144
+    /* "libzim.pyx":145
  *     bool bool_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a bool"""
  *         try:             # <<<<<<<<<<<<<<
@@ -5248,7 +5313,7 @@ bool bool_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, std::st
     __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
   }
 
-  /* "libzim.pyx":149
+  /* "libzim.pyx":150
  *             error[0] = traceback.format_exc().encode('UTF-8')
  * 
  *         return False             # <<<<<<<<<<<<<<
@@ -5258,7 +5323,7 @@ bool bool_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, std::st
   __pyx_r = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":142
+  /* "libzim.pyx":143
  *         return NULL
  * 
  *     bool bool_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -5287,7 +5352,7 @@ bool bool_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, std::st
   return __pyx_r;
 }
 
-/* "libzim.pyx":151
+/* "libzim.pyx":152
  *         return False
  * 
  *     uint64_t uint64_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -5329,7 +5394,7 @@ uint64_t uint64_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
   __Pyx_RefNannySetupContext("uint64_cy_call_fct", 0);
   __Pyx_INCREF(__pyx_v_obj);
 
-  /* "libzim.pyx":153
+  /* "libzim.pyx":154
  *     uint64_t uint64_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning an uint64_t"""
  *         try:             # <<<<<<<<<<<<<<
@@ -5345,21 +5410,21 @@ uint64_t uint64_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "libzim.pyx":154
+      /* "libzim.pyx":155
  *         """Lookup and execute a pure virtual method on object returning an uint64_t"""
  *         try:
  *             return <uint64_t> call_method(obj, method)             # <<<<<<<<<<<<<<
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')
  */
-      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 154, __pyx_L3_error)
+      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 155, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_5 = __Pyx_PyInt_As_uint64_t(__pyx_t_4); if (unlikely((__pyx_t_5 == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 154, __pyx_L3_error)
+      __pyx_t_5 = __Pyx_PyInt_As_uint64_t(__pyx_t_4); if (unlikely((__pyx_t_5 == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 155, __pyx_L3_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_r = ((uint64_t)__pyx_t_5);
       goto __pyx_L7_try_return;
 
-      /* "libzim.pyx":153
+      /* "libzim.pyx":154
  *     uint64_t uint64_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning an uint64_t"""
  *         try:             # <<<<<<<<<<<<<<
@@ -5370,7 +5435,7 @@ uint64_t uint64_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "libzim.pyx":155
+    /* "libzim.pyx":156
  *         try:
  *             return <uint64_t> call_method(obj, method)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -5380,7 +5445,7 @@ uint64_t uint64_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
     __pyx_t_6 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_6) {
       __Pyx_AddTraceback("libzim.uint64_cy_call_fct", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(0, 155, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(0, 156, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GOTREF(__pyx_t_8);
@@ -5388,16 +5453,16 @@ uint64_t uint64_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
       __pyx_v_e = __pyx_t_7;
       /*try:*/ {
 
-        /* "libzim.pyx":156
+        /* "libzim.pyx":157
  *             return <uint64_t> call_method(obj, method)
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')             # <<<<<<<<<<<<<<
  * 
  *         return 0
  */
-        __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_traceback); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 156, __pyx_L14_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_traceback); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 157, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 156, __pyx_L14_error)
+        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 157, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         __pyx_t_11 = NULL;
@@ -5412,10 +5477,10 @@ uint64_t uint64_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
         }
         __pyx_t_10 = (__pyx_t_11) ? __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_t_11) : __Pyx_PyObject_CallNoArg(__pyx_t_12);
         __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
-        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 156, __pyx_L14_error)
+        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 157, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_encode); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 156, __pyx_L14_error)
+        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_encode); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 157, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         __pyx_t_10 = NULL;
@@ -5430,15 +5495,15 @@ uint64_t uint64_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
         }
         __pyx_t_9 = (__pyx_t_10) ? __Pyx_PyObject_Call2Args(__pyx_t_12, __pyx_t_10, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_kp_u_UTF_8);
         __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
-        if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 156, __pyx_L14_error)
+        if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 157, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-        __pyx_t_13 = __pyx_convert_string_from_py_std__in_string(__pyx_t_9); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 156, __pyx_L14_error)
+        __pyx_t_13 = __pyx_convert_string_from_py_std__in_string(__pyx_t_9); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 157, __pyx_L14_error)
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         (__pyx_v_error[0]) = __pyx_t_13;
       }
 
-      /* "libzim.pyx":155
+      /* "libzim.pyx":156
  *         try:
  *             return <uint64_t> call_method(obj, method)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -5497,7 +5562,7 @@ uint64_t uint64_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "libzim.pyx":153
+    /* "libzim.pyx":154
  *     uint64_t uint64_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning an uint64_t"""
  *         try:             # <<<<<<<<<<<<<<
@@ -5522,7 +5587,7 @@ uint64_t uint64_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
     __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
   }
 
-  /* "libzim.pyx":158
+  /* "libzim.pyx":159
  *             error[0] = traceback.format_exc().encode('UTF-8')
  * 
  *         return 0             # <<<<<<<<<<<<<<
@@ -5532,7 +5597,7 @@ uint64_t uint64_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
   __pyx_r = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":151
+  /* "libzim.pyx":152
  *         return False
  * 
  *     uint64_t uint64_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -5561,7 +5626,7 @@ uint64_t uint64_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
   return __pyx_r;
 }
 
-/* "libzim.pyx":160
+/* "libzim.pyx":161
  *         return 0
  * 
  *     uint32_t uint32_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -5603,7 +5668,7 @@ uint32_t uint32_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
   __Pyx_RefNannySetupContext("uint32_cy_call_fct", 0);
   __Pyx_INCREF(__pyx_v_obj);
 
-  /* "libzim.pyx":162
+  /* "libzim.pyx":163
  *     uint32_t uint32_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning an uint_32"""
  *         try:             # <<<<<<<<<<<<<<
@@ -5619,21 +5684,21 @@ uint32_t uint32_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "libzim.pyx":163
+      /* "libzim.pyx":164
  *         """Lookup and execute a pure virtual method on object returning an uint_32"""
  *         try:
  *             return <uint32_t> call_method(obj, method)             # <<<<<<<<<<<<<<
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')
  */
-      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 163, __pyx_L3_error)
+      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 164, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_5 = __Pyx_PyInt_As_uint32_t(__pyx_t_4); if (unlikely((__pyx_t_5 == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 163, __pyx_L3_error)
+      __pyx_t_5 = __Pyx_PyInt_As_uint32_t(__pyx_t_4); if (unlikely((__pyx_t_5 == ((uint32_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 164, __pyx_L3_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_r = ((uint32_t)__pyx_t_5);
       goto __pyx_L7_try_return;
 
-      /* "libzim.pyx":162
+      /* "libzim.pyx":163
  *     uint32_t uint32_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning an uint_32"""
  *         try:             # <<<<<<<<<<<<<<
@@ -5644,7 +5709,7 @@ uint32_t uint32_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "libzim.pyx":164
+    /* "libzim.pyx":165
  *         try:
  *             return <uint32_t> call_method(obj, method)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -5654,7 +5719,7 @@ uint32_t uint32_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
     __pyx_t_6 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_6) {
       __Pyx_AddTraceback("libzim.uint32_cy_call_fct", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(0, 164, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_7, &__pyx_t_8) < 0) __PYX_ERR(0, 165, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_7);
       __Pyx_GOTREF(__pyx_t_8);
@@ -5662,16 +5727,16 @@ uint32_t uint32_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
       __pyx_v_e = __pyx_t_7;
       /*try:*/ {
 
-        /* "libzim.pyx":165
+        /* "libzim.pyx":166
  *             return <uint32_t> call_method(obj, method)
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')             # <<<<<<<<<<<<<<
  * 
  *         return 0
  */
-        __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_traceback); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 165, __pyx_L14_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_traceback); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 166, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 165, __pyx_L14_error)
+        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 166, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         __pyx_t_11 = NULL;
@@ -5686,10 +5751,10 @@ uint32_t uint32_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
         }
         __pyx_t_10 = (__pyx_t_11) ? __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_t_11) : __Pyx_PyObject_CallNoArg(__pyx_t_12);
         __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
-        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 165, __pyx_L14_error)
+        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 166, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_encode); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 165, __pyx_L14_error)
+        __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_encode); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 166, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         __pyx_t_10 = NULL;
@@ -5704,15 +5769,15 @@ uint32_t uint32_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
         }
         __pyx_t_9 = (__pyx_t_10) ? __Pyx_PyObject_Call2Args(__pyx_t_12, __pyx_t_10, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_12, __pyx_kp_u_UTF_8);
         __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
-        if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 165, __pyx_L14_error)
+        if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 166, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-        __pyx_t_13 = __pyx_convert_string_from_py_std__in_string(__pyx_t_9); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 165, __pyx_L14_error)
+        __pyx_t_13 = __pyx_convert_string_from_py_std__in_string(__pyx_t_9); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 166, __pyx_L14_error)
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         (__pyx_v_error[0]) = __pyx_t_13;
       }
 
-      /* "libzim.pyx":164
+      /* "libzim.pyx":165
  *         try:
  *             return <uint32_t> call_method(obj, method)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -5771,7 +5836,7 @@ uint32_t uint32_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "libzim.pyx":162
+    /* "libzim.pyx":163
  *     uint32_t uint32_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning an uint_32"""
  *         try:             # <<<<<<<<<<<<<<
@@ -5796,7 +5861,7 @@ uint32_t uint32_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
     __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
   }
 
-  /* "libzim.pyx":167
+  /* "libzim.pyx":168
  *             error[0] = traceback.format_exc().encode('UTF-8')
  * 
  *         return 0             # <<<<<<<<<<<<<<
@@ -5806,7 +5871,7 @@ uint32_t uint32_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
   __pyx_r = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":160
+  /* "libzim.pyx":161
  *         return 0
  * 
  *     uint32_t uint32_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -5835,7 +5900,7 @@ uint32_t uint32_cy_call_fct(PyObject *__pyx_v_obj, std::string __pyx_v_method, s
   return __pyx_r;
 }
 
-/* "libzim.pyx":169
+/* "libzim.pyx":170
  *         return 0
  * 
  *     zim.GeoPosition geoposition_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -5880,7 +5945,7 @@ zim::writer::IndexData::GeoPosition geoposition_cy_call_fct(PyObject *__pyx_v_ob
   __Pyx_RefNannySetupContext("geoposition_cy_call_fct", 0);
   __Pyx_INCREF(__pyx_v_obj);
 
-  /* "libzim.pyx":171
+  /* "libzim.pyx":172
  *     zim.GeoPosition geoposition_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a GeoPosition"""
  *         try:             # <<<<<<<<<<<<<<
@@ -5896,47 +5961,47 @@ zim::writer::IndexData::GeoPosition geoposition_cy_call_fct(PyObject *__pyx_v_ob
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "libzim.pyx":172
+      /* "libzim.pyx":173
  *         """Lookup and execute a pure virtual method on object returning a GeoPosition"""
  *         try:
  *             geoPosition = call_method(obj, method)             # <<<<<<<<<<<<<<
  *             if geoPosition:
  *                 return zim.GeoPosition(True, geoPosition[0], geoPosition[1]);
  */
-      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 172, __pyx_L3_error)
+      __pyx_t_4 = __pyx_f_6libzim_call_method(__pyx_v_obj, __pyx_v_method); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 173, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
       __pyx_v_geoPosition = __pyx_t_4;
       __pyx_t_4 = 0;
 
-      /* "libzim.pyx":173
+      /* "libzim.pyx":174
  *         try:
  *             geoPosition = call_method(obj, method)
  *             if geoPosition:             # <<<<<<<<<<<<<<
  *                 return zim.GeoPosition(True, geoPosition[0], geoPosition[1]);
  *         except Exception as e:
  */
-      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_geoPosition); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 173, __pyx_L3_error)
+      __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_geoPosition); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 174, __pyx_L3_error)
       if (__pyx_t_5) {
 
-        /* "libzim.pyx":174
+        /* "libzim.pyx":175
  *             geoPosition = call_method(obj, method)
  *             if geoPosition:
  *                 return zim.GeoPosition(True, geoPosition[0], geoPosition[1]);             # <<<<<<<<<<<<<<
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')
  */
-        __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_geoPosition, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 174, __pyx_L3_error)
+        __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_geoPosition, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 175, __pyx_L3_error)
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 174, __pyx_L3_error)
+        __pyx_t_6 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_6 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 175, __pyx_L3_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_geoPosition, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 174, __pyx_L3_error)
+        __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_geoPosition, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 175, __pyx_L3_error)
         __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 174, __pyx_L3_error)
+        __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_t_4); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 175, __pyx_L3_error)
         __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
         __pyx_r = zim::writer::IndexData::GeoPosition(1, __pyx_t_6, __pyx_t_7);
         goto __pyx_L7_try_return;
 
-        /* "libzim.pyx":173
+        /* "libzim.pyx":174
  *         try:
  *             geoPosition = call_method(obj, method)
  *             if geoPosition:             # <<<<<<<<<<<<<<
@@ -5945,7 +6010,7 @@ zim::writer::IndexData::GeoPosition geoposition_cy_call_fct(PyObject *__pyx_v_ob
  */
       }
 
-      /* "libzim.pyx":171
+      /* "libzim.pyx":172
  *     zim.GeoPosition geoposition_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a GeoPosition"""
  *         try:             # <<<<<<<<<<<<<<
@@ -5960,7 +6025,7 @@ zim::writer::IndexData::GeoPosition geoposition_cy_call_fct(PyObject *__pyx_v_ob
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "libzim.pyx":175
+    /* "libzim.pyx":176
  *             if geoPosition:
  *                 return zim.GeoPosition(True, geoPosition[0], geoPosition[1]);
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -5970,7 +6035,7 @@ zim::writer::IndexData::GeoPosition geoposition_cy_call_fct(PyObject *__pyx_v_ob
     __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_8) {
       __Pyx_AddTraceback("libzim.geoposition_cy_call_fct", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_9, &__pyx_t_10) < 0) __PYX_ERR(0, 175, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_9, &__pyx_t_10) < 0) __PYX_ERR(0, 176, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_GOTREF(__pyx_t_10);
@@ -5978,16 +6043,16 @@ zim::writer::IndexData::GeoPosition geoposition_cy_call_fct(PyObject *__pyx_v_ob
       __pyx_v_e = __pyx_t_9;
       /*try:*/ {
 
-        /* "libzim.pyx":176
+        /* "libzim.pyx":177
  *                 return zim.GeoPosition(True, geoPosition[0], geoPosition[1]);
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')             # <<<<<<<<<<<<<<
  * 
  *         return zim.GeoPosition(False, 0, 0)
  */
-        __Pyx_GetModuleGlobalName(__pyx_t_13, __pyx_n_s_traceback); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 176, __pyx_L15_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_13, __pyx_n_s_traceback); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 177, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_13);
-        __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_13, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 176, __pyx_L15_error)
+        __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_13, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 177, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_14);
         __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
         __pyx_t_13 = NULL;
@@ -6002,10 +6067,10 @@ zim::writer::IndexData::GeoPosition geoposition_cy_call_fct(PyObject *__pyx_v_ob
         }
         __pyx_t_12 = (__pyx_t_13) ? __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_t_13) : __Pyx_PyObject_CallNoArg(__pyx_t_14);
         __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
-        if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 176, __pyx_L15_error)
+        if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 177, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-        __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_n_s_encode); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 176, __pyx_L15_error)
+        __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_n_s_encode); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 177, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_14);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
         __pyx_t_12 = NULL;
@@ -6020,15 +6085,15 @@ zim::writer::IndexData::GeoPosition geoposition_cy_call_fct(PyObject *__pyx_v_ob
         }
         __pyx_t_11 = (__pyx_t_12) ? __Pyx_PyObject_Call2Args(__pyx_t_14, __pyx_t_12, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_kp_u_UTF_8);
         __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
-        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 176, __pyx_L15_error)
+        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 177, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_11);
         __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
-        __pyx_t_15 = __pyx_convert_string_from_py_std__in_string(__pyx_t_11); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 176, __pyx_L15_error)
+        __pyx_t_15 = __pyx_convert_string_from_py_std__in_string(__pyx_t_11); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 177, __pyx_L15_error)
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         (__pyx_v_error[0]) = __pyx_t_15;
       }
 
-      /* "libzim.pyx":175
+      /* "libzim.pyx":176
  *             if geoPosition:
  *                 return zim.GeoPosition(True, geoPosition[0], geoPosition[1]);
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -6087,7 +6152,7 @@ zim::writer::IndexData::GeoPosition geoposition_cy_call_fct(PyObject *__pyx_v_ob
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "libzim.pyx":171
+    /* "libzim.pyx":172
  *     zim.GeoPosition geoposition_cy_call_fct(object obj, string method, string *error) with gil:
  *         """Lookup and execute a pure virtual method on object returning a GeoPosition"""
  *         try:             # <<<<<<<<<<<<<<
@@ -6113,7 +6178,7 @@ zim::writer::IndexData::GeoPosition geoposition_cy_call_fct(PyObject *__pyx_v_ob
     __pyx_L8_try_end:;
   }
 
-  /* "libzim.pyx":178
+  /* "libzim.pyx":179
  *             error[0] = traceback.format_exc().encode('UTF-8')
  * 
  *         return zim.GeoPosition(False, 0, 0)             # <<<<<<<<<<<<<<
@@ -6123,7 +6188,7 @@ zim::writer::IndexData::GeoPosition geoposition_cy_call_fct(PyObject *__pyx_v_ob
   __pyx_r = zim::writer::IndexData::GeoPosition(0, 0.0, 0.0);
   goto __pyx_L0;
 
-  /* "libzim.pyx":169
+  /* "libzim.pyx":170
  *         return 0
  * 
  *     zim.GeoPosition geoposition_cy_call_fct(object obj, string method, string *error) with gil:             # <<<<<<<<<<<<<<
@@ -6153,7 +6218,7 @@ zim::writer::IndexData::GeoPosition geoposition_cy_call_fct(PyObject *__pyx_v_ob
   return __pyx_r;
 }
 
-/* "libzim.pyx":180
+/* "libzim.pyx":181
  *         return zim.GeoPosition(False, 0, 0)
  * 
  *     map[zim.HintKeys, uint64_t] convertToCppHints(dict hintsDict):             # <<<<<<<<<<<<<<
@@ -6181,7 +6246,7 @@ std::map<zim::writer::HintKeys,uint64_t>  convertToCppHints(PyObject *__pyx_v_hi
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("convertToCppHints", 0);
 
-  /* "libzim.pyx":183
+  /* "libzim.pyx":184
  *         """C++ Hints from Python dict"""
  *         cdef map[zim.HintKeys, uint64_t] ret;
  *         for key, value in hintsDict.items():             # <<<<<<<<<<<<<<
@@ -6191,9 +6256,9 @@ std::map<zim::writer::HintKeys,uint64_t>  convertToCppHints(PyObject *__pyx_v_hi
   __pyx_t_2 = 0;
   if (unlikely(__pyx_v_hintsDict == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "items");
-    __PYX_ERR(0, 183, __pyx_L1_error)
+    __PYX_ERR(0, 184, __pyx_L1_error)
   }
-  __pyx_t_5 = __Pyx_dict_iterator(__pyx_v_hintsDict, 1, __pyx_n_s_items, (&__pyx_t_3), (&__pyx_t_4)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 183, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_dict_iterator(__pyx_v_hintsDict, 1, __pyx_n_s_items, (&__pyx_t_3), (&__pyx_t_4)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 184, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_1);
   __pyx_t_1 = __pyx_t_5;
@@ -6201,7 +6266,7 @@ std::map<zim::writer::HintKeys,uint64_t>  convertToCppHints(PyObject *__pyx_v_hi
   while (1) {
     __pyx_t_7 = __Pyx_dict_iter_next(__pyx_t_1, __pyx_t_3, &__pyx_t_2, &__pyx_t_5, &__pyx_t_6, NULL, __pyx_t_4);
     if (unlikely(__pyx_t_7 == 0)) break;
-    if (unlikely(__pyx_t_7 == -1)) __PYX_ERR(0, 183, __pyx_L1_error)
+    if (unlikely(__pyx_t_7 == -1)) __PYX_ERR(0, 184, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_XDECREF_SET(__pyx_v_key, __pyx_t_5);
@@ -6209,23 +6274,23 @@ std::map<zim::writer::HintKeys,uint64_t>  convertToCppHints(PyObject *__pyx_v_hi
     __Pyx_XDECREF_SET(__pyx_v_value, __pyx_t_6);
     __pyx_t_6 = 0;
 
-    /* "libzim.pyx":184
+    /* "libzim.pyx":185
  *         cdef map[zim.HintKeys, uint64_t] ret;
  *         for key, value in hintsDict.items():
  *             ret[key.value] = <uint64_t>value             # <<<<<<<<<<<<<<
  *         return ret
  * 
  */
-    __pyx_t_8 = __Pyx_PyInt_As_uint64_t(__pyx_v_value); if (unlikely((__pyx_t_8 == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 184, __pyx_L1_error)
-    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_key, __pyx_n_s_value); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 184, __pyx_L1_error)
+    __pyx_t_8 = __Pyx_PyInt_As_uint64_t(__pyx_v_value); if (unlikely((__pyx_t_8 == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 185, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_key, __pyx_n_s_value); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 185, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_9 = ((zim::writer::HintKeys)__Pyx_PyInt_As_zim_3a__3a_writer_3a__3a_HintKeys(__pyx_t_6)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 184, __pyx_L1_error)
+    __pyx_t_9 = ((zim::writer::HintKeys)__Pyx_PyInt_As_zim_3a__3a_writer_3a__3a_HintKeys(__pyx_t_6)); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 185, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     (__pyx_v_ret[__pyx_t_9]) = ((uint64_t)__pyx_t_8);
   }
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":185
+  /* "libzim.pyx":186
  *         for key, value in hintsDict.items():
  *             ret[key.value] = <uint64_t>value
  *         return ret             # <<<<<<<<<<<<<<
@@ -6235,7 +6300,7 @@ std::map<zim::writer::HintKeys,uint64_t>  convertToCppHints(PyObject *__pyx_v_hi
   __pyx_r = __pyx_v_ret;
   goto __pyx_L0;
 
-  /* "libzim.pyx":180
+  /* "libzim.pyx":181
  *         return zim.GeoPosition(False, 0, 0)
  * 
  *     map[zim.HintKeys, uint64_t] convertToCppHints(dict hintsDict):             # <<<<<<<<<<<<<<
@@ -6257,7 +6322,7 @@ std::map<zim::writer::HintKeys,uint64_t>  convertToCppHints(PyObject *__pyx_v_hi
   return __pyx_r;
 }
 
-/* "libzim.pyx":187
+/* "libzim.pyx":188
  *         return ret
  * 
  *     map[zim.HintKeys, uint64_t] hints_cy_call_fct(object obj, string method, string* error) with gil:             # <<<<<<<<<<<<<<
@@ -6307,7 +6372,7 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
   __Pyx_RefNannySetupContext("hints_cy_call_fct", 0);
   __Pyx_INCREF(__pyx_v_obj);
 
-  /* "libzim.pyx":190
+  /* "libzim.pyx":191
  *         """Lookup and execute a pure virtual method on object returning Hints"""
  *         cdef map[zim.HintKeys, uint64_t] ret;
  *         try:             # <<<<<<<<<<<<<<
@@ -6323,22 +6388,22 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "libzim.pyx":191
+      /* "libzim.pyx":192
  *         cdef map[zim.HintKeys, uint64_t] ret;
  *         try:
  *             func = getattr(obj, method.decode('UTF-8'))             # <<<<<<<<<<<<<<
  *             hintsDict = {k: pybool(v) for k, v in func().items() if isinstance(k, Hint)}
  *             return convertToCppHints(hintsDict)
  */
-      __pyx_t_4 = __Pyx_decode_cpp_string(__pyx_v_method, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 191, __pyx_L3_error)
+      __pyx_t_4 = __Pyx_decode_cpp_string(__pyx_v_method, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 192, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_5 = __Pyx_GetAttr(__pyx_v_obj, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 191, __pyx_L3_error)
+      __pyx_t_5 = __Pyx_GetAttr(__pyx_v_obj, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 192, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_v_func = __pyx_t_5;
       __pyx_t_5 = 0;
 
-      /* "libzim.pyx":192
+      /* "libzim.pyx":193
  *         try:
  *             func = getattr(obj, method.decode('UTF-8'))
  *             hintsDict = {k: pybool(v) for k, v in func().items() if isinstance(k, Hint)}             # <<<<<<<<<<<<<<
@@ -6346,7 +6411,7 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
  *         except Exception as e:
  */
       { /* enter inner scope */
-        __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 192, __pyx_L11_error)
+        __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 193, __pyx_L11_error)
         __Pyx_GOTREF(__pyx_t_5);
         __pyx_t_6 = 0;
         __Pyx_INCREF(__pyx_v_func);
@@ -6362,14 +6427,14 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
         }
         __pyx_t_9 = (__pyx_t_11) ? __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_11) : __Pyx_PyObject_CallNoArg(__pyx_t_10);
         __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
-        if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 192, __pyx_L11_error)
+        if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 193, __pyx_L11_error)
         __Pyx_GOTREF(__pyx_t_9);
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         if (unlikely(__pyx_t_9 == Py_None)) {
           PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "items");
-          __PYX_ERR(0, 192, __pyx_L11_error)
+          __PYX_ERR(0, 193, __pyx_L11_error)
         }
-        __pyx_t_10 = __Pyx_dict_iterator(__pyx_t_9, 0, __pyx_n_s_items, (&__pyx_t_7), (&__pyx_t_8)); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 192, __pyx_L11_error)
+        __pyx_t_10 = __Pyx_dict_iterator(__pyx_t_9, 0, __pyx_n_s_items, (&__pyx_t_7), (&__pyx_t_8)); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 193, __pyx_L11_error)
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
         __Pyx_XDECREF(__pyx_t_4);
@@ -6378,20 +6443,20 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
         while (1) {
           __pyx_t_12 = __Pyx_dict_iter_next(__pyx_t_4, __pyx_t_7, &__pyx_t_6, &__pyx_t_10, &__pyx_t_9, NULL, __pyx_t_8);
           if (unlikely(__pyx_t_12 == 0)) break;
-          if (unlikely(__pyx_t_12 == -1)) __PYX_ERR(0, 192, __pyx_L11_error)
+          if (unlikely(__pyx_t_12 == -1)) __PYX_ERR(0, 193, __pyx_L11_error)
           __Pyx_GOTREF(__pyx_t_10);
           __Pyx_GOTREF(__pyx_t_9);
           __Pyx_XDECREF_SET(__pyx_7genexpr__pyx_v_k, __pyx_t_10);
           __pyx_t_10 = 0;
           __Pyx_XDECREF_SET(__pyx_7genexpr__pyx_v_v, __pyx_t_9);
           __pyx_t_9 = 0;
-          __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_Hint); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 192, __pyx_L11_error)
+          __Pyx_GetModuleGlobalName(__pyx_t_9, __pyx_n_s_Hint); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 193, __pyx_L11_error)
           __Pyx_GOTREF(__pyx_t_9);
-          __pyx_t_13 = PyObject_IsInstance(__pyx_7genexpr__pyx_v_k, __pyx_t_9); if (unlikely(__pyx_t_13 == ((int)-1))) __PYX_ERR(0, 192, __pyx_L11_error)
+          __pyx_t_13 = PyObject_IsInstance(__pyx_7genexpr__pyx_v_k, __pyx_t_9); if (unlikely(__pyx_t_13 == ((int)-1))) __PYX_ERR(0, 193, __pyx_L11_error)
           __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           __pyx_t_14 = (__pyx_t_13 != 0);
           if (__pyx_t_14) {
-            __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_pybool); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 192, __pyx_L11_error)
+            __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_pybool); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 193, __pyx_L11_error)
             __Pyx_GOTREF(__pyx_t_10);
             __pyx_t_11 = NULL;
             if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_10))) {
@@ -6405,10 +6470,10 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
             }
             __pyx_t_9 = (__pyx_t_11) ? __Pyx_PyObject_Call2Args(__pyx_t_10, __pyx_t_11, __pyx_7genexpr__pyx_v_v) : __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_7genexpr__pyx_v_v);
             __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
-            if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 192, __pyx_L11_error)
+            if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 193, __pyx_L11_error)
             __Pyx_GOTREF(__pyx_t_9);
             __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-            if (unlikely(PyDict_SetItem(__pyx_t_5, (PyObject*)__pyx_7genexpr__pyx_v_k, (PyObject*)__pyx_t_9))) __PYX_ERR(0, 192, __pyx_L11_error)
+            if (unlikely(PyDict_SetItem(__pyx_t_5, (PyObject*)__pyx_7genexpr__pyx_v_k, (PyObject*)__pyx_t_9))) __PYX_ERR(0, 193, __pyx_L11_error)
             __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
           }
         }
@@ -6425,7 +6490,7 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
       __pyx_v_hintsDict = ((PyObject*)__pyx_t_5);
       __pyx_t_5 = 0;
 
-      /* "libzim.pyx":193
+      /* "libzim.pyx":194
  *             func = getattr(obj, method.decode('UTF-8'))
  *             hintsDict = {k: pybool(v) for k, v in func().items() if isinstance(k, Hint)}
  *             return convertToCppHints(hintsDict)             # <<<<<<<<<<<<<<
@@ -6435,7 +6500,7 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
       __pyx_r = convertToCppHints(__pyx_v_hintsDict);
       goto __pyx_L7_try_return;
 
-      /* "libzim.pyx":190
+      /* "libzim.pyx":191
  *         """Lookup and execute a pure virtual method on object returning Hints"""
  *         cdef map[zim.HintKeys, uint64_t] ret;
  *         try:             # <<<<<<<<<<<<<<
@@ -6450,7 +6515,7 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
     __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-    /* "libzim.pyx":194
+    /* "libzim.pyx":195
  *             hintsDict = {k: pybool(v) for k, v in func().items() if isinstance(k, Hint)}
  *             return convertToCppHints(hintsDict)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -6460,7 +6525,7 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
     __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_8) {
       __Pyx_AddTraceback("libzim.hints_cy_call_fct", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_4, &__pyx_t_9) < 0) __PYX_ERR(0, 194, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_4, &__pyx_t_9) < 0) __PYX_ERR(0, 195, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_5);
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_9);
@@ -6468,16 +6533,16 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
       __pyx_v_e = __pyx_t_4;
       /*try:*/ {
 
-        /* "libzim.pyx":195
+        /* "libzim.pyx":196
  *             return convertToCppHints(hintsDict)
  *         except Exception as e:
  *             error[0] = traceback.format_exc().encode('UTF-8')             # <<<<<<<<<<<<<<
  * 
  *         return ret
  */
-        __Pyx_GetModuleGlobalName(__pyx_t_15, __pyx_n_s_traceback); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 195, __pyx_L21_error)
+        __Pyx_GetModuleGlobalName(__pyx_t_15, __pyx_n_s_traceback); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 196, __pyx_L21_error)
         __Pyx_GOTREF(__pyx_t_15);
-        __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_t_15, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 195, __pyx_L21_error)
+        __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_t_15, __pyx_n_s_format_exc); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 196, __pyx_L21_error)
         __Pyx_GOTREF(__pyx_t_16);
         __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
         __pyx_t_15 = NULL;
@@ -6492,10 +6557,10 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
         }
         __pyx_t_11 = (__pyx_t_15) ? __Pyx_PyObject_CallOneArg(__pyx_t_16, __pyx_t_15) : __Pyx_PyObject_CallNoArg(__pyx_t_16);
         __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
-        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 195, __pyx_L21_error)
+        if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 196, __pyx_L21_error)
         __Pyx_GOTREF(__pyx_t_11);
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-        __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_encode); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 195, __pyx_L21_error)
+        __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_encode); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 196, __pyx_L21_error)
         __Pyx_GOTREF(__pyx_t_16);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         __pyx_t_11 = NULL;
@@ -6510,15 +6575,15 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
         }
         __pyx_t_10 = (__pyx_t_11) ? __Pyx_PyObject_Call2Args(__pyx_t_16, __pyx_t_11, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_16, __pyx_kp_u_UTF_8);
         __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
-        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 195, __pyx_L21_error)
+        if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 196, __pyx_L21_error)
         __Pyx_GOTREF(__pyx_t_10);
         __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
-        __pyx_t_17 = __pyx_convert_string_from_py_std__in_string(__pyx_t_10); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 195, __pyx_L21_error)
+        __pyx_t_17 = __pyx_convert_string_from_py_std__in_string(__pyx_t_10); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 196, __pyx_L21_error)
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         (__pyx_v_error[0]) = __pyx_t_17;
       }
 
-      /* "libzim.pyx":194
+      /* "libzim.pyx":195
  *             hintsDict = {k: pybool(v) for k, v in func().items() if isinstance(k, Hint)}
  *             return convertToCppHints(hintsDict)
  *         except Exception as e:             # <<<<<<<<<<<<<<
@@ -6577,7 +6642,7 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "libzim.pyx":190
+    /* "libzim.pyx":191
  *         """Lookup and execute a pure virtual method on object returning Hints"""
  *         cdef map[zim.HintKeys, uint64_t] ret;
  *         try:             # <<<<<<<<<<<<<<
@@ -6602,7 +6667,7 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
     __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
   }
 
-  /* "libzim.pyx":197
+  /* "libzim.pyx":198
  *             error[0] = traceback.format_exc().encode('UTF-8')
  * 
  *         return ret             # <<<<<<<<<<<<<<
@@ -6612,7 +6677,7 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
   __pyx_r = __pyx_v_ret;
   goto __pyx_L0;
 
-  /* "libzim.pyx":187
+  /* "libzim.pyx":188
  *         return ret
  * 
  *     map[zim.HintKeys, uint64_t] hints_cy_call_fct(object obj, string method, string* error) with gil:             # <<<<<<<<<<<<<<
@@ -6645,7 +6710,7 @@ std::map<zim::writer::HintKeys,uint64_t>  hints_cy_call_fct(PyObject *__pyx_v_ob
   return __pyx_r;
 }
 
-/* "libzim.pyx":211
+/* "libzim.pyx":212
  *     cdef bytes ref_content
  * 
  *     def __cinit__(self, content: Union[str, bytes]):             # <<<<<<<<<<<<<<
@@ -6682,7 +6747,7 @@ static int __pyx_pw_6libzim_11WritingBlob_1__cinit__(PyObject *__pyx_v_self, PyO
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 211, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 212, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -6693,7 +6758,7 @@ static int __pyx_pw_6libzim_11WritingBlob_1__cinit__(PyObject *__pyx_v_self, PyO
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 211, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 212, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.WritingBlob.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -6722,7 +6787,7 @@ static int __pyx_pf_6libzim_11WritingBlob___cinit__(struct __pyx_obj_6libzim_Wri
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "libzim.pyx":212
+  /* "libzim.pyx":213
  * 
  *     def __cinit__(self, content: Union[str, bytes]):
  *         if isinstance(content, str):             # <<<<<<<<<<<<<<
@@ -6733,14 +6798,14 @@ static int __pyx_pf_6libzim_11WritingBlob___cinit__(struct __pyx_obj_6libzim_Wri
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "libzim.pyx":213
+    /* "libzim.pyx":214
  *     def __cinit__(self, content: Union[str, bytes]):
  *         if isinstance(content, str):
  *             self.ref_content = content.encode('UTF-8')             # <<<<<<<<<<<<<<
  *         else:
  *             self.ref_content = content
  */
-    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_content, __pyx_n_s_encode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 213, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_content, __pyx_n_s_encode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 214, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
@@ -6754,17 +6819,17 @@ static int __pyx_pf_6libzim_11WritingBlob___cinit__(struct __pyx_obj_6libzim_Wri
     }
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_5, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_UTF_8);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 213, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 214, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (!(likely(PyBytes_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_3)->tp_name), 0))) __PYX_ERR(0, 213, __pyx_L1_error)
+    if (!(likely(PyBytes_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||((void)PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_3)->tp_name), 0))) __PYX_ERR(0, 214, __pyx_L1_error)
     __Pyx_GIVEREF(__pyx_t_3);
     __Pyx_GOTREF(__pyx_v_self->ref_content);
     __Pyx_DECREF(__pyx_v_self->ref_content);
     __pyx_v_self->ref_content = ((PyObject*)__pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "libzim.pyx":212
+    /* "libzim.pyx":213
  * 
  *     def __cinit__(self, content: Union[str, bytes]):
  *         if isinstance(content, str):             # <<<<<<<<<<<<<<
@@ -6774,7 +6839,7 @@ static int __pyx_pf_6libzim_11WritingBlob___cinit__(struct __pyx_obj_6libzim_Wri
     goto __pyx_L3;
   }
 
-  /* "libzim.pyx":215
+  /* "libzim.pyx":216
  *             self.ref_content = content.encode('UTF-8')
  *         else:
  *             self.ref_content = content             # <<<<<<<<<<<<<<
@@ -6782,7 +6847,7 @@ static int __pyx_pf_6libzim_11WritingBlob___cinit__(struct __pyx_obj_6libzim_Wri
  * 
  */
   /*else*/ {
-    if (!(likely(PyBytes_CheckExact(__pyx_v_content))||((__pyx_v_content) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_content)->tp_name), 0))) __PYX_ERR(0, 215, __pyx_L1_error)
+    if (!(likely(PyBytes_CheckExact(__pyx_v_content))||((__pyx_v_content) == Py_None)||((void)PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_content)->tp_name), 0))) __PYX_ERR(0, 216, __pyx_L1_error)
     __pyx_t_3 = __pyx_v_content;
     __Pyx_INCREF(__pyx_t_3);
     __Pyx_GIVEREF(__pyx_t_3);
@@ -6793,7 +6858,7 @@ static int __pyx_pf_6libzim_11WritingBlob___cinit__(struct __pyx_obj_6libzim_Wri
   }
   __pyx_L3:;
 
-  /* "libzim.pyx":216
+  /* "libzim.pyx":217
  *         else:
  *             self.ref_content = content
  *         self.c_blob = move(zim.Blob(<char *> self.ref_content, len(self.ref_content)))             # <<<<<<<<<<<<<<
@@ -6802,26 +6867,26 @@ static int __pyx_pf_6libzim_11WritingBlob___cinit__(struct __pyx_obj_6libzim_Wri
  */
   if (unlikely(__pyx_v_self->ref_content == Py_None)) {
     PyErr_SetString(PyExc_TypeError, "expected bytes, NoneType found");
-    __PYX_ERR(0, 216, __pyx_L1_error)
+    __PYX_ERR(0, 217, __pyx_L1_error)
   }
-  __pyx_t_6 = __Pyx_PyBytes_AsWritableString(__pyx_v_self->ref_content); if (unlikely((!__pyx_t_6) && PyErr_Occurred())) __PYX_ERR(0, 216, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyBytes_AsWritableString(__pyx_v_self->ref_content); if (unlikely((!__pyx_t_6) && PyErr_Occurred())) __PYX_ERR(0, 217, __pyx_L1_error)
   __pyx_t_3 = __pyx_v_self->ref_content;
   __Pyx_INCREF(__pyx_t_3);
   if (unlikely(__pyx_t_3 == Py_None)) {
     PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
-    __PYX_ERR(0, 216, __pyx_L1_error)
+    __PYX_ERR(0, 217, __pyx_L1_error)
   }
-  __pyx_t_7 = PyBytes_GET_SIZE(__pyx_t_3); if (unlikely(__pyx_t_7 == ((Py_ssize_t)-1))) __PYX_ERR(0, 216, __pyx_L1_error)
+  __pyx_t_7 = PyBytes_GET_SIZE(__pyx_t_3); if (unlikely(__pyx_t_7 == ((Py_ssize_t)-1))) __PYX_ERR(0, 217, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   try {
     __pyx_t_8 = wrapper::Blob(((char *)__pyx_t_6), __pyx_t_7);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 216, __pyx_L1_error)
+    __PYX_ERR(0, 217, __pyx_L1_error)
   }
   __pyx_v_self->c_blob = cython_std::move<wrapper::Blob>(__pyx_t_8);
 
-  /* "libzim.pyx":211
+  /* "libzim.pyx":212
  *     cdef bytes ref_content
  * 
  *     def __cinit__(self, content: Union[str, bytes]):             # <<<<<<<<<<<<<<
@@ -6843,7 +6908,7 @@ static int __pyx_pf_6libzim_11WritingBlob___cinit__(struct __pyx_obj_6libzim_Wri
   return __pyx_r;
 }
 
-/* "libzim.pyx":218
+/* "libzim.pyx":219
  *         self.c_blob = move(zim.Blob(<char *> self.ref_content, len(self.ref_content)))
  * 
  *     def size(self):             # <<<<<<<<<<<<<<
@@ -6874,7 +6939,7 @@ static PyObject *__pyx_pf_6libzim_11WritingBlob_2size(struct __pyx_obj_6libzim_W
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("size", 0);
 
-  /* "libzim.pyx":219
+  /* "libzim.pyx":220
  * 
  *     def size(self):
  *         return self.c_blob.size()             # <<<<<<<<<<<<<<
@@ -6886,15 +6951,15 @@ static PyObject *__pyx_pf_6libzim_11WritingBlob_2size(struct __pyx_obj_6libzim_W
     __pyx_t_1 = __pyx_v_self->c_blob.size();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 219, __pyx_L1_error)
+    __PYX_ERR(0, 220, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 219, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 220, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":218
+  /* "libzim.pyx":219
  *         self.c_blob = move(zim.Blob(<char *> self.ref_content, len(self.ref_content)))
  * 
  *     def size(self):             # <<<<<<<<<<<<<<
@@ -7026,7 +7091,7 @@ static PyObject *__pyx_pf_6libzim_11WritingBlob_6__setstate_cython__(CYTHON_UNUS
   return __pyx_r;
 }
 
-/* "libzim.pyx":256
+/* "libzim.pyx":257
  *     cdef object _started
  * 
  *     def __cinit__(self, object filename: pathlib.Path, *args, **kwargs):             # <<<<<<<<<<<<<<
@@ -7079,7 +7144,7 @@ static int __pyx_pw_6libzim_8_Creator_1__cinit__(PyObject *__pyx_v_self, PyObjec
       }
       if (unlikely(kw_args > 0)) {
         const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, __pyx_v_kwargs, values, used_pos_args, "__cinit__") < 0)) __PYX_ERR(0, 256, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, __pyx_v_kwargs, values, used_pos_args, "__cinit__") < 0)) __PYX_ERR(0, 257, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
       goto __pyx_L5_argtuple_error;
@@ -7090,7 +7155,7 @@ static int __pyx_pw_6libzim_8_Creator_1__cinit__(PyObject *__pyx_v_self, PyObjec
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 256, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 257, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_DECREF(__pyx_v_args); __pyx_v_args = 0;
   __Pyx_DECREF(__pyx_v_kwargs); __pyx_v_kwargs = 0;
@@ -7124,16 +7189,16 @@ static int __pyx_pf_6libzim_8_Creator___cinit__(struct __pyx_obj_6libzim__Creato
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "libzim.pyx":257
+  /* "libzim.pyx":258
  * 
  *     def __cinit__(self, object filename: pathlib.Path, *args, **kwargs):
  *         self._filename = pathlib.Path(filename)             # <<<<<<<<<<<<<<
  *         self._started = False
  *         # fail early if destination is not writable
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_pathlib); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 257, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_pathlib); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 258, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_Path); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 257, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_Path); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 258, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_t_2 = NULL;
@@ -7148,7 +7213,7 @@ static int __pyx_pf_6libzim_8_Creator___cinit__(struct __pyx_obj_6libzim__Creato
   }
   __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_2, __pyx_v_filename) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename);
   __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 257, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 258, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_GIVEREF(__pyx_t_1);
@@ -7157,7 +7222,7 @@ static int __pyx_pf_6libzim_8_Creator___cinit__(struct __pyx_obj_6libzim__Creato
   __pyx_v_self->_filename = __pyx_t_1;
   __pyx_t_1 = 0;
 
-  /* "libzim.pyx":258
+  /* "libzim.pyx":259
  *     def __cinit__(self, object filename: pathlib.Path, *args, **kwargs):
  *         self._filename = pathlib.Path(filename)
  *         self._started = False             # <<<<<<<<<<<<<<
@@ -7170,14 +7235,14 @@ static int __pyx_pf_6libzim_8_Creator___cinit__(struct __pyx_obj_6libzim__Creato
   __Pyx_DECREF(__pyx_v_self->_started);
   __pyx_v_self->_started = Py_False;
 
-  /* "libzim.pyx":260
+  /* "libzim.pyx":261
  *         self._started = False
  *         # fail early if destination is not writable
  *         parent = self._filename.expanduser().resolve().parent             # <<<<<<<<<<<<<<
  *         if not os.access(parent, mode=os.W_OK, effective_ids=(os.access in os.supports_effective_ids)):
  *             raise IOError(f"Unable to write ZIM file at {self._filename}")
  */
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_filename, __pyx_n_s_expanduser); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 260, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self->_filename, __pyx_n_s_expanduser); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 261, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -7191,10 +7256,10 @@ static int __pyx_pf_6libzim_8_Creator___cinit__(struct __pyx_obj_6libzim__Creato
   }
   __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 260, __pyx_L1_error)
+  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 261, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_resolve); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 260, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_resolve); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 261, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_t_3 = NULL;
@@ -7209,88 +7274,88 @@ static int __pyx_pf_6libzim_8_Creator___cinit__(struct __pyx_obj_6libzim__Creato
   }
   __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2);
   __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 260, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 261, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_parent); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 260, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_parent); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 261, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_v_parent = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "libzim.pyx":261
+  /* "libzim.pyx":262
  *         # fail early if destination is not writable
  *         parent = self._filename.expanduser().resolve().parent
  *         if not os.access(parent, mode=os.W_OK, effective_ids=(os.access in os.supports_effective_ids)):             # <<<<<<<<<<<<<<
  *             raise IOError(f"Unable to write ZIM file at {self._filename}")
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_os); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_os); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_access); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_access); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(__pyx_v_parent);
   __Pyx_GIVEREF(__pyx_v_parent);
   PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_parent);
-  __pyx_t_3 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_os); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_os); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_W_OK); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_W_OK); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_mode, __pyx_t_5) < 0) __PYX_ERR(0, 261, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_mode, __pyx_t_5) < 0) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_os); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_os); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_access); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_access); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_os); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_os); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_supports_effective_ids); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_supports_effective_ids); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_7 = (__Pyx_PySequence_ContainsTF(__pyx_t_4, __pyx_t_6, Py_EQ)); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __pyx_t_7 = (__Pyx_PySequence_ContainsTF(__pyx_t_4, __pyx_t_6, Py_EQ)); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_effective_ids, __pyx_t_6) < 0) __PYX_ERR(0, 261, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_effective_ids, __pyx_t_6) < 0) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 261, __pyx_L1_error)
+  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 262, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
   __pyx_t_8 = ((!__pyx_t_7) != 0);
   if (unlikely(__pyx_t_8)) {
 
-    /* "libzim.pyx":262
+    /* "libzim.pyx":263
  *         parent = self._filename.expanduser().resolve().parent
  *         if not os.access(parent, mode=os.W_OK, effective_ids=(os.access in os.supports_effective_ids)):
  *             raise IOError(f"Unable to write ZIM file at {self._filename}")             # <<<<<<<<<<<<<<
  * 
  *     def __init__(self, filename: pathlib.Path):
  */
-    __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_self->_filename, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 262, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_self->_filename, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 263, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unable_to_write_ZIM_file_at, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 262, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyUnicode_Concat(__pyx_kp_u_Unable_to_write_ZIM_file_at, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 263, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_IOError, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 262, __pyx_L1_error)
+    __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_builtin_IOError, __pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 263, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_6);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_Raise(__pyx_t_6, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __PYX_ERR(0, 262, __pyx_L1_error)
+    __PYX_ERR(0, 263, __pyx_L1_error)
 
-    /* "libzim.pyx":261
+    /* "libzim.pyx":262
  *         # fail early if destination is not writable
  *         parent = self._filename.expanduser().resolve().parent
  *         if not os.access(parent, mode=os.W_OK, effective_ids=(os.access in os.supports_effective_ids)):             # <<<<<<<<<<<<<<
@@ -7299,7 +7364,7 @@ static int __pyx_pf_6libzim_8_Creator___cinit__(struct __pyx_obj_6libzim__Creato
  */
   }
 
-  /* "libzim.pyx":256
+  /* "libzim.pyx":257
  *     cdef object _started
  * 
  *     def __cinit__(self, object filename: pathlib.Path, *args, **kwargs):             # <<<<<<<<<<<<<<
@@ -7325,7 +7390,7 @@ static int __pyx_pf_6libzim_8_Creator___cinit__(struct __pyx_obj_6libzim__Creato
   return __pyx_r;
 }
 
-/* "libzim.pyx":264
+/* "libzim.pyx":265
  *             raise IOError(f"Unable to write ZIM file at {self._filename}")
  * 
  *     def __init__(self, filename: pathlib.Path):             # <<<<<<<<<<<<<<
@@ -7366,7 +7431,7 @@ static int __pyx_pw_6libzim_8_Creator_3__init__(PyObject *__pyx_v_self, PyObject
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 264, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 265, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -7377,7 +7442,7 @@ static int __pyx_pw_6libzim_8_Creator_3__init__(PyObject *__pyx_v_self, PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 264, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 265, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim._Creator.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -7401,7 +7466,7 @@ static int __pyx_pf_6libzim_8_Creator_2__init__(CYTHON_UNUSED struct __pyx_obj_6
   return __pyx_r;
 }
 
-/* "libzim.pyx":273
+/* "libzim.pyx":274
  *         pass
  * 
  *     def config_verbose(self, bool verbose: bool) -> Creator:             # <<<<<<<<<<<<<<
@@ -7421,7 +7486,7 @@ static PyObject *__pyx_pw_6libzim_8_Creator_5config_verbose(PyObject *__pyx_v_se
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("config_verbose (wrapper)", 0);
   assert(__pyx_arg_verbose); {
-    __pyx_v_verbose = __Pyx_PyObject_IsTrue(__pyx_arg_verbose); if (unlikely((__pyx_v_verbose == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 273, __pyx_L3_error)
+    __pyx_v_verbose = __Pyx_PyObject_IsTrue(__pyx_arg_verbose); if (unlikely((__pyx_v_verbose == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 274, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -7446,30 +7511,30 @@ static PyObject *__pyx_pf_6libzim_8_Creator_4config_verbose(struct __pyx_obj_6li
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("config_verbose", 0);
 
-  /* "libzim.pyx":275
+  /* "libzim.pyx":276
  *     def config_verbose(self, bool verbose: bool) -> Creator:
  *         """Set creator verbosity (inside libzim). Default is off"""
  *         if self._started:             # <<<<<<<<<<<<<<
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configVerbose(verbose)
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 275, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 276, __pyx_L1_error)
   if (unlikely(__pyx_t_1)) {
 
-    /* "libzim.pyx":276
+    /* "libzim.pyx":277
  *         """Set creator verbosity (inside libzim). Default is off"""
  *         if self._started:
  *             raise RuntimeError("Creator started")             # <<<<<<<<<<<<<<
  *         self.c_creator.configVerbose(verbose)
  *         return self
  */
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 276, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 277, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 276, __pyx_L1_error)
+    __PYX_ERR(0, 277, __pyx_L1_error)
 
-    /* "libzim.pyx":275
+    /* "libzim.pyx":276
  *     def config_verbose(self, bool verbose: bool) -> Creator:
  *         """Set creator verbosity (inside libzim). Default is off"""
  *         if self._started:             # <<<<<<<<<<<<<<
@@ -7478,7 +7543,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_4config_verbose(struct __pyx_obj_6li
  */
   }
 
-  /* "libzim.pyx":277
+  /* "libzim.pyx":278
  *         if self._started:
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configVerbose(verbose)             # <<<<<<<<<<<<<<
@@ -7487,7 +7552,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_4config_verbose(struct __pyx_obj_6li
  */
   __pyx_v_self->c_creator.configVerbose(__pyx_v_verbose);
 
-  /* "libzim.pyx":278
+  /* "libzim.pyx":279
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configVerbose(verbose)
  *         return self             # <<<<<<<<<<<<<<
@@ -7499,7 +7564,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_4config_verbose(struct __pyx_obj_6li
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "libzim.pyx":273
+  /* "libzim.pyx":274
  *         pass
  * 
  *     def config_verbose(self, bool verbose: bool) -> Creator:             # <<<<<<<<<<<<<<
@@ -7518,7 +7583,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_4config_verbose(struct __pyx_obj_6li
   return __pyx_r;
 }
 
-/* "libzim.pyx":280
+/* "libzim.pyx":281
  *         return self
  * 
  *     def config_compression(self, compression: Compression) -> Creator:             # <<<<<<<<<<<<<<
@@ -7551,30 +7616,30 @@ static PyObject *__pyx_pf_6libzim_8_Creator_6config_compression(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("config_compression", 0);
 
-  /* "libzim.pyx":284
+  /* "libzim.pyx":285
  * 
  *             Fall 2021 default: zstd"""
  *         if self._started:             # <<<<<<<<<<<<<<
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configCompression(zim.comp_from_int(compression.value))
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 284, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 285, __pyx_L1_error)
   if (unlikely(__pyx_t_1)) {
 
-    /* "libzim.pyx":285
+    /* "libzim.pyx":286
  *             Fall 2021 default: zstd"""
  *         if self._started:
  *             raise RuntimeError("Creator started")             # <<<<<<<<<<<<<<
  *         self.c_creator.configCompression(zim.comp_from_int(compression.value))
  *         return self
  */
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 285, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 286, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 285, __pyx_L1_error)
+    __PYX_ERR(0, 286, __pyx_L1_error)
 
-    /* "libzim.pyx":284
+    /* "libzim.pyx":285
  * 
  *             Fall 2021 default: zstd"""
  *         if self._started:             # <<<<<<<<<<<<<<
@@ -7583,20 +7648,20 @@ static PyObject *__pyx_pf_6libzim_8_Creator_6config_compression(struct __pyx_obj
  */
   }
 
-  /* "libzim.pyx":286
+  /* "libzim.pyx":287
  *         if self._started:
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configCompression(zim.comp_from_int(compression.value))             # <<<<<<<<<<<<<<
  *         return self
  * 
  */
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_compression, __pyx_n_s_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 286, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_compression, __pyx_n_s_value); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 287, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 286, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 287, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_v_self->c_creator.configCompression(comp_from_int(__pyx_t_3));
 
-  /* "libzim.pyx":287
+  /* "libzim.pyx":288
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configCompression(zim.comp_from_int(compression.value))
  *         return self             # <<<<<<<<<<<<<<
@@ -7608,7 +7673,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_6config_compression(struct __pyx_obj
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "libzim.pyx":280
+  /* "libzim.pyx":281
  *         return self
  * 
  *     def config_compression(self, compression: Compression) -> Creator:             # <<<<<<<<<<<<<<
@@ -7627,7 +7692,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_6config_compression(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "libzim.pyx":289
+/* "libzim.pyx":290
  *         return self
  * 
  *     def config_clustersize(self, int size: pyint) -> Creator:             # <<<<<<<<<<<<<<
@@ -7647,7 +7712,7 @@ static PyObject *__pyx_pw_6libzim_8_Creator_9config_clustersize(PyObject *__pyx_
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("config_clustersize (wrapper)", 0);
   assert(__pyx_arg_size); {
-    __pyx_v_size = __Pyx_PyInt_As_int(__pyx_arg_size); if (unlikely((__pyx_v_size == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 289, __pyx_L3_error)
+    __pyx_v_size = __Pyx_PyInt_As_int(__pyx_arg_size); if (unlikely((__pyx_v_size == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 290, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -7672,30 +7737,30 @@ static PyObject *__pyx_pf_6libzim_8_Creator_8config_clustersize(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("config_clustersize", 0);
 
-  /* "libzim.pyx":295
+  /* "libzim.pyx":296
  *             another one.
  *             Fall 2021 default: 2Mib"""
  *         if self._started:             # <<<<<<<<<<<<<<
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configClusterSize(size)
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 295, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 296, __pyx_L1_error)
   if (unlikely(__pyx_t_1)) {
 
-    /* "libzim.pyx":296
+    /* "libzim.pyx":297
  *             Fall 2021 default: 2Mib"""
  *         if self._started:
  *             raise RuntimeError("Creator started")             # <<<<<<<<<<<<<<
  *         self.c_creator.configClusterSize(size)
  *         return self
  */
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 296, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 297, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 296, __pyx_L1_error)
+    __PYX_ERR(0, 297, __pyx_L1_error)
 
-    /* "libzim.pyx":295
+    /* "libzim.pyx":296
  *             another one.
  *             Fall 2021 default: 2Mib"""
  *         if self._started:             # <<<<<<<<<<<<<<
@@ -7704,7 +7769,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_8config_clustersize(struct __pyx_obj
  */
   }
 
-  /* "libzim.pyx":297
+  /* "libzim.pyx":298
  *         if self._started:
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configClusterSize(size)             # <<<<<<<<<<<<<<
@@ -7713,7 +7778,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_8config_clustersize(struct __pyx_obj
  */
   __pyx_v_self->c_creator.configClusterSize(__pyx_v_size);
 
-  /* "libzim.pyx":298
+  /* "libzim.pyx":299
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configClusterSize(size)
  *         return self             # <<<<<<<<<<<<<<
@@ -7725,7 +7790,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_8config_clustersize(struct __pyx_obj
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "libzim.pyx":289
+  /* "libzim.pyx":290
  *         return self
  * 
  *     def config_clustersize(self, int size: pyint) -> Creator:             # <<<<<<<<<<<<<<
@@ -7744,7 +7809,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_8config_clustersize(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "libzim.pyx":300
+/* "libzim.pyx":301
  *         return self
  * 
  *     def config_indexing(self, bool indexing: bool, str language: str) -> Creator:             # <<<<<<<<<<<<<<
@@ -7787,11 +7852,11 @@ static PyObject *__pyx_pw_6libzim_8_Creator_11config_indexing(PyObject *__pyx_v_
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_language)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("config_indexing", 1, 2, 2, 1); __PYX_ERR(0, 300, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("config_indexing", 1, 2, 2, 1); __PYX_ERR(0, 301, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "config_indexing") < 0)) __PYX_ERR(0, 300, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "config_indexing") < 0)) __PYX_ERR(0, 301, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -7799,18 +7864,18 @@ static PyObject *__pyx_pw_6libzim_8_Creator_11config_indexing(PyObject *__pyx_v_
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_indexing = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_indexing == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 300, __pyx_L3_error)
+    __pyx_v_indexing = __Pyx_PyObject_IsTrue(values[0]); if (unlikely((__pyx_v_indexing == ((bool)-1)) && PyErr_Occurred())) __PYX_ERR(0, 301, __pyx_L3_error)
     __pyx_v_language = ((PyObject*)values[1]);
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("config_indexing", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 300, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("config_indexing", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 301, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim._Creator.config_indexing", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_language), (&PyUnicode_Type), 1, "language", 1))) __PYX_ERR(0, 300, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_language), (&PyUnicode_Type), 1, "language", 1))) __PYX_ERR(0, 301, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_8_Creator_10config_indexing(((struct __pyx_obj_6libzim__Creator *)__pyx_v_self), __pyx_v_indexing, __pyx_v_language);
 
   /* function exit code */
@@ -7833,30 +7898,30 @@ static PyObject *__pyx_pf_6libzim_8_Creator_10config_indexing(struct __pyx_obj_6
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("config_indexing", 0);
 
-  /* "libzim.pyx":305
+  /* "libzim.pyx":306
  *             indexing: whether to create a full-text index of the content
  *             language: language (ISO-639-3 code) to assume content in during indexation"""
  *         if self._started:             # <<<<<<<<<<<<<<
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configIndexing(indexing, language.encode('UTF-8'))
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 305, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 306, __pyx_L1_error)
   if (unlikely(__pyx_t_1)) {
 
-    /* "libzim.pyx":306
+    /* "libzim.pyx":307
  *             language: language (ISO-639-3 code) to assume content in during indexation"""
  *         if self._started:
  *             raise RuntimeError("Creator started")             # <<<<<<<<<<<<<<
  *         self.c_creator.configIndexing(indexing, language.encode('UTF-8'))
  *         return self
  */
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 306, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 307, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 306, __pyx_L1_error)
+    __PYX_ERR(0, 307, __pyx_L1_error)
 
-    /* "libzim.pyx":305
+    /* "libzim.pyx":306
  *             indexing: whether to create a full-text index of the content
  *             language: language (ISO-639-3 code) to assume content in during indexation"""
  *         if self._started:             # <<<<<<<<<<<<<<
@@ -7865,7 +7930,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_10config_indexing(struct __pyx_obj_6
  */
   }
 
-  /* "libzim.pyx":307
+  /* "libzim.pyx":308
  *         if self._started:
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configIndexing(indexing, language.encode('UTF-8'))             # <<<<<<<<<<<<<<
@@ -7874,15 +7939,15 @@ static PyObject *__pyx_pf_6libzim_8_Creator_10config_indexing(struct __pyx_obj_6
  */
   if (unlikely(__pyx_v_language == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 307, __pyx_L1_error)
+    __PYX_ERR(0, 308, __pyx_L1_error)
   }
-  __pyx_t_2 = PyUnicode_AsUTF8String(__pyx_v_language); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 307, __pyx_L1_error)
+  __pyx_t_2 = PyUnicode_AsUTF8String(__pyx_v_language); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 308, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 307, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 308, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_v_self->c_creator.configIndexing(__pyx_v_indexing, __pyx_t_3);
 
-  /* "libzim.pyx":308
+  /* "libzim.pyx":309
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configIndexing(indexing, language.encode('UTF-8'))
  *         return self             # <<<<<<<<<<<<<<
@@ -7894,7 +7959,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_10config_indexing(struct __pyx_obj_6
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "libzim.pyx":300
+  /* "libzim.pyx":301
  *         return self
  * 
  *     def config_indexing(self, bool indexing: bool, str language: str) -> Creator:             # <<<<<<<<<<<<<<
@@ -7913,7 +7978,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_10config_indexing(struct __pyx_obj_6
   return __pyx_r;
 }
 
-/* "libzim.pyx":310
+/* "libzim.pyx":311
  *         return self
  * 
  *     def config_nbworkers(self, int nbWorkers: pyint) -> Creator:             # <<<<<<<<<<<<<<
@@ -7933,7 +7998,7 @@ static PyObject *__pyx_pw_6libzim_8_Creator_13config_nbworkers(PyObject *__pyx_v
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("config_nbworkers (wrapper)", 0);
   assert(__pyx_arg_nbWorkers); {
-    __pyx_v_nbWorkers = __Pyx_PyInt_As_int(__pyx_arg_nbWorkers); if (unlikely((__pyx_v_nbWorkers == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 310, __pyx_L3_error)
+    __pyx_v_nbWorkers = __Pyx_PyInt_As_int(__pyx_arg_nbWorkers); if (unlikely((__pyx_v_nbWorkers == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 311, __pyx_L3_error)
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L3_error:;
@@ -7958,30 +8023,30 @@ static PyObject *__pyx_pf_6libzim_8_Creator_12config_nbworkers(struct __pyx_obj_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("config_nbworkers", 0);
 
-  /* "libzim.pyx":312
+  /* "libzim.pyx":313
  *     def config_nbworkers(self, int nbWorkers: pyint) -> Creator:
  *         """Number of thread to use for internal worker"""
  *         if self._started:             # <<<<<<<<<<<<<<
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configNbWorkers(nbWorkers)
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 312, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 313, __pyx_L1_error)
   if (unlikely(__pyx_t_1)) {
 
-    /* "libzim.pyx":313
+    /* "libzim.pyx":314
  *         """Number of thread to use for internal worker"""
  *         if self._started:
  *             raise RuntimeError("Creator started")             # <<<<<<<<<<<<<<
  *         self.c_creator.configNbWorkers(nbWorkers)
  *         return self
  */
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 313, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 314, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 313, __pyx_L1_error)
+    __PYX_ERR(0, 314, __pyx_L1_error)
 
-    /* "libzim.pyx":312
+    /* "libzim.pyx":313
  *     def config_nbworkers(self, int nbWorkers: pyint) -> Creator:
  *         """Number of thread to use for internal worker"""
  *         if self._started:             # <<<<<<<<<<<<<<
@@ -7990,7 +8055,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_12config_nbworkers(struct __pyx_obj_
  */
   }
 
-  /* "libzim.pyx":314
+  /* "libzim.pyx":315
  *         if self._started:
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configNbWorkers(nbWorkers)             # <<<<<<<<<<<<<<
@@ -7999,7 +8064,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_12config_nbworkers(struct __pyx_obj_
  */
   __pyx_v_self->c_creator.configNbWorkers(__pyx_v_nbWorkers);
 
-  /* "libzim.pyx":315
+  /* "libzim.pyx":316
  *             raise RuntimeError("Creator started")
  *         self.c_creator.configNbWorkers(nbWorkers)
  *         return self             # <<<<<<<<<<<<<<
@@ -8011,7 +8076,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_12config_nbworkers(struct __pyx_obj_
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "libzim.pyx":310
+  /* "libzim.pyx":311
  *         return self
  * 
  *     def config_nbworkers(self, int nbWorkers: pyint) -> Creator:             # <<<<<<<<<<<<<<
@@ -8030,7 +8095,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_12config_nbworkers(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "libzim.pyx":317
+/* "libzim.pyx":318
  *         return self
  * 
  *     def set_mainpath(self, str mainPath: str) -> Creator:             # <<<<<<<<<<<<<<
@@ -8048,7 +8113,7 @@ static PyObject *__pyx_pw_6libzim_8_Creator_15set_mainpath(PyObject *__pyx_v_sel
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_mainpath (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mainPath), (&PyUnicode_Type), 1, "mainPath", 1))) __PYX_ERR(0, 317, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mainPath), (&PyUnicode_Type), 1, "mainPath", 1))) __PYX_ERR(0, 318, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_8_Creator_14set_mainpath(((struct __pyx_obj_6libzim__Creator *)__pyx_v_self), ((PyObject*)__pyx_v_mainPath));
 
   /* function exit code */
@@ -8070,7 +8135,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_14set_mainpath(struct __pyx_obj_6lib
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_mainpath", 0);
 
-  /* "libzim.pyx":319
+  /* "libzim.pyx":320
  *     def set_mainpath(self, str mainPath: str) -> Creator:
  *         """Set path of the main entry"""
  *         self.c_creator.setMainPath(mainPath.encode('UTF-8'))             # <<<<<<<<<<<<<<
@@ -8079,15 +8144,15 @@ static PyObject *__pyx_pf_6libzim_8_Creator_14set_mainpath(struct __pyx_obj_6lib
  */
   if (unlikely(__pyx_v_mainPath == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 319, __pyx_L1_error)
+    __PYX_ERR(0, 320, __pyx_L1_error)
   }
-  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_mainPath); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 319, __pyx_L1_error)
+  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_mainPath); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 320, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 319, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 320, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_v_self->c_creator.setMainPath(__pyx_t_2);
 
-  /* "libzim.pyx":320
+  /* "libzim.pyx":321
  *         """Set path of the main entry"""
  *         self.c_creator.setMainPath(mainPath.encode('UTF-8'))
  *         return self             # <<<<<<<<<<<<<<
@@ -8099,7 +8164,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_14set_mainpath(struct __pyx_obj_6lib
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "libzim.pyx":317
+  /* "libzim.pyx":318
  *         return self
  * 
  *     def set_mainpath(self, str mainPath: str) -> Creator:             # <<<<<<<<<<<<<<
@@ -8118,7 +8183,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_14set_mainpath(struct __pyx_obj_6lib
   return __pyx_r;
 }
 
-/* "libzim.pyx":322
+/* "libzim.pyx":323
  *         return self
  * 
  *     def add_illustration(self, int size: pyint, content: bytes):             # <<<<<<<<<<<<<<
@@ -8161,11 +8226,11 @@ static PyObject *__pyx_pw_6libzim_8_Creator_17add_illustration(PyObject *__pyx_v
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_content)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_illustration", 1, 2, 2, 1); __PYX_ERR(0, 322, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_illustration", 1, 2, 2, 1); __PYX_ERR(0, 323, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_illustration") < 0)) __PYX_ERR(0, 322, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_illustration") < 0)) __PYX_ERR(0, 323, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -8173,18 +8238,18 @@ static PyObject *__pyx_pw_6libzim_8_Creator_17add_illustration(PyObject *__pyx_v
       values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
       values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
     }
-    __pyx_v_size = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_size == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 322, __pyx_L3_error)
+    __pyx_v_size = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_size == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 323, __pyx_L3_error)
     __pyx_v_content = ((PyObject*)values[1]);
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add_illustration", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 322, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_illustration", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 323, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim._Creator.add_illustration", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_content), (&PyBytes_Type), 1, "content", 1))) __PYX_ERR(0, 322, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_content), (&PyBytes_Type), 1, "content", 1))) __PYX_ERR(0, 323, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_8_Creator_16add_illustration(((struct __pyx_obj_6libzim__Creator *)__pyx_v_self), __pyx_v_size, __pyx_v_content);
 
   /* function exit code */
@@ -8206,17 +8271,17 @@ static PyObject *__pyx_pf_6libzim_8_Creator_16add_illustration(struct __pyx_obj_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_illustration", 0);
 
-  /* "libzim.pyx":331
+  /* "libzim.pyx":332
  *                 RuntimeError
  *                     If an Illustration exists with the same size"""
  *         cdef string _content = content             # <<<<<<<<<<<<<<
  *         self.c_creator.addIllustration(size, _content)
  * 
  */
-  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_content); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 331, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_string_from_py_std__in_string(__pyx_v_content); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 332, __pyx_L1_error)
   __pyx_v__content = __pyx_t_1;
 
-  /* "libzim.pyx":332
+  /* "libzim.pyx":333
  *                     If an Illustration exists with the same size"""
  *         cdef string _content = content
  *         self.c_creator.addIllustration(size, _content)             # <<<<<<<<<<<<<<
@@ -8227,10 +8292,10 @@ static PyObject *__pyx_pf_6libzim_8_Creator_16add_illustration(struct __pyx_obj_
     __pyx_v_self->c_creator.addIllustration(__pyx_v_size, __pyx_v__content);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 332, __pyx_L1_error)
+    __PYX_ERR(0, 333, __pyx_L1_error)
   }
 
-  /* "libzim.pyx":322
+  /* "libzim.pyx":323
  *         return self
  * 
  *     def add_illustration(self, int size: pyint, content: bytes):             # <<<<<<<<<<<<<<
@@ -8250,7 +8315,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_16add_illustration(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "libzim.pyx":337
+/* "libzim.pyx":338
  * #        self.c_creator.setUuid(uuid)
  * 
  *     def add_item(self, writer_item not None: BaseWritingItem):             # <<<<<<<<<<<<<<
@@ -8269,7 +8334,7 @@ static PyObject *__pyx_pw_6libzim_8_Creator_19add_item(PyObject *__pyx_v_self, P
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("add_item (wrapper)", 0);
   if (unlikely(((PyObject *)__pyx_v_writer_item) == Py_None)) {
-    PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "writer_item"); __PYX_ERR(0, 337, __pyx_L1_error)
+    PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "writer_item"); __PYX_ERR(0, 338, __pyx_L1_error)
   }
   __pyx_r = __pyx_pf_6libzim_8_Creator_18add_item(((struct __pyx_obj_6libzim__Creator *)__pyx_v_self), ((PyObject *)__pyx_v_writer_item));
 
@@ -8295,31 +8360,31 @@ static PyObject *__pyx_pf_6libzim_8_Creator_18add_item(struct __pyx_obj_6libzim_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_item", 0);
 
-  /* "libzim.pyx":350
+  /* "libzim.pyx":351
  *                 RuntimeError
  *                     If the ZimCreator was already finalized"""
  *         if not self._started:             # <<<<<<<<<<<<<<
  *             raise RuntimeError("Creator not started")
  * 
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 350, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 351, __pyx_L1_error)
   __pyx_t_2 = ((!__pyx_t_1) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "libzim.pyx":351
+    /* "libzim.pyx":352
  *                     If the ZimCreator was already finalized"""
  *         if not self._started:
  *             raise RuntimeError("Creator not started")             # <<<<<<<<<<<<<<
  * 
  *         # Make a shared pointer to ZimArticleWrapper from the ZimArticle object
  */
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 351, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 352, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 351, __pyx_L1_error)
+    __PYX_ERR(0, 352, __pyx_L1_error)
 
-    /* "libzim.pyx":350
+    /* "libzim.pyx":351
  *                 RuntimeError
  *                     If the ZimCreator was already finalized"""
  *         if not self._started:             # <<<<<<<<<<<<<<
@@ -8328,7 +8393,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_18add_item(struct __pyx_obj_6libzim_
  */
   }
 
-  /* "libzim.pyx":355
+  /* "libzim.pyx":356
  *         # Make a shared pointer to ZimArticleWrapper from the ZimArticle object
  *         cdef shared_ptr[zim.WriterItem] item = shared_ptr[zim.WriterItem](
  *             new zim.WriterItemWrapper(<PyObject*>writer_item));             # <<<<<<<<<<<<<<
@@ -8339,10 +8404,10 @@ static PyObject *__pyx_pf_6libzim_8_Creator_18add_item(struct __pyx_obj_6libzim_
     __pyx_t_4 = new WriterItemWrapper(((PyObject *)__pyx_v_writer_item));
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 355, __pyx_L1_error)
+    __PYX_ERR(0, 356, __pyx_L1_error)
   }
 
-  /* "libzim.pyx":354
+  /* "libzim.pyx":355
  * 
  *         # Make a shared pointer to ZimArticleWrapper from the ZimArticle object
  *         cdef shared_ptr[zim.WriterItem] item = shared_ptr[zim.WriterItem](             # <<<<<<<<<<<<<<
@@ -8351,7 +8416,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_18add_item(struct __pyx_obj_6libzim_
  */
   __pyx_v_item = std::shared_ptr<zim::writer::Item> (__pyx_t_4);
 
-  /* "libzim.pyx":356
+  /* "libzim.pyx":357
  *         cdef shared_ptr[zim.WriterItem] item = shared_ptr[zim.WriterItem](
  *             new zim.WriterItemWrapper(<PyObject*>writer_item));
  *         with nogil:             # <<<<<<<<<<<<<<
@@ -8366,7 +8431,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_18add_item(struct __pyx_obj_6libzim_
       #endif
       /*try:*/ {
 
-        /* "libzim.pyx":357
+        /* "libzim.pyx":358
  *             new zim.WriterItemWrapper(<PyObject*>writer_item));
  *         with nogil:
  *             self.c_creator.addItem(item)             # <<<<<<<<<<<<<<
@@ -8383,11 +8448,11 @@ static PyObject *__pyx_pf_6libzim_8_Creator_18add_item(struct __pyx_obj_6libzim_
           #ifdef WITH_THREAD
           __Pyx_PyGILState_Release(__pyx_gilstate_save);
           #endif
-          __PYX_ERR(0, 357, __pyx_L5_error)
+          __PYX_ERR(0, 358, __pyx_L5_error)
         }
       }
 
-      /* "libzim.pyx":356
+      /* "libzim.pyx":357
  *         cdef shared_ptr[zim.WriterItem] item = shared_ptr[zim.WriterItem](
  *             new zim.WriterItemWrapper(<PyObject*>writer_item));
  *         with nogil:             # <<<<<<<<<<<<<<
@@ -8413,7 +8478,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_18add_item(struct __pyx_obj_6libzim_
       }
   }
 
-  /* "libzim.pyx":337
+  /* "libzim.pyx":338
  * #        self.c_creator.setUuid(uuid)
  * 
  *     def add_item(self, writer_item not None: BaseWritingItem):             # <<<<<<<<<<<<<<
@@ -8434,7 +8499,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_18add_item(struct __pyx_obj_6libzim_
   return __pyx_r;
 }
 
-/* "libzim.pyx":359
+/* "libzim.pyx":360
  *             self.c_creator.addItem(item)
  * 
  *     def add_metadata(self, str name: str, bytes content: bytes, str mimetype: str):             # <<<<<<<<<<<<<<
@@ -8480,17 +8545,17 @@ static PyObject *__pyx_pw_6libzim_8_Creator_21add_metadata(PyObject *__pyx_v_sel
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_content)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_metadata", 1, 3, 3, 1); __PYX_ERR(0, 359, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_metadata", 1, 3, 3, 1); __PYX_ERR(0, 360, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
         if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mimetype)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_metadata", 1, 3, 3, 2); __PYX_ERR(0, 359, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_metadata", 1, 3, 3, 2); __PYX_ERR(0, 360, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_metadata") < 0)) __PYX_ERR(0, 359, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_metadata") < 0)) __PYX_ERR(0, 360, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -8505,15 +8570,15 @@ static PyObject *__pyx_pw_6libzim_8_Creator_21add_metadata(PyObject *__pyx_v_sel
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add_metadata", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 359, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_metadata", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 360, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim._Creator.add_metadata", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_name), (&PyUnicode_Type), 1, "name", 1))) __PYX_ERR(0, 359, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_content), (&PyBytes_Type), 1, "content", 1))) __PYX_ERR(0, 359, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mimetype), (&PyUnicode_Type), 1, "mimetype", 1))) __PYX_ERR(0, 359, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_name), (&PyUnicode_Type), 1, "name", 1))) __PYX_ERR(0, 360, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_content), (&PyBytes_Type), 1, "content", 1))) __PYX_ERR(0, 360, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mimetype), (&PyUnicode_Type), 1, "mimetype", 1))) __PYX_ERR(0, 360, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_8_Creator_20add_metadata(((struct __pyx_obj_6libzim__Creator *)__pyx_v_self), __pyx_v_name, __pyx_v_content, __pyx_v_mimetype);
 
   /* function exit code */
@@ -8540,31 +8605,31 @@ static PyObject *__pyx_pf_6libzim_8_Creator_20add_metadata(struct __pyx_obj_6lib
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_metadata", 0);
 
-  /* "libzim.pyx":368
+  /* "libzim.pyx":369
  *                 RuntimeError
  *                     If a Metadata exists with the same name"""
  *         if not self._started:             # <<<<<<<<<<<<<<
  *             raise RuntimeError("Creator not started")
  * 
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 368, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 369, __pyx_L1_error)
   __pyx_t_2 = ((!__pyx_t_1) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "libzim.pyx":369
+    /* "libzim.pyx":370
  *                     If a Metadata exists with the same name"""
  *         if not self._started:
  *             raise RuntimeError("Creator not started")             # <<<<<<<<<<<<<<
  * 
  *         cdef string _name = name.encode('UTF-8')
  */
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 369, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 370, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 369, __pyx_L1_error)
+    __PYX_ERR(0, 370, __pyx_L1_error)
 
-    /* "libzim.pyx":368
+    /* "libzim.pyx":369
  *                 RuntimeError
  *                     If a Metadata exists with the same name"""
  *         if not self._started:             # <<<<<<<<<<<<<<
@@ -8573,7 +8638,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_20add_metadata(struct __pyx_obj_6lib
  */
   }
 
-  /* "libzim.pyx":371
+  /* "libzim.pyx":372
  *             raise RuntimeError("Creator not started")
  * 
  *         cdef string _name = name.encode('UTF-8')             # <<<<<<<<<<<<<<
@@ -8582,25 +8647,25 @@ static PyObject *__pyx_pf_6libzim_8_Creator_20add_metadata(struct __pyx_obj_6lib
  */
   if (unlikely(__pyx_v_name == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 371, __pyx_L1_error)
+    __PYX_ERR(0, 372, __pyx_L1_error)
   }
-  __pyx_t_3 = PyUnicode_AsUTF8String(__pyx_v_name); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 371, __pyx_L1_error)
+  __pyx_t_3 = PyUnicode_AsUTF8String(__pyx_v_name); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 372, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __pyx_convert_string_from_py_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 371, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_string_from_py_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 372, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_v__name = __pyx_t_4;
 
-  /* "libzim.pyx":372
+  /* "libzim.pyx":373
  * 
  *         cdef string _name = name.encode('UTF-8')
  *         cdef string _content = content             # <<<<<<<<<<<<<<
  *         cdef string _mimetype = mimetype.encode('UTF-8')
  *         with nogil:
  */
-  __pyx_t_4 = __pyx_convert_string_from_py_std__in_string(__pyx_v_content); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 372, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_string_from_py_std__in_string(__pyx_v_content); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 373, __pyx_L1_error)
   __pyx_v__content = __pyx_t_4;
 
-  /* "libzim.pyx":373
+  /* "libzim.pyx":374
  *         cdef string _name = name.encode('UTF-8')
  *         cdef string _content = content
  *         cdef string _mimetype = mimetype.encode('UTF-8')             # <<<<<<<<<<<<<<
@@ -8609,15 +8674,15 @@ static PyObject *__pyx_pf_6libzim_8_Creator_20add_metadata(struct __pyx_obj_6lib
  */
   if (unlikely(__pyx_v_mimetype == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 373, __pyx_L1_error)
+    __PYX_ERR(0, 374, __pyx_L1_error)
   }
-  __pyx_t_3 = PyUnicode_AsUTF8String(__pyx_v_mimetype); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 373, __pyx_L1_error)
+  __pyx_t_3 = PyUnicode_AsUTF8String(__pyx_v_mimetype); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 374, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __pyx_convert_string_from_py_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 373, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_string_from_py_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 374, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_v__mimetype = __pyx_t_4;
 
-  /* "libzim.pyx":374
+  /* "libzim.pyx":375
  *         cdef string _content = content
  *         cdef string _mimetype = mimetype.encode('UTF-8')
  *         with nogil:             # <<<<<<<<<<<<<<
@@ -8632,7 +8697,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_20add_metadata(struct __pyx_obj_6lib
       #endif
       /*try:*/ {
 
-        /* "libzim.pyx":375
+        /* "libzim.pyx":376
  *         cdef string _mimetype = mimetype.encode('UTF-8')
  *         with nogil:
  *             self.c_creator.addMetadata(_name, _content, _mimetype)             # <<<<<<<<<<<<<<
@@ -8649,11 +8714,11 @@ static PyObject *__pyx_pf_6libzim_8_Creator_20add_metadata(struct __pyx_obj_6lib
           #ifdef WITH_THREAD
           __Pyx_PyGILState_Release(__pyx_gilstate_save);
           #endif
-          __PYX_ERR(0, 375, __pyx_L5_error)
+          __PYX_ERR(0, 376, __pyx_L5_error)
         }
       }
 
-      /* "libzim.pyx":374
+      /* "libzim.pyx":375
  *         cdef string _content = content
  *         cdef string _mimetype = mimetype.encode('UTF-8')
  *         with nogil:             # <<<<<<<<<<<<<<
@@ -8679,7 +8744,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_20add_metadata(struct __pyx_obj_6lib
       }
   }
 
-  /* "libzim.pyx":359
+  /* "libzim.pyx":360
  *             self.c_creator.addItem(item)
  * 
  *     def add_metadata(self, str name: str, bytes content: bytes, str mimetype: str):             # <<<<<<<<<<<<<<
@@ -8700,7 +8765,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_20add_metadata(struct __pyx_obj_6lib
   return __pyx_r;
 }
 
-/* "libzim.pyx":377
+/* "libzim.pyx":378
  *             self.c_creator.addMetadata(_name, _content, _mimetype)
  * 
  *     def add_redirection(self, str path: str, str title: str, str targetPath: str, dict hints: Dict[Hint, pyint]):             # <<<<<<<<<<<<<<
@@ -8749,23 +8814,23 @@ static PyObject *__pyx_pw_6libzim_8_Creator_23add_redirection(PyObject *__pyx_v_
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_title)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_redirection", 1, 4, 4, 1); __PYX_ERR(0, 377, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_redirection", 1, 4, 4, 1); __PYX_ERR(0, 378, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
         if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_targetPath)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_redirection", 1, 4, 4, 2); __PYX_ERR(0, 377, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_redirection", 1, 4, 4, 2); __PYX_ERR(0, 378, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  3:
         if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_hints)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_redirection", 1, 4, 4, 3); __PYX_ERR(0, 377, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_redirection", 1, 4, 4, 3); __PYX_ERR(0, 378, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_redirection") < 0)) __PYX_ERR(0, 377, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_redirection") < 0)) __PYX_ERR(0, 378, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
       goto __pyx_L5_argtuple_error;
@@ -8782,16 +8847,16 @@ static PyObject *__pyx_pw_6libzim_8_Creator_23add_redirection(PyObject *__pyx_v_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add_redirection", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 377, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_redirection", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 378, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim._Creator.add_redirection", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_path), (&PyUnicode_Type), 1, "path", 1))) __PYX_ERR(0, 377, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_title), (&PyUnicode_Type), 1, "title", 1))) __PYX_ERR(0, 377, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_targetPath), (&PyUnicode_Type), 1, "targetPath", 1))) __PYX_ERR(0, 377, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_hints), (&PyDict_Type), 1, "hints", 1))) __PYX_ERR(0, 377, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_path), (&PyUnicode_Type), 1, "path", 1))) __PYX_ERR(0, 378, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_title), (&PyUnicode_Type), 1, "title", 1))) __PYX_ERR(0, 378, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_targetPath), (&PyUnicode_Type), 1, "targetPath", 1))) __PYX_ERR(0, 378, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_hints), (&PyDict_Type), 1, "hints", 1))) __PYX_ERR(0, 378, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_8_Creator_22add_redirection(((struct __pyx_obj_6libzim__Creator *)__pyx_v_self), __pyx_v_path, __pyx_v_title, __pyx_v_targetPath, __pyx_v_hints);
 
   /* function exit code */
@@ -8819,31 +8884,31 @@ static PyObject *__pyx_pf_6libzim_8_Creator_22add_redirection(struct __pyx_obj_6
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_redirection", 0);
 
-  /* "libzim.pyx":387
+  /* "libzim.pyx":388
  *                     If a Rediction exists with the same path
  *             """
  *         if not self._started:             # <<<<<<<<<<<<<<
  *             raise RuntimeError("Creator not started")
  * 
  */
-  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 387, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_self->_started); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 388, __pyx_L1_error)
   __pyx_t_2 = ((!__pyx_t_1) != 0);
   if (unlikely(__pyx_t_2)) {
 
-    /* "libzim.pyx":388
+    /* "libzim.pyx":389
  *             """
  *         if not self._started:
  *             raise RuntimeError("Creator not started")             # <<<<<<<<<<<<<<
  * 
  *         cdef string _path = path.encode('UTF-8')
  */
-    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 388, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 389, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_Raise(__pyx_t_3, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __PYX_ERR(0, 388, __pyx_L1_error)
+    __PYX_ERR(0, 389, __pyx_L1_error)
 
-    /* "libzim.pyx":387
+    /* "libzim.pyx":388
  *                     If a Rediction exists with the same path
  *             """
  *         if not self._started:             # <<<<<<<<<<<<<<
@@ -8852,7 +8917,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_22add_redirection(struct __pyx_obj_6
  */
   }
 
-  /* "libzim.pyx":390
+  /* "libzim.pyx":391
  *             raise RuntimeError("Creator not started")
  * 
  *         cdef string _path = path.encode('UTF-8')             # <<<<<<<<<<<<<<
@@ -8861,15 +8926,15 @@ static PyObject *__pyx_pf_6libzim_8_Creator_22add_redirection(struct __pyx_obj_6
  */
   if (unlikely(__pyx_v_path == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 390, __pyx_L1_error)
+    __PYX_ERR(0, 391, __pyx_L1_error)
   }
-  __pyx_t_3 = PyUnicode_AsUTF8String(__pyx_v_path); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 390, __pyx_L1_error)
+  __pyx_t_3 = PyUnicode_AsUTF8String(__pyx_v_path); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 391, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __pyx_convert_string_from_py_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 390, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_string_from_py_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 391, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_v__path = __pyx_t_4;
 
-  /* "libzim.pyx":391
+  /* "libzim.pyx":392
  * 
  *         cdef string _path = path.encode('UTF-8')
  *         cdef string _title = title.encode('UTF-8')             # <<<<<<<<<<<<<<
@@ -8878,15 +8943,15 @@ static PyObject *__pyx_pf_6libzim_8_Creator_22add_redirection(struct __pyx_obj_6
  */
   if (unlikely(__pyx_v_title == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 391, __pyx_L1_error)
+    __PYX_ERR(0, 392, __pyx_L1_error)
   }
-  __pyx_t_3 = PyUnicode_AsUTF8String(__pyx_v_title); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 391, __pyx_L1_error)
+  __pyx_t_3 = PyUnicode_AsUTF8String(__pyx_v_title); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 392, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __pyx_convert_string_from_py_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 391, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_string_from_py_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 392, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_v__title = __pyx_t_4;
 
-  /* "libzim.pyx":392
+  /* "libzim.pyx":393
  *         cdef string _path = path.encode('UTF-8')
  *         cdef string _title = title.encode('UTF-8')
  *         cdef string _targetPath = targetPath.encode('UTF-8')             # <<<<<<<<<<<<<<
@@ -8895,15 +8960,15 @@ static PyObject *__pyx_pf_6libzim_8_Creator_22add_redirection(struct __pyx_obj_6
  */
   if (unlikely(__pyx_v_targetPath == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 392, __pyx_L1_error)
+    __PYX_ERR(0, 393, __pyx_L1_error)
   }
-  __pyx_t_3 = PyUnicode_AsUTF8String(__pyx_v_targetPath); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 392, __pyx_L1_error)
+  __pyx_t_3 = PyUnicode_AsUTF8String(__pyx_v_targetPath); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 393, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __pyx_convert_string_from_py_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 392, __pyx_L1_error)
+  __pyx_t_4 = __pyx_convert_string_from_py_std__in_string(__pyx_t_3); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 393, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_v__targetPath = __pyx_t_4;
 
-  /* "libzim.pyx":393
+  /* "libzim.pyx":394
  *         cdef string _title = title.encode('UTF-8')
  *         cdef string _targetPath = targetPath.encode('UTF-8')
  *         cdef map[zim.HintKeys, uint64_t] _hints = convertToCppHints(hints)             # <<<<<<<<<<<<<<
@@ -8912,7 +8977,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_22add_redirection(struct __pyx_obj_6
  */
   __pyx_v__hints = convertToCppHints(__pyx_v_hints);
 
-  /* "libzim.pyx":394
+  /* "libzim.pyx":395
  *         cdef string _targetPath = targetPath.encode('UTF-8')
  *         cdef map[zim.HintKeys, uint64_t] _hints = convertToCppHints(hints)
  *         with nogil:             # <<<<<<<<<<<<<<
@@ -8927,7 +8992,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_22add_redirection(struct __pyx_obj_6
       #endif
       /*try:*/ {
 
-        /* "libzim.pyx":395
+        /* "libzim.pyx":396
  *         cdef map[zim.HintKeys, uint64_t] _hints = convertToCppHints(hints)
  *         with nogil:
  *             self.c_creator.addRedirection(_path, _title, _targetPath, _hints)             # <<<<<<<<<<<<<<
@@ -8944,11 +9009,11 @@ static PyObject *__pyx_pf_6libzim_8_Creator_22add_redirection(struct __pyx_obj_6
           #ifdef WITH_THREAD
           __Pyx_PyGILState_Release(__pyx_gilstate_save);
           #endif
-          __PYX_ERR(0, 395, __pyx_L5_error)
+          __PYX_ERR(0, 396, __pyx_L5_error)
         }
       }
 
-      /* "libzim.pyx":394
+      /* "libzim.pyx":395
  *         cdef string _targetPath = targetPath.encode('UTF-8')
  *         cdef map[zim.HintKeys, uint64_t] _hints = convertToCppHints(hints)
  *         with nogil:             # <<<<<<<<<<<<<<
@@ -8974,7 +9039,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_22add_redirection(struct __pyx_obj_6
       }
   }
 
-  /* "libzim.pyx":377
+  /* "libzim.pyx":378
  *             self.c_creator.addMetadata(_name, _content, _mimetype)
  * 
  *     def add_redirection(self, str path: str, str title: str, str targetPath: str, dict hints: Dict[Hint, pyint]):             # <<<<<<<<<<<<<<
@@ -8995,7 +9060,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_22add_redirection(struct __pyx_obj_6
   return __pyx_r;
 }
 
-/* "libzim.pyx":397
+/* "libzim.pyx":398
  *             self.c_creator.addRedirection(_path, _title, _targetPath, _hints)
  * 
  *     def __enter__(self):             # <<<<<<<<<<<<<<
@@ -9028,23 +9093,23 @@ static PyObject *__pyx_pf_6libzim_8_Creator_24__enter__(struct __pyx_obj_6libzim
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__enter__", 0);
 
-  /* "libzim.pyx":398
+  /* "libzim.pyx":399
  * 
  *     def __enter__(self):
  *         cdef string _path = str(self._filename).encode('UTF-8')             # <<<<<<<<<<<<<<
  *         with nogil:
  *             self.c_creator.startZimCreation(_path)
  */
-  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_self->_filename); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 398, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_self->_filename); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 399, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyUnicode_AsUTF8String(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 398, __pyx_L1_error)
+  __pyx_t_2 = PyUnicode_AsUTF8String(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 399, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 398, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 399, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_v__path = __pyx_t_3;
 
-  /* "libzim.pyx":399
+  /* "libzim.pyx":400
  *     def __enter__(self):
  *         cdef string _path = str(self._filename).encode('UTF-8')
  *         with nogil:             # <<<<<<<<<<<<<<
@@ -9059,7 +9124,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_24__enter__(struct __pyx_obj_6libzim
       #endif
       /*try:*/ {
 
-        /* "libzim.pyx":400
+        /* "libzim.pyx":401
  *         cdef string _path = str(self._filename).encode('UTF-8')
  *         with nogil:
  *             self.c_creator.startZimCreation(_path)             # <<<<<<<<<<<<<<
@@ -9076,11 +9141,11 @@ static PyObject *__pyx_pf_6libzim_8_Creator_24__enter__(struct __pyx_obj_6libzim
           #ifdef WITH_THREAD
           __Pyx_PyGILState_Release(__pyx_gilstate_save);
           #endif
-          __PYX_ERR(0, 400, __pyx_L4_error)
+          __PYX_ERR(0, 401, __pyx_L4_error)
         }
       }
 
-      /* "libzim.pyx":399
+      /* "libzim.pyx":400
  *     def __enter__(self):
  *         cdef string _path = str(self._filename).encode('UTF-8')
  *         with nogil:             # <<<<<<<<<<<<<<
@@ -9106,7 +9171,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_24__enter__(struct __pyx_obj_6libzim
       }
   }
 
-  /* "libzim.pyx":401
+  /* "libzim.pyx":402
  *         with nogil:
  *             self.c_creator.startZimCreation(_path)
  *         self._started = True             # <<<<<<<<<<<<<<
@@ -9119,7 +9184,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_24__enter__(struct __pyx_obj_6libzim
   __Pyx_DECREF(__pyx_v_self->_started);
   __pyx_v_self->_started = Py_True;
 
-  /* "libzim.pyx":402
+  /* "libzim.pyx":403
  *             self.c_creator.startZimCreation(_path)
  *         self._started = True
  *         return self             # <<<<<<<<<<<<<<
@@ -9131,7 +9196,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_24__enter__(struct __pyx_obj_6libzim
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "libzim.pyx":397
+  /* "libzim.pyx":398
  *             self.c_creator.addRedirection(_path, _title, _targetPath, _hints)
  * 
  *     def __enter__(self):             # <<<<<<<<<<<<<<
@@ -9151,7 +9216,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_24__enter__(struct __pyx_obj_6libzim
   return __pyx_r;
 }
 
-/* "libzim.pyx":404
+/* "libzim.pyx":405
  *         return self
  * 
  *     def __exit__(self, exc_type, exc_val, exc_tb):             # <<<<<<<<<<<<<<
@@ -9196,17 +9261,17 @@ static PyObject *__pyx_pw_6libzim_8_Creator_27__exit__(PyObject *__pyx_v_self, P
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_exc_val)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__exit__", 1, 3, 3, 1); __PYX_ERR(0, 404, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__exit__", 1, 3, 3, 1); __PYX_ERR(0, 405, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
         if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_exc_tb)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__exit__", 1, 3, 3, 2); __PYX_ERR(0, 404, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__exit__", 1, 3, 3, 2); __PYX_ERR(0, 405, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__exit__") < 0)) __PYX_ERR(0, 404, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__exit__") < 0)) __PYX_ERR(0, 405, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
       goto __pyx_L5_argtuple_error;
@@ -9221,7 +9286,7 @@ static PyObject *__pyx_pw_6libzim_8_Creator_27__exit__(PyObject *__pyx_v_self, P
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__exit__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 404, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__exit__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 405, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim._Creator.__exit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -9242,7 +9307,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_26__exit__(struct __pyx_obj_6libzim_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__exit__", 0);
 
-  /* "libzim.pyx":406
+  /* "libzim.pyx":407
  *     def __exit__(self, exc_type, exc_val, exc_tb):
  *         if True or exc_type is None:
  *             with nogil:             # <<<<<<<<<<<<<<
@@ -9257,7 +9322,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_26__exit__(struct __pyx_obj_6libzim_
       #endif
       /*try:*/ {
 
-        /* "libzim.pyx":407
+        /* "libzim.pyx":408
  *         if True or exc_type is None:
  *             with nogil:
  *                 self.c_creator.finishZimCreation()             # <<<<<<<<<<<<<<
@@ -9274,11 +9339,11 @@ static PyObject *__pyx_pf_6libzim_8_Creator_26__exit__(struct __pyx_obj_6libzim_
           #ifdef WITH_THREAD
           __Pyx_PyGILState_Release(__pyx_gilstate_save);
           #endif
-          __PYX_ERR(0, 407, __pyx_L4_error)
+          __PYX_ERR(0, 408, __pyx_L4_error)
         }
       }
 
-      /* "libzim.pyx":406
+      /* "libzim.pyx":407
  *     def __exit__(self, exc_type, exc_val, exc_tb):
  *         if True or exc_type is None:
  *             with nogil:             # <<<<<<<<<<<<<<
@@ -9304,7 +9369,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_26__exit__(struct __pyx_obj_6libzim_
       }
   }
 
-  /* "libzim.pyx":408
+  /* "libzim.pyx":409
  *             with nogil:
  *                 self.c_creator.finishZimCreation()
  *         self._started = False             # <<<<<<<<<<<<<<
@@ -9317,7 +9382,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_26__exit__(struct __pyx_obj_6libzim_
   __Pyx_DECREF(__pyx_v_self->_started);
   __pyx_v_self->_started = Py_False;
 
-  /* "libzim.pyx":404
+  /* "libzim.pyx":405
  *         return self
  * 
  *     def __exit__(self, exc_type, exc_val, exc_tb):             # <<<<<<<<<<<<<<
@@ -9337,7 +9402,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_26__exit__(struct __pyx_obj_6libzim_
   return __pyx_r;
 }
 
-/* "libzim.pyx":411
+/* "libzim.pyx":412
  * 
  *     @property
  *     def filename(self) -> pathlib.Path:             # <<<<<<<<<<<<<<
@@ -9363,7 +9428,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_8filename___get__(struct __pyx_obj_6
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":412
+  /* "libzim.pyx":413
  *     @property
  *     def filename(self) -> pathlib.Path:
  *         return self._filename             # <<<<<<<<<<<<<<
@@ -9375,7 +9440,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_8filename___get__(struct __pyx_obj_6
   __pyx_r = __pyx_v_self->_filename;
   goto __pyx_L0;
 
-  /* "libzim.pyx":411
+  /* "libzim.pyx":412
  * 
  *     @property
  *     def filename(self) -> pathlib.Path:             # <<<<<<<<<<<<<<
@@ -9503,7 +9568,7 @@ static PyObject *__pyx_pf_6libzim_8_Creator_30__setstate_cython__(CYTHON_UNUSED
   return __pyx_r;
 }
 
-/* "libzim.pyx":416
+/* "libzim.pyx":417
  * class ContentProvider:
  *     __module__ = writer_module_name
  *     def __init__(self):             # <<<<<<<<<<<<<<
@@ -9533,16 +9598,16 @@ static PyObject *__pyx_pf_6libzim_15ContentProvider___init__(CYTHON_UNUSED PyObj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "libzim.pyx":417
+  /* "libzim.pyx":418
  *     __module__ = writer_module_name
  *     def __init__(self):
  *         self.generator = None             # <<<<<<<<<<<<<<
  * 
  *     def get_size(self) -> pyint:
  */
-  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_generator, Py_None) < 0) __PYX_ERR(0, 417, __pyx_L1_error)
+  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_generator, Py_None) < 0) __PYX_ERR(0, 418, __pyx_L1_error)
 
-  /* "libzim.pyx":416
+  /* "libzim.pyx":417
  * class ContentProvider:
  *     __module__ = writer_module_name
  *     def __init__(self):             # <<<<<<<<<<<<<<
@@ -9562,7 +9627,7 @@ static PyObject *__pyx_pf_6libzim_15ContentProvider___init__(CYTHON_UNUSED PyObj
   return __pyx_r;
 }
 
-/* "libzim.pyx":419
+/* "libzim.pyx":420
  *         self.generator = None
  * 
  *     def get_size(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -9594,20 +9659,20 @@ static PyObject *__pyx_pf_6libzim_15ContentProvider_2get_size(CYTHON_UNUSED PyOb
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_size", 0);
 
-  /* "libzim.pyx":421
+  /* "libzim.pyx":422
  *     def get_size(self) -> pyint:
  *         """Size of get_data's result in bytes"""
  *         raise NotImplementedError("get_size must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def feed(self) -> WritingBlob:
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 421, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 422, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 421, __pyx_L1_error)
+  __PYX_ERR(0, 422, __pyx_L1_error)
 
-  /* "libzim.pyx":419
+  /* "libzim.pyx":420
  *         self.generator = None
  * 
  *     def get_size(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -9625,7 +9690,7 @@ static PyObject *__pyx_pf_6libzim_15ContentProvider_2get_size(CYTHON_UNUSED PyOb
   return __pyx_r;
 }
 
-/* "libzim.pyx":423
+/* "libzim.pyx":424
  *         raise NotImplementedError("get_size must be implemented.")
  * 
  *     def feed(self) -> WritingBlob:             # <<<<<<<<<<<<<<
@@ -9666,28 +9731,28 @@ static struct __pyx_obj_6libzim_WritingBlob *__pyx_pf_6libzim_15ContentProvider_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("feed", 0);
 
-  /* "libzim.pyx":428
+  /* "libzim.pyx":429
  *         Sum(size(blobs)) must be equals to `self.get_size()`
  *         """
  *         if self.generator is None:             # <<<<<<<<<<<<<<
  *             self.generator = self.gen_blob()
  * 
  */
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_generator); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 428, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_generator); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 429, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = (__pyx_t_1 == Py_None);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_t_3 = (__pyx_t_2 != 0);
   if (__pyx_t_3) {
 
-    /* "libzim.pyx":429
+    /* "libzim.pyx":430
  *         """
  *         if self.generator is None:
  *             self.generator = self.gen_blob()             # <<<<<<<<<<<<<<
  * 
  *         try:
  */
-    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_gen_blob); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 429, __pyx_L1_error)
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_gen_blob); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 430, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
@@ -9701,13 +9766,13 @@ static struct __pyx_obj_6libzim_WritingBlob *__pyx_pf_6libzim_15ContentProvider_
     }
     __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 429, __pyx_L1_error)
+    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 430, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_generator, __pyx_t_1) < 0) __PYX_ERR(0, 429, __pyx_L1_error)
+    if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_generator, __pyx_t_1) < 0) __PYX_ERR(0, 430, __pyx_L1_error)
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "libzim.pyx":428
+    /* "libzim.pyx":429
  *         Sum(size(blobs)) must be equals to `self.get_size()`
  *         """
  *         if self.generator is None:             # <<<<<<<<<<<<<<
@@ -9716,7 +9781,7 @@ static struct __pyx_obj_6libzim_WritingBlob *__pyx_pf_6libzim_15ContentProvider_
  */
   }
 
-  /* "libzim.pyx":431
+  /* "libzim.pyx":432
  *             self.generator = self.gen_blob()
  * 
  *         try:             # <<<<<<<<<<<<<<
@@ -9732,22 +9797,22 @@ static struct __pyx_obj_6libzim_WritingBlob *__pyx_pf_6libzim_15ContentProvider_
     __Pyx_XGOTREF(__pyx_t_8);
     /*try:*/ {
 
-      /* "libzim.pyx":434
+      /* "libzim.pyx":435
  *             # We have to keep a ref to _blob to be sure gc do not del it while cpp is
  *             # using it
  *             self._blob = next(self.generator)             # <<<<<<<<<<<<<<
  *         except StopIteration:
  *             self._blob = WritingBlob("")
  */
-      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_generator); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 434, __pyx_L4_error)
+      __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_generator); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 435, __pyx_L4_error)
       __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_4 = __Pyx_PyIter_Next(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 434, __pyx_L4_error)
+      __pyx_t_4 = __Pyx_PyIter_Next(__pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 435, __pyx_L4_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_blob, __pyx_t_4) < 0) __PYX_ERR(0, 434, __pyx_L4_error)
+      if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_blob, __pyx_t_4) < 0) __PYX_ERR(0, 435, __pyx_L4_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-      /* "libzim.pyx":431
+      /* "libzim.pyx":432
  *             self.generator = self.gen_blob()
  * 
  *         try:             # <<<<<<<<<<<<<<
@@ -9764,7 +9829,7 @@ static struct __pyx_obj_6libzim_WritingBlob *__pyx_pf_6libzim_15ContentProvider_
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-    /* "libzim.pyx":435
+    /* "libzim.pyx":436
  *             # using it
  *             self._blob = next(self.generator)
  *         except StopIteration:             # <<<<<<<<<<<<<<
@@ -9774,21 +9839,21 @@ static struct __pyx_obj_6libzim_WritingBlob *__pyx_pf_6libzim_15ContentProvider_
     __pyx_t_9 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_StopIteration);
     if (__pyx_t_9) {
       __Pyx_AddTraceback("libzim.ContentProvider.feed", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_1, &__pyx_t_5) < 0) __PYX_ERR(0, 435, __pyx_L6_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_1, &__pyx_t_5) < 0) __PYX_ERR(0, 436, __pyx_L6_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_GOTREF(__pyx_t_5);
 
-      /* "libzim.pyx":436
+      /* "libzim.pyx":437
  *             self._blob = next(self.generator)
  *         except StopIteration:
  *             self._blob = WritingBlob("")             # <<<<<<<<<<<<<<
  * 
  *         return self._blob
  */
-      __pyx_t_10 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_6libzim_WritingBlob), __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 436, __pyx_L6_except_error)
+      __pyx_t_10 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_6libzim_WritingBlob), __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 437, __pyx_L6_except_error)
       __Pyx_GOTREF(__pyx_t_10);
-      if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_blob, __pyx_t_10) < 0) __PYX_ERR(0, 436, __pyx_L6_except_error)
+      if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_blob, __pyx_t_10) < 0) __PYX_ERR(0, 437, __pyx_L6_except_error)
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
       __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -9798,7 +9863,7 @@ static struct __pyx_obj_6libzim_WritingBlob *__pyx_pf_6libzim_15ContentProvider_
     goto __pyx_L6_except_error;
     __pyx_L6_except_error:;
 
-    /* "libzim.pyx":431
+    /* "libzim.pyx":432
  *             self.generator = self.gen_blob()
  * 
  *         try:             # <<<<<<<<<<<<<<
@@ -9818,7 +9883,7 @@ static struct __pyx_obj_6libzim_WritingBlob *__pyx_pf_6libzim_15ContentProvider_
     __pyx_L9_try_end:;
   }
 
-  /* "libzim.pyx":438
+  /* "libzim.pyx":439
  *             self._blob = WritingBlob("")
  * 
  *         return self._blob             # <<<<<<<<<<<<<<
@@ -9826,14 +9891,14 @@ static struct __pyx_obj_6libzim_WritingBlob *__pyx_pf_6libzim_15ContentProvider_
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_blob); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 438, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_blob); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 439, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_6libzim_WritingBlob))))) __PYX_ERR(0, 438, __pyx_L1_error)
+  if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_6libzim_WritingBlob))))) __PYX_ERR(0, 439, __pyx_L1_error)
   __pyx_r = ((struct __pyx_obj_6libzim_WritingBlob *)__pyx_t_5);
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":423
+  /* "libzim.pyx":424
  *         raise NotImplementedError("get_size must be implemented.")
  * 
  *     def feed(self) -> WritingBlob:             # <<<<<<<<<<<<<<
@@ -9855,7 +9920,7 @@ static struct __pyx_obj_6libzim_WritingBlob *__pyx_pf_6libzim_15ContentProvider_
   return __pyx_r;
 }
 
-/* "libzim.pyx":440
+/* "libzim.pyx":441
  *         return self._blob
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
@@ -9887,20 +9952,20 @@ static PyObject *__pyx_pf_6libzim_15ContentProvider_6gen_blob(CYTHON_UNUSED PyOb
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("gen_blob", 0);
 
-  /* "libzim.pyx":442
+  /* "libzim.pyx":443
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:
  *         """Generator yielding blobs for the content of the article"""
  *         raise NotImplementedError("gen_blob (ro feed) must be implemented")             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 442, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 443, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 442, __pyx_L1_error)
+  __PYX_ERR(0, 443, __pyx_L1_error)
 
-  /* "libzim.pyx":440
+  /* "libzim.pyx":441
  *         return self._blob
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
@@ -9918,7 +9983,7 @@ static PyObject *__pyx_pf_6libzim_15ContentProvider_6gen_blob(CYTHON_UNUSED PyOb
   return __pyx_r;
 }
 
-/* "libzim.pyx":448
+/* "libzim.pyx":449
  *     """ContentProvider for a single encoded-or-not UTF-8 string"""
  *     __module__ = writer_module_name
  *     def __init__(self, content: Union[str, bytes]):             # <<<<<<<<<<<<<<
@@ -9961,11 +10026,11 @@ static PyObject *__pyx_pw_6libzim_14StringProvider_1__init__(PyObject *__pyx_sel
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_content)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 448, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 449, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 448, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 449, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -9978,7 +10043,7 @@ static PyObject *__pyx_pw_6libzim_14StringProvider_1__init__(PyObject *__pyx_sel
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 448, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 449, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.StringProvider.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -10004,7 +10069,7 @@ static PyObject *__pyx_pf_6libzim_14StringProvider___init__(CYTHON_UNUSED PyObje
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "libzim.pyx":449
+  /* "libzim.pyx":450
  *     __module__ = writer_module_name
  *     def __init__(self, content: Union[str, bytes]):
  *         super().__init__()             # <<<<<<<<<<<<<<
@@ -10012,9 +10077,9 @@ static PyObject *__pyx_pf_6libzim_14StringProvider___init__(CYTHON_UNUSED PyObje
  * 
  */
   __pyx_t_2 = __Pyx_CyFunction_GetClassObj(__pyx_self);
-  if (!__pyx_t_2) { PyErr_SetString(PyExc_SystemError, "super(): empty __class__ cell"); __PYX_ERR(0, 449, __pyx_L1_error) }
+  if (!__pyx_t_2) { PyErr_SetString(PyExc_SystemError, "super(): empty __class__ cell"); __PYX_ERR(0, 450, __pyx_L1_error) }
   __Pyx_INCREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 449, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 450, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
@@ -10022,10 +10087,10 @@ static PyObject *__pyx_pf_6libzim_14StringProvider___init__(CYTHON_UNUSED PyObje
   __Pyx_GIVEREF(__pyx_v_self);
   PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self);
   __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_super, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 449, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_super, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 450, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_init); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 449, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_init); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 450, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_t_2 = NULL;
@@ -10040,12 +10105,12 @@ static PyObject *__pyx_pf_6libzim_14StringProvider___init__(CYTHON_UNUSED PyObje
   }
   __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 449, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 450, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":450
+  /* "libzim.pyx":451
  *     def __init__(self, content: Union[str, bytes]):
  *         super().__init__()
  *         self.content = content.encode("UTF-8") if isinstance(content, str) else content             # <<<<<<<<<<<<<<
@@ -10054,7 +10119,7 @@ static PyObject *__pyx_pf_6libzim_14StringProvider___init__(CYTHON_UNUSED PyObje
  */
   __pyx_t_4 = PyUnicode_Check(__pyx_v_content); 
   if ((__pyx_t_4 != 0)) {
-    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_content, __pyx_n_s_encode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 450, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_content, __pyx_n_s_encode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 451, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -10068,7 +10133,7 @@ static PyObject *__pyx_pf_6libzim_14StringProvider___init__(CYTHON_UNUSED PyObje
     }
     __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_UTF_8);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 450, __pyx_L1_error)
+    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 451, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
     __pyx_t_1 = __pyx_t_3;
@@ -10077,10 +10142,10 @@ static PyObject *__pyx_pf_6libzim_14StringProvider___init__(CYTHON_UNUSED PyObje
     __Pyx_INCREF(__pyx_v_content);
     __pyx_t_1 = __pyx_v_content;
   }
-  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_content, __pyx_t_1) < 0) __PYX_ERR(0, 450, __pyx_L1_error)
+  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_content, __pyx_t_1) < 0) __PYX_ERR(0, 451, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":448
+  /* "libzim.pyx":449
  *     """ContentProvider for a single encoded-or-not UTF-8 string"""
  *     __module__ = writer_module_name
  *     def __init__(self, content: Union[str, bytes]):             # <<<<<<<<<<<<<<
@@ -10104,7 +10169,7 @@ static PyObject *__pyx_pf_6libzim_14StringProvider___init__(CYTHON_UNUSED PyObje
   return __pyx_r;
 }
 
-/* "libzim.pyx":452
+/* "libzim.pyx":453
  *         self.content = content.encode("UTF-8") if isinstance(content, str) else content
  * 
  *     def get_size(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -10136,7 +10201,7 @@ static PyObject *__pyx_pf_6libzim_14StringProvider_2get_size(CYTHON_UNUSED PyObj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_size", 0);
 
-  /* "libzim.pyx":453
+  /* "libzim.pyx":454
  * 
  *     def get_size(self) -> pyint:
  *         return len(self.content)             # <<<<<<<<<<<<<<
@@ -10144,17 +10209,17 @@ static PyObject *__pyx_pf_6libzim_14StringProvider_2get_size(CYTHON_UNUSED PyObj
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_content); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 453, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_content); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 454, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 453, __pyx_L1_error)
+  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 454, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 453, __pyx_L1_error)
+  __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 454, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":452
+  /* "libzim.pyx":453
  *         self.content = content.encode("UTF-8") if isinstance(content, str) else content
  * 
  *     def get_size(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -10174,7 +10239,7 @@ static PyObject *__pyx_pf_6libzim_14StringProvider_2get_size(CYTHON_UNUSED PyObj
 }
 static PyObject *__pyx_gb_6libzim_14StringProvider_6generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
 
-/* "libzim.pyx":455
+/* "libzim.pyx":456
  *         return len(self.content)
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
@@ -10208,7 +10273,7 @@ static PyObject *__pyx_pf_6libzim_14StringProvider_4gen_blob(CYTHON_UNUSED PyObj
   if (unlikely(!__pyx_cur_scope)) {
     __pyx_cur_scope = ((struct __pyx_obj_6libzim___pyx_scope_struct__gen_blob *)Py_None);
     __Pyx_INCREF(Py_None);
-    __PYX_ERR(0, 455, __pyx_L1_error)
+    __PYX_ERR(0, 456, __pyx_L1_error)
   } else {
     __Pyx_GOTREF(__pyx_cur_scope);
   }
@@ -10216,7 +10281,7 @@ static PyObject *__pyx_pf_6libzim_14StringProvider_4gen_blob(CYTHON_UNUSED PyObj
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_self);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_self);
   {
-    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_6libzim_14StringProvider_6generator, __pyx_codeobj__13, (PyObject *) __pyx_cur_scope, __pyx_n_s_gen_blob, __pyx_n_s_StringProvider_gen_blob, __pyx_n_s_libzim); if (unlikely(!gen)) __PYX_ERR(0, 455, __pyx_L1_error)
+    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_6libzim_14StringProvider_6generator, __pyx_codeobj__13, (PyObject *) __pyx_cur_scope, __pyx_n_s_gen_blob, __pyx_n_s_StringProvider_gen_blob, __pyx_n_s_libzim); if (unlikely(!gen)) __PYX_ERR(0, 456, __pyx_L1_error)
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -10251,18 +10316,18 @@ static PyObject *__pyx_gb_6libzim_14StringProvider_6generator(__pyx_CoroutineObj
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 455, __pyx_L1_error)
+  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 456, __pyx_L1_error)
 
-  /* "libzim.pyx":456
+  /* "libzim.pyx":457
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:
  *         yield WritingBlob(self.content)             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_self, __pyx_n_s_content); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 456, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_self, __pyx_n_s_content); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 457, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_6libzim_WritingBlob), __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 456, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_6libzim_WritingBlob), __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 457, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_2;
@@ -10274,10 +10339,10 @@ static PyObject *__pyx_gb_6libzim_14StringProvider_6generator(__pyx_CoroutineObj
   __pyx_generator->resume_label = 1;
   return __pyx_r;
   __pyx_L4_resume_from_yield:;
-  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 456, __pyx_L1_error)
+  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 457, __pyx_L1_error)
   CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);
 
-  /* "libzim.pyx":455
+  /* "libzim.pyx":456
  *         return len(self.content)
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
@@ -10303,7 +10368,7 @@ static PyObject *__pyx_gb_6libzim_14StringProvider_6generator(__pyx_CoroutineObj
   return __pyx_r;
 }
 
-/* "libzim.pyx":462
+/* "libzim.pyx":463
  *     """ContentProvider for a file using its local path"""
  *     __module__ = writer_module_name
  *     def __init__(self, filepath: Union[pathlib.Path, str]):             # <<<<<<<<<<<<<<
@@ -10346,11 +10411,11 @@ static PyObject *__pyx_pw_6libzim_12FileProvider_1__init__(PyObject *__pyx_self,
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_filepath)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 462, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); __PYX_ERR(0, 463, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 462, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 463, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -10363,7 +10428,7 @@ static PyObject *__pyx_pw_6libzim_12FileProvider_1__init__(PyObject *__pyx_self,
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 462, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 463, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.FileProvider.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -10388,7 +10453,7 @@ static PyObject *__pyx_pf_6libzim_12FileProvider___init__(CYTHON_UNUSED PyObject
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "libzim.pyx":463
+  /* "libzim.pyx":464
  *     __module__ = writer_module_name
  *     def __init__(self, filepath: Union[pathlib.Path, str]):
  *         super().__init__()             # <<<<<<<<<<<<<<
@@ -10396,9 +10461,9 @@ static PyObject *__pyx_pf_6libzim_12FileProvider___init__(CYTHON_UNUSED PyObject
  *         self.size = os.path.getsize(self.filepath)
  */
   __pyx_t_2 = __Pyx_CyFunction_GetClassObj(__pyx_self);
-  if (!__pyx_t_2) { PyErr_SetString(PyExc_SystemError, "super(): empty __class__ cell"); __PYX_ERR(0, 463, __pyx_L1_error) }
+  if (!__pyx_t_2) { PyErr_SetString(PyExc_SystemError, "super(): empty __class__ cell"); __PYX_ERR(0, 464, __pyx_L1_error) }
   __Pyx_INCREF(__pyx_t_2);
-  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 463, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 464, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_2);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
@@ -10406,10 +10471,10 @@ static PyObject *__pyx_pf_6libzim_12FileProvider___init__(CYTHON_UNUSED PyObject
   __Pyx_GIVEREF(__pyx_v_self);
   PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_self);
   __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_super, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 463, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_super, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 464, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_init); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 463, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_init); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 464, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_t_2 = NULL;
@@ -10424,36 +10489,36 @@ static PyObject *__pyx_pf_6libzim_12FileProvider___init__(CYTHON_UNUSED PyObject
   }
   __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 463, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 464, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":464
+  /* "libzim.pyx":465
  *     def __init__(self, filepath: Union[pathlib.Path, str]):
  *         super().__init__()
  *         self.filepath = filepath             # <<<<<<<<<<<<<<
  *         self.size = os.path.getsize(self.filepath)
  * 
  */
-  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_filepath, __pyx_v_filepath) < 0) __PYX_ERR(0, 464, __pyx_L1_error)
+  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_filepath, __pyx_v_filepath) < 0) __PYX_ERR(0, 465, __pyx_L1_error)
 
-  /* "libzim.pyx":465
+  /* "libzim.pyx":466
  *         super().__init__()
  *         self.filepath = filepath
  *         self.size = os.path.getsize(self.filepath)             # <<<<<<<<<<<<<<
  * 
  *     def get_size(self) -> pyint:
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_os); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 465, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_os); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 466, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_path); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 465, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_path); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 466, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_getsize); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 465, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_getsize); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 466, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_filepath); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 465, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_filepath); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 466, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
@@ -10468,13 +10533,13 @@ static PyObject *__pyx_pf_6libzim_12FileProvider___init__(CYTHON_UNUSED PyObject
   __pyx_t_1 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_4, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 465, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 466, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_size, __pyx_t_1) < 0) __PYX_ERR(0, 465, __pyx_L1_error)
+  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_size, __pyx_t_1) < 0) __PYX_ERR(0, 466, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":462
+  /* "libzim.pyx":463
  *     """ContentProvider for a file using its local path"""
  *     __module__ = writer_module_name
  *     def __init__(self, filepath: Union[pathlib.Path, str]):             # <<<<<<<<<<<<<<
@@ -10498,7 +10563,7 @@ static PyObject *__pyx_pf_6libzim_12FileProvider___init__(CYTHON_UNUSED PyObject
   return __pyx_r;
 }
 
-/* "libzim.pyx":467
+/* "libzim.pyx":468
  *         self.size = os.path.getsize(self.filepath)
  * 
  *     def get_size(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -10529,7 +10594,7 @@ static PyObject *__pyx_pf_6libzim_12FileProvider_2get_size(CYTHON_UNUSED PyObjec
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_size", 0);
 
-  /* "libzim.pyx":468
+  /* "libzim.pyx":469
  * 
  *     def get_size(self) -> pyint:
  *         return self.size             # <<<<<<<<<<<<<<
@@ -10537,13 +10602,13 @@ static PyObject *__pyx_pf_6libzim_12FileProvider_2get_size(CYTHON_UNUSED PyObjec
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_size); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 468, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_size); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 469, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":467
+  /* "libzim.pyx":468
  *         self.size = os.path.getsize(self.filepath)
  * 
  *     def get_size(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -10563,7 +10628,7 @@ static PyObject *__pyx_pf_6libzim_12FileProvider_2get_size(CYTHON_UNUSED PyObjec
 }
 static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
 
-/* "libzim.pyx":470
+/* "libzim.pyx":471
  *         return self.size
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
@@ -10597,7 +10662,7 @@ static PyObject *__pyx_pf_6libzim_12FileProvider_4gen_blob(CYTHON_UNUSED PyObjec
   if (unlikely(!__pyx_cur_scope)) {
     __pyx_cur_scope = ((struct __pyx_obj_6libzim___pyx_scope_struct_1_gen_blob *)Py_None);
     __Pyx_INCREF(Py_None);
-    __PYX_ERR(0, 470, __pyx_L1_error)
+    __PYX_ERR(0, 471, __pyx_L1_error)
   } else {
     __Pyx_GOTREF(__pyx_cur_scope);
   }
@@ -10605,7 +10670,7 @@ static PyObject *__pyx_pf_6libzim_12FileProvider_4gen_blob(CYTHON_UNUSED PyObjec
   __Pyx_INCREF(__pyx_cur_scope->__pyx_v_self);
   __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_self);
   {
-    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_6libzim_12FileProvider_6generator1, __pyx_codeobj__14, (PyObject *) __pyx_cur_scope, __pyx_n_s_gen_blob, __pyx_n_s_FileProvider_gen_blob, __pyx_n_s_libzim); if (unlikely(!gen)) __PYX_ERR(0, 470, __pyx_L1_error)
+    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_6libzim_12FileProvider_6generator1, __pyx_codeobj__14, (PyObject *) __pyx_cur_scope, __pyx_n_s_gen_blob, __pyx_n_s_FileProvider_gen_blob, __pyx_n_s_libzim); if (unlikely(!gen)) __PYX_ERR(0, 471, __pyx_L1_error)
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -10649,9 +10714,9 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 470, __pyx_L1_error)
+  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 471, __pyx_L1_error)
 
-  /* "libzim.pyx":471
+  /* "libzim.pyx":472
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:
  *         bsize = 1048576  # 1MiB chunk             # <<<<<<<<<<<<<<
@@ -10660,7 +10725,7 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
  */
   __pyx_cur_scope->__pyx_v_bsize = 0x100000;
 
-  /* "libzim.pyx":472
+  /* "libzim.pyx":473
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:
  *         bsize = 1048576  # 1MiB chunk
  *         with open(self.filepath, "rb") as fh:             # <<<<<<<<<<<<<<
@@ -10668,9 +10733,9 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
  *             while res:
  */
   /*with:*/ {
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_self, __pyx_n_s_filepath); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 472, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_self, __pyx_n_s_filepath); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 473, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 472, __pyx_L1_error)
+    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 473, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_GIVEREF(__pyx_t_1);
     PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
@@ -10678,12 +10743,12 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
     __Pyx_GIVEREF(__pyx_n_u_rb);
     PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_n_u_rb);
     __pyx_t_1 = 0;
-    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_open, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 472, __pyx_L1_error)
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_open, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 473, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_3 = __Pyx_PyObject_LookupSpecial(__pyx_t_1, __pyx_n_s_exit); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 472, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_LookupSpecial(__pyx_t_1, __pyx_n_s_exit); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 473, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_4 = __Pyx_PyObject_LookupSpecial(__pyx_t_1, __pyx_n_s_enter); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 472, __pyx_L4_error)
+    __pyx_t_4 = __Pyx_PyObject_LookupSpecial(__pyx_t_1, __pyx_n_s_enter); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 473, __pyx_L4_error)
     __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_5 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
@@ -10697,7 +10762,7 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
     }
     __pyx_t_2 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_4);
     __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 472, __pyx_L4_error)
+    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 473, __pyx_L4_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __pyx_t_4 = __pyx_t_2;
@@ -10714,16 +10779,16 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
           __pyx_cur_scope->__pyx_v_fh = __pyx_t_4;
           __pyx_t_4 = 0;
 
-          /* "libzim.pyx":473
+          /* "libzim.pyx":474
  *         bsize = 1048576  # 1MiB chunk
  *         with open(self.filepath, "rb") as fh:
  *             res = fh.read(bsize)             # <<<<<<<<<<<<<<
  *             while res:
  *                 yield WritingBlob(res)
  */
-          __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_fh, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 473, __pyx_L8_error)
+          __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_fh, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 474, __pyx_L8_error)
           __Pyx_GOTREF(__pyx_t_1);
-          __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_cur_scope->__pyx_v_bsize); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 473, __pyx_L8_error)
+          __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_cur_scope->__pyx_v_bsize); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 474, __pyx_L8_error)
           __Pyx_GOTREF(__pyx_t_2);
           __pyx_t_5 = NULL;
           if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
@@ -10738,14 +10803,14 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
           __pyx_t_4 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_5, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_2);
           __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
           __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-          if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 473, __pyx_L8_error)
+          if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 474, __pyx_L8_error)
           __Pyx_GOTREF(__pyx_t_4);
           __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
           __Pyx_GIVEREF(__pyx_t_4);
           __pyx_cur_scope->__pyx_v_res = __pyx_t_4;
           __pyx_t_4 = 0;
 
-          /* "libzim.pyx":474
+          /* "libzim.pyx":475
  *         with open(self.filepath, "rb") as fh:
  *             res = fh.read(bsize)
  *             while res:             # <<<<<<<<<<<<<<
@@ -10753,17 +10818,17 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
  *                 res = fh.read(bsize)
  */
           while (1) {
-            __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_res); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 474, __pyx_L8_error)
+            __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_cur_scope->__pyx_v_res); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 475, __pyx_L8_error)
             if (!__pyx_t_9) break;
 
-            /* "libzim.pyx":475
+            /* "libzim.pyx":476
  *             res = fh.read(bsize)
  *             while res:
  *                 yield WritingBlob(res)             # <<<<<<<<<<<<<<
  *                 res = fh.read(bsize)
  * 
  */
-            __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_6libzim_WritingBlob), __pyx_cur_scope->__pyx_v_res); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 475, __pyx_L8_error)
+            __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)__pyx_ptype_6libzim_WritingBlob), __pyx_cur_scope->__pyx_v_res); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 476, __pyx_L8_error)
             __Pyx_GOTREF(__pyx_t_4);
             __pyx_r = __pyx_t_4;
             __pyx_t_4 = 0;
@@ -10794,18 +10859,18 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
             __pyx_t_8 = __pyx_cur_scope->__pyx_t_3;
             __pyx_cur_scope->__pyx_t_3 = 0;
             __Pyx_XGOTREF(__pyx_t_8);
-            if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 475, __pyx_L8_error)
+            if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 476, __pyx_L8_error)
 
-            /* "libzim.pyx":476
+            /* "libzim.pyx":477
  *             while res:
  *                 yield WritingBlob(res)
  *                 res = fh.read(bsize)             # <<<<<<<<<<<<<<
  * 
  * class IndexData:
  */
-            __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_fh, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 476, __pyx_L8_error)
+            __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_fh, __pyx_n_s_read); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 477, __pyx_L8_error)
             __Pyx_GOTREF(__pyx_t_1);
-            __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_cur_scope->__pyx_v_bsize); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 476, __pyx_L8_error)
+            __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_cur_scope->__pyx_v_bsize); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 477, __pyx_L8_error)
             __Pyx_GOTREF(__pyx_t_2);
             __pyx_t_5 = NULL;
             if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
@@ -10820,7 +10885,7 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
             __pyx_t_4 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_5, __pyx_t_2) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_2);
             __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
             __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-            if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 476, __pyx_L8_error)
+            if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 477, __pyx_L8_error)
             __Pyx_GOTREF(__pyx_t_4);
             __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
             __Pyx_GOTREF(__pyx_cur_scope->__pyx_v_res);
@@ -10829,7 +10894,7 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
             __pyx_t_4 = 0;
           }
 
-          /* "libzim.pyx":472
+          /* "libzim.pyx":473
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:
  *         bsize = 1048576  # 1MiB chunk
  *         with open(self.filepath, "rb") as fh:             # <<<<<<<<<<<<<<
@@ -10848,20 +10913,20 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
         __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
         /*except:*/ {
           __Pyx_AddTraceback("libzim.FileProvider.gen_blob", __pyx_clineno, __pyx_lineno, __pyx_filename);
-          if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_1, &__pyx_t_2) < 0) __PYX_ERR(0, 472, __pyx_L10_except_error)
+          if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_1, &__pyx_t_2) < 0) __PYX_ERR(0, 473, __pyx_L10_except_error)
           __Pyx_GOTREF(__pyx_t_4);
           __Pyx_GOTREF(__pyx_t_1);
           __Pyx_GOTREF(__pyx_t_2);
-          __pyx_t_5 = PyTuple_Pack(3, __pyx_t_4, __pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 472, __pyx_L10_except_error)
+          __pyx_t_5 = PyTuple_Pack(3, __pyx_t_4, __pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 473, __pyx_L10_except_error)
           __Pyx_GOTREF(__pyx_t_5);
           __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
           __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-          if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 472, __pyx_L10_except_error)
+          if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 473, __pyx_L10_except_error)
           __Pyx_GOTREF(__pyx_t_10);
           __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_10);
           __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-          if (__pyx_t_9 < 0) __PYX_ERR(0, 472, __pyx_L10_except_error)
+          if (__pyx_t_9 < 0) __PYX_ERR(0, 473, __pyx_L10_except_error)
           __pyx_t_11 = ((!(__pyx_t_9 != 0)) != 0);
           if (__pyx_t_11) {
             __Pyx_GIVEREF(__pyx_t_4);
@@ -10869,7 +10934,7 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
             __Pyx_XGIVEREF(__pyx_t_2);
             __Pyx_ErrRestoreWithState(__pyx_t_4, __pyx_t_1, __pyx_t_2);
             __pyx_t_4 = 0; __pyx_t_1 = 0; __pyx_t_2 = 0; 
-            __PYX_ERR(0, 472, __pyx_L10_except_error)
+            __PYX_ERR(0, 473, __pyx_L10_except_error)
           }
           __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
           __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -10895,7 +10960,7 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
         if (__pyx_t_3) {
           __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__15, NULL);
           __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-          if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 472, __pyx_L1_error)
+          if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 473, __pyx_L1_error)
           __Pyx_GOTREF(__pyx_t_8);
           __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
         }
@@ -10911,7 +10976,7 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
   }
   CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);
 
-  /* "libzim.pyx":470
+  /* "libzim.pyx":471
  *         return self.size
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
@@ -10939,7 +11004,7 @@ static PyObject *__pyx_gb_6libzim_12FileProvider_6generator1(__pyx_CoroutineObje
   return __pyx_r;
 }
 
-/* "libzim.pyx":484
+/* "libzim.pyx":485
  *     __module__ = writer_module_name
  * 
  *     def has_indexdata(self) -> bool:             # <<<<<<<<<<<<<<
@@ -10967,7 +11032,7 @@ static PyObject *__pyx_pf_6libzim_9IndexData_has_indexdata(CYTHON_UNUSED PyObjec
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("has_indexdata", 0);
 
-  /* "libzim.pyx":486
+  /* "libzim.pyx":487
  *     def has_indexdata(self) -> bool:
  *         """Return true if the IndexData actually contains data"""
  *         return False             # <<<<<<<<<<<<<<
@@ -10979,7 +11044,7 @@ static PyObject *__pyx_pf_6libzim_9IndexData_has_indexdata(CYTHON_UNUSED PyObjec
   __pyx_r = Py_False;
   goto __pyx_L0;
 
-  /* "libzim.pyx":484
+  /* "libzim.pyx":485
  *     __module__ = writer_module_name
  * 
  *     def has_indexdata(self) -> bool:             # <<<<<<<<<<<<<<
@@ -10994,7 +11059,7 @@ static PyObject *__pyx_pf_6libzim_9IndexData_has_indexdata(CYTHON_UNUSED PyObjec
   return __pyx_r;
 }
 
-/* "libzim.pyx":488
+/* "libzim.pyx":489
  *         return False
  * 
  *     def get_title(self) -> str:             # <<<<<<<<<<<<<<
@@ -11026,20 +11091,20 @@ static PyObject *__pyx_pf_6libzim_9IndexData_2get_title(CYTHON_UNUSED PyObject *
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_title", 0);
 
-  /* "libzim.pyx":490
+  /* "libzim.pyx":491
  *     def get_title(self) -> str:
  *         """Title to index. Might be the same as Item.get_title or not"""
  *         raise NotImplementedError("get_title must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_content(self) -> str:
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 490, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 491, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 490, __pyx_L1_error)
+  __PYX_ERR(0, 491, __pyx_L1_error)
 
-  /* "libzim.pyx":488
+  /* "libzim.pyx":489
  *         return False
  * 
  *     def get_title(self) -> str:             # <<<<<<<<<<<<<<
@@ -11057,7 +11122,7 @@ static PyObject *__pyx_pf_6libzim_9IndexData_2get_title(CYTHON_UNUSED PyObject *
   return __pyx_r;
 }
 
-/* "libzim.pyx":492
+/* "libzim.pyx":493
  *         raise NotImplementedError("get_title must be implemented.")
  * 
  *     def get_content(self) -> str:             # <<<<<<<<<<<<<<
@@ -11089,20 +11154,20 @@ static PyObject *__pyx_pf_6libzim_9IndexData_4get_content(CYTHON_UNUSED PyObject
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_content", 0);
 
-  /* "libzim.pyx":494
+  /* "libzim.pyx":495
  *     def get_content(self) -> str:
  *         """Content to index. Might be the same as Item.get_title or not"""
  *         raise NotImplementedError("get_content must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_keywords(self) -> str:
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 494, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 495, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 494, __pyx_L1_error)
+  __PYX_ERR(0, 495, __pyx_L1_error)
 
-  /* "libzim.pyx":492
+  /* "libzim.pyx":493
  *         raise NotImplementedError("get_title must be implemented.")
  * 
  *     def get_content(self) -> str:             # <<<<<<<<<<<<<<
@@ -11120,7 +11185,7 @@ static PyObject *__pyx_pf_6libzim_9IndexData_4get_content(CYTHON_UNUSED PyObject
   return __pyx_r;
 }
 
-/* "libzim.pyx":496
+/* "libzim.pyx":497
  *         raise NotImplementedError("get_content must be implemented.")
  * 
  *     def get_keywords(self) -> str:             # <<<<<<<<<<<<<<
@@ -11152,20 +11217,20 @@ static PyObject *__pyx_pf_6libzim_9IndexData_6get_keywords(CYTHON_UNUSED PyObjec
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_keywords", 0);
 
-  /* "libzim.pyx":500
+  /* "libzim.pyx":501
  * 
  *         Must be a string containing keywords separated by a space"""
  *         raise NotImplementedError("get_keywords must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_wordcount(self) -> int:
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 500, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 501, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 500, __pyx_L1_error)
+  __PYX_ERR(0, 501, __pyx_L1_error)
 
-  /* "libzim.pyx":496
+  /* "libzim.pyx":497
  *         raise NotImplementedError("get_content must be implemented.")
  * 
  *     def get_keywords(self) -> str:             # <<<<<<<<<<<<<<
@@ -11183,7 +11248,7 @@ static PyObject *__pyx_pf_6libzim_9IndexData_6get_keywords(CYTHON_UNUSED PyObjec
   return __pyx_r;
 }
 
-/* "libzim.pyx":502
+/* "libzim.pyx":503
  *         raise NotImplementedError("get_keywords must be implemented.")
  * 
  *     def get_wordcount(self) -> int:             # <<<<<<<<<<<<<<
@@ -11215,20 +11280,20 @@ static PyObject *__pyx_pf_6libzim_9IndexData_8get_wordcount(CYTHON_UNUSED PyObje
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_wordcount", 0);
 
-  /* "libzim.pyx":504
+  /* "libzim.pyx":505
  *     def get_wordcount(self) -> int:
  *         """Number of word in content"""
  *         raise NotImplementedError("get_wordcount must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_geoposition(self) -> Optional[Tuple[float, float]]:
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 504, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 505, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 504, __pyx_L1_error)
+  __PYX_ERR(0, 505, __pyx_L1_error)
 
-  /* "libzim.pyx":502
+  /* "libzim.pyx":503
  *         raise NotImplementedError("get_keywords must be implemented.")
  * 
  *     def get_wordcount(self) -> int:             # <<<<<<<<<<<<<<
@@ -11246,7 +11311,7 @@ static PyObject *__pyx_pf_6libzim_9IndexData_8get_wordcount(CYTHON_UNUSED PyObje
   return __pyx_r;
 }
 
-/* "libzim.pyx":506
+/* "libzim.pyx":507
  *         raise NotImplementedError("get_wordcount must be implemented.")
  * 
  *     def get_geoposition(self) -> Optional[Tuple[float, float]]:             # <<<<<<<<<<<<<<
@@ -11274,7 +11339,7 @@ static PyObject *__pyx_pf_6libzim_9IndexData_10get_geoposition(CYTHON_UNUSED PyO
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("get_geoposition", 0);
 
-  /* "libzim.pyx":510
+  /* "libzim.pyx":511
  * 
  *         Must be a tuple (latitude, longitude) or None"""
  *         return None             # <<<<<<<<<<<<<<
@@ -11285,7 +11350,7 @@ static PyObject *__pyx_pf_6libzim_9IndexData_10get_geoposition(CYTHON_UNUSED PyO
   __pyx_r = Py_None; __Pyx_INCREF(Py_None);
   goto __pyx_L0;
 
-  /* "libzim.pyx":506
+  /* "libzim.pyx":507
  *         raise NotImplementedError("get_wordcount must be implemented.")
  * 
  *     def get_geoposition(self) -> Optional[Tuple[float, float]]:             # <<<<<<<<<<<<<<
@@ -11300,7 +11365,7 @@ static PyObject *__pyx_pf_6libzim_9IndexData_10get_geoposition(CYTHON_UNUSED PyO
   return __pyx_r;
 }
 
-/* "libzim.pyx":519
+/* "libzim.pyx":520
  *     __module__ = writer_module_name
  * 
  *     def __init__(self):             # <<<<<<<<<<<<<<
@@ -11330,16 +11395,16 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem___init__(CYTHON_UNUSED PyObj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__init__", 0);
 
-  /* "libzim.pyx":520
+  /* "libzim.pyx":521
  * 
  *     def __init__(self):
  *         self._blob = None             # <<<<<<<<<<<<<<
  * 
  *     def get_path(self) -> str:
  */
-  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_blob, Py_None) < 0) __PYX_ERR(0, 520, __pyx_L1_error)
+  if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_blob, Py_None) < 0) __PYX_ERR(0, 521, __pyx_L1_error)
 
-  /* "libzim.pyx":519
+  /* "libzim.pyx":520
  *     __module__ = writer_module_name
  * 
  *     def __init__(self):             # <<<<<<<<<<<<<<
@@ -11359,7 +11424,7 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem___init__(CYTHON_UNUSED PyObj
   return __pyx_r;
 }
 
-/* "libzim.pyx":522
+/* "libzim.pyx":523
  *         self._blob = None
  * 
  *     def get_path(self) -> str:             # <<<<<<<<<<<<<<
@@ -11391,20 +11456,20 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_2get_path(CYTHON_UNUSED PyOb
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_path", 0);
 
-  /* "libzim.pyx":524
+  /* "libzim.pyx":525
  *     def get_path(self) -> str:
  *         """Full path of item"""
  *         raise NotImplementedError("get_path must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_title(self) -> str:
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 524, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 525, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 524, __pyx_L1_error)
+  __PYX_ERR(0, 525, __pyx_L1_error)
 
-  /* "libzim.pyx":522
+  /* "libzim.pyx":523
  *         self._blob = None
  * 
  *     def get_path(self) -> str:             # <<<<<<<<<<<<<<
@@ -11422,7 +11487,7 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_2get_path(CYTHON_UNUSED PyOb
   return __pyx_r;
 }
 
-/* "libzim.pyx":526
+/* "libzim.pyx":527
  *         raise NotImplementedError("get_path must be implemented.")
  * 
  *     def get_title(self) -> str:             # <<<<<<<<<<<<<<
@@ -11454,20 +11519,20 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_4get_title(CYTHON_UNUSED PyO
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_title", 0);
 
-  /* "libzim.pyx":528
+  /* "libzim.pyx":529
  *     def get_title(self) -> str:
  *         """Item title. Might be indexed and used in suggestions"""
  *         raise NotImplementedError("get_title must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_mimetype(self) -> str:
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 528, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 529, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 528, __pyx_L1_error)
+  __PYX_ERR(0, 529, __pyx_L1_error)
 
-  /* "libzim.pyx":526
+  /* "libzim.pyx":527
  *         raise NotImplementedError("get_path must be implemented.")
  * 
  *     def get_title(self) -> str:             # <<<<<<<<<<<<<<
@@ -11485,7 +11550,7 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_4get_title(CYTHON_UNUSED PyO
   return __pyx_r;
 }
 
-/* "libzim.pyx":530
+/* "libzim.pyx":531
  *         raise NotImplementedError("get_title must be implemented.")
  * 
  *     def get_mimetype(self) -> str:             # <<<<<<<<<<<<<<
@@ -11517,20 +11582,20 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_6get_mimetype(CYTHON_UNUSED
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_mimetype", 0);
 
-  /* "libzim.pyx":532
+  /* "libzim.pyx":533
  *     def get_mimetype(self) -> str:
  *         """MIME-type of the item's content."""
  *         raise NotImplementedError("get_mimetype must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_contentprovider(self) -> ContentProvider:
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 532, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 533, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 532, __pyx_L1_error)
+  __PYX_ERR(0, 533, __pyx_L1_error)
 
-  /* "libzim.pyx":530
+  /* "libzim.pyx":531
  *         raise NotImplementedError("get_title must be implemented.")
  * 
  *     def get_mimetype(self) -> str:             # <<<<<<<<<<<<<<
@@ -11548,7 +11613,7 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_6get_mimetype(CYTHON_UNUSED
   return __pyx_r;
 }
 
-/* "libzim.pyx":534
+/* "libzim.pyx":535
  *         raise NotImplementedError("get_mimetype must be implemented.")
  * 
  *     def get_contentprovider(self) -> ContentProvider:             # <<<<<<<<<<<<<<
@@ -11580,20 +11645,20 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_8get_contentprovider(CYTHON_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_contentprovider", 0);
 
-  /* "libzim.pyx":536
+  /* "libzim.pyx":537
  *     def get_contentprovider(self) -> ContentProvider:
  *         """ContentProvider containing the complete content of the item"""
  *         raise NotImplementedError("get_contentprovider must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_hints(self) -> Dict[Hint, pyint]:
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 536, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 537, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 536, __pyx_L1_error)
+  __PYX_ERR(0, 537, __pyx_L1_error)
 
-  /* "libzim.pyx":534
+  /* "libzim.pyx":535
  *         raise NotImplementedError("get_mimetype must be implemented.")
  * 
  *     def get_contentprovider(self) -> ContentProvider:             # <<<<<<<<<<<<<<
@@ -11611,7 +11676,7 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_8get_contentprovider(CYTHON_
   return __pyx_r;
 }
 
-/* "libzim.pyx":538
+/* "libzim.pyx":539
  *         raise NotImplementedError("get_contentprovider must be implemented.")
  * 
  *     def get_hints(self) -> Dict[Hint, pyint]:             # <<<<<<<<<<<<<<
@@ -11643,20 +11708,20 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_10get_hints(CYTHON_UNUSED Py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_hints", 0);
 
-  /* "libzim.pyx":540
+  /* "libzim.pyx":541
  *     def get_hints(self) -> Dict[Hint, pyint]:
  *         """Dict of Hint: value informing Creator how to handle this item"""
  *         raise NotImplementedError("get_hints must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def __repr__(self) -> str:
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 540, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_NotImplementedError, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 541, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(0, 540, __pyx_L1_error)
+  __PYX_ERR(0, 541, __pyx_L1_error)
 
-  /* "libzim.pyx":538
+  /* "libzim.pyx":539
  *         raise NotImplementedError("get_contentprovider must be implemented.")
  * 
  *     def get_hints(self) -> Dict[Hint, pyint]:             # <<<<<<<<<<<<<<
@@ -11674,7 +11739,7 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_10get_hints(CYTHON_UNUSED Py
   return __pyx_r;
 }
 
-/* "libzim.pyx":542
+/* "libzim.pyx":543
  *         raise NotImplementedError("get_hints must be implemented.")
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
@@ -11710,7 +11775,7 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_12__repr__(CYTHON_UNUSED PyO
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "libzim.pyx":543
+  /* "libzim.pyx":544
  * 
  *     def __repr__(self) -> str:
  *         return (             # <<<<<<<<<<<<<<
@@ -11719,23 +11784,23 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_12__repr__(CYTHON_UNUSED PyO
  */
   __Pyx_XDECREF(__pyx_r);
 
-  /* "libzim.pyx":544
+  /* "libzim.pyx":545
  *     def __repr__(self) -> str:
  *         return (
  *             f"{self.__class__.__name__}(path={self.get_path()}, "             # <<<<<<<<<<<<<<
  *             f"title={self.get_title()})"
  *         )
  */
-  __pyx_t_1 = PyTuple_New(6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 544, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 545, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_class); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 544, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_class); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 545, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 544, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 545, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 544, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 545, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
@@ -11747,7 +11812,7 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_12__repr__(CYTHON_UNUSED PyO
   __pyx_t_2 += 6;
   __Pyx_GIVEREF(__pyx_kp_u_path_2);
   PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_kp_u_path_2);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_get_path); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 544, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_get_path); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 545, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __pyx_t_6 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -11761,10 +11826,10 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_12__repr__(CYTHON_UNUSED PyO
   }
   __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallNoArg(__pyx_t_5);
   __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 544, __pyx_L1_error)
+  if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 545, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 544, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 545, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -11777,14 +11842,14 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_12__repr__(CYTHON_UNUSED PyO
   __Pyx_GIVEREF(__pyx_kp_u_title_2);
   PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_kp_u_title_2);
 
-  /* "libzim.pyx":545
+  /* "libzim.pyx":546
  *         return (
  *             f"{self.__class__.__name__}(path={self.get_path()}, "
  *             f"title={self.get_title()})"             # <<<<<<<<<<<<<<
  *         )
  * 
  */
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_get_title); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 545, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_get_title); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 546, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __pyx_t_6 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
@@ -11798,10 +11863,10 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_12__repr__(CYTHON_UNUSED PyO
   }
   __pyx_t_5 = (__pyx_t_6) ? __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_6) : __Pyx_PyObject_CallNoArg(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 545, __pyx_L1_error)
+  if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 546, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 545, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 546, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
@@ -11814,21 +11879,21 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_12__repr__(CYTHON_UNUSED PyO
   __Pyx_GIVEREF(__pyx_kp_u__24);
   PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_kp_u__24);
 
-  /* "libzim.pyx":544
+  /* "libzim.pyx":545
  *     def __repr__(self) -> str:
  *         return (
  *             f"{self.__class__.__name__}(path={self.get_path()}, "             # <<<<<<<<<<<<<<
  *             f"title={self.get_title()})"
  *         )
  */
-  __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_1, 6, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 544, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_1, 6, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 545, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = ((PyObject*)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":542
+  /* "libzim.pyx":543
  *         raise NotImplementedError("get_hints must be implemented.")
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
@@ -11850,135 +11915,20 @@ static PyObject *__pyx_pf_6libzim_15BaseWritingItem_12__repr__(CYTHON_UNUSED PyO
   return __pyx_r;
 }
 
-/* "libzim.pyx":549
- * 
- * 
- * def pascalize(keyword: str):             # <<<<<<<<<<<<<<
- *     """Converts python case to pascal case.
- * 
+/* "libzim.pyx":552
+ * class Creator(_Creator):
+ *     __module__ = writer_module_name
+ *     def config_compression(self, compression: Compression):             # <<<<<<<<<<<<<<
+ *         if not isinstance(compression, Compression):
+ *             compression = getattr(Compression, compression.lower())
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_6libzim_3pascalize(PyObject *__pyx_self, PyObject *__pyx_v_keyword); /*proto*/
-static char __pyx_doc_6libzim_2pascalize[] = "Converts python case to pascal case.\n\n    example: long_description -> LongDescription";
-static PyMethodDef __pyx_mdef_6libzim_3pascalize = {"pascalize", (PyCFunction)__pyx_pw_6libzim_3pascalize, METH_O, __pyx_doc_6libzim_2pascalize};
-static PyObject *__pyx_pw_6libzim_3pascalize(PyObject *__pyx_self, PyObject *__pyx_v_keyword) {
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("pascalize (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_keyword), (&PyUnicode_Type), 1, "keyword", 1))) __PYX_ERR(0, 549, __pyx_L1_error)
-  __pyx_r = __pyx_pf_6libzim_2pascalize(__pyx_self, ((PyObject*)__pyx_v_keyword));
-
-  /* function exit code */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_6libzim_2pascalize(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_keyword) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("pascalize", 0);
-
-  /* "libzim.pyx":553
- * 
- *     example: long_description -> LongDescription"""
- *     return "".join(keyword.title().split("_"))             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_keyword, __pyx_n_s_title); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 553, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
-    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
-    if (likely(__pyx_t_4)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_3, function);
-    }
-  }
-  __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 553, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_split); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 553, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = NULL;
-  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
-    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
-    if (likely(__pyx_t_2)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
-      __Pyx_INCREF(__pyx_t_2);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_3, function);
-    }
-  }
-  __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_2, __pyx_n_u__25) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_n_u__25);
-  __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 553, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = PyUnicode_Join(__pyx_kp_u_, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 553, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_r = __pyx_t_3;
-  __pyx_t_3 = 0;
-  goto __pyx_L0;
-
-  /* "libzim.pyx":549
- * 
- * 
- * def pascalize(keyword: str):             # <<<<<<<<<<<<<<
- *     """Converts python case to pascal case.
- * 
- */
-
-  /* function exit code */
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("libzim.pascalize", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "libzim.pyx":558
- * class Creator(_Creator):
- *     __module__ = writer_module_name
- *     def config_compression(self, compression: Compression):             # <<<<<<<<<<<<<<
- *         if not isinstance(compression, Compression):
- *             compression = getattr(Compression, compression.lower())
- */
-
-/* Python wrapper */
-static PyObject *__pyx_pw_6libzim_7Creator_1config_compression(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_6libzim_7Creator_1config_compression = {"config_compression", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_6libzim_7Creator_1config_compression, METH_VARARGS|METH_KEYWORDS, 0};
-static PyObject *__pyx_pw_6libzim_7Creator_1config_compression(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_self = 0;
-  PyObject *__pyx_v_compression = 0;
+static PyObject *__pyx_pw_6libzim_7Creator_1config_compression(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_6libzim_7Creator_1config_compression = {"config_compression", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_6libzim_7Creator_1config_compression, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pw_6libzim_7Creator_1config_compression(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_self = 0;
+  PyObject *__pyx_v_compression = 0;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
@@ -12008,11 +11958,11 @@ static PyObject *__pyx_pw_6libzim_7Creator_1config_compression(PyObject *__pyx_s
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_compression)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("config_compression", 1, 2, 2, 1); __PYX_ERR(0, 558, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("config_compression", 1, 2, 2, 1); __PYX_ERR(0, 552, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "config_compression") < 0)) __PYX_ERR(0, 558, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "config_compression") < 0)) __PYX_ERR(0, 552, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -12025,7 +11975,7 @@ static PyObject *__pyx_pw_6libzim_7Creator_1config_compression(PyObject *__pyx_s
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("config_compression", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 558, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("config_compression", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 552, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.Creator.config_compression", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -12053,30 +12003,30 @@ static PyObject *__pyx_pf_6libzim_7Creator_config_compression(CYTHON_UNUSED PyOb
   __Pyx_RefNannySetupContext("config_compression", 0);
   __Pyx_INCREF(__pyx_v_compression);
 
-  /* "libzim.pyx":559
+  /* "libzim.pyx":553
  *     __module__ = writer_module_name
  *     def config_compression(self, compression: Compression):
  *         if not isinstance(compression, Compression):             # <<<<<<<<<<<<<<
  *             compression = getattr(Compression, compression.lower())
  *         return super().config_compression(compression)
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Compression); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 559, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Compression); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 553, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_IsInstance(__pyx_v_compression, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 559, __pyx_L1_error)
+  __pyx_t_2 = PyObject_IsInstance(__pyx_v_compression, __pyx_t_1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 553, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0);
   if (__pyx_t_3) {
 
-    /* "libzim.pyx":560
+    /* "libzim.pyx":554
  *     def config_compression(self, compression: Compression):
  *         if not isinstance(compression, Compression):
  *             compression = getattr(Compression, compression.lower())             # <<<<<<<<<<<<<<
  *         return super().config_compression(compression)
  * 
  */
-    __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Compression); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 560, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Compression); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 554, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_compression, __pyx_n_s_lower); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 560, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_compression, __pyx_n_s_lower); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 554, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_t_6 = NULL;
     if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_5))) {
@@ -12090,17 +12040,17 @@ static PyObject *__pyx_pf_6libzim_7Creator_config_compression(CYTHON_UNUSED PyOb
     }
     __pyx_t_4 = (__pyx_t_6) ? __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6) : __Pyx_PyObject_CallNoArg(__pyx_t_5);
     __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 560, __pyx_L1_error)
+    if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 554, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_4);
     __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = __Pyx_GetAttr(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 560, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_GetAttr(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 554, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
     __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
     __Pyx_DECREF_SET(__pyx_v_compression, __pyx_t_5);
     __pyx_t_5 = 0;
 
-    /* "libzim.pyx":559
+    /* "libzim.pyx":553
  *     __module__ = writer_module_name
  *     def config_compression(self, compression: Compression):
  *         if not isinstance(compression, Compression):             # <<<<<<<<<<<<<<
@@ -12109,7 +12059,7 @@ static PyObject *__pyx_pf_6libzim_7Creator_config_compression(CYTHON_UNUSED PyOb
  */
   }
 
-  /* "libzim.pyx":561
+  /* "libzim.pyx":555
  *         if not isinstance(compression, Compression):
  *             compression = getattr(Compression, compression.lower())
  *         return super().config_compression(compression)             # <<<<<<<<<<<<<<
@@ -12118,9 +12068,9 @@ static PyObject *__pyx_pf_6libzim_7Creator_config_compression(CYTHON_UNUSED PyOb
  */
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_4 = __Pyx_CyFunction_GetClassObj(__pyx_self);
-  if (!__pyx_t_4) { PyErr_SetString(PyExc_SystemError, "super(): empty __class__ cell"); __PYX_ERR(0, 561, __pyx_L1_error) }
+  if (!__pyx_t_4) { PyErr_SetString(PyExc_SystemError, "super(): empty __class__ cell"); __PYX_ERR(0, 555, __pyx_L1_error) }
   __Pyx_INCREF(__pyx_t_4);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 561, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 555, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_4);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
@@ -12128,10 +12078,10 @@ static PyObject *__pyx_pf_6libzim_7Creator_config_compression(CYTHON_UNUSED PyOb
   __Pyx_GIVEREF(__pyx_v_self);
   PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self);
   __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_super, __pyx_t_1, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 561, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_super, __pyx_t_1, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 555, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_config_compression); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 561, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_config_compression); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 555, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_4 = NULL;
@@ -12146,14 +12096,14 @@ static PyObject *__pyx_pf_6libzim_7Creator_config_compression(CYTHON_UNUSED PyOb
   }
   __pyx_t_5 = (__pyx_t_4) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_4, __pyx_v_compression) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_compression);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 561, __pyx_L1_error)
+  if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 555, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":558
+  /* "libzim.pyx":552
  * class Creator(_Creator):
  *     __module__ = writer_module_name
  *     def config_compression(self, compression: Compression):             # <<<<<<<<<<<<<<
@@ -12176,7 +12126,7 @@ static PyObject *__pyx_pf_6libzim_7Creator_config_compression(CYTHON_UNUSED PyOb
   return __pyx_r;
 }
 
-/* "libzim.pyx":563
+/* "libzim.pyx":557
  *         return super().config_compression(compression)
  * 
  *     def add_metadata(             # <<<<<<<<<<<<<<
@@ -12226,13 +12176,13 @@ static PyObject *__pyx_pw_6libzim_7Creator_3add_metadata(PyObject *__pyx_self, P
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_metadata", 0, 3, 4, 1); __PYX_ERR(0, 563, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_metadata", 0, 3, 4, 1); __PYX_ERR(0, 557, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
         if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_content)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("add_metadata", 0, 3, 4, 2); __PYX_ERR(0, 563, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("add_metadata", 0, 3, 4, 2); __PYX_ERR(0, 557, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  3:
@@ -12242,7 +12192,7 @@ static PyObject *__pyx_pw_6libzim_7Creator_3add_metadata(PyObject *__pyx_self, P
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_metadata") < 0)) __PYX_ERR(0, 563, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_metadata") < 0)) __PYX_ERR(0, 557, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -12262,14 +12212,14 @@ static PyObject *__pyx_pw_6libzim_7Creator_3add_metadata(PyObject *__pyx_self, P
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("add_metadata", 0, 3, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 563, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("add_metadata", 0, 3, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 557, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.Creator.add_metadata", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_name), (&PyUnicode_Type), 1, "name", 1))) __PYX_ERR(0, 564, __pyx_L1_error)
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mimetype), (&PyUnicode_Type), 1, "mimetype", 1))) __PYX_ERR(0, 565, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_name), (&PyUnicode_Type), 1, "name", 1))) __PYX_ERR(0, 558, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mimetype), (&PyUnicode_Type), 1, "mimetype", 1))) __PYX_ERR(0, 559, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_7Creator_2add_metadata(__pyx_self, __pyx_v_self, __pyx_v_name, __pyx_v_content, __pyx_v_mimetype);
 
   /* function exit code */
@@ -12284,184 +12234,155 @@ static PyObject *__pyx_pw_6libzim_7Creator_3add_metadata(PyObject *__pyx_self, P
 static PyObject *__pyx_pf_6libzim_7Creator_2add_metadata(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_name, PyObject *__pyx_v_content, PyObject *__pyx_v_mimetype) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  int __pyx_t_4;
-  int __pyx_t_5;
-  int __pyx_t_6;
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
   int __pyx_t_7;
   PyObject *__pyx_t_8 = NULL;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("add_metadata", 0);
-  __Pyx_INCREF(__pyx_v_name);
   __Pyx_INCREF(__pyx_v_content);
 
-  /* "libzim.pyx":567
+  /* "libzim.pyx":561
  *         mimetype: str = "text/plain;charset=UTF-8"
  *     ):
- *         name = pascalize(name)             # <<<<<<<<<<<<<<
- *         if name == "Date" and isinstance(content, (datetime.date, datetime.datetime)):
- *             content = content.strftime("%Y-%m-%d").encode("UTF-8")
- */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_pascalize); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 567, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = NULL;
-  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
-    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
-    if (likely(__pyx_t_3)) {
-      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
-      __Pyx_INCREF(__pyx_t_3);
-      __Pyx_INCREF(function);
-      __Pyx_DECREF_SET(__pyx_t_2, function);
-    }
-  }
-  __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_v_name) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_name);
-  __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 567, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_1)->tp_name), 0))) __PYX_ERR(0, 567, __pyx_L1_error)
-  __Pyx_DECREF_SET(__pyx_v_name, ((PyObject*)__pyx_t_1));
-  __pyx_t_1 = 0;
-
-  /* "libzim.pyx":568
- *     ):
- *         name = pascalize(name)
  *         if name == "Date" and isinstance(content, (datetime.date, datetime.datetime)):             # <<<<<<<<<<<<<<
  *             content = content.strftime("%Y-%m-%d").encode("UTF-8")
  *         if isinstance(content, str):
  */
-  __pyx_t_5 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_Date, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 568, __pyx_L1_error)
-  __pyx_t_6 = (__pyx_t_5 != 0);
-  if (__pyx_t_6) {
+  __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_name, __pyx_n_u_Date, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(0, 561, __pyx_L1_error)
+  __pyx_t_3 = (__pyx_t_2 != 0);
+  if (__pyx_t_3) {
   } else {
-    __pyx_t_4 = __pyx_t_6;
+    __pyx_t_1 = __pyx_t_3;
     goto __pyx_L4_bool_binop_done;
   }
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_datetime); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 568, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_date); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 568, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_datetime); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 568, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_datetime); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 568, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_5 = PyObject_IsInstance(__pyx_v_content, __pyx_t_2); 
-  __pyx_t_7 = (__pyx_t_5 != 0);
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_datetime); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 561, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_date); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 561, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_datetime); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 561, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_datetime); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 561, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_2 = PyObject_IsInstance(__pyx_v_content, __pyx_t_5); 
+  __pyx_t_7 = (__pyx_t_2 != 0);
   if (!__pyx_t_7) {
   } else {
-    __pyx_t_6 = __pyx_t_7;
+    __pyx_t_3 = __pyx_t_7;
     goto __pyx_L6_bool_binop_done;
   }
-  __pyx_t_7 = PyObject_IsInstance(__pyx_v_content, __pyx_t_3); 
-  __pyx_t_5 = (__pyx_t_7 != 0);
-  __pyx_t_6 = __pyx_t_5;
+  __pyx_t_7 = PyObject_IsInstance(__pyx_v_content, __pyx_t_6); 
+  __pyx_t_2 = (__pyx_t_7 != 0);
+  __pyx_t_3 = __pyx_t_2;
   __pyx_L6_bool_binop_done:;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_5 = (__pyx_t_6 != 0);
-  __pyx_t_4 = __pyx_t_5;
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_2 = (__pyx_t_3 != 0);
+  __pyx_t_1 = __pyx_t_2;
   __pyx_L4_bool_binop_done:;
-  if (__pyx_t_4) {
+  if (__pyx_t_1) {
 
-    /* "libzim.pyx":569
- *         name = pascalize(name)
+    /* "libzim.pyx":562
+ *     ):
  *         if name == "Date" and isinstance(content, (datetime.date, datetime.datetime)):
  *             content = content.strftime("%Y-%m-%d").encode("UTF-8")             # <<<<<<<<<<<<<<
  *         if isinstance(content, str):
  *             content = content.encode("UTF-8")
  */
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_content, __pyx_n_s_strftime); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 569, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_content, __pyx_n_s_strftime); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 562, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
     __pyx_t_8 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
-      __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_1);
+    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
+      __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_4);
       if (likely(__pyx_t_8)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
         __Pyx_INCREF(__pyx_t_8);
         __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_1, function);
+        __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_3 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_8, __pyx_kp_u_Y_m_d) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_kp_u_Y_m_d);
+    __pyx_t_6 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_8, __pyx_kp_u_Y_m_d) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_Y_m_d);
     __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
-    if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 569, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_encode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 569, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_3 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
-      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1);
-      if (likely(__pyx_t_3)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
-        __Pyx_INCREF(__pyx_t_3);
+    if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 562, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_encode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 562, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_6 = NULL;
+    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+        __Pyx_INCREF(__pyx_t_6);
         __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_1, function);
+        __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_3, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_kp_u_UTF_8);
-    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 569, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_2);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __Pyx_DECREF_SET(__pyx_v_content, __pyx_t_2);
-    __pyx_t_2 = 0;
+    __pyx_t_5 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_UTF_8);
+    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 562, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF_SET(__pyx_v_content, __pyx_t_5);
+    __pyx_t_5 = 0;
 
-    /* "libzim.pyx":568
+    /* "libzim.pyx":561
+ *         mimetype: str = "text/plain;charset=UTF-8"
  *     ):
- *         name = pascalize(name)
  *         if name == "Date" and isinstance(content, (datetime.date, datetime.datetime)):             # <<<<<<<<<<<<<<
  *             content = content.strftime("%Y-%m-%d").encode("UTF-8")
  *         if isinstance(content, str):
  */
   }
 
-  /* "libzim.pyx":570
+  /* "libzim.pyx":563
  *         if name == "Date" and isinstance(content, (datetime.date, datetime.datetime)):
  *             content = content.strftime("%Y-%m-%d").encode("UTF-8")
  *         if isinstance(content, str):             # <<<<<<<<<<<<<<
  *             content = content.encode("UTF-8")
  *         super().add_metadata(name=name, content=content, mimetype=mimetype)
  */
-  __pyx_t_4 = PyUnicode_Check(__pyx_v_content); 
-  __pyx_t_5 = (__pyx_t_4 != 0);
-  if (__pyx_t_5) {
+  __pyx_t_1 = PyUnicode_Check(__pyx_v_content); 
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
 
-    /* "libzim.pyx":571
+    /* "libzim.pyx":564
  *             content = content.strftime("%Y-%m-%d").encode("UTF-8")
  *         if isinstance(content, str):
  *             content = content.encode("UTF-8")             # <<<<<<<<<<<<<<
  *         super().add_metadata(name=name, content=content, mimetype=mimetype)
  * 
  */
-    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_content, __pyx_n_s_encode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 571, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_3 = NULL;
-    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
-      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1);
-      if (likely(__pyx_t_3)) {
-        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
-        __Pyx_INCREF(__pyx_t_3);
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_content, __pyx_n_s_encode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 564, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_6 = NULL;
+    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
+      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+      if (likely(__pyx_t_6)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+        __Pyx_INCREF(__pyx_t_6);
         __Pyx_INCREF(function);
-        __Pyx_DECREF_SET(__pyx_t_1, function);
+        __Pyx_DECREF_SET(__pyx_t_4, function);
       }
     }
-    __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_3, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_kp_u_UTF_8);
-    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 571, __pyx_L1_error)
-    __Pyx_GOTREF(__pyx_t_2);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __Pyx_DECREF_SET(__pyx_v_content, __pyx_t_2);
-    __pyx_t_2 = 0;
+    __pyx_t_5 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_4, __pyx_t_6, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_kp_u_UTF_8);
+    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+    if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 564, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF_SET(__pyx_v_content, __pyx_t_5);
+    __pyx_t_5 = 0;
 
-    /* "libzim.pyx":570
+    /* "libzim.pyx":563
  *         if name == "Date" and isinstance(content, (datetime.date, datetime.datetime)):
  *             content = content.strftime("%Y-%m-%d").encode("UTF-8")
  *         if isinstance(content, str):             # <<<<<<<<<<<<<<
@@ -12470,42 +12391,42 @@ static PyObject *__pyx_pf_6libzim_7Creator_2add_metadata(CYTHON_UNUSED PyObject
  */
   }
 
-  /* "libzim.pyx":572
+  /* "libzim.pyx":565
  *         if isinstance(content, str):
  *             content = content.encode("UTF-8")
  *         super().add_metadata(name=name, content=content, mimetype=mimetype)             # <<<<<<<<<<<<<<
  * 
  *     def __repr__(self) -> str:
  */
-  __pyx_t_2 = __Pyx_CyFunction_GetClassObj(__pyx_self);
-  if (!__pyx_t_2) { PyErr_SetString(PyExc_SystemError, "super(): empty __class__ cell"); __PYX_ERR(0, 572, __pyx_L1_error) }
-  __Pyx_INCREF(__pyx_t_2);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 572, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_2);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+  __pyx_t_5 = __Pyx_CyFunction_GetClassObj(__pyx_self);
+  if (!__pyx_t_5) { PyErr_SetString(PyExc_SystemError, "super(): empty __class__ cell"); __PYX_ERR(0, 565, __pyx_L1_error) }
+  __Pyx_INCREF(__pyx_t_5);
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 565, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5);
   __Pyx_INCREF(__pyx_v_self);
   __Pyx_GIVEREF(__pyx_v_self);
-  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_self);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_super, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 572, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_add_metadata); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 572, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 572, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_name, __pyx_v_name) < 0) __PYX_ERR(0, 572, __pyx_L1_error)
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_content, __pyx_v_content) < 0) __PYX_ERR(0, 572, __pyx_L1_error)
-  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_mimetype, __pyx_v_mimetype) < 0) __PYX_ERR(0, 572, __pyx_L1_error)
-  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_empty_tuple, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 572, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_self);
+  __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_super, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 565, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_add_metadata); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 565, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __pyx_t_5 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 565, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_name, __pyx_v_name) < 0) __PYX_ERR(0, 565, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_content, __pyx_v_content) < 0) __PYX_ERR(0, 565, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_mimetype, __pyx_v_mimetype) < 0) __PYX_ERR(0, 565, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_empty_tuple, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 565, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-  /* "libzim.pyx":563
+  /* "libzim.pyx":557
  *         return super().config_compression(compression)
  * 
  *     def add_metadata(             # <<<<<<<<<<<<<<
@@ -12517,21 +12438,20 @@ static PyObject *__pyx_pf_6libzim_7Creator_2add_metadata(CYTHON_UNUSED PyObject
   __pyx_r = Py_None; __Pyx_INCREF(Py_None);
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_8);
   __Pyx_AddTraceback("libzim.Creator.add_metadata", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_name);
   __Pyx_XDECREF(__pyx_v_content);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "libzim.pyx":574
+/* "libzim.pyx":567
  *         super().add_metadata(name=name, content=content, mimetype=mimetype)
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
@@ -12566,7 +12486,7 @@ static PyObject *__pyx_pf_6libzim_7Creator_4__repr__(CYTHON_UNUSED PyObject *__p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "libzim.pyx":575
+  /* "libzim.pyx":568
  * 
  *     def __repr__(self) -> str:
  *         return f"Creator(filename={self.filename})"             # <<<<<<<<<<<<<<
@@ -12574,7 +12494,7 @@ static PyObject *__pyx_pf_6libzim_7Creator_4__repr__(CYTHON_UNUSED PyObject *__p
  * writer_module_doc = """libzim writer module
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 575, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 568, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
@@ -12582,9 +12502,9 @@ static PyObject *__pyx_pf_6libzim_7Creator_4__repr__(CYTHON_UNUSED PyObject *__p
   __pyx_t_2 += 17;
   __Pyx_GIVEREF(__pyx_kp_u_Creator_filename);
   PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_kp_u_Creator_filename);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_filename); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 575, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_filename); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 568, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 575, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 568, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -12596,14 +12516,14 @@ static PyObject *__pyx_pf_6libzim_7Creator_4__repr__(CYTHON_UNUSED PyObject *__p
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__24);
   PyTuple_SET_ITEM(__pyx_t_1, 2, __pyx_kp_u__24);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 575, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 3, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 568, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = ((PyObject*)__pyx_t_5);
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":574
+  /* "libzim.pyx":567
  *         super().add_metadata(name=name, content=content, mimetype=mimetype)
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
@@ -12624,7 +12544,7 @@ static PyObject *__pyx_pf_6libzim_7Creator_4__repr__(CYTHON_UNUSED PyObject *__p
   return __pyx_r;
 }
 
-/* "libzim.pyx":623
+/* "libzim.pyx":615
  *     # Factory functions - Currently Cython can't use classmethods
  *     @staticmethod
  *     cdef from_blob(zim.Blob blob):             # <<<<<<<<<<<<<<
@@ -12643,19 +12563,19 @@ static PyObject *__pyx_f_6libzim_11ReadingBlob_from_blob(wrapper::Blob __pyx_v_b
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("from_blob", 0);
 
-  /* "libzim.pyx":634
+  /* "libzim.pyx":626
  *             Blob
  *                 Casted blob"""
  *         cdef ReadingBlob rblob = ReadingBlob()             # <<<<<<<<<<<<<<
  *         rblob.c_blob = move(blob)
  *         rblob.size = rblob.c_blob.size()
  */
-  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_ReadingBlob)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 634, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_ReadingBlob)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 626, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_rblob = ((struct __pyx_obj_6libzim_ReadingBlob *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "libzim.pyx":635
+  /* "libzim.pyx":627
  *                 Casted blob"""
  *         cdef ReadingBlob rblob = ReadingBlob()
  *         rblob.c_blob = move(blob)             # <<<<<<<<<<<<<<
@@ -12664,7 +12584,7 @@ static PyObject *__pyx_f_6libzim_11ReadingBlob_from_blob(wrapper::Blob __pyx_v_b
  */
   __pyx_v_rblob->c_blob = cython_std::move<wrapper::Blob>(__pyx_v_blob);
 
-  /* "libzim.pyx":636
+  /* "libzim.pyx":628
  *         cdef ReadingBlob rblob = ReadingBlob()
  *         rblob.c_blob = move(blob)
  *         rblob.size = rblob.c_blob.size()             # <<<<<<<<<<<<<<
@@ -12675,11 +12595,11 @@ static PyObject *__pyx_f_6libzim_11ReadingBlob_from_blob(wrapper::Blob __pyx_v_b
     __pyx_t_2 = __pyx_v_rblob->c_blob.size();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 636, __pyx_L1_error)
+    __PYX_ERR(0, 628, __pyx_L1_error)
   }
   __pyx_v_rblob->size = __pyx_t_2;
 
-  /* "libzim.pyx":637
+  /* "libzim.pyx":629
  *         rblob.c_blob = move(blob)
  *         rblob.size = rblob.c_blob.size()
  *         rblob.view_count = 0             # <<<<<<<<<<<<<<
@@ -12688,7 +12608,7 @@ static PyObject *__pyx_f_6libzim_11ReadingBlob_from_blob(wrapper::Blob __pyx_v_b
  */
   __pyx_v_rblob->view_count = 0;
 
-  /* "libzim.pyx":638
+  /* "libzim.pyx":630
  *         rblob.size = rblob.c_blob.size()
  *         rblob.view_count = 0
  *         return rblob             # <<<<<<<<<<<<<<
@@ -12700,7 +12620,7 @@ static PyObject *__pyx_f_6libzim_11ReadingBlob_from_blob(wrapper::Blob __pyx_v_b
   __pyx_r = ((PyObject *)__pyx_v_rblob);
   goto __pyx_L0;
 
-  /* "libzim.pyx":623
+  /* "libzim.pyx":615
  *     # Factory functions - Currently Cython can't use classmethods
  *     @staticmethod
  *     cdef from_blob(zim.Blob blob):             # <<<<<<<<<<<<<<
@@ -12720,7 +12640,7 @@ static PyObject *__pyx_f_6libzim_11ReadingBlob_from_blob(wrapper::Blob __pyx_v_b
   return __pyx_r;
 }
 
-/* "libzim.pyx":640
+/* "libzim.pyx":632
  *         return rblob
  * 
  *     def __dealloc__(self):             # <<<<<<<<<<<<<<
@@ -12748,7 +12668,7 @@ static void __pyx_pf_6libzim_11ReadingBlob___dealloc__(struct __pyx_obj_6libzim_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__dealloc__", 0);
 
-  /* "libzim.pyx":641
+  /* "libzim.pyx":633
  * 
  *     def __dealloc__(self):
  *         if self.view_count:             # <<<<<<<<<<<<<<
@@ -12758,20 +12678,20 @@ static void __pyx_pf_6libzim_11ReadingBlob___dealloc__(struct __pyx_obj_6libzim_
   __pyx_t_1 = (__pyx_v_self->view_count != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "libzim.pyx":642
+    /* "libzim.pyx":634
  *     def __dealloc__(self):
  *         if self.view_count:
  *             raise RuntimeError("Blob has views")             # <<<<<<<<<<<<<<
  * 
  *     def __getbuffer__(self, Py_buffer *buffer, int flags):
  */
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 642, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 634, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 642, __pyx_L1_error)
+    __PYX_ERR(0, 634, __pyx_L1_error)
 
-    /* "libzim.pyx":641
+    /* "libzim.pyx":633
  * 
  *     def __dealloc__(self):
  *         if self.view_count:             # <<<<<<<<<<<<<<
@@ -12780,7 +12700,7 @@ static void __pyx_pf_6libzim_11ReadingBlob___dealloc__(struct __pyx_obj_6libzim_
  */
   }
 
-  /* "libzim.pyx":640
+  /* "libzim.pyx":632
  *         return rblob
  * 
  *     def __dealloc__(self):             # <<<<<<<<<<<<<<
@@ -12797,7 +12717,7 @@ static void __pyx_pf_6libzim_11ReadingBlob___dealloc__(struct __pyx_obj_6libzim_
   __Pyx_RefNannyFinishContext();
 }
 
-/* "libzim.pyx":644
+/* "libzim.pyx":636
  *             raise RuntimeError("Blob has views")
  * 
  *     def __getbuffer__(self, Py_buffer *buffer, int flags):             # <<<<<<<<<<<<<<
@@ -12836,7 +12756,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
   __pyx_v_buffer->obj = Py_None; __Pyx_INCREF(Py_None);
   __Pyx_GIVEREF(__pyx_v_buffer->obj);
 
-  /* "libzim.pyx":645
+  /* "libzim.pyx":637
  * 
  *     def __getbuffer__(self, Py_buffer *buffer, int flags):
  *         if flags&PyBUF_WRITABLE:             # <<<<<<<<<<<<<<
@@ -12846,20 +12766,20 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
   __pyx_t_1 = ((__pyx_v_flags & PyBUF_WRITABLE) != 0);
   if (unlikely(__pyx_t_1)) {
 
-    /* "libzim.pyx":646
+    /* "libzim.pyx":638
  *     def __getbuffer__(self, Py_buffer *buffer, int flags):
  *         if flags&PyBUF_WRITABLE:
  *             raise BufferError("Cannot create writable memoryview on readonly data")             # <<<<<<<<<<<<<<
  *         buffer.obj = self
  *         buffer.buf = <void*>self.c_blob.data()
  */
-    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_BufferError, __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 646, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_BufferError, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 638, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_Raise(__pyx_t_2, 0, 0, 0);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __PYX_ERR(0, 646, __pyx_L1_error)
+    __PYX_ERR(0, 638, __pyx_L1_error)
 
-    /* "libzim.pyx":645
+    /* "libzim.pyx":637
  * 
  *     def __getbuffer__(self, Py_buffer *buffer, int flags):
  *         if flags&PyBUF_WRITABLE:             # <<<<<<<<<<<<<<
@@ -12868,7 +12788,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
  */
   }
 
-  /* "libzim.pyx":647
+  /* "libzim.pyx":639
  *         if flags&PyBUF_WRITABLE:
  *             raise BufferError("Cannot create writable memoryview on readonly data")
  *         buffer.obj = self             # <<<<<<<<<<<<<<
@@ -12881,7 +12801,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
   __Pyx_DECREF(__pyx_v_buffer->obj);
   __pyx_v_buffer->obj = ((PyObject *)__pyx_v_self);
 
-  /* "libzim.pyx":648
+  /* "libzim.pyx":640
  *             raise BufferError("Cannot create writable memoryview on readonly data")
  *         buffer.obj = self
  *         buffer.buf = <void*>self.c_blob.data()             # <<<<<<<<<<<<<<
@@ -12892,11 +12812,11 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
     __pyx_t_3 = __pyx_v_self->c_blob.data();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 648, __pyx_L1_error)
+    __PYX_ERR(0, 640, __pyx_L1_error)
   }
   __pyx_v_buffer->buf = ((void *)__pyx_t_3);
 
-  /* "libzim.pyx":649
+  /* "libzim.pyx":641
  *         buffer.obj = self
  *         buffer.buf = <void*>self.c_blob.data()
  *         buffer.len = self.size             # <<<<<<<<<<<<<<
@@ -12906,7 +12826,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
   __pyx_t_4 = __pyx_v_self->size;
   __pyx_v_buffer->len = __pyx_t_4;
 
-  /* "libzim.pyx":650
+  /* "libzim.pyx":642
  *         buffer.buf = <void*>self.c_blob.data()
  *         buffer.len = self.size
  *         buffer.readonly = 1             # <<<<<<<<<<<<<<
@@ -12915,7 +12835,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
  */
   __pyx_v_buffer->readonly = 1;
 
-  /* "libzim.pyx":651
+  /* "libzim.pyx":643
  *         buffer.len = self.size
  *         buffer.readonly = 1
  *         buffer.format = 'c'             # <<<<<<<<<<<<<<
@@ -12924,7 +12844,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
  */
   __pyx_v_buffer->format = ((char *)"c");
 
-  /* "libzim.pyx":652
+  /* "libzim.pyx":644
  *         buffer.readonly = 1
  *         buffer.format = 'c'
  *         buffer.internal = NULL                  # see References             # <<<<<<<<<<<<<<
@@ -12933,7 +12853,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
  */
   __pyx_v_buffer->internal = NULL;
 
-  /* "libzim.pyx":653
+  /* "libzim.pyx":645
  *         buffer.format = 'c'
  *         buffer.internal = NULL                  # see References
  *         buffer.itemsize = itemsize             # <<<<<<<<<<<<<<
@@ -12942,7 +12862,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
  */
   __pyx_v_buffer->itemsize = __pyx_v_6libzim_itemsize;
 
-  /* "libzim.pyx":654
+  /* "libzim.pyx":646
  *         buffer.internal = NULL                  # see References
  *         buffer.itemsize = itemsize
  *         buffer.ndim = 1             # <<<<<<<<<<<<<<
@@ -12951,7 +12871,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
  */
   __pyx_v_buffer->ndim = 1;
 
-  /* "libzim.pyx":655
+  /* "libzim.pyx":647
  *         buffer.itemsize = itemsize
  *         buffer.ndim = 1
  *         buffer.shape = &self.size             # <<<<<<<<<<<<<<
@@ -12960,7 +12880,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
  */
   __pyx_v_buffer->shape = (&__pyx_v_self->size);
 
-  /* "libzim.pyx":656
+  /* "libzim.pyx":648
  *         buffer.ndim = 1
  *         buffer.shape = &self.size
  *         buffer.strides = &itemsize             # <<<<<<<<<<<<<<
@@ -12969,7 +12889,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
  */
   __pyx_v_buffer->strides = (&__pyx_v_6libzim_itemsize);
 
-  /* "libzim.pyx":657
+  /* "libzim.pyx":649
  *         buffer.shape = &self.size
  *         buffer.strides = &itemsize
  *         buffer.suboffsets = NULL                # for pointer arrays only             # <<<<<<<<<<<<<<
@@ -12978,7 +12898,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
  */
   __pyx_v_buffer->suboffsets = NULL;
 
-  /* "libzim.pyx":659
+  /* "libzim.pyx":651
  *         buffer.suboffsets = NULL                # for pointer arrays only
  * 
  *         self.view_count += 1             # <<<<<<<<<<<<<<
@@ -12987,7 +12907,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
  */
   __pyx_v_self->view_count = (__pyx_v_self->view_count + 1);
 
-  /* "libzim.pyx":644
+  /* "libzim.pyx":636
  *             raise RuntimeError("Blob has views")
  * 
  *     def __getbuffer__(self, Py_buffer *buffer, int flags):             # <<<<<<<<<<<<<<
@@ -13017,7 +12937,7 @@ static int __pyx_pf_6libzim_11ReadingBlob_2__getbuffer__(struct __pyx_obj_6libzi
   return __pyx_r;
 }
 
-/* "libzim.pyx":661
+/* "libzim.pyx":653
  *         self.view_count += 1
  * 
  *     def __releasebuffer__(self, Py_buffer *buffer):             # <<<<<<<<<<<<<<
@@ -13040,7 +12960,7 @@ static void __pyx_pf_6libzim_11ReadingBlob_4__releasebuffer__(struct __pyx_obj_6
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__releasebuffer__", 0);
 
-  /* "libzim.pyx":662
+  /* "libzim.pyx":654
  * 
  *     def __releasebuffer__(self, Py_buffer *buffer):
  *         self.view_count -= 1             # <<<<<<<<<<<<<<
@@ -13049,7 +12969,7 @@ static void __pyx_pf_6libzim_11ReadingBlob_4__releasebuffer__(struct __pyx_obj_6
  */
   __pyx_v_self->view_count = (__pyx_v_self->view_count - 1);
 
-  /* "libzim.pyx":661
+  /* "libzim.pyx":653
  *         self.view_count += 1
  * 
  *     def __releasebuffer__(self, Py_buffer *buffer):             # <<<<<<<<<<<<<<
@@ -13095,7 +13015,7 @@ static PyObject *__pyx_pf_6libzim_11ReadingBlob_6__reduce_cython__(CYTHON_UNUSED
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_blob cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -13151,7 +13071,7 @@ static PyObject *__pyx_pf_6libzim_11ReadingBlob_8__setstate_cython__(CYTHON_UNUS
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_blob cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -13174,7 +13094,7 @@ static PyObject *__pyx_pf_6libzim_11ReadingBlob_8__setstate_cython__(CYTHON_UNUS
   return __pyx_r;
 }
 
-/* "libzim.pyx":677
+/* "libzim.pyx":669
  *     # Factory functions - Currently Cython can't use classmethods
  *     @staticmethod
  *     cdef from_entry(zim.Entry ent):             # <<<<<<<<<<<<<<
@@ -13192,19 +13112,19 @@ static PyObject *__pyx_f_6libzim_5Entry_from_entry(wrapper::Entry __pyx_v_ent) {
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("from_entry", 0);
 
-  /* "libzim.pyx":688
+  /* "libzim.pyx":680
  *             Entry
  *                 Casted entry"""
  *         cdef Entry entry = Entry()             # <<<<<<<<<<<<<<
  *         entry.c_entry = move(ent)
  *         return entry
  */
-  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_Entry)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 688, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_Entry)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 680, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_entry = ((struct __pyx_obj_6libzim_Entry *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "libzim.pyx":689
+  /* "libzim.pyx":681
  *                 Casted entry"""
  *         cdef Entry entry = Entry()
  *         entry.c_entry = move(ent)             # <<<<<<<<<<<<<<
@@ -13213,7 +13133,7 @@ static PyObject *__pyx_f_6libzim_5Entry_from_entry(wrapper::Entry __pyx_v_ent) {
  */
   __pyx_v_entry->c_entry = cython_std::move<wrapper::Entry>(__pyx_v_ent);
 
-  /* "libzim.pyx":690
+  /* "libzim.pyx":682
  *         cdef Entry entry = Entry()
  *         entry.c_entry = move(ent)
  *         return entry             # <<<<<<<<<<<<<<
@@ -13225,7 +13145,7 @@ static PyObject *__pyx_f_6libzim_5Entry_from_entry(wrapper::Entry __pyx_v_ent) {
   __pyx_r = ((PyObject *)__pyx_v_entry);
   goto __pyx_L0;
 
-  /* "libzim.pyx":677
+  /* "libzim.pyx":669
  *     # Factory functions - Currently Cython can't use classmethods
  *     @staticmethod
  *     cdef from_entry(zim.Entry ent):             # <<<<<<<<<<<<<<
@@ -13245,7 +13165,7 @@ static PyObject *__pyx_f_6libzim_5Entry_from_entry(wrapper::Entry __pyx_v_ent) {
   return __pyx_r;
 }
 
-/* "libzim.pyx":693
+/* "libzim.pyx":685
  * 
  *     @property
  *     def title(self) -> str:             # <<<<<<<<<<<<<<
@@ -13275,7 +13195,7 @@ static PyObject *__pyx_pf_6libzim_5Entry_5title___get__(struct __pyx_obj_6libzim
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":694
+  /* "libzim.pyx":686
  *     @property
  *     def title(self) -> str:
  *         return self.c_entry.getTitle().decode('UTF-8')             # <<<<<<<<<<<<<<
@@ -13283,13 +13203,13 @@ static PyObject *__pyx_pf_6libzim_5Entry_5title___get__(struct __pyx_obj_6libzim
  *     @property
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_decode_cpp_string(__pyx_v_self->c_entry.getTitle(), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 694, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_decode_cpp_string(__pyx_v_self->c_entry.getTitle(), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 686, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":693
+  /* "libzim.pyx":685
  * 
  *     @property
  *     def title(self) -> str:             # <<<<<<<<<<<<<<
@@ -13308,7 +13228,7 @@ static PyObject *__pyx_pf_6libzim_5Entry_5title___get__(struct __pyx_obj_6libzim
   return __pyx_r;
 }
 
-/* "libzim.pyx":697
+/* "libzim.pyx":689
  * 
  *     @property
  *     def path(self) -> str:             # <<<<<<<<<<<<<<
@@ -13339,7 +13259,7 @@ static PyObject *__pyx_pf_6libzim_5Entry_4path___get__(struct __pyx_obj_6libzim_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":698
+  /* "libzim.pyx":690
  *     @property
  *     def path(self) -> str:
  *         return self.c_entry.getPath().decode("UTF-8", "strict")             # <<<<<<<<<<<<<<
@@ -13351,15 +13271,15 @@ static PyObject *__pyx_pf_6libzim_5Entry_4path___get__(struct __pyx_obj_6libzim_
     __pyx_t_1 = __pyx_v_self->c_entry.getPath();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 698, __pyx_L1_error)
+    __PYX_ERR(0, 690, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_1, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 698, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_1, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 690, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":697
+  /* "libzim.pyx":689
  * 
  *     @property
  *     def path(self) -> str:             # <<<<<<<<<<<<<<
@@ -13378,7 +13298,7 @@ static PyObject *__pyx_pf_6libzim_5Entry_4path___get__(struct __pyx_obj_6libzim_
   return __pyx_r;
 }
 
-/* "libzim.pyx":701
+/* "libzim.pyx":693
  * 
  *     @property
  *     def _index(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -13409,7 +13329,7 @@ static PyObject *__pyx_pf_6libzim_5Entry_6_index___get__(struct __pyx_obj_6libzi
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":703
+  /* "libzim.pyx":695
  *     def _index(self) -> pyint:
  *         """Internal index in Archive"""
  *         return self.c_entry.getIndex()             # <<<<<<<<<<<<<<
@@ -13421,15 +13341,15 @@ static PyObject *__pyx_pf_6libzim_5Entry_6_index___get__(struct __pyx_obj_6libzi
     __pyx_t_1 = __pyx_v_self->c_entry.getIndex();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 703, __pyx_L1_error)
+    __PYX_ERR(0, 695, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 703, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 695, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":701
+  /* "libzim.pyx":693
  * 
  *     @property
  *     def _index(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -13448,7 +13368,7 @@ static PyObject *__pyx_pf_6libzim_5Entry_6_index___get__(struct __pyx_obj_6libzi
   return __pyx_r;
 }
 
-/* "libzim.pyx":706
+/* "libzim.pyx":698
  * 
  *     @property
  *     def is_redirect(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -13478,7 +13398,7 @@ static PyObject *__pyx_pf_6libzim_5Entry_11is_redirect___get__(struct __pyx_obj_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":708
+  /* "libzim.pyx":700
  *     def is_redirect(self) -> pybool:
  *         """Whether entry is a redirect"""
  *         return self.c_entry.isRedirect()             # <<<<<<<<<<<<<<
@@ -13486,13 +13406,13 @@ static PyObject *__pyx_pf_6libzim_5Entry_11is_redirect___get__(struct __pyx_obj_
  *     def get_redirect_entry(self) -> Entry:
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_self->c_entry.isRedirect()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 708, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_self->c_entry.isRedirect()); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 700, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":706
+  /* "libzim.pyx":698
  * 
  *     @property
  *     def is_redirect(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -13511,7 +13431,7 @@ static PyObject *__pyx_pf_6libzim_5Entry_11is_redirect___get__(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "libzim.pyx":710
+/* "libzim.pyx":702
  *         return self.c_entry.isRedirect()
  * 
  *     def get_redirect_entry(self) -> Entry:             # <<<<<<<<<<<<<<
@@ -13544,7 +13464,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_5Entry_get_redirect_entr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_redirect_entry", 0);
 
-  /* "libzim.pyx":712
+  /* "libzim.pyx":704
  *     def get_redirect_entry(self) -> Entry:
  *         """Target of this entry, if a redirect"""
  *         cdef zim.Entry entry = move(self.c_entry.getRedirectEntry())             # <<<<<<<<<<<<<<
@@ -13555,11 +13475,11 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_5Entry_get_redirect_entr
     __pyx_t_1 = __pyx_v_self->c_entry.getRedirectEntry();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 712, __pyx_L1_error)
+    __PYX_ERR(0, 704, __pyx_L1_error)
   }
   __pyx_v_entry = cython_std::move<wrapper::Entry>(__pyx_t_1);
 
-  /* "libzim.pyx":713
+  /* "libzim.pyx":705
  *         """Target of this entry, if a redirect"""
  *         cdef zim.Entry entry = move(self.c_entry.getRedirectEntry())
  *         return Entry.from_entry(move(entry))             # <<<<<<<<<<<<<<
@@ -13567,14 +13487,14 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_5Entry_get_redirect_entr
  *     def get_item(self) -> Item:
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = __pyx_f_6libzim_5Entry_from_entry(cython_std::move<wrapper::Entry>(__pyx_v_entry)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 713, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_6libzim_5Entry_from_entry(cython_std::move<wrapper::Entry>(__pyx_v_entry)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 705, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_6libzim_Entry))))) __PYX_ERR(0, 713, __pyx_L1_error)
+  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_6libzim_Entry))))) __PYX_ERR(0, 705, __pyx_L1_error)
   __pyx_r = ((struct __pyx_obj_6libzim_Entry *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":710
+  /* "libzim.pyx":702
  *         return self.c_entry.isRedirect()
  * 
  *     def get_redirect_entry(self) -> Entry:             # <<<<<<<<<<<<<<
@@ -13593,7 +13513,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_5Entry_get_redirect_entr
   return __pyx_r;
 }
 
-/* "libzim.pyx":715
+/* "libzim.pyx":707
  *         return Entry.from_entry(move(entry))
  * 
  *     def get_item(self) -> Item:             # <<<<<<<<<<<<<<
@@ -13625,7 +13545,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_5Entry_2get_item(struct _
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_item", 0);
 
-  /* "libzim.pyx":716
+  /* "libzim.pyx":708
  * 
  *     def get_item(self) -> Item:
  *         cdef zim.Item item = move(self.c_entry.getItem(True))             # <<<<<<<<<<<<<<
@@ -13636,11 +13556,11 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_5Entry_2get_item(struct _
     __pyx_t_1 = __pyx_v_self->c_entry.getItem(1);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 716, __pyx_L1_error)
+    __PYX_ERR(0, 708, __pyx_L1_error)
   }
   __pyx_v_item = cython_std::move<wrapper::Item>(__pyx_t_1);
 
-  /* "libzim.pyx":717
+  /* "libzim.pyx":709
  *     def get_item(self) -> Item:
  *         cdef zim.Item item = move(self.c_entry.getItem(True))
  *         return Item.from_item(move(item))             # <<<<<<<<<<<<<<
@@ -13648,14 +13568,14 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_5Entry_2get_item(struct _
  *     def __repr__(self) -> str:
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_2 = __pyx_f_6libzim_4Item_from_item(cython_std::move<wrapper::Item>(__pyx_v_item)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 717, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_6libzim_4Item_from_item(cython_std::move<wrapper::Item>(__pyx_v_item)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 709, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_6libzim_Item))))) __PYX_ERR(0, 717, __pyx_L1_error)
+  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_6libzim_Item))))) __PYX_ERR(0, 709, __pyx_L1_error)
   __pyx_r = ((struct __pyx_obj_6libzim_Item *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":715
+  /* "libzim.pyx":707
  *         return Entry.from_entry(move(entry))
  * 
  *     def get_item(self) -> Item:             # <<<<<<<<<<<<<<
@@ -13674,7 +13594,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_5Entry_2get_item(struct _
   return __pyx_r;
 }
 
-/* "libzim.pyx":719
+/* "libzim.pyx":711
  *         return Item.from_item(move(item))
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
@@ -13708,7 +13628,7 @@ static PyObject *__pyx_pf_6libzim_5Entry_4__repr__(struct __pyx_obj_6libzim_Entr
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "libzim.pyx":720
+  /* "libzim.pyx":712
  * 
  *     def __repr__(self) -> str:
  *         return f"{self.__class__.__name__}(url={self.path}, title={self.title})"             # <<<<<<<<<<<<<<
@@ -13716,16 +13636,16 @@ static PyObject *__pyx_pf_6libzim_5Entry_4__repr__(struct __pyx_obj_6libzim_Entr
  * cdef class Item:
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 720, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 712, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 720, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 712, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 720, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 712, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 720, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 712, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
@@ -13737,9 +13657,9 @@ static PyObject *__pyx_pf_6libzim_5Entry_4__repr__(struct __pyx_obj_6libzim_Entr
   __pyx_t_2 += 5;
   __Pyx_GIVEREF(__pyx_kp_u_url);
   PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_kp_u_url);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_path); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 720, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_path); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 712, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 720, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 712, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -13751,9 +13671,9 @@ static PyObject *__pyx_pf_6libzim_5Entry_4__repr__(struct __pyx_obj_6libzim_Entr
   __pyx_t_2 += 8;
   __Pyx_GIVEREF(__pyx_kp_u_title_2);
   PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_kp_u_title_2);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_title); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 720, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_title); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 712, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 720, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 712, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
@@ -13765,14 +13685,14 @@ static PyObject *__pyx_pf_6libzim_5Entry_4__repr__(struct __pyx_obj_6libzim_Entr
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__24);
   PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_kp_u__24);
-  __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_1, 6, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 720, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_1, 6, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 712, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_4;
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":719
+  /* "libzim.pyx":711
  *         return Item.from_item(move(item))
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
@@ -13827,7 +13747,7 @@ static PyObject *__pyx_pf_6libzim_5Entry_6__reduce_cython__(CYTHON_UNUSED struct
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_entry cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -13883,7 +13803,7 @@ static PyObject *__pyx_pf_6libzim_5Entry_8__setstate_cython__(CYTHON_UNUSED stru
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_entry cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -13906,7 +13826,7 @@ static PyObject *__pyx_pf_6libzim_5Entry_8__setstate_cython__(CYTHON_UNUSED stru
   return __pyx_r;
 }
 
-/* "libzim.pyx":736
+/* "libzim.pyx":728
  *     # Factory functions - Currently Cython can't use classmethods
  *     @staticmethod
  *     cdef from_item(zim.Item _item):             # <<<<<<<<<<<<<<
@@ -13924,19 +13844,19 @@ static PyObject *__pyx_f_6libzim_4Item_from_item(wrapper::Item __pyx_v__item) {
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("from_item", 0);
 
-  /* "libzim.pyx":747
+  /* "libzim.pyx":739
  *             Item
  *                 Casted item"""
  *         cdef Item item = Item()             # <<<<<<<<<<<<<<
  *         item.c_item = move(_item)
  *         return item
  */
-  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_Item)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 747, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_Item)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 739, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_item = ((struct __pyx_obj_6libzim_Item *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "libzim.pyx":748
+  /* "libzim.pyx":740
  *                 Casted item"""
  *         cdef Item item = Item()
  *         item.c_item = move(_item)             # <<<<<<<<<<<<<<
@@ -13945,7 +13865,7 @@ static PyObject *__pyx_f_6libzim_4Item_from_item(wrapper::Item __pyx_v__item) {
  */
   __pyx_v_item->c_item = cython_std::move<wrapper::Item>(__pyx_v__item);
 
-  /* "libzim.pyx":749
+  /* "libzim.pyx":741
  *         cdef Item item = Item()
  *         item.c_item = move(_item)
  *         return item             # <<<<<<<<<<<<<<
@@ -13957,7 +13877,7 @@ static PyObject *__pyx_f_6libzim_4Item_from_item(wrapper::Item __pyx_v__item) {
   __pyx_r = ((PyObject *)__pyx_v_item);
   goto __pyx_L0;
 
-  /* "libzim.pyx":736
+  /* "libzim.pyx":728
  *     # Factory functions - Currently Cython can't use classmethods
  *     @staticmethod
  *     cdef from_item(zim.Item _item):             # <<<<<<<<<<<<<<
@@ -13977,7 +13897,7 @@ static PyObject *__pyx_f_6libzim_4Item_from_item(wrapper::Item __pyx_v__item) {
   return __pyx_r;
 }
 
-/* "libzim.pyx":752
+/* "libzim.pyx":744
  * 
  *     @property
  *     def title(self) -> str:             # <<<<<<<<<<<<<<
@@ -14008,7 +13928,7 @@ static PyObject *__pyx_pf_6libzim_4Item_5title___get__(struct __pyx_obj_6libzim_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":753
+  /* "libzim.pyx":745
  *     @property
  *     def title(self) -> str:
  *         return self.c_item.getTitle().decode('UTF-8')             # <<<<<<<<<<<<<<
@@ -14020,15 +13940,15 @@ static PyObject *__pyx_pf_6libzim_4Item_5title___get__(struct __pyx_obj_6libzim_
     __pyx_t_1 = __pyx_v_self->c_item.getTitle();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 753, __pyx_L1_error)
+    __PYX_ERR(0, 745, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_1, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 753, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_1, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 745, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":752
+  /* "libzim.pyx":744
  * 
  *     @property
  *     def title(self) -> str:             # <<<<<<<<<<<<<<
@@ -14047,7 +13967,7 @@ static PyObject *__pyx_pf_6libzim_4Item_5title___get__(struct __pyx_obj_6libzim_
   return __pyx_r;
 }
 
-/* "libzim.pyx":756
+/* "libzim.pyx":748
  * 
  *     @property
  *     def path(self) -> str:             # <<<<<<<<<<<<<<
@@ -14078,7 +13998,7 @@ static PyObject *__pyx_pf_6libzim_4Item_4path___get__(struct __pyx_obj_6libzim_I
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":757
+  /* "libzim.pyx":749
  *     @property
  *     def path(self) -> str:
  *         return self.c_item.getPath().decode("UTF-8", "strict")             # <<<<<<<<<<<<<<
@@ -14090,15 +14010,15 @@ static PyObject *__pyx_pf_6libzim_4Item_4path___get__(struct __pyx_obj_6libzim_I
     __pyx_t_1 = __pyx_v_self->c_item.getPath();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 757, __pyx_L1_error)
+    __PYX_ERR(0, 749, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_1, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 757, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_1, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 749, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":756
+  /* "libzim.pyx":748
  * 
  *     @property
  *     def path(self) -> str:             # <<<<<<<<<<<<<<
@@ -14117,7 +14037,7 @@ static PyObject *__pyx_pf_6libzim_4Item_4path___get__(struct __pyx_obj_6libzim_I
   return __pyx_r;
 }
 
-/* "libzim.pyx":760
+/* "libzim.pyx":752
  * 
  *     @property
  *     def content(self) -> memoryview:             # <<<<<<<<<<<<<<
@@ -14150,7 +14070,7 @@ static PyObject *__pyx_pf_6libzim_4Item_7content___get__(struct __pyx_obj_6libzi
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":761
+  /* "libzim.pyx":753
  *     @property
  *     def content(self) -> memoryview:
  *         if not self._haveBlob:             # <<<<<<<<<<<<<<
@@ -14160,7 +14080,7 @@ static PyObject *__pyx_pf_6libzim_4Item_7content___get__(struct __pyx_obj_6libzi
   __pyx_t_1 = ((!(__pyx_v_self->_haveBlob != 0)) != 0);
   if (__pyx_t_1) {
 
-    /* "libzim.pyx":762
+    /* "libzim.pyx":754
  *     def content(self) -> memoryview:
  *         if not self._haveBlob:
  *             self._blob = ReadingBlob.from_blob(move(self.c_item.getData(<int> 0)))             # <<<<<<<<<<<<<<
@@ -14171,18 +14091,18 @@ static PyObject *__pyx_pf_6libzim_4Item_7content___get__(struct __pyx_obj_6libzi
       __pyx_t_2 = __pyx_v_self->c_item.getData(((int)0));
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 762, __pyx_L1_error)
+      __PYX_ERR(0, 754, __pyx_L1_error)
     }
-    __pyx_t_3 = __pyx_f_6libzim_11ReadingBlob_from_blob(cython_std::move<wrapper::Blob>(__pyx_t_2)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 762, __pyx_L1_error)
+    __pyx_t_3 = __pyx_f_6libzim_11ReadingBlob_from_blob(cython_std::move<wrapper::Blob>(__pyx_t_2)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 754, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
-    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_6libzim_ReadingBlob))))) __PYX_ERR(0, 762, __pyx_L1_error)
+    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_6libzim_ReadingBlob))))) __PYX_ERR(0, 754, __pyx_L1_error)
     __Pyx_GIVEREF(__pyx_t_3);
     __Pyx_GOTREF(__pyx_v_self->_blob);
     __Pyx_DECREF(((PyObject *)__pyx_v_self->_blob));
     __pyx_v_self->_blob = ((struct __pyx_obj_6libzim_ReadingBlob *)__pyx_t_3);
     __pyx_t_3 = 0;
 
-    /* "libzim.pyx":763
+    /* "libzim.pyx":755
  *         if not self._haveBlob:
  *             self._blob = ReadingBlob.from_blob(move(self.c_item.getData(<int> 0)))
  *             self._haveBlob = True             # <<<<<<<<<<<<<<
@@ -14191,7 +14111,7 @@ static PyObject *__pyx_pf_6libzim_4Item_7content___get__(struct __pyx_obj_6libzi
  */
     __pyx_v_self->_haveBlob = 1;
 
-    /* "libzim.pyx":761
+    /* "libzim.pyx":753
  *     @property
  *     def content(self) -> memoryview:
  *         if not self._haveBlob:             # <<<<<<<<<<<<<<
@@ -14200,7 +14120,7 @@ static PyObject *__pyx_pf_6libzim_4Item_7content___get__(struct __pyx_obj_6libzi
  */
   }
 
-  /* "libzim.pyx":764
+  /* "libzim.pyx":756
  *             self._blob = ReadingBlob.from_blob(move(self.c_item.getData(<int> 0)))
  *             self._haveBlob = True
  *         return memoryview(self._blob)             # <<<<<<<<<<<<<<
@@ -14208,16 +14128,16 @@ static PyObject *__pyx_pf_6libzim_4Item_7content___get__(struct __pyx_obj_6libzi
  *     @property
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_memoryview); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 764, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_memoryview); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 756, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_self->_blob)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 764, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_self->_blob)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 756, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __pyx_r = __pyx_t_4;
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":760
+  /* "libzim.pyx":752
  * 
  *     @property
  *     def content(self) -> memoryview:             # <<<<<<<<<<<<<<
@@ -14237,7 +14157,7 @@ static PyObject *__pyx_pf_6libzim_4Item_7content___get__(struct __pyx_obj_6libzi
   return __pyx_r;
 }
 
-/* "libzim.pyx":767
+/* "libzim.pyx":759
  * 
  *     @property
  *     def mimetype(self) -> str:             # <<<<<<<<<<<<<<
@@ -14268,7 +14188,7 @@ static PyObject *__pyx_pf_6libzim_4Item_8mimetype___get__(struct __pyx_obj_6libz
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":768
+  /* "libzim.pyx":760
  *     @property
  *     def mimetype(self) -> str:
  *         return self.c_item.getMimetype().decode('UTF-8')             # <<<<<<<<<<<<<<
@@ -14280,15 +14200,15 @@ static PyObject *__pyx_pf_6libzim_4Item_8mimetype___get__(struct __pyx_obj_6libz
     __pyx_t_1 = __pyx_v_self->c_item.getMimetype();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 768, __pyx_L1_error)
+    __PYX_ERR(0, 760, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_1, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 768, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_1, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 760, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":767
+  /* "libzim.pyx":759
  * 
  *     @property
  *     def mimetype(self) -> str:             # <<<<<<<<<<<<<<
@@ -14307,7 +14227,7 @@ static PyObject *__pyx_pf_6libzim_4Item_8mimetype___get__(struct __pyx_obj_6libz
   return __pyx_r;
 }
 
-/* "libzim.pyx":771
+/* "libzim.pyx":763
  * 
  *     @property
  *     def _index(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -14338,7 +14258,7 @@ static PyObject *__pyx_pf_6libzim_4Item_6_index___get__(struct __pyx_obj_6libzim
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":773
+  /* "libzim.pyx":765
  *     def _index(self) -> pyint:
  *         """Internal index in Archive"""
  *         return self.c_item.getIndex()             # <<<<<<<<<<<<<<
@@ -14350,15 +14270,15 @@ static PyObject *__pyx_pf_6libzim_4Item_6_index___get__(struct __pyx_obj_6libzim
     __pyx_t_1 = __pyx_v_self->c_item.getIndex();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 773, __pyx_L1_error)
+    __PYX_ERR(0, 765, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 773, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 765, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":771
+  /* "libzim.pyx":763
  * 
  *     @property
  *     def _index(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -14377,7 +14297,7 @@ static PyObject *__pyx_pf_6libzim_4Item_6_index___get__(struct __pyx_obj_6libzim
   return __pyx_r;
 }
 
-/* "libzim.pyx":776
+/* "libzim.pyx":768
  * 
  *     @property
  *     def size(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -14408,7 +14328,7 @@ static PyObject *__pyx_pf_6libzim_4Item_4size___get__(struct __pyx_obj_6libzim_I
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":777
+  /* "libzim.pyx":769
  *     @property
  *     def size(self) -> pyint:
  *         return self.c_item.getSize()             # <<<<<<<<<<<<<<
@@ -14420,15 +14340,15 @@ static PyObject *__pyx_pf_6libzim_4Item_4size___get__(struct __pyx_obj_6libzim_I
     __pyx_t_1 = __pyx_v_self->c_item.getSize();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 777, __pyx_L1_error)
+    __PYX_ERR(0, 769, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 777, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 769, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":776
+  /* "libzim.pyx":768
  * 
  *     @property
  *     def size(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -14447,7 +14367,7 @@ static PyObject *__pyx_pf_6libzim_4Item_4size___get__(struct __pyx_obj_6libzim_I
   return __pyx_r;
 }
 
-/* "libzim.pyx":779
+/* "libzim.pyx":771
  *         return self.c_item.getSize()
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
@@ -14481,7 +14401,7 @@ static PyObject *__pyx_pf_6libzim_4Item___repr__(struct __pyx_obj_6libzim_Item *
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "libzim.pyx":780
+  /* "libzim.pyx":772
  * 
  *     def __repr__(self) -> str:
  *         return f"{self.__class__.__name__}(url={self.path}, title={self.title})"             # <<<<<<<<<<<<<<
@@ -14489,16 +14409,16 @@ static PyObject *__pyx_pf_6libzim_4Item___repr__(struct __pyx_obj_6libzim_Item *
  * 
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 780, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 772, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 780, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 772, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 780, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 772, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 780, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 772, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
@@ -14510,9 +14430,9 @@ static PyObject *__pyx_pf_6libzim_4Item___repr__(struct __pyx_obj_6libzim_Item *
   __pyx_t_2 += 5;
   __Pyx_GIVEREF(__pyx_kp_u_url);
   PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_kp_u_url);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_path); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 780, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_path); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 772, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 780, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 772, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -14524,9 +14444,9 @@ static PyObject *__pyx_pf_6libzim_4Item___repr__(struct __pyx_obj_6libzim_Item *
   __pyx_t_2 += 8;
   __Pyx_GIVEREF(__pyx_kp_u_title_2);
   PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_kp_u_title_2);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_title); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 780, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_title); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 772, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 780, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 772, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
@@ -14538,14 +14458,14 @@ static PyObject *__pyx_pf_6libzim_4Item___repr__(struct __pyx_obj_6libzim_Item *
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__24);
   PyTuple_SET_ITEM(__pyx_t_1, 5, __pyx_kp_u__24);
-  __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_1, 6, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 780, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_1, 6, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 772, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_4;
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":779
+  /* "libzim.pyx":771
  *         return self.c_item.getSize()
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
@@ -14600,7 +14520,7 @@ static PyObject *__pyx_pf_6libzim_4Item_2__reduce_cython__(CYTHON_UNUSED struct
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_item cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -14656,7 +14576,7 @@ static PyObject *__pyx_pf_6libzim_4Item_4__setstate_cython__(CYTHON_UNUSED struc
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_item cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -14679,7 +14599,7 @@ static PyObject *__pyx_pf_6libzim_4Item_4__setstate_cython__(CYTHON_UNUSED struc
   return __pyx_r;
 }
 
-/* "libzim.pyx":797
+/* "libzim.pyx":789
  *     cdef object _filename
  * 
  *     def __cinit__(self, object filename: pathlib.Path):             # <<<<<<<<<<<<<<
@@ -14716,7 +14636,7 @@ static int __pyx_pw_6libzim_7Archive_1__cinit__(PyObject *__pyx_v_self, PyObject
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 797, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 789, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -14727,7 +14647,7 @@ static int __pyx_pw_6libzim_7Archive_1__cinit__(PyObject *__pyx_v_self, PyObject
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 797, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 789, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.Archive.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -14754,47 +14674,47 @@ static int __pyx_pf_6libzim_7Archive___cinit__(struct __pyx_obj_6libzim_Archive
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "libzim.pyx":805
+  /* "libzim.pyx":797
  *                 Full path to a zim file"""
  * 
  *         self.c_archive = move(zim.Archive(str(filename).encode('UTF-8')))             # <<<<<<<<<<<<<<
  *         self._filename = pathlib.Path(self.c_archive.getFilename().decode("UTF-8", "strict"))
  * 
  */
-  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_filename); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 805, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_filename); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 797, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyUnicode_AsUTF8String(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 805, __pyx_L1_error)
+  __pyx_t_2 = PyUnicode_AsUTF8String(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 797, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 805, __pyx_L1_error)
+  __pyx_t_3 = __pyx_convert_string_from_py_std__in_string(__pyx_t_2); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 797, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   try {
     __pyx_t_4 = wrapper::Archive(__pyx_t_3);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 805, __pyx_L1_error)
+    __PYX_ERR(0, 797, __pyx_L1_error)
   }
   __pyx_v_self->c_archive = cython_std::move<wrapper::Archive>(__pyx_t_4);
 
-  /* "libzim.pyx":806
+  /* "libzim.pyx":798
  * 
  *         self.c_archive = move(zim.Archive(str(filename).encode('UTF-8')))
  *         self._filename = pathlib.Path(self.c_archive.getFilename().decode("UTF-8", "strict"))             # <<<<<<<<<<<<<<
  * 
  *     def __eq__(self, other) -> pybool:
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_pathlib); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 806, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_pathlib); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 798, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Path); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 806, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Path); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 798, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   try {
     __pyx_t_3 = __pyx_v_self->c_archive.getFilename();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 806, __pyx_L1_error)
+    __PYX_ERR(0, 798, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_decode_cpp_string(__pyx_t_3, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 806, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_decode_cpp_string(__pyx_t_3, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 798, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_6 = NULL;
   if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
@@ -14809,7 +14729,7 @@ static int __pyx_pf_6libzim_7Archive___cinit__(struct __pyx_obj_6libzim_Archive
   __pyx_t_2 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_5, __pyx_t_6, __pyx_t_1) : __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_1);
   __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 806, __pyx_L1_error)
+  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 798, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __Pyx_GIVEREF(__pyx_t_2);
@@ -14818,7 +14738,7 @@ static int __pyx_pf_6libzim_7Archive___cinit__(struct __pyx_obj_6libzim_Archive
   __pyx_v_self->_filename = __pyx_t_2;
   __pyx_t_2 = 0;
 
-  /* "libzim.pyx":797
+  /* "libzim.pyx":789
  *     cdef object _filename
  * 
  *     def __cinit__(self, object filename: pathlib.Path):             # <<<<<<<<<<<<<<
@@ -14841,7 +14761,7 @@ static int __pyx_pf_6libzim_7Archive___cinit__(struct __pyx_obj_6libzim_Archive
   return __pyx_r;
 }
 
-/* "libzim.pyx":808
+/* "libzim.pyx":800
  *         self._filename = pathlib.Path(self.c_archive.getFilename().decode("UTF-8", "strict"))
  * 
  *     def __eq__(self, other) -> pybool:             # <<<<<<<<<<<<<<
@@ -14882,14 +14802,14 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__eq__", 0);
 
-  /* "libzim.pyx":809
+  /* "libzim.pyx":801
  * 
  *     def __eq__(self, other) -> pybool:
  *         if Archive not in type(self).mro() or Archive not in type(other).mro():             # <<<<<<<<<<<<<<
  *             return False
  *         try:
  */
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))), __pyx_n_s_mro); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 809, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))), __pyx_n_s_mro); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 801, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
@@ -14903,10 +14823,10 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
   }
   __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 809, __pyx_L1_error)
+  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 801, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_5 = (__Pyx_PySequence_ContainsTF(((PyObject *)__pyx_ptype_6libzim_Archive), __pyx_t_2, Py_NE)); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 809, __pyx_L1_error)
+  __pyx_t_5 = (__Pyx_PySequence_ContainsTF(((PyObject *)__pyx_ptype_6libzim_Archive), __pyx_t_2, Py_NE)); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 801, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_t_6 = (__pyx_t_5 != 0);
   if (!__pyx_t_6) {
@@ -14914,7 +14834,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
     __pyx_t_1 = __pyx_t_6;
     goto __pyx_L4_bool_binop_done;
   }
-  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)Py_TYPE(__pyx_v_other)), __pyx_n_s_mro); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 809, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)Py_TYPE(__pyx_v_other)), __pyx_n_s_mro); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 801, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __pyx_t_4 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
@@ -14928,17 +14848,17 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
   }
   __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 809, __pyx_L1_error)
+  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 801, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_6 = (__Pyx_PySequence_ContainsTF(((PyObject *)__pyx_ptype_6libzim_Archive), __pyx_t_2, Py_NE)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 809, __pyx_L1_error)
+  __pyx_t_6 = (__Pyx_PySequence_ContainsTF(((PyObject *)__pyx_ptype_6libzim_Archive), __pyx_t_2, Py_NE)); if (unlikely(__pyx_t_6 < 0)) __PYX_ERR(0, 801, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_t_5 = (__pyx_t_6 != 0);
   __pyx_t_1 = __pyx_t_5;
   __pyx_L4_bool_binop_done:;
   if (__pyx_t_1) {
 
-    /* "libzim.pyx":810
+    /* "libzim.pyx":802
  *     def __eq__(self, other) -> pybool:
  *         if Archive not in type(self).mro() or Archive not in type(other).mro():
  *             return False             # <<<<<<<<<<<<<<
@@ -14950,7 +14870,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
     __pyx_r = Py_False;
     goto __pyx_L0;
 
-    /* "libzim.pyx":809
+    /* "libzim.pyx":801
  * 
  *     def __eq__(self, other) -> pybool:
  *         if Archive not in type(self).mro() or Archive not in type(other).mro():             # <<<<<<<<<<<<<<
@@ -14959,7 +14879,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
  */
   }
 
-  /* "libzim.pyx":811
+  /* "libzim.pyx":803
  *         if Archive not in type(self).mro() or Archive not in type(other).mro():
  *             return False
  *         try:             # <<<<<<<<<<<<<<
@@ -14975,7 +14895,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
     __Pyx_XGOTREF(__pyx_t_9);
     /*try:*/ {
 
-      /* "libzim.pyx":812
+      /* "libzim.pyx":804
  *             return False
  *         try:
  *             return self.filename.expanduser().resolve() == other.filename.expanduser().resolve()             # <<<<<<<<<<<<<<
@@ -14983,9 +14903,9 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
  *             return False
  */
       __Pyx_XDECREF(__pyx_r);
-      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_filename); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 812, __pyx_L6_error)
+      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_filename); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 804, __pyx_L6_error)
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_expanduser); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 812, __pyx_L6_error)
+      __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_expanduser); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 804, __pyx_L6_error)
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_t_4 = NULL;
@@ -15000,10 +14920,10 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
       }
       __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_10);
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 812, __pyx_L6_error)
+      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 804, __pyx_L6_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-      __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_resolve); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 812, __pyx_L6_error)
+      __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_resolve); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 804, __pyx_L6_error)
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __pyx_t_3 = NULL;
@@ -15018,12 +14938,12 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
       }
       __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_10);
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 812, __pyx_L6_error)
+      if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 804, __pyx_L6_error)
       __Pyx_GOTREF(__pyx_t_2);
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_other, __pyx_n_s_filename); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 812, __pyx_L6_error)
+      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_other, __pyx_n_s_filename); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 804, __pyx_L6_error)
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_expanduser); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 812, __pyx_L6_error)
+      __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_expanduser); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 804, __pyx_L6_error)
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       __pyx_t_4 = NULL;
@@ -15038,10 +14958,10 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
       }
       __pyx_t_3 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_11, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_11);
       __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 812, __pyx_L6_error)
+      if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 804, __pyx_L6_error)
       __Pyx_GOTREF(__pyx_t_3);
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-      __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_resolve); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 812, __pyx_L6_error)
+      __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_resolve); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 804, __pyx_L6_error)
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
       __pyx_t_3 = NULL;
@@ -15056,17 +14976,17 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
       }
       __pyx_t_10 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_11, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_11);
       __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 812, __pyx_L6_error)
+      if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 804, __pyx_L6_error)
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-      __pyx_t_11 = PyObject_RichCompare(__pyx_t_2, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_11); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 812, __pyx_L6_error)
+      __pyx_t_11 = PyObject_RichCompare(__pyx_t_2, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_11); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 804, __pyx_L6_error)
       __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
       __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
       __pyx_r = __pyx_t_11;
       __pyx_t_11 = 0;
       goto __pyx_L10_try_return;
 
-      /* "libzim.pyx":811
+      /* "libzim.pyx":803
  *         if Archive not in type(self).mro() or Archive not in type(other).mro():
  *             return False
  *         try:             # <<<<<<<<<<<<<<
@@ -15081,7 +15001,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
     __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "libzim.pyx":813
+    /* "libzim.pyx":805
  *         try:
  *             return self.filename.expanduser().resolve() == other.filename.expanduser().resolve()
  *         except Exception:             # <<<<<<<<<<<<<<
@@ -15091,12 +15011,12 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
     __pyx_t_12 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(&((PyTypeObject*)PyExc_Exception)[0])));
     if (__pyx_t_12) {
       __Pyx_AddTraceback("libzim.Archive.__eq__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_11, &__pyx_t_10, &__pyx_t_2) < 0) __PYX_ERR(0, 813, __pyx_L8_except_error)
+      if (__Pyx_GetException(&__pyx_t_11, &__pyx_t_10, &__pyx_t_2) < 0) __PYX_ERR(0, 805, __pyx_L8_except_error)
       __Pyx_GOTREF(__pyx_t_11);
       __Pyx_GOTREF(__pyx_t_10);
       __Pyx_GOTREF(__pyx_t_2);
 
-      /* "libzim.pyx":814
+      /* "libzim.pyx":806
  *             return self.filename.expanduser().resolve() == other.filename.expanduser().resolve()
  *         except Exception:
  *             return False             # <<<<<<<<<<<<<<
@@ -15114,7 +15034,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
     goto __pyx_L8_except_error;
     __pyx_L8_except_error:;
 
-    /* "libzim.pyx":811
+    /* "libzim.pyx":803
  *         if Archive not in type(self).mro() or Archive not in type(other).mro():
  *             return False
  *         try:             # <<<<<<<<<<<<<<
@@ -15140,7 +15060,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
     goto __pyx_L0;
   }
 
-  /* "libzim.pyx":808
+  /* "libzim.pyx":800
  *         self._filename = pathlib.Path(self.c_archive.getFilename().decode("UTF-8", "strict"))
  * 
  *     def __eq__(self, other) -> pybool:             # <<<<<<<<<<<<<<
@@ -15163,7 +15083,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_2__eq__(struct __pyx_obj_6libzim_Arch
   return __pyx_r;
 }
 
-/* "libzim.pyx":817
+/* "libzim.pyx":809
  * 
  *     @property
  *     def filename(self) -> pathlib.Path:             # <<<<<<<<<<<<<<
@@ -15189,7 +15109,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_8filename___get__(struct __pyx_obj_6l
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":818
+  /* "libzim.pyx":810
  *     @property
  *     def filename(self) -> pathlib.Path:
  *         return self._filename             # <<<<<<<<<<<<<<
@@ -15201,7 +15121,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_8filename___get__(struct __pyx_obj_6l
   __pyx_r = __pyx_v_self->_filename;
   goto __pyx_L0;
 
-  /* "libzim.pyx":817
+  /* "libzim.pyx":809
  * 
  *     @property
  *     def filename(self) -> pathlib.Path:             # <<<<<<<<<<<<<<
@@ -15216,7 +15136,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_8filename___get__(struct __pyx_obj_6l
   return __pyx_r;
 }
 
-/* "libzim.pyx":821
+/* "libzim.pyx":813
  * 
  *     @property
  *     def filesize(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -15247,7 +15167,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_8filesize___get__(struct __pyx_obj_6l
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":823
+  /* "libzim.pyx":815
  *     def filesize(self) -> pyint:
  *         """Total size of ZIM file (or files if split"""
  *         return self.c_archive.getFilesize()             # <<<<<<<<<<<<<<
@@ -15259,15 +15179,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_8filesize___get__(struct __pyx_obj_6l
     __pyx_t_1 = __pyx_v_self->c_archive.getFilesize();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 823, __pyx_L1_error)
+    __PYX_ERR(0, 815, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 823, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 815, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":821
+  /* "libzim.pyx":813
  * 
  *     @property
  *     def filesize(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -15286,7 +15206,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_8filesize___get__(struct __pyx_obj_6l
   return __pyx_r;
 }
 
-/* "libzim.pyx":825
+/* "libzim.pyx":817
  *         return self.c_archive.getFilesize()
  * 
  *     def has_entry_by_path(self, path: str) -> pybool:             # <<<<<<<<<<<<<<
@@ -15304,7 +15224,7 @@ static PyObject *__pyx_pw_6libzim_7Archive_5has_entry_by_path(PyObject *__pyx_v_
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("has_entry_by_path (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_path), (&PyUnicode_Type), 1, "path", 1))) __PYX_ERR(0, 825, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_path), (&PyUnicode_Type), 1, "path", 1))) __PYX_ERR(0, 817, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_7Archive_4has_entry_by_path(((struct __pyx_obj_6libzim_Archive *)__pyx_v_self), ((PyObject*)__pyx_v_path));
 
   /* function exit code */
@@ -15327,7 +15247,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_4has_entry_by_path(struct __pyx_obj_6
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("has_entry_by_path", 0);
 
-  /* "libzim.pyx":827
+  /* "libzim.pyx":819
  *     def has_entry_by_path(self, path: str) -> pybool:
  *         """Whether Archive has an entry with this path"""
  *         return self.c_archive.hasEntryByPath(<string>path.encode('UTF-8'))             # <<<<<<<<<<<<<<
@@ -15337,25 +15257,25 @@ static PyObject *__pyx_pf_6libzim_7Archive_4has_entry_by_path(struct __pyx_obj_6
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(__pyx_v_path == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 827, __pyx_L1_error)
+    __PYX_ERR(0, 819, __pyx_L1_error)
   }
-  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_path); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 827, __pyx_L1_error)
+  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_path); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 819, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 827, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 819, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   try {
     __pyx_t_3 = __pyx_v_self->c_archive.hasEntryByPath(((std::string)__pyx_t_2));
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 827, __pyx_L1_error)
+    __PYX_ERR(0, 819, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 827, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 819, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":825
+  /* "libzim.pyx":817
  *         return self.c_archive.getFilesize()
  * 
  *     def has_entry_by_path(self, path: str) -> pybool:             # <<<<<<<<<<<<<<
@@ -15374,7 +15294,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_4has_entry_by_path(struct __pyx_obj_6
   return __pyx_r;
 }
 
-/* "libzim.pyx":829
+/* "libzim.pyx":821
  *         return self.c_archive.hasEntryByPath(<string>path.encode('UTF-8'))
  * 
  *     def get_entry_by_path(self, path: str) -> Entry:             # <<<<<<<<<<<<<<
@@ -15392,7 +15312,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pw_6libzim_7Archive_7get_entry_by_p
   struct __pyx_obj_6libzim_Entry *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("get_entry_by_path (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_path), (&PyUnicode_Type), 1, "path", 1))) __PYX_ERR(0, 829, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_path), (&PyUnicode_Type), 1, "path", 1))) __PYX_ERR(0, 821, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_7Archive_6get_entry_by_path(((struct __pyx_obj_6libzim_Archive *)__pyx_v_self), ((PyObject*)__pyx_v_path));
 
   /* function exit code */
@@ -15433,7 +15353,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_6get_entry_by_p
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_entry_by_path", 0);
 
-  /* "libzim.pyx":845
+  /* "libzim.pyx":837
  *                     If an entry with the provided path is not found in the archive"""
  *         cdef zim.Entry entry
  *         try:             # <<<<<<<<<<<<<<
@@ -15449,7 +15369,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_6get_entry_by_p
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "libzim.pyx":846
+      /* "libzim.pyx":838
  *         cdef zim.Entry entry
  *         try:
  *             entry = move(self.c_archive.getEntryByPath(<string>path.encode('UTF-8')))             # <<<<<<<<<<<<<<
@@ -15458,21 +15378,21 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_6get_entry_by_p
  */
       if (unlikely(__pyx_v_path == Py_None)) {
         PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-        __PYX_ERR(0, 846, __pyx_L3_error)
+        __PYX_ERR(0, 838, __pyx_L3_error)
       }
-      __pyx_t_4 = PyUnicode_AsUTF8String(__pyx_v_path); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 846, __pyx_L3_error)
+      __pyx_t_4 = PyUnicode_AsUTF8String(__pyx_v_path); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 838, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 846, __pyx_L3_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 838, __pyx_L3_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       try {
         __pyx_t_6 = __pyx_v_self->c_archive.getEntryByPath(((std::string)__pyx_t_5));
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 846, __pyx_L3_error)
+        __PYX_ERR(0, 838, __pyx_L3_error)
       }
       __pyx_v_entry = cython_std::move<wrapper::Entry>(__pyx_t_6);
 
-      /* "libzim.pyx":845
+      /* "libzim.pyx":837
  *                     If an entry with the provided path is not found in the archive"""
  *         cdef zim.Entry entry
  *         try:             # <<<<<<<<<<<<<<
@@ -15487,7 +15407,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_6get_entry_by_p
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "libzim.pyx":847
+    /* "libzim.pyx":839
  *         try:
  *             entry = move(self.c_archive.getEntryByPath(<string>path.encode('UTF-8')))
  *         except RuntimeError as e:             # <<<<<<<<<<<<<<
@@ -15497,7 +15417,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_6get_entry_by_p
     __pyx_t_7 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_RuntimeError);
     if (__pyx_t_7) {
       __Pyx_AddTraceback("libzim.Archive.get_entry_by_path", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_8, &__pyx_t_9) < 0) __PYX_ERR(0, 847, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_8, &__pyx_t_9) < 0) __PYX_ERR(0, 839, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_GOTREF(__pyx_t_9);
@@ -15505,24 +15425,24 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_6get_entry_by_p
       __pyx_v_e = __pyx_t_8;
       /*try:*/ {
 
-        /* "libzim.pyx":848
+        /* "libzim.pyx":840
  *             entry = move(self.c_archive.getEntryByPath(<string>path.encode('UTF-8')))
  *         except RuntimeError as e:
  *             raise KeyError(str(e))             # <<<<<<<<<<<<<<
  *         return Entry.from_entry(move(entry))
  * 
  */
-        __pyx_t_10 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_e); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 848, __pyx_L14_error)
+        __pyx_t_10 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_e); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 840, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_10);
-        __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 848, __pyx_L14_error)
+        __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 840, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_11);
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         __Pyx_Raise(__pyx_t_11, 0, 0, 0);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-        __PYX_ERR(0, 848, __pyx_L14_error)
+        __PYX_ERR(0, 840, __pyx_L14_error)
       }
 
-      /* "libzim.pyx":847
+      /* "libzim.pyx":839
  *         try:
  *             entry = move(self.c_archive.getEntryByPath(<string>path.encode('UTF-8')))
  *         except RuntimeError as e:             # <<<<<<<<<<<<<<
@@ -15569,7 +15489,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_6get_entry_by_p
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "libzim.pyx":845
+    /* "libzim.pyx":837
  *                     If an entry with the provided path is not found in the archive"""
  *         cdef zim.Entry entry
  *         try:             # <<<<<<<<<<<<<<
@@ -15584,7 +15504,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_6get_entry_by_p
     __pyx_L8_try_end:;
   }
 
-  /* "libzim.pyx":849
+  /* "libzim.pyx":841
  *         except RuntimeError as e:
  *             raise KeyError(str(e))
  *         return Entry.from_entry(move(entry))             # <<<<<<<<<<<<<<
@@ -15592,14 +15512,14 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_6get_entry_by_p
  *     def has_entry_by_title(self, title: str) -> pybool:
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_9 = __pyx_f_6libzim_5Entry_from_entry(cython_std::move<wrapper::Entry>(__pyx_v_entry)); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 849, __pyx_L1_error)
+  __pyx_t_9 = __pyx_f_6libzim_5Entry_from_entry(cython_std::move<wrapper::Entry>(__pyx_v_entry)); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 841, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_9);
-  if (!(likely(((__pyx_t_9) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_9, __pyx_ptype_6libzim_Entry))))) __PYX_ERR(0, 849, __pyx_L1_error)
+  if (!(likely(((__pyx_t_9) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_9, __pyx_ptype_6libzim_Entry))))) __PYX_ERR(0, 841, __pyx_L1_error)
   __pyx_r = ((struct __pyx_obj_6libzim_Entry *)__pyx_t_9);
   __pyx_t_9 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":829
+  /* "libzim.pyx":821
  *         return self.c_archive.hasEntryByPath(<string>path.encode('UTF-8'))
  * 
  *     def get_entry_by_path(self, path: str) -> Entry:             # <<<<<<<<<<<<<<
@@ -15623,7 +15543,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_6get_entry_by_p
   return __pyx_r;
 }
 
-/* "libzim.pyx":851
+/* "libzim.pyx":843
  *         return Entry.from_entry(move(entry))
  * 
  *     def has_entry_by_title(self, title: str) -> pybool:             # <<<<<<<<<<<<<<
@@ -15641,7 +15561,7 @@ static PyObject *__pyx_pw_6libzim_7Archive_9has_entry_by_title(PyObject *__pyx_v
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("has_entry_by_title (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_title), (&PyUnicode_Type), 1, "title", 1))) __PYX_ERR(0, 851, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_title), (&PyUnicode_Type), 1, "title", 1))) __PYX_ERR(0, 843, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_7Archive_8has_entry_by_title(((struct __pyx_obj_6libzim_Archive *)__pyx_v_self), ((PyObject*)__pyx_v_title));
 
   /* function exit code */
@@ -15664,7 +15584,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_8has_entry_by_title(struct __pyx_obj_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("has_entry_by_title", 0);
 
-  /* "libzim.pyx":855
+  /* "libzim.pyx":847
  * 
  *             Uses get_entry_by_title() so it's specificities apply as well"""
  *         return self.c_archive.hasEntryByTitle(<string>title.encode('UTF-8'))             # <<<<<<<<<<<<<<
@@ -15674,25 +15594,25 @@ static PyObject *__pyx_pf_6libzim_7Archive_8has_entry_by_title(struct __pyx_obj_
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(__pyx_v_title == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 855, __pyx_L1_error)
+    __PYX_ERR(0, 847, __pyx_L1_error)
   }
-  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_title); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 855, __pyx_L1_error)
+  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_title); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 847, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 855, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 847, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   try {
     __pyx_t_3 = __pyx_v_self->c_archive.hasEntryByTitle(((std::string)__pyx_t_2));
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 855, __pyx_L1_error)
+    __PYX_ERR(0, 847, __pyx_L1_error)
   }
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 855, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 847, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":851
+  /* "libzim.pyx":843
  *         return Entry.from_entry(move(entry))
  * 
  *     def has_entry_by_title(self, title: str) -> pybool:             # <<<<<<<<<<<<<<
@@ -15711,7 +15631,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_8has_entry_by_title(struct __pyx_obj_
   return __pyx_r;
 }
 
-/* "libzim.pyx":857
+/* "libzim.pyx":849
  *         return self.c_archive.hasEntryByTitle(<string>title.encode('UTF-8'))
  * 
  *     def get_entry_by_title(self, title: str) -> Entry:             # <<<<<<<<<<<<<<
@@ -15729,7 +15649,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pw_6libzim_7Archive_11get_entry_by_
   struct __pyx_obj_6libzim_Entry *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("get_entry_by_title (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_title), (&PyUnicode_Type), 1, "title", 1))) __PYX_ERR(0, 857, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_title), (&PyUnicode_Type), 1, "title", 1))) __PYX_ERR(0, 849, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_7Archive_10get_entry_by_title(((struct __pyx_obj_6libzim_Archive *)__pyx_v_self), ((PyObject*)__pyx_v_title));
 
   /* function exit code */
@@ -15770,7 +15690,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_10get_entry_by_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_entry_by_title", 0);
 
-  /* "libzim.pyx":878
+  /* "libzim.pyx":870
  *                     If an entry with the provided title is not found in the archive"""
  *         cdef zim.Entry entry
  *         try:             # <<<<<<<<<<<<<<
@@ -15786,7 +15706,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_10get_entry_by_
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "libzim.pyx":879
+      /* "libzim.pyx":871
  *         cdef zim.Entry entry
  *         try:
  *             entry = move(self.c_archive.getEntryByTitle(<string>title.encode('UTF-8')))             # <<<<<<<<<<<<<<
@@ -15795,21 +15715,21 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_10get_entry_by_
  */
       if (unlikely(__pyx_v_title == Py_None)) {
         PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-        __PYX_ERR(0, 879, __pyx_L3_error)
+        __PYX_ERR(0, 871, __pyx_L3_error)
       }
-      __pyx_t_4 = PyUnicode_AsUTF8String(__pyx_v_title); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 879, __pyx_L3_error)
+      __pyx_t_4 = PyUnicode_AsUTF8String(__pyx_v_title); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 871, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 879, __pyx_L3_error)
+      __pyx_t_5 = __pyx_convert_string_from_py_std__in_string(__pyx_t_4); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 871, __pyx_L3_error)
       __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
       try {
         __pyx_t_6 = __pyx_v_self->c_archive.getEntryByTitle(((std::string)__pyx_t_5));
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 879, __pyx_L3_error)
+        __PYX_ERR(0, 871, __pyx_L3_error)
       }
       __pyx_v_entry = cython_std::move<wrapper::Entry>(__pyx_t_6);
 
-      /* "libzim.pyx":878
+      /* "libzim.pyx":870
  *                     If an entry with the provided title is not found in the archive"""
  *         cdef zim.Entry entry
  *         try:             # <<<<<<<<<<<<<<
@@ -15824,7 +15744,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_10get_entry_by_
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-    /* "libzim.pyx":880
+    /* "libzim.pyx":872
  *         try:
  *             entry = move(self.c_archive.getEntryByTitle(<string>title.encode('UTF-8')))
  *         except RuntimeError as e:             # <<<<<<<<<<<<<<
@@ -15834,7 +15754,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_10get_entry_by_
     __pyx_t_7 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_RuntimeError);
     if (__pyx_t_7) {
       __Pyx_AddTraceback("libzim.Archive.get_entry_by_title", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_8, &__pyx_t_9) < 0) __PYX_ERR(0, 880, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_8, &__pyx_t_9) < 0) __PYX_ERR(0, 872, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_4);
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_GOTREF(__pyx_t_9);
@@ -15842,24 +15762,24 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_10get_entry_by_
       __pyx_v_e = __pyx_t_8;
       /*try:*/ {
 
-        /* "libzim.pyx":881
+        /* "libzim.pyx":873
  *             entry = move(self.c_archive.getEntryByTitle(<string>title.encode('UTF-8')))
  *         except RuntimeError as e:
  *             raise KeyError(str(e))             # <<<<<<<<<<<<<<
  *         return Entry.from_entry(move(entry))
  * 
  */
-        __pyx_t_10 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_e); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 881, __pyx_L14_error)
+        __pyx_t_10 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_e); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 873, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_10);
-        __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 881, __pyx_L14_error)
+        __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 873, __pyx_L14_error)
         __Pyx_GOTREF(__pyx_t_11);
         __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
         __Pyx_Raise(__pyx_t_11, 0, 0, 0);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-        __PYX_ERR(0, 881, __pyx_L14_error)
+        __PYX_ERR(0, 873, __pyx_L14_error)
       }
 
-      /* "libzim.pyx":880
+      /* "libzim.pyx":872
  *         try:
  *             entry = move(self.c_archive.getEntryByTitle(<string>title.encode('UTF-8')))
  *         except RuntimeError as e:             # <<<<<<<<<<<<<<
@@ -15906,7 +15826,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_10get_entry_by_
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "libzim.pyx":878
+    /* "libzim.pyx":870
  *                     If an entry with the provided title is not found in the archive"""
  *         cdef zim.Entry entry
  *         try:             # <<<<<<<<<<<<<<
@@ -15921,7 +15841,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_10get_entry_by_
     __pyx_L8_try_end:;
   }
 
-  /* "libzim.pyx":882
+  /* "libzim.pyx":874
  *         except RuntimeError as e:
  *             raise KeyError(str(e))
  *         return Entry.from_entry(move(entry))             # <<<<<<<<<<<<<<
@@ -15929,14 +15849,14 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_10get_entry_by_
  *     @property
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_9 = __pyx_f_6libzim_5Entry_from_entry(cython_std::move<wrapper::Entry>(__pyx_v_entry)); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 882, __pyx_L1_error)
+  __pyx_t_9 = __pyx_f_6libzim_5Entry_from_entry(cython_std::move<wrapper::Entry>(__pyx_v_entry)); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 874, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_9);
-  if (!(likely(((__pyx_t_9) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_9, __pyx_ptype_6libzim_Entry))))) __PYX_ERR(0, 882, __pyx_L1_error)
+  if (!(likely(((__pyx_t_9) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_9, __pyx_ptype_6libzim_Entry))))) __PYX_ERR(0, 874, __pyx_L1_error)
   __pyx_r = ((struct __pyx_obj_6libzim_Entry *)__pyx_t_9);
   __pyx_t_9 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":857
+  /* "libzim.pyx":849
  *         return self.c_archive.hasEntryByTitle(<string>title.encode('UTF-8'))
  * 
  *     def get_entry_by_title(self, title: str) -> Entry:             # <<<<<<<<<<<<<<
@@ -15960,7 +15880,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_10get_entry_by_
   return __pyx_r;
 }
 
-/* "libzim.pyx":885
+/* "libzim.pyx":877
  * 
  *     @property
  *     def metadata_keys(self) -> List[str]:             # <<<<<<<<<<<<<<
@@ -15996,7 +15916,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_13metadata_keys___get__(struct __pyx_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":887
+  /* "libzim.pyx":879
  *     def metadata_keys(self) -> List[str]:
  *         """List of Metadata keys present in this archive"""
  *         return [key.decode("UTF-8", "strict") for key in self.c_archive.getMetadataKeys()]             # <<<<<<<<<<<<<<
@@ -16005,13 +15925,13 @@ static PyObject *__pyx_pf_6libzim_7Archive_13metadata_keys___get__(struct __pyx_
  */
   __Pyx_XDECREF(__pyx_r);
   { /* enter inner scope */
-    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 887, __pyx_L1_error)
+    __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 879, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_1);
     try {
       __pyx_t_2 = __pyx_v_self->c_archive.getMetadataKeys();
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 887, __pyx_L1_error)
+      __PYX_ERR(0, 879, __pyx_L1_error)
     }
     __pyx_t_4 = &__pyx_t_2;
     __pyx_t_3 = __pyx_t_4->begin();
@@ -16020,9 +15940,9 @@ static PyObject *__pyx_pf_6libzim_7Archive_13metadata_keys___get__(struct __pyx_
       __pyx_t_5 = *__pyx_t_3;
       ++__pyx_t_3;
       __pyx_8genexpr1__pyx_v_key = __pyx_t_5;
-      __pyx_t_6 = __Pyx_decode_cpp_string(__pyx_8genexpr1__pyx_v_key, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 887, __pyx_L1_error)
+      __pyx_t_6 = __Pyx_decode_cpp_string(__pyx_8genexpr1__pyx_v_key, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 879, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_6);
-      if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_6))) __PYX_ERR(0, 887, __pyx_L1_error)
+      if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_6))) __PYX_ERR(0, 879, __pyx_L1_error)
       __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
     }
   } /* exit inner scope */
@@ -16030,7 +15950,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_13metadata_keys___get__(struct __pyx_
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":885
+  /* "libzim.pyx":877
  * 
  *     @property
  *     def metadata_keys(self) -> List[str]:             # <<<<<<<<<<<<<<
@@ -16050,7 +15970,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_13metadata_keys___get__(struct __pyx_
   return __pyx_r;
 }
 
-/* "libzim.pyx":889
+/* "libzim.pyx":881
  *         return [key.decode("UTF-8", "strict") for key in self.c_archive.getMetadataKeys()]
  * 
  *     def get_metadata_item(self, name: str) -> Item:             # <<<<<<<<<<<<<<
@@ -16068,7 +15988,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pw_6libzim_7Archive_13get_metadata_i
   struct __pyx_obj_6libzim_Item *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("get_metadata_item (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_name), (&PyUnicode_Type), 1, "name", 1))) __PYX_ERR(0, 889, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_name), (&PyUnicode_Type), 1, "name", 1))) __PYX_ERR(0, 881, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_7Archive_12get_metadata_item(((struct __pyx_obj_6libzim_Archive *)__pyx_v_self), ((PyObject*)__pyx_v_name));
 
   /* function exit code */
@@ -16092,7 +16012,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_12get_metadata_i
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_metadata_item", 0);
 
-  /* "libzim.pyx":891
+  /* "libzim.pyx":883
  *     def get_metadata_item(self, name: str) -> Item:
  *         """A Metadata's Item"""
  *         cdef zim.Item item = move(self.c_archive.getMetadataItem(name.encode('UTF-8')))             # <<<<<<<<<<<<<<
@@ -16101,21 +16021,21 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_12get_metadata_i
  */
   if (unlikely(__pyx_v_name == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 891, __pyx_L1_error)
+    __PYX_ERR(0, 883, __pyx_L1_error)
   }
-  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 891, __pyx_L1_error)
+  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 883, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 891, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 883, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   try {
     __pyx_t_3 = __pyx_v_self->c_archive.getMetadataItem(__pyx_t_2);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 891, __pyx_L1_error)
+    __PYX_ERR(0, 883, __pyx_L1_error)
   }
   __pyx_v_item = cython_std::move<wrapper::Item>(__pyx_t_3);
 
-  /* "libzim.pyx":892
+  /* "libzim.pyx":884
  *         """A Metadata's Item"""
  *         cdef zim.Item item = move(self.c_archive.getMetadataItem(name.encode('UTF-8')))
  *         return Item.from_item(move(item))             # <<<<<<<<<<<<<<
@@ -16123,14 +16043,14 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_12get_metadata_i
  *     def get_metadata(self, name: str) -> bytes:
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __pyx_f_6libzim_4Item_from_item(cython_std::move<wrapper::Item>(__pyx_v_item)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 892, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_6libzim_4Item_from_item(cython_std::move<wrapper::Item>(__pyx_v_item)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 884, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_6libzim_Item))))) __PYX_ERR(0, 892, __pyx_L1_error)
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_6libzim_Item))))) __PYX_ERR(0, 884, __pyx_L1_error)
   __pyx_r = ((struct __pyx_obj_6libzim_Item *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":889
+  /* "libzim.pyx":881
  *         return [key.decode("UTF-8", "strict") for key in self.c_archive.getMetadataKeys()]
  * 
  *     def get_metadata_item(self, name: str) -> Item:             # <<<<<<<<<<<<<<
@@ -16149,7 +16069,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_12get_metadata_i
   return __pyx_r;
 }
 
-/* "libzim.pyx":894
+/* "libzim.pyx":886
  *         return Item.from_item(move(item))
  * 
  *     def get_metadata(self, name: str) -> bytes:             # <<<<<<<<<<<<<<
@@ -16167,7 +16087,7 @@ static PyObject *__pyx_pw_6libzim_7Archive_15get_metadata(PyObject *__pyx_v_self
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("get_metadata (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_name), (&PyUnicode_Type), 1, "name", 1))) __PYX_ERR(0, 894, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_name), (&PyUnicode_Type), 1, "name", 1))) __PYX_ERR(0, 886, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_7Archive_14get_metadata(((struct __pyx_obj_6libzim_Archive *)__pyx_v_self), ((PyObject*)__pyx_v_name));
 
   /* function exit code */
@@ -16191,7 +16111,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_14get_metadata(struct __pyx_obj_6libz
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_metadata", 0);
 
-  /* "libzim.pyx":905
+  /* "libzim.pyx":897
  *             bytes
  *                 Metadata entry's content. Can be of any type."""
  *         return bytes(self.c_archive.getMetadata(name.encode('UTF-8')))             # <<<<<<<<<<<<<<
@@ -16201,28 +16121,28 @@ static PyObject *__pyx_pf_6libzim_7Archive_14get_metadata(struct __pyx_obj_6libz
   __Pyx_XDECREF(__pyx_r);
   if (unlikely(__pyx_v_name == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 905, __pyx_L1_error)
+    __PYX_ERR(0, 897, __pyx_L1_error)
   }
-  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 905, __pyx_L1_error)
+  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 897, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 905, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 897, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   try {
     __pyx_t_3 = __pyx_v_self->c_archive.getMetadata(__pyx_t_2);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 905, __pyx_L1_error)
+    __PYX_ERR(0, 897, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 905, __pyx_L1_error)
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 897, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyBytes_Type)), __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 905, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyBytes_Type)), __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 897, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = ((PyObject*)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":894
+  /* "libzim.pyx":886
  *         return Item.from_item(move(item))
  * 
  *     def get_metadata(self, name: str) -> bytes:             # <<<<<<<<<<<<<<
@@ -16242,7 +16162,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_14get_metadata(struct __pyx_obj_6libz
   return __pyx_r;
 }
 
-/* "libzim.pyx":907
+/* "libzim.pyx":899
  *         return bytes(self.c_archive.getMetadata(name.encode('UTF-8')))
  * 
  *     def _get_entry_by_id(self, entry_id: pyint) -> Entry:             # <<<<<<<<<<<<<<
@@ -16276,23 +16196,23 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_16_get_entry_by
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("_get_entry_by_id", 0);
 
-  /* "libzim.pyx":909
+  /* "libzim.pyx":901
  *     def _get_entry_by_id(self, entry_id: pyint) -> Entry:
  *         """Entry from an entry Id"""
  *         cdef zim.Entry entry = move(self.c_archive.getEntryByPath(<zim.entry_index_type>entry_id))             # <<<<<<<<<<<<<<
  *         return Entry.from_entry(move(entry))
  * 
  */
-  __pyx_t_1 = __Pyx_PyInt_As_uint32_t(__pyx_v_entry_id); if (unlikely((__pyx_t_1 == ((zim::entry_index_type)-1)) && PyErr_Occurred())) __PYX_ERR(0, 909, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_As_uint32_t(__pyx_v_entry_id); if (unlikely((__pyx_t_1 == ((zim::entry_index_type)-1)) && PyErr_Occurred())) __PYX_ERR(0, 901, __pyx_L1_error)
   try {
     __pyx_t_2 = __pyx_v_self->c_archive.getEntryByPath(((zim::entry_index_type)__pyx_t_1));
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 909, __pyx_L1_error)
+    __PYX_ERR(0, 901, __pyx_L1_error)
   }
   __pyx_v_entry = cython_std::move<wrapper::Entry>(__pyx_t_2);
 
-  /* "libzim.pyx":910
+  /* "libzim.pyx":902
  *         """Entry from an entry Id"""
  *         cdef zim.Entry entry = move(self.c_archive.getEntryByPath(<zim.entry_index_type>entry_id))
  *         return Entry.from_entry(move(entry))             # <<<<<<<<<<<<<<
@@ -16300,14 +16220,14 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_16_get_entry_by
  *     @property
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_3 = __pyx_f_6libzim_5Entry_from_entry(cython_std::move<wrapper::Entry>(__pyx_v_entry)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 910, __pyx_L1_error)
+  __pyx_t_3 = __pyx_f_6libzim_5Entry_from_entry(cython_std::move<wrapper::Entry>(__pyx_v_entry)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 902, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_6libzim_Entry))))) __PYX_ERR(0, 910, __pyx_L1_error)
+  if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_6libzim_Entry))))) __PYX_ERR(0, 902, __pyx_L1_error)
   __pyx_r = ((struct __pyx_obj_6libzim_Entry *)__pyx_t_3);
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":907
+  /* "libzim.pyx":899
  *         return bytes(self.c_archive.getMetadata(name.encode('UTF-8')))
  * 
  *     def _get_entry_by_id(self, entry_id: pyint) -> Entry:             # <<<<<<<<<<<<<<
@@ -16326,7 +16246,7 @@ static struct __pyx_obj_6libzim_Entry *__pyx_pf_6libzim_7Archive_16_get_entry_by
   return __pyx_r;
 }
 
-/* "libzim.pyx":913
+/* "libzim.pyx":905
  * 
  *     @property
  *     def has_main_entry(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -16357,7 +16277,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_14has_main_entry___get__(struct __pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":915
+  /* "libzim.pyx":907
  *     def has_main_entry(self) -> pybool:
  *         """Whether Archive has a Main Entry set"""
  *         return self.c_archive.hasMainEntry()             # <<<<<<<<<<<<<<
@@ -16369,15 +16289,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_14has_main_entry___get__(struct __pyx
     __pyx_t_1 = __pyx_v_self->c_archive.hasMainEntry();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 915, __pyx_L1_error)
+    __PYX_ERR(0, 907, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 915, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 907, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":913
+  /* "libzim.pyx":905
  * 
  *     @property
  *     def has_main_entry(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -16396,7 +16316,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_14has_main_entry___get__(struct __pyx
   return __pyx_r;
 }
 
-/* "libzim.pyx":918
+/* "libzim.pyx":910
  * 
  *     @property
  *     def main_entry(self) -> Entry:             # <<<<<<<<<<<<<<
@@ -16427,7 +16347,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_10main_entry___get__(struct __pyx_obj
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":920
+  /* "libzim.pyx":912
  *     def main_entry(self) -> Entry:
  *         """Main Entry of the Archive"""
  *         return Entry.from_entry(move(self.c_archive.getMainEntry()))             # <<<<<<<<<<<<<<
@@ -16439,15 +16359,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_10main_entry___get__(struct __pyx_obj
     __pyx_t_1 = __pyx_v_self->c_archive.getMainEntry();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 920, __pyx_L1_error)
+    __PYX_ERR(0, 912, __pyx_L1_error)
   }
-  __pyx_t_2 = __pyx_f_6libzim_5Entry_from_entry(cython_std::move<wrapper::Entry>(__pyx_t_1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 920, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_6libzim_5Entry_from_entry(cython_std::move<wrapper::Entry>(__pyx_t_1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 912, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":918
+  /* "libzim.pyx":910
  * 
  *     @property
  *     def main_entry(self) -> Entry:             # <<<<<<<<<<<<<<
@@ -16466,7 +16386,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_10main_entry___get__(struct __pyx_obj
   return __pyx_r;
 }
 
-/* "libzim.pyx":923
+/* "libzim.pyx":915
  * 
  *     @property
  *     def uuid(self) -> UUID:             # <<<<<<<<<<<<<<
@@ -16501,7 +16421,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_4uuid___get__(struct __pyx_obj_6libzi
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":925
+  /* "libzim.pyx":917
  *     def uuid(self) -> UUID:
  *         """Archive UUID"""
  *         return UUID(self.c_archive.getUuid().hex())             # <<<<<<<<<<<<<<
@@ -16509,17 +16429,17 @@ static PyObject *__pyx_pf_6libzim_7Archive_4uuid___get__(struct __pyx_obj_6libzi
  *     @property
  */
   __Pyx_XDECREF(__pyx_r);
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_UUID); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 925, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_UUID); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 917, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   try {
     __pyx_t_4 = __pyx_v_self->c_archive.getUuid();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 925, __pyx_L1_error)
+    __PYX_ERR(0, 917, __pyx_L1_error)
   }
-  __pyx_t_5 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 925, __pyx_L1_error)
+  __pyx_t_5 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 917, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_hex); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 925, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_hex); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 917, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_5 = NULL;
@@ -16534,7 +16454,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_4uuid___get__(struct __pyx_obj_6libzi
   }
   __pyx_t_3 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_6);
   __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 925, __pyx_L1_error)
+  if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 917, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
   __pyx_t_6 = NULL;
@@ -16550,14 +16470,14 @@ static PyObject *__pyx_pf_6libzim_7Archive_4uuid___get__(struct __pyx_obj_6libzi
   __pyx_t_1 = (__pyx_t_6) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_6, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
   __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 925, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 917, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":923
+  /* "libzim.pyx":915
  * 
  *     @property
  *     def uuid(self) -> UUID:             # <<<<<<<<<<<<<<
@@ -16580,7 +16500,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_4uuid___get__(struct __pyx_obj_6libzi
   return __pyx_r;
 }
 
-/* "libzim.pyx":928
+/* "libzim.pyx":920
  * 
  *     @property
  *     def has_new_namespace_scheme(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -16611,7 +16531,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_24has_new_namespace_scheme___get__(st
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":930
+  /* "libzim.pyx":922
  *     def has_new_namespace_scheme(self) -> pybool:
  *         """Whether Archive is using new namespaceless namespace scheme"""
  *         return self.c_archive.hasNewNamespaceScheme()             # <<<<<<<<<<<<<<
@@ -16623,15 +16543,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_24has_new_namespace_scheme___get__(st
     __pyx_t_1 = __pyx_v_self->c_archive.hasNewNamespaceScheme();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 930, __pyx_L1_error)
+    __PYX_ERR(0, 922, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 930, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 922, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":928
+  /* "libzim.pyx":920
  * 
  *     @property
  *     def has_new_namespace_scheme(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -16650,7 +16570,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_24has_new_namespace_scheme___get__(st
   return __pyx_r;
 }
 
-/* "libzim.pyx":933
+/* "libzim.pyx":925
  * 
  *     @property
  *     def is_multipart(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -16681,7 +16601,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_12is_multipart___get__(struct __pyx_o
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":935
+  /* "libzim.pyx":927
  *     def is_multipart(self) -> pybool:
  *         """Whether Archive is multipart (split over multiple files)"""
  *         return self.c_archive.isMultiPart()             # <<<<<<<<<<<<<<
@@ -16693,15 +16613,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_12is_multipart___get__(struct __pyx_o
     __pyx_t_1 = __pyx_v_self->c_archive.isMultiPart();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 935, __pyx_L1_error)
+    __PYX_ERR(0, 927, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 935, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 927, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":933
+  /* "libzim.pyx":925
  * 
  *     @property
  *     def is_multipart(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -16720,7 +16640,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_12is_multipart___get__(struct __pyx_o
   return __pyx_r;
 }
 
-/* "libzim.pyx":938
+/* "libzim.pyx":930
  * 
  *     @property
  *     def has_fulltext_index(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -16751,7 +16671,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_18has_fulltext_index___get__(struct _
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":940
+  /* "libzim.pyx":932
  *     def has_fulltext_index(self) -> pybool:
  *         """Whether Archive includes a full-text index"""
  *         return self.c_archive.hasFulltextIndex()             # <<<<<<<<<<<<<<
@@ -16763,15 +16683,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_18has_fulltext_index___get__(struct _
     __pyx_t_1 = __pyx_v_self->c_archive.hasFulltextIndex();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 940, __pyx_L1_error)
+    __PYX_ERR(0, 932, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 940, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 932, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":938
+  /* "libzim.pyx":930
  * 
  *     @property
  *     def has_fulltext_index(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -16790,7 +16710,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_18has_fulltext_index___get__(struct _
   return __pyx_r;
 }
 
-/* "libzim.pyx":943
+/* "libzim.pyx":935
  * 
  *     @property
  *     def has_title_index(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -16821,7 +16741,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_15has_title_index___get__(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":945
+  /* "libzim.pyx":937
  *     def has_title_index(self) -> pybool:
  *         """Whether Archive includes a Title index"""
  *         return self.c_archive.hasTitleIndex()             # <<<<<<<<<<<<<<
@@ -16833,15 +16753,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_15has_title_index___get__(struct __py
     __pyx_t_1 = __pyx_v_self->c_archive.hasTitleIndex();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 945, __pyx_L1_error)
+    __PYX_ERR(0, 937, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 945, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 937, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":943
+  /* "libzim.pyx":935
  * 
  *     @property
  *     def has_title_index(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -16860,7 +16780,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_15has_title_index___get__(struct __py
   return __pyx_r;
 }
 
-/* "libzim.pyx":948
+/* "libzim.pyx":940
  * 
  *     @property
  *     def has_checksum(self) -> str:             # <<<<<<<<<<<<<<
@@ -16891,7 +16811,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_12has_checksum___get__(struct __pyx_o
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":950
+  /* "libzim.pyx":942
  *     def has_checksum(self) -> str:
  *         """Whether Archive includes a checksum of its content"""
  *         return self.c_archive.hasChecksum()             # <<<<<<<<<<<<<<
@@ -16903,15 +16823,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_12has_checksum___get__(struct __pyx_o
     __pyx_t_1 = __pyx_v_self->c_archive.hasChecksum();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 950, __pyx_L1_error)
+    __PYX_ERR(0, 942, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 950, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 942, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":948
+  /* "libzim.pyx":940
  * 
  *     @property
  *     def has_checksum(self) -> str:             # <<<<<<<<<<<<<<
@@ -16930,7 +16850,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_12has_checksum___get__(struct __pyx_o
   return __pyx_r;
 }
 
-/* "libzim.pyx":953
+/* "libzim.pyx":945
  * 
  *     @property
  *     def checksum(self) -> str:             # <<<<<<<<<<<<<<
@@ -16961,7 +16881,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_8checksum___get__(struct __pyx_obj_6l
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":955
+  /* "libzim.pyx":947
  *     def checksum(self) -> str:
  *         """Archive's checksum"""
  *         return self.c_archive.getChecksum().decode("UTF-8", "strict")             # <<<<<<<<<<<<<<
@@ -16973,15 +16893,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_8checksum___get__(struct __pyx_obj_6l
     __pyx_t_1 = __pyx_v_self->c_archive.getChecksum();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 955, __pyx_L1_error)
+    __PYX_ERR(0, 947, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_1, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 955, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_t_1, 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 947, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":953
+  /* "libzim.pyx":945
  * 
  *     @property
  *     def checksum(self) -> str:             # <<<<<<<<<<<<<<
@@ -17000,7 +16920,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_8checksum___get__(struct __pyx_obj_6l
   return __pyx_r;
 }
 
-/* "libzim.pyx":957
+/* "libzim.pyx":949
  *         return self.c_archive.getChecksum().decode("UTF-8", "strict")
  * 
  *     def check(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -17032,7 +16952,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_18check(struct __pyx_obj_6libzim_Arch
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("check", 0);
 
-  /* "libzim.pyx":959
+  /* "libzim.pyx":951
  *     def check(self) -> pybool:
  *         """Whether Archive has a checksum and file verifies it"""
  *         return self.c_archive.check()             # <<<<<<<<<<<<<<
@@ -17044,15 +16964,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_18check(struct __pyx_obj_6libzim_Arch
     __pyx_t_1 = __pyx_v_self->c_archive.check();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 959, __pyx_L1_error)
+    __PYX_ERR(0, 951, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 959, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 951, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":957
+  /* "libzim.pyx":949
  *         return self.c_archive.getChecksum().decode("UTF-8", "strict")
  * 
  *     def check(self) -> pybool:             # <<<<<<<<<<<<<<
@@ -17071,7 +16991,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_18check(struct __pyx_obj_6libzim_Arch
   return __pyx_r;
 }
 
-/* "libzim.pyx":962
+/* "libzim.pyx":954
  * 
  *     @property
  *     def entry_count(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -17102,7 +17022,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_11entry_count___get__(struct __pyx_ob
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":967
+  /* "libzim.pyx":959
  *             If Archive doesn't support user entries
  *             then this returns `all_entry_count`"""
  *         return self.c_archive.getEntryCount()             # <<<<<<<<<<<<<<
@@ -17114,15 +17034,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_11entry_count___get__(struct __pyx_ob
     __pyx_t_1 = __pyx_v_self->c_archive.getEntryCount();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 967, __pyx_L1_error)
+    __PYX_ERR(0, 959, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 967, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 959, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":962
+  /* "libzim.pyx":954
  * 
  *     @property
  *     def entry_count(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -17141,7 +17061,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_11entry_count___get__(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "libzim.pyx":970
+/* "libzim.pyx":962
  * 
  *     @property
  *     def all_entry_count(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -17172,7 +17092,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_15all_entry_count___get__(struct __py
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":975
+  /* "libzim.pyx":967
  *             Total number of entries in the archive, including internal entries
  *             created by libzim itself, metadata, indexes, etc."""
  *         return self.c_archive.getAllEntryCount()             # <<<<<<<<<<<<<<
@@ -17184,15 +17104,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_15all_entry_count___get__(struct __py
     __pyx_t_1 = __pyx_v_self->c_archive.getAllEntryCount();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 975, __pyx_L1_error)
+    __PYX_ERR(0, 967, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 975, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 967, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":970
+  /* "libzim.pyx":962
  * 
  *     @property
  *     def all_entry_count(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -17211,7 +17131,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_15all_entry_count___get__(struct __py
   return __pyx_r;
 }
 
-/* "libzim.pyx":978
+/* "libzim.pyx":970
  * 
  *     @property
  *     def article_count(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -17242,7 +17162,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_13article_count___get__(struct __pyx_
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":988
+  /* "libzim.pyx":980
  *             Note: a few ZIM created during transition might have new scheme but no
  *             listing, resulting in this returning all entries."""
  *         return self.c_archive.getArticleCount()             # <<<<<<<<<<<<<<
@@ -17254,15 +17174,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_13article_count___get__(struct __pyx_
     __pyx_t_1 = __pyx_v_self->c_archive.getArticleCount();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 988, __pyx_L1_error)
+    __PYX_ERR(0, 980, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 988, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 980, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":978
+  /* "libzim.pyx":970
  * 
  *     @property
  *     def article_count(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -17281,7 +17201,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_13article_count___get__(struct __pyx_
   return __pyx_r;
 }
 
-/* "libzim.pyx":991
+/* "libzim.pyx":983
  * 
  *     @property
  *     def media_count(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -17312,7 +17232,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_11media_count___get__(struct __pyx_ob
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__get__", 0);
 
-  /* "libzim.pyx":995
+  /* "libzim.pyx":987
  * 
  *             This definition of "media" is based on the mimetype."""
  *         return self.c_archive.getMediaCount()             # <<<<<<<<<<<<<<
@@ -17324,15 +17244,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_11media_count___get__(struct __pyx_ob
     __pyx_t_1 = __pyx_v_self->c_archive.getMediaCount();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 995, __pyx_L1_error)
+    __PYX_ERR(0, 987, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 995, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_uint64_t(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 987, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":991
+  /* "libzim.pyx":983
  * 
  *     @property
  *     def media_count(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -17351,7 +17271,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_11media_count___get__(struct __pyx_ob
   return __pyx_r;
 }
 
-/* "libzim.pyx":997
+/* "libzim.pyx":989
  *         return self.c_archive.getMediaCount()
  * 
  *     def get_illustration_sizes(self) -> Set[pyint]:             # <<<<<<<<<<<<<<
@@ -17383,7 +17303,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_20get_illustration_sizes(struct __pyx
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_illustration_sizes", 0);
 
-  /* "libzim.pyx":999
+  /* "libzim.pyx":991
  *     def get_illustration_sizes(self) -> Set[pyint]:
  *         """Sizes for which an illustration is available (@1 scale only)"""
  *         return self.c_archive.getIllustrationSizes()             # <<<<<<<<<<<<<<
@@ -17395,15 +17315,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_20get_illustration_sizes(struct __pyx
     __pyx_t_1 = __pyx_v_self->c_archive.getIllustrationSizes();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 999, __pyx_L1_error)
+    __PYX_ERR(0, 991, __pyx_L1_error)
   }
-  __pyx_t_2 = __pyx_convert_set_to_py_unsigned_int(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 999, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_set_to_py_unsigned_int(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 991, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":997
+  /* "libzim.pyx":989
  *         return self.c_archive.getMediaCount()
  * 
  *     def get_illustration_sizes(self) -> Set[pyint]:             # <<<<<<<<<<<<<<
@@ -17422,7 +17342,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_20get_illustration_sizes(struct __pyx
   return __pyx_r;
 }
 
-/* "libzim.pyx":1001
+/* "libzim.pyx":993
  *         return self.c_archive.getIllustrationSizes()
  * 
  *     def has_illustration(self, size: pyint = None) -> pybool:             # <<<<<<<<<<<<<<
@@ -17463,7 +17383,7 @@ static PyObject *__pyx_pw_6libzim_7Archive_23has_illustration(PyObject *__pyx_v_
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "has_illustration") < 0)) __PYX_ERR(0, 1001, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "has_illustration") < 0)) __PYX_ERR(0, 993, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -17477,7 +17397,7 @@ static PyObject *__pyx_pw_6libzim_7Archive_23has_illustration(PyObject *__pyx_v_
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("has_illustration", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1001, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("has_illustration", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 993, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.Archive.has_illustration", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -17503,7 +17423,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_22has_illustration(struct __pyx_obj_6
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("has_illustration", 0);
 
-  /* "libzim.pyx":1003
+  /* "libzim.pyx":995
  *     def has_illustration(self, size: pyint = None) -> pybool:
  *         """Whether Archive has an illustration metadata for this size"""
  *         if size is not None:             # <<<<<<<<<<<<<<
@@ -17514,7 +17434,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_22has_illustration(struct __pyx_obj_6
   __pyx_t_2 = (__pyx_t_1 != 0);
   if (__pyx_t_2) {
 
-    /* "libzim.pyx":1004
+    /* "libzim.pyx":996
  *         """Whether Archive has an illustration metadata for this size"""
  *         if size is not None:
  *             return self.c_archive.hasIllustration(size)             # <<<<<<<<<<<<<<
@@ -17522,20 +17442,20 @@ static PyObject *__pyx_pf_6libzim_7Archive_22has_illustration(struct __pyx_obj_6
  * 
  */
     __Pyx_XDECREF(__pyx_r);
-    __pyx_t_3 = __Pyx_PyInt_As_unsigned_int(__pyx_v_size); if (unlikely((__pyx_t_3 == (unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1004, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyInt_As_unsigned_int(__pyx_v_size); if (unlikely((__pyx_t_3 == (unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 996, __pyx_L1_error)
     try {
       __pyx_t_4 = __pyx_v_self->c_archive.hasIllustration(__pyx_t_3);
     } catch(...) {
       __Pyx_CppExn2PyErr();
-      __PYX_ERR(0, 1004, __pyx_L1_error)
+      __PYX_ERR(0, 996, __pyx_L1_error)
     }
-    __pyx_t_5 = __Pyx_PyBool_FromLong(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1004, __pyx_L1_error)
+    __pyx_t_5 = __Pyx_PyBool_FromLong(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 996, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_5);
     __pyx_r = __pyx_t_5;
     __pyx_t_5 = 0;
     goto __pyx_L0;
 
-    /* "libzim.pyx":1003
+    /* "libzim.pyx":995
  *     def has_illustration(self, size: pyint = None) -> pybool:
  *         """Whether Archive has an illustration metadata for this size"""
  *         if size is not None:             # <<<<<<<<<<<<<<
@@ -17544,7 +17464,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_22has_illustration(struct __pyx_obj_6
  */
   }
 
-  /* "libzim.pyx":1005
+  /* "libzim.pyx":997
  *         if size is not None:
  *             return self.c_archive.hasIllustration(size)
  *         return self.c_archive.hasIllustration()             # <<<<<<<<<<<<<<
@@ -17556,15 +17476,15 @@ static PyObject *__pyx_pf_6libzim_7Archive_22has_illustration(struct __pyx_obj_6
     __pyx_t_4 = __pyx_v_self->c_archive.hasIllustration();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 1005, __pyx_L1_error)
+    __PYX_ERR(0, 997, __pyx_L1_error)
   }
-  __pyx_t_5 = __Pyx_PyBool_FromLong(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1005, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyBool_FromLong(__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 997, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":1001
+  /* "libzim.pyx":993
  *         return self.c_archive.getIllustrationSizes()
  * 
  *     def has_illustration(self, size: pyint = None) -> pybool:             # <<<<<<<<<<<<<<
@@ -17583,7 +17503,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_22has_illustration(struct __pyx_obj_6
   return __pyx_r;
 }
 
-/* "libzim.pyx":1007
+/* "libzim.pyx":999
  *         return self.c_archive.hasIllustration()
  * 
  *     def get_illustration_item(self, size: pyint = None) -> Item:             # <<<<<<<<<<<<<<
@@ -17624,7 +17544,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pw_6libzim_7Archive_25get_illustrati
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_illustration_item") < 0)) __PYX_ERR(0, 1007, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_illustration_item") < 0)) __PYX_ERR(0, 999, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -17638,7 +17558,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pw_6libzim_7Archive_25get_illustrati
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("get_illustration_item", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1007, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("get_illustration_item", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 999, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.Archive.get_illustration_item", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -17680,7 +17600,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_24get_illustrati
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("get_illustration_item", 0);
 
-  /* "libzim.pyx":1009
+  /* "libzim.pyx":1001
  *     def get_illustration_item(self, size: pyint = None) -> Item:
  *         """Illustration Metadata Item for this size"""
  *         try:             # <<<<<<<<<<<<<<
@@ -17696,7 +17616,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_24get_illustrati
     __Pyx_XGOTREF(__pyx_t_3);
     /*try:*/ {
 
-      /* "libzim.pyx":1010
+      /* "libzim.pyx":1002
  *         """Illustration Metadata Item for this size"""
  *         try:
  *             if size is not None:             # <<<<<<<<<<<<<<
@@ -17707,7 +17627,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_24get_illustrati
       __pyx_t_5 = (__pyx_t_4 != 0);
       if (__pyx_t_5) {
 
-        /* "libzim.pyx":1011
+        /* "libzim.pyx":1003
  *         try:
  *             if size is not None:
  *                 return Item.from_item(move(self.c_archive.getIllustrationItem(size)))             # <<<<<<<<<<<<<<
@@ -17715,21 +17635,21 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_24get_illustrati
  *         except RuntimeError as e:
  */
         __Pyx_XDECREF(((PyObject *)__pyx_r));
-        __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_v_size); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1011, __pyx_L3_error)
+        __pyx_t_6 = __Pyx_PyInt_As_int(__pyx_v_size); if (unlikely((__pyx_t_6 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1003, __pyx_L3_error)
         try {
           __pyx_t_7 = __pyx_v_self->c_archive.getIllustrationItem(__pyx_t_6);
         } catch(...) {
           __Pyx_CppExn2PyErr();
-          __PYX_ERR(0, 1011, __pyx_L3_error)
+          __PYX_ERR(0, 1003, __pyx_L3_error)
         }
-        __pyx_t_8 = __pyx_f_6libzim_4Item_from_item(cython_std::move<wrapper::Item>(__pyx_t_7)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1011, __pyx_L3_error)
+        __pyx_t_8 = __pyx_f_6libzim_4Item_from_item(cython_std::move<wrapper::Item>(__pyx_t_7)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1003, __pyx_L3_error)
         __Pyx_GOTREF(__pyx_t_8);
-        if (!(likely(((__pyx_t_8) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_8, __pyx_ptype_6libzim_Item))))) __PYX_ERR(0, 1011, __pyx_L3_error)
+        if (!(likely(((__pyx_t_8) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_8, __pyx_ptype_6libzim_Item))))) __PYX_ERR(0, 1003, __pyx_L3_error)
         __pyx_r = ((struct __pyx_obj_6libzim_Item *)__pyx_t_8);
         __pyx_t_8 = 0;
         goto __pyx_L7_try_return;
 
-        /* "libzim.pyx":1010
+        /* "libzim.pyx":1002
  *         """Illustration Metadata Item for this size"""
  *         try:
  *             if size is not None:             # <<<<<<<<<<<<<<
@@ -17738,7 +17658,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_24get_illustrati
  */
       }
 
-      /* "libzim.pyx":1012
+      /* "libzim.pyx":1004
  *             if size is not None:
  *                 return Item.from_item(move(self.c_archive.getIllustrationItem(size)))
  *             return Item.from_item(move(self.c_archive.getIllustrationItem()))             # <<<<<<<<<<<<<<
@@ -17750,16 +17670,16 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_24get_illustrati
         __pyx_t_7 = __pyx_v_self->c_archive.getIllustrationItem();
       } catch(...) {
         __Pyx_CppExn2PyErr();
-        __PYX_ERR(0, 1012, __pyx_L3_error)
+        __PYX_ERR(0, 1004, __pyx_L3_error)
       }
-      __pyx_t_8 = __pyx_f_6libzim_4Item_from_item(cython_std::move<wrapper::Item>(__pyx_t_7)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1012, __pyx_L3_error)
+      __pyx_t_8 = __pyx_f_6libzim_4Item_from_item(cython_std::move<wrapper::Item>(__pyx_t_7)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1004, __pyx_L3_error)
       __Pyx_GOTREF(__pyx_t_8);
-      if (!(likely(((__pyx_t_8) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_8, __pyx_ptype_6libzim_Item))))) __PYX_ERR(0, 1012, __pyx_L3_error)
+      if (!(likely(((__pyx_t_8) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_8, __pyx_ptype_6libzim_Item))))) __PYX_ERR(0, 1004, __pyx_L3_error)
       __pyx_r = ((struct __pyx_obj_6libzim_Item *)__pyx_t_8);
       __pyx_t_8 = 0;
       goto __pyx_L7_try_return;
 
-      /* "libzim.pyx":1009
+      /* "libzim.pyx":1001
  *     def get_illustration_item(self, size: pyint = None) -> Item:
  *         """Illustration Metadata Item for this size"""
  *         try:             # <<<<<<<<<<<<<<
@@ -17770,7 +17690,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_24get_illustrati
     __pyx_L3_error:;
     __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
 
-    /* "libzim.pyx":1013
+    /* "libzim.pyx":1005
  *                 return Item.from_item(move(self.c_archive.getIllustrationItem(size)))
  *             return Item.from_item(move(self.c_archive.getIllustrationItem()))
  *         except RuntimeError as e:             # <<<<<<<<<<<<<<
@@ -17780,7 +17700,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_24get_illustrati
     __pyx_t_6 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_RuntimeError);
     if (__pyx_t_6) {
       __Pyx_AddTraceback("libzim.Archive.get_illustration_item", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10) < 0) __PYX_ERR(0, 1013, __pyx_L5_except_error)
+      if (__Pyx_GetException(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10) < 0) __PYX_ERR(0, 1005, __pyx_L5_except_error)
       __Pyx_GOTREF(__pyx_t_8);
       __Pyx_GOTREF(__pyx_t_9);
       __Pyx_GOTREF(__pyx_t_10);
@@ -17788,24 +17708,24 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_24get_illustrati
       __pyx_v_e = __pyx_t_9;
       /*try:*/ {
 
-        /* "libzim.pyx":1014
+        /* "libzim.pyx":1006
  *             return Item.from_item(move(self.c_archive.getIllustrationItem()))
  *         except RuntimeError as e:
  *             raise KeyError(str(e))             # <<<<<<<<<<<<<<
  * 
  *     def __repr__(self) -> str:
  */
-        __pyx_t_11 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_e); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1014, __pyx_L15_error)
+        __pyx_t_11 = __Pyx_PyObject_CallOneArg(((PyObject *)(&PyUnicode_Type)), __pyx_v_e); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1006, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_11);
-        __pyx_t_12 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1014, __pyx_L15_error)
+        __pyx_t_12 = __Pyx_PyObject_CallOneArg(__pyx_builtin_KeyError, __pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1006, __pyx_L15_error)
         __Pyx_GOTREF(__pyx_t_12);
         __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
         __Pyx_Raise(__pyx_t_12, 0, 0, 0);
         __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
-        __PYX_ERR(0, 1014, __pyx_L15_error)
+        __PYX_ERR(0, 1006, __pyx_L15_error)
       }
 
-      /* "libzim.pyx":1013
+      /* "libzim.pyx":1005
  *                 return Item.from_item(move(self.c_archive.getIllustrationItem(size)))
  *             return Item.from_item(move(self.c_archive.getIllustrationItem()))
  *         except RuntimeError as e:             # <<<<<<<<<<<<<<
@@ -17852,7 +17772,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_24get_illustrati
     goto __pyx_L5_except_error;
     __pyx_L5_except_error:;
 
-    /* "libzim.pyx":1009
+    /* "libzim.pyx":1001
  *     def get_illustration_item(self, size: pyint = None) -> Item:
  *         """Illustration Metadata Item for this size"""
  *         try:             # <<<<<<<<<<<<<<
@@ -17872,7 +17792,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_24get_illustrati
     goto __pyx_L0;
   }
 
-  /* "libzim.pyx":1007
+  /* "libzim.pyx":999
  *         return self.c_archive.hasIllustration()
  * 
  *     def get_illustration_item(self, size: pyint = None) -> Item:             # <<<<<<<<<<<<<<
@@ -17896,7 +17816,7 @@ static struct __pyx_obj_6libzim_Item *__pyx_pf_6libzim_7Archive_24get_illustrati
   return __pyx_r;
 }
 
-/* "libzim.pyx":1016
+/* "libzim.pyx":1008
  *             raise KeyError(str(e))
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
@@ -17930,7 +17850,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_26__repr__(struct __pyx_obj_6libzim_A
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__repr__", 0);
 
-  /* "libzim.pyx":1017
+  /* "libzim.pyx":1009
  * 
  *     def __repr__(self) -> str:
  *         return f"{self.__class__.__name__}(filename={self.filename})"             # <<<<<<<<<<<<<<
@@ -17938,16 +17858,16 @@ static PyObject *__pyx_pf_6libzim_7Archive_26__repr__(struct __pyx_obj_6libzim_A
  * reader_module_doc = """libzim reader module
  */
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1017, __pyx_L1_error)
+  __pyx_t_1 = PyTuple_New(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1009, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_t_2 = 0;
   __pyx_t_3 = 127;
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1017, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_class); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1009, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1017, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_name_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1009, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1017, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_t_5, __pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1009, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) : __pyx_t_3;
@@ -17959,9 +17879,9 @@ static PyObject *__pyx_pf_6libzim_7Archive_26__repr__(struct __pyx_obj_6libzim_A
   __pyx_t_2 += 10;
   __Pyx_GIVEREF(__pyx_kp_u_filename_2);
   PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_kp_u_filename_2);
-  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_filename); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1017, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_filename); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1009, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1017, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_empty_unicode); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1009, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __pyx_t_3 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) > __pyx_t_3) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_5) : __pyx_t_3;
@@ -17973,14 +17893,14 @@ static PyObject *__pyx_pf_6libzim_7Archive_26__repr__(struct __pyx_obj_6libzim_A
   __pyx_t_2 += 1;
   __Pyx_GIVEREF(__pyx_kp_u__24);
   PyTuple_SET_ITEM(__pyx_t_1, 3, __pyx_kp_u__24);
-  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 4, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1017, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyUnicode_Join(__pyx_t_1, 4, __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1009, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __pyx_r = __pyx_t_5;
   __pyx_t_5 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":1016
+  /* "libzim.pyx":1008
  *             raise KeyError(str(e))
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
@@ -18035,7 +17955,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_28__reduce_cython__(CYTHON_UNUSED str
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__34, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18091,7 +18011,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_30__setstate_cython__(CYTHON_UNUSED s
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__35, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__34, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18114,7 +18034,7 @@ static PyObject *__pyx_pf_6libzim_7Archive_30__setstate_cython__(CYTHON_UNUSED s
   return __pyx_r;
 }
 
-/* "libzim.pyx":1050
+/* "libzim.pyx":1042
  *     cdef zim.Query c_query
  * 
  *     def set_query(self, query: str):             # <<<<<<<<<<<<<<
@@ -18131,7 +18051,7 @@ static PyObject *__pyx_pw_6libzim_5Query_1set_query(PyObject *__pyx_v_self, PyOb
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("set_query (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_query), (&PyUnicode_Type), 1, "query", 1))) __PYX_ERR(0, 1050, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_query), (&PyUnicode_Type), 1, "query", 1))) __PYX_ERR(0, 1042, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_5Query_set_query(((struct __pyx_obj_6libzim_Query *)__pyx_v_self), ((PyObject*)__pyx_v_query));
 
   /* function exit code */
@@ -18153,7 +18073,7 @@ static PyObject *__pyx_pf_6libzim_5Query_set_query(struct __pyx_obj_6libzim_Quer
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("set_query", 0);
 
-  /* "libzim.pyx":1051
+  /* "libzim.pyx":1043
  * 
  *     def set_query(self, query: str):
  *         self.c_query.setQuery(query.encode('UTF-8'))             # <<<<<<<<<<<<<<
@@ -18162,15 +18082,15 @@ static PyObject *__pyx_pf_6libzim_5Query_set_query(struct __pyx_obj_6libzim_Quer
  */
   if (unlikely(__pyx_v_query == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 1051, __pyx_L1_error)
+    __PYX_ERR(0, 1043, __pyx_L1_error)
   }
-  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_query); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1051, __pyx_L1_error)
+  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_query); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1043, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1051, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1043, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   (void)(__pyx_v_self->c_query.setQuery(__pyx_t_2));
 
-  /* "libzim.pyx":1052
+  /* "libzim.pyx":1044
  *     def set_query(self, query: str):
  *         self.c_query.setQuery(query.encode('UTF-8'))
  *         return self             # <<<<<<<<<<<<<<
@@ -18182,7 +18102,7 @@ static PyObject *__pyx_pf_6libzim_5Query_set_query(struct __pyx_obj_6libzim_Quer
   __pyx_r = ((PyObject *)__pyx_v_self);
   goto __pyx_L0;
 
-  /* "libzim.pyx":1050
+  /* "libzim.pyx":1042
  *     cdef zim.Query c_query
  * 
  *     def set_query(self, query: str):             # <<<<<<<<<<<<<<
@@ -18235,7 +18155,7 @@ static PyObject *__pyx_pf_6libzim_5Query_2__reduce_cython__(CYTHON_UNUSED struct
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_query cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__36, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__35, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18291,7 +18211,7 @@ static PyObject *__pyx_pf_6libzim_5Query_4__setstate_cython__(CYTHON_UNUSED stru
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_query cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__37, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__36, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18314,7 +18234,7 @@ static PyObject *__pyx_pf_6libzim_5Query_4__setstate_cython__(CYTHON_UNUSED stru
   return __pyx_r;
 }
 
-/* "libzim.pyx":1061
+/* "libzim.pyx":1053
  * 
  *     @staticmethod
  *     cdef from_resultset(zim.SearchResultSet _resultset):             # <<<<<<<<<<<<<<
@@ -18332,19 +18252,19 @@ static PyObject *__pyx_f_6libzim_15SearchResultSet_from_resultset(wrapper::Searc
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("from_resultset", 0);
 
-  /* "libzim.pyx":1062
+  /* "libzim.pyx":1054
  *     @staticmethod
  *     cdef from_resultset(zim.SearchResultSet _resultset):
  *         cdef SearchResultSet resultset = SearchResultSet()             # <<<<<<<<<<<<<<
  *         resultset.c_resultset = move(_resultset)
  *         return resultset
  */
-  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_SearchResultSet)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1062, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_SearchResultSet)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1054, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_resultset = ((struct __pyx_obj_6libzim_SearchResultSet *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "libzim.pyx":1063
+  /* "libzim.pyx":1055
  *     cdef from_resultset(zim.SearchResultSet _resultset):
  *         cdef SearchResultSet resultset = SearchResultSet()
  *         resultset.c_resultset = move(_resultset)             # <<<<<<<<<<<<<<
@@ -18353,7 +18273,7 @@ static PyObject *__pyx_f_6libzim_15SearchResultSet_from_resultset(wrapper::Searc
  */
   __pyx_v_resultset->c_resultset = cython_std::move<wrapper::SearchResultSet>(__pyx_v__resultset);
 
-  /* "libzim.pyx":1064
+  /* "libzim.pyx":1056
  *         cdef SearchResultSet resultset = SearchResultSet()
  *         resultset.c_resultset = move(_resultset)
  *         return resultset             # <<<<<<<<<<<<<<
@@ -18365,7 +18285,7 @@ static PyObject *__pyx_f_6libzim_15SearchResultSet_from_resultset(wrapper::Searc
   __pyx_r = ((PyObject *)__pyx_v_resultset);
   goto __pyx_L0;
 
-  /* "libzim.pyx":1061
+  /* "libzim.pyx":1053
  * 
  *     @staticmethod
  *     cdef from_resultset(zim.SearchResultSet _resultset):             # <<<<<<<<<<<<<<
@@ -18386,7 +18306,7 @@ static PyObject *__pyx_f_6libzim_15SearchResultSet_from_resultset(wrapper::Searc
 }
 static PyObject *__pyx_gb_6libzim_15SearchResultSet_2generator2(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
 
-/* "libzim.pyx":1066
+/* "libzim.pyx":1058
  *         return resultset
  * 
  *     def __iter__(self) -> Iterator[str]:             # <<<<<<<<<<<<<<
@@ -18423,7 +18343,7 @@ static PyObject *__pyx_pf_6libzim_15SearchResultSet___iter__(struct __pyx_obj_6l
   if (unlikely(!__pyx_cur_scope)) {
     __pyx_cur_scope = ((struct __pyx_obj_6libzim___pyx_scope_struct_2___iter__ *)Py_None);
     __Pyx_INCREF(Py_None);
-    __PYX_ERR(0, 1066, __pyx_L1_error)
+    __PYX_ERR(0, 1058, __pyx_L1_error)
   } else {
     __Pyx_GOTREF(__pyx_cur_scope);
   }
@@ -18431,7 +18351,7 @@ static PyObject *__pyx_pf_6libzim_15SearchResultSet___iter__(struct __pyx_obj_6l
   __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
   __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
   {
-    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_6libzim_15SearchResultSet_2generator2, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_SearchResultSet___iter, __pyx_n_s_libzim); if (unlikely(!gen)) __PYX_ERR(0, 1066, __pyx_L1_error)
+    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_6libzim_15SearchResultSet_2generator2, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_SearchResultSet___iter, __pyx_n_s_libzim); if (unlikely(!gen)) __PYX_ERR(0, 1058, __pyx_L1_error)
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -18466,9 +18386,9 @@ static PyObject *__pyx_gb_6libzim_15SearchResultSet_2generator2(__pyx_CoroutineO
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1066, __pyx_L1_error)
+  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1058, __pyx_L1_error)
 
-  /* "libzim.pyx":1068
+  /* "libzim.pyx":1060
  *     def __iter__(self) -> Iterator[str]:
  *         """Entry paths found in Archive for Search"""
  *         cdef zim.SearchIterator current = self.c_resultset.begin()             # <<<<<<<<<<<<<<
@@ -18477,7 +18397,7 @@ static PyObject *__pyx_gb_6libzim_15SearchResultSet_2generator2(__pyx_CoroutineO
  */
   __pyx_cur_scope->__pyx_v_current = __pyx_cur_scope->__pyx_v_self->c_resultset.begin();
 
-  /* "libzim.pyx":1069
+  /* "libzim.pyx":1061
  *         """Entry paths found in Archive for Search"""
  *         cdef zim.SearchIterator current = self.c_resultset.begin()
  *         cdef zim.SearchIterator end = self.c_resultset.end()             # <<<<<<<<<<<<<<
@@ -18486,7 +18406,7 @@ static PyObject *__pyx_gb_6libzim_15SearchResultSet_2generator2(__pyx_CoroutineO
  */
   __pyx_cur_scope->__pyx_v_end = __pyx_cur_scope->__pyx_v_self->c_resultset.end();
 
-  /* "libzim.pyx":1070
+  /* "libzim.pyx":1062
  *         cdef zim.SearchIterator current = self.c_resultset.begin()
  *         cdef zim.SearchIterator end = self.c_resultset.end()
  *         while current != end:             # <<<<<<<<<<<<<<
@@ -18497,14 +18417,14 @@ static PyObject *__pyx_gb_6libzim_15SearchResultSet_2generator2(__pyx_CoroutineO
     __pyx_t_1 = ((__pyx_cur_scope->__pyx_v_current != __pyx_cur_scope->__pyx_v_end) != 0);
     if (!__pyx_t_1) break;
 
-    /* "libzim.pyx":1071
+    /* "libzim.pyx":1063
  *         cdef zim.SearchIterator end = self.c_resultset.end()
  *         while current != end:
  *             yield current.getPath().decode('UTF-8')             # <<<<<<<<<<<<<<
  *             preincrement(current)
  * 
  */
-    __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_cur_scope->__pyx_v_current.getPath(), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1071, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_cur_scope->__pyx_v_current.getPath(), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1063, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_r = __pyx_t_2;
     __pyx_t_2 = 0;
@@ -18515,9 +18435,9 @@ static PyObject *__pyx_gb_6libzim_15SearchResultSet_2generator2(__pyx_CoroutineO
     __pyx_generator->resume_label = 1;
     return __pyx_r;
     __pyx_L6_resume_from_yield:;
-    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1071, __pyx_L1_error)
+    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1063, __pyx_L1_error)
 
-    /* "libzim.pyx":1072
+    /* "libzim.pyx":1064
  *         while current != end:
  *             yield current.getPath().decode('UTF-8')
  *             preincrement(current)             # <<<<<<<<<<<<<<
@@ -18528,7 +18448,7 @@ static PyObject *__pyx_gb_6libzim_15SearchResultSet_2generator2(__pyx_CoroutineO
   }
   CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);
 
-  /* "libzim.pyx":1066
+  /* "libzim.pyx":1058
  *         return resultset
  * 
  *     def __iter__(self) -> Iterator[str]:             # <<<<<<<<<<<<<<
@@ -18587,7 +18507,7 @@ static PyObject *__pyx_pf_6libzim_15SearchResultSet_3__reduce_cython__(CYTHON_UN
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_resultset cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__38, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__37, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18643,7 +18563,7 @@ static PyObject *__pyx_pf_6libzim_15SearchResultSet_5__setstate_cython__(CYTHON_
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_resultset cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__39, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__38, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -18666,7 +18586,7 @@ static PyObject *__pyx_pf_6libzim_15SearchResultSet_5__setstate_cython__(CYTHON_
   return __pyx_r;
 }
 
-/* "libzim.pyx":1081
+/* "libzim.pyx":1073
  *     # Factory functions - Currently Cython can't use classmethods
  *     @staticmethod
  *     cdef from_search(zim.Search _search):             # <<<<<<<<<<<<<<
@@ -18684,19 +18604,19 @@ static PyObject *__pyx_f_6libzim_6Search_from_search(wrapper::Search __pyx_v__se
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("from_search", 0);
 
-  /* "libzim.pyx":1092
+  /* "libzim.pyx":1084
  *             Item
  *                 Casted item"""
  *         cdef Search search = Search()             # <<<<<<<<<<<<<<
  *         search.c_search = move(_search)
  *         return search
  */
-  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_Search)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1092, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_Search)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1084, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_search = ((struct __pyx_obj_6libzim_Search *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "libzim.pyx":1093
+  /* "libzim.pyx":1085
  *                 Casted item"""
  *         cdef Search search = Search()
  *         search.c_search = move(_search)             # <<<<<<<<<<<<<<
@@ -18705,7 +18625,7 @@ static PyObject *__pyx_f_6libzim_6Search_from_search(wrapper::Search __pyx_v__se
  */
   __pyx_v_search->c_search = cython_std::move<wrapper::Search>(__pyx_v__search);
 
-  /* "libzim.pyx":1094
+  /* "libzim.pyx":1086
  *         cdef Search search = Search()
  *         search.c_search = move(_search)
  *         return search             # <<<<<<<<<<<<<<
@@ -18717,7 +18637,7 @@ static PyObject *__pyx_f_6libzim_6Search_from_search(wrapper::Search __pyx_v__se
   __pyx_r = ((PyObject *)__pyx_v_search);
   goto __pyx_L0;
 
-  /* "libzim.pyx":1081
+  /* "libzim.pyx":1073
  *     # Factory functions - Currently Cython can't use classmethods
  *     @staticmethod
  *     cdef from_search(zim.Search _search):             # <<<<<<<<<<<<<<
@@ -18737,7 +18657,7 @@ static PyObject *__pyx_f_6libzim_6Search_from_search(wrapper::Search __pyx_v__se
   return __pyx_r;
 }
 
-/* "libzim.pyx":1096
+/* "libzim.pyx":1088
  *         return search
  * 
  *     def getEstimatedMatches(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -18769,7 +18689,7 @@ static PyObject *__pyx_pf_6libzim_6Search_getEstimatedMatches(struct __pyx_obj_6
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("getEstimatedMatches", 0);
 
-  /* "libzim.pyx":1098
+  /* "libzim.pyx":1090
  *     def getEstimatedMatches(self) -> pyint:
  *         """Estimated number of results in Archive for the search"""
  *         return self.c_search.getEstimatedMatches()             # <<<<<<<<<<<<<<
@@ -18781,15 +18701,15 @@ static PyObject *__pyx_pf_6libzim_6Search_getEstimatedMatches(struct __pyx_obj_6
     __pyx_t_1 = __pyx_v_self->c_search.getEstimatedMatches();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 1098, __pyx_L1_error)
+    __PYX_ERR(0, 1090, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1098, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1090, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":1096
+  /* "libzim.pyx":1088
  *         return search
  * 
  *     def getEstimatedMatches(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -18808,7 +18728,7 @@ static PyObject *__pyx_pf_6libzim_6Search_getEstimatedMatches(struct __pyx_obj_6
   return __pyx_r;
 }
 
-/* "libzim.pyx":1100
+/* "libzim.pyx":1092
  *         return self.c_search.getEstimatedMatches()
  * 
  *     def getResults(self, start: pyint, count: pyint) -> SearchResultSet:             # <<<<<<<<<<<<<<
@@ -18851,11 +18771,11 @@ static struct __pyx_obj_6libzim_SearchResultSet *__pyx_pw_6libzim_6Search_3getRe
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_count)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("getResults", 1, 2, 2, 1); __PYX_ERR(0, 1100, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("getResults", 1, 2, 2, 1); __PYX_ERR(0, 1092, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "getResults") < 0)) __PYX_ERR(0, 1100, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "getResults") < 0)) __PYX_ERR(0, 1092, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -18868,7 +18788,7 @@ static struct __pyx_obj_6libzim_SearchResultSet *__pyx_pw_6libzim_6Search_3getRe
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("getResults", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1100, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("getResults", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1092, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.Search.getResults", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -18893,7 +18813,7 @@ static struct __pyx_obj_6libzim_SearchResultSet *__pyx_pf_6libzim_6Search_2getRe
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("getResults", 0);
 
-  /* "libzim.pyx":1102
+  /* "libzim.pyx":1094
  *     def getResults(self, start: pyint, count: pyint) -> SearchResultSet:
  *         """Iterator over Entry paths found in Archive for the search"""
  *         return SearchResultSet.from_resultset(move(self.c_search.getResults(start, count)))             # <<<<<<<<<<<<<<
@@ -18901,22 +18821,22 @@ static struct __pyx_obj_6libzim_SearchResultSet *__pyx_pf_6libzim_6Search_2getRe
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyInt_As_int(__pyx_v_start); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1102, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_count); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1102, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_As_int(__pyx_v_start); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1094, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_count); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1094, __pyx_L1_error)
   try {
     __pyx_t_3 = __pyx_v_self->c_search.getResults(__pyx_t_1, __pyx_t_2);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 1102, __pyx_L1_error)
+    __PYX_ERR(0, 1094, __pyx_L1_error)
   }
-  __pyx_t_4 = __pyx_f_6libzim_15SearchResultSet_from_resultset(cython_std::move<wrapper::SearchResultSet>(__pyx_t_3)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1102, __pyx_L1_error)
+  __pyx_t_4 = __pyx_f_6libzim_15SearchResultSet_from_resultset(cython_std::move<wrapper::SearchResultSet>(__pyx_t_3)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1094, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_6libzim_SearchResultSet))))) __PYX_ERR(0, 1102, __pyx_L1_error)
+  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_6libzim_SearchResultSet))))) __PYX_ERR(0, 1094, __pyx_L1_error)
   __pyx_r = ((struct __pyx_obj_6libzim_SearchResultSet *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":1100
+  /* "libzim.pyx":1092
  *         return self.c_search.getEstimatedMatches()
  * 
  *     def getResults(self, start: pyint, count: pyint) -> SearchResultSet:             # <<<<<<<<<<<<<<
@@ -18969,7 +18889,7 @@ static PyObject *__pyx_pf_6libzim_6Search_4__reduce_cython__(CYTHON_UNUSED struc
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_search cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__40, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__39, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19025,7 +18945,7 @@ static PyObject *__pyx_pf_6libzim_6Search_6__setstate_cython__(CYTHON_UNUSED str
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_search cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__41, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__40, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19048,7 +18968,7 @@ static PyObject *__pyx_pf_6libzim_6Search_6__setstate_cython__(CYTHON_UNUSED str
   return __pyx_r;
 }
 
-/* "libzim.pyx":1116
+/* "libzim.pyx":1108
  *     cdef zim.Searcher c_searcher
  * 
  *     def __cinit__(self, object archive: Archive):             # <<<<<<<<<<<<<<
@@ -19085,7 +19005,7 @@ static int __pyx_pw_6libzim_8Searcher_1__cinit__(PyObject *__pyx_v_self, PyObjec
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 1116, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 1108, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -19096,13 +19016,13 @@ static int __pyx_pw_6libzim_8Searcher_1__cinit__(PyObject *__pyx_v_self, PyObjec
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1116, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1108, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.Searcher.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_archive), __pyx_ptype_6libzim_Archive, 1, "archive", 0))) __PYX_ERR(0, 1116, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_archive), __pyx_ptype_6libzim_Archive, 1, "archive", 0))) __PYX_ERR(0, 1108, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_8Searcher___cinit__(((struct __pyx_obj_6libzim_Searcher *)__pyx_v_self), __pyx_v_archive);
 
   /* function exit code */
@@ -19123,7 +19043,7 @@ static int __pyx_pf_6libzim_8Searcher___cinit__(struct __pyx_obj_6libzim_Searche
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "libzim.pyx":1124
+  /* "libzim.pyx":1116
  *                 Full path to a zim file"""
  * 
  *         self.c_searcher = move(zim.Searcher(archive.c_archive))             # <<<<<<<<<<<<<<
@@ -19134,11 +19054,11 @@ static int __pyx_pf_6libzim_8Searcher___cinit__(struct __pyx_obj_6libzim_Searche
     __pyx_t_1 = wrapper::Searcher(__pyx_v_archive->c_archive);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 1124, __pyx_L1_error)
+    __PYX_ERR(0, 1116, __pyx_L1_error)
   }
   __pyx_v_self->c_searcher = cython_std::move<wrapper::Searcher>(__pyx_t_1);
 
-  /* "libzim.pyx":1116
+  /* "libzim.pyx":1108
  *     cdef zim.Searcher c_searcher
  * 
  *     def __cinit__(self, object archive: Archive):             # <<<<<<<<<<<<<<
@@ -19157,7 +19077,7 @@ static int __pyx_pf_6libzim_8Searcher___cinit__(struct __pyx_obj_6libzim_Searche
   return __pyx_r;
 }
 
-/* "libzim.pyx":1126
+/* "libzim.pyx":1118
  *         self.c_searcher = move(zim.Searcher(archive.c_archive))
  * 
  *     def search(self, object query: Query) -> Search:             # <<<<<<<<<<<<<<
@@ -19175,7 +19095,7 @@ static struct __pyx_obj_6libzim_Search *__pyx_pw_6libzim_8Searcher_3search(PyObj
   struct __pyx_obj_6libzim_Search *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("search (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_query), __pyx_ptype_6libzim_Query, 1, "query", 0))) __PYX_ERR(0, 1126, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_query), __pyx_ptype_6libzim_Query, 1, "query", 0))) __PYX_ERR(0, 1118, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_8Searcher_2search(((struct __pyx_obj_6libzim_Searcher *)__pyx_v_self), ((struct __pyx_obj_6libzim_Query *)__pyx_v_query));
 
   /* function exit code */
@@ -19197,7 +19117,7 @@ static struct __pyx_obj_6libzim_Search *__pyx_pf_6libzim_8Searcher_2search(struc
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("search", 0);
 
-  /* "libzim.pyx":1128
+  /* "libzim.pyx":1120
  *     def search(self, object query: Query) -> Search:
  *         """Search object for a query of this Searcher's ZIM Archive"""
  *         return Search.from_search(move(self.c_searcher.search(query.c_query)))             # <<<<<<<<<<<<<<
@@ -19209,16 +19129,16 @@ static struct __pyx_obj_6libzim_Search *__pyx_pf_6libzim_8Searcher_2search(struc
     __pyx_t_1 = __pyx_v_self->c_searcher.search(__pyx_v_query->c_query);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 1128, __pyx_L1_error)
+    __PYX_ERR(0, 1120, __pyx_L1_error)
   }
-  __pyx_t_2 = __pyx_f_6libzim_6Search_from_search(cython_std::move<wrapper::Search>(__pyx_t_1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1128, __pyx_L1_error)
+  __pyx_t_2 = __pyx_f_6libzim_6Search_from_search(cython_std::move<wrapper::Search>(__pyx_t_1)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1120, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_6libzim_Search))))) __PYX_ERR(0, 1128, __pyx_L1_error)
+  if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_6libzim_Search))))) __PYX_ERR(0, 1120, __pyx_L1_error)
   __pyx_r = ((struct __pyx_obj_6libzim_Search *)__pyx_t_2);
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":1126
+  /* "libzim.pyx":1118
  *         self.c_searcher = move(zim.Searcher(archive.c_archive))
  * 
  *     def search(self, object query: Query) -> Search:             # <<<<<<<<<<<<<<
@@ -19271,7 +19191,7 @@ static PyObject *__pyx_pf_6libzim_8Searcher_4__reduce_cython__(CYTHON_UNUSED str
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__42, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__41, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19327,7 +19247,7 @@ static PyObject *__pyx_pf_6libzim_8Searcher_6__setstate_cython__(CYTHON_UNUSED s
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__43, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__42, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19350,7 +19270,7 @@ static PyObject *__pyx_pf_6libzim_8Searcher_6__setstate_cython__(CYTHON_UNUSED s
   return __pyx_r;
 }
 
-/* "libzim.pyx":1162
+/* "libzim.pyx":1154
  * 
  *     @staticmethod
  *     cdef from_resultset(zim.SuggestionResultSet _resultset):             # <<<<<<<<<<<<<<
@@ -19368,19 +19288,19 @@ static PyObject *__pyx_f_6libzim_19SuggestionResultSet_from_resultset(wrapper::S
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("from_resultset", 0);
 
-  /* "libzim.pyx":1163
+  /* "libzim.pyx":1155
  *     @staticmethod
  *     cdef from_resultset(zim.SuggestionResultSet _resultset):
  *         cdef SuggestionResultSet resultset = SuggestionResultSet()             # <<<<<<<<<<<<<<
  *         resultset.c_resultset = move(_resultset)
  *         return resultset
  */
-  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_SuggestionResultSet)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1163, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_SuggestionResultSet)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1155, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_resultset = ((struct __pyx_obj_6libzim_SuggestionResultSet *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "libzim.pyx":1164
+  /* "libzim.pyx":1156
  *     cdef from_resultset(zim.SuggestionResultSet _resultset):
  *         cdef SuggestionResultSet resultset = SuggestionResultSet()
  *         resultset.c_resultset = move(_resultset)             # <<<<<<<<<<<<<<
@@ -19389,7 +19309,7 @@ static PyObject *__pyx_f_6libzim_19SuggestionResultSet_from_resultset(wrapper::S
  */
   __pyx_v_resultset->c_resultset = cython_std::move<wrapper::SuggestionResultSet>(__pyx_v__resultset);
 
-  /* "libzim.pyx":1165
+  /* "libzim.pyx":1157
  *         cdef SuggestionResultSet resultset = SuggestionResultSet()
  *         resultset.c_resultset = move(_resultset)
  *         return resultset             # <<<<<<<<<<<<<<
@@ -19401,7 +19321,7 @@ static PyObject *__pyx_f_6libzim_19SuggestionResultSet_from_resultset(wrapper::S
   __pyx_r = ((PyObject *)__pyx_v_resultset);
   goto __pyx_L0;
 
-  /* "libzim.pyx":1162
+  /* "libzim.pyx":1154
  * 
  *     @staticmethod
  *     cdef from_resultset(zim.SuggestionResultSet _resultset):             # <<<<<<<<<<<<<<
@@ -19422,7 +19342,7 @@ static PyObject *__pyx_f_6libzim_19SuggestionResultSet_from_resultset(wrapper::S
 }
 static PyObject *__pyx_gb_6libzim_19SuggestionResultSet_2generator3(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
 
-/* "libzim.pyx":1167
+/* "libzim.pyx":1159
  *         return resultset
  * 
  *     def __iter__(self) -> Iterator[str]:             # <<<<<<<<<<<<<<
@@ -19459,7 +19379,7 @@ static PyObject *__pyx_pf_6libzim_19SuggestionResultSet___iter__(struct __pyx_ob
   if (unlikely(!__pyx_cur_scope)) {
     __pyx_cur_scope = ((struct __pyx_obj_6libzim___pyx_scope_struct_3___iter__ *)Py_None);
     __Pyx_INCREF(Py_None);
-    __PYX_ERR(0, 1167, __pyx_L1_error)
+    __PYX_ERR(0, 1159, __pyx_L1_error)
   } else {
     __Pyx_GOTREF(__pyx_cur_scope);
   }
@@ -19467,7 +19387,7 @@ static PyObject *__pyx_pf_6libzim_19SuggestionResultSet___iter__(struct __pyx_ob
   __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
   __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
   {
-    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_6libzim_19SuggestionResultSet_2generator3, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_SuggestionResultSet___iter, __pyx_n_s_libzim); if (unlikely(!gen)) __PYX_ERR(0, 1167, __pyx_L1_error)
+    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_6libzim_19SuggestionResultSet_2generator3, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_SuggestionResultSet___iter, __pyx_n_s_libzim); if (unlikely(!gen)) __PYX_ERR(0, 1159, __pyx_L1_error)
     __Pyx_DECREF(__pyx_cur_scope);
     __Pyx_RefNannyFinishContext();
     return (PyObject *) gen;
@@ -19502,9 +19422,9 @@ static PyObject *__pyx_gb_6libzim_19SuggestionResultSet_2generator3(__pyx_Corout
     return NULL;
   }
   __pyx_L3_first_run:;
-  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1167, __pyx_L1_error)
+  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1159, __pyx_L1_error)
 
-  /* "libzim.pyx":1169
+  /* "libzim.pyx":1161
  *     def __iter__(self) -> Iterator[str]:
  *         """Entry paths found in Archive for SuggestionSearch"""
  *         cdef zim.SuggestionIterator current = self.c_resultset.begin()             # <<<<<<<<<<<<<<
@@ -19513,7 +19433,7 @@ static PyObject *__pyx_gb_6libzim_19SuggestionResultSet_2generator3(__pyx_Corout
  */
   __pyx_cur_scope->__pyx_v_current = __pyx_cur_scope->__pyx_v_self->c_resultset.begin();
 
-  /* "libzim.pyx":1170
+  /* "libzim.pyx":1162
  *         """Entry paths found in Archive for SuggestionSearch"""
  *         cdef zim.SuggestionIterator current = self.c_resultset.begin()
  *         cdef zim.SuggestionIterator end = self.c_resultset.end()             # <<<<<<<<<<<<<<
@@ -19522,7 +19442,7 @@ static PyObject *__pyx_gb_6libzim_19SuggestionResultSet_2generator3(__pyx_Corout
  */
   __pyx_cur_scope->__pyx_v_end = __pyx_cur_scope->__pyx_v_self->c_resultset.end();
 
-  /* "libzim.pyx":1171
+  /* "libzim.pyx":1163
  *         cdef zim.SuggestionIterator current = self.c_resultset.begin()
  *         cdef zim.SuggestionIterator end = self.c_resultset.end()
  *         while current != end:             # <<<<<<<<<<<<<<
@@ -19533,14 +19453,14 @@ static PyObject *__pyx_gb_6libzim_19SuggestionResultSet_2generator3(__pyx_Corout
     __pyx_t_1 = ((__pyx_cur_scope->__pyx_v_current != __pyx_cur_scope->__pyx_v_end) != 0);
     if (!__pyx_t_1) break;
 
-    /* "libzim.pyx":1172
+    /* "libzim.pyx":1164
  *         cdef zim.SuggestionIterator end = self.c_resultset.end()
  *         while current != end:
  *             yield current.getSuggestionItem().getPath().decode('UTF-8')             # <<<<<<<<<<<<<<
  *             preincrement(current)
  * 
  */
-    __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_cur_scope->__pyx_v_current.getSuggestionItem().getPath(), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1172, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_decode_cpp_string(__pyx_cur_scope->__pyx_v_current.getSuggestionItem().getPath(), 0, PY_SSIZE_T_MAX, NULL, NULL, PyUnicode_DecodeUTF8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1164, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __pyx_r = __pyx_t_2;
     __pyx_t_2 = 0;
@@ -19551,9 +19471,9 @@ static PyObject *__pyx_gb_6libzim_19SuggestionResultSet_2generator3(__pyx_Corout
     __pyx_generator->resume_label = 1;
     return __pyx_r;
     __pyx_L6_resume_from_yield:;
-    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1172, __pyx_L1_error)
+    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 1164, __pyx_L1_error)
 
-    /* "libzim.pyx":1173
+    /* "libzim.pyx":1165
  *         while current != end:
  *             yield current.getSuggestionItem().getPath().decode('UTF-8')
  *             preincrement(current)             # <<<<<<<<<<<<<<
@@ -19564,7 +19484,7 @@ static PyObject *__pyx_gb_6libzim_19SuggestionResultSet_2generator3(__pyx_Corout
   }
   CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);
 
-  /* "libzim.pyx":1167
+  /* "libzim.pyx":1159
  *         return resultset
  * 
  *     def __iter__(self) -> Iterator[str]:             # <<<<<<<<<<<<<<
@@ -19623,7 +19543,7 @@ static PyObject *__pyx_pf_6libzim_19SuggestionResultSet_3__reduce_cython__(CYTHO
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_resultset cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__44, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__43, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19679,7 +19599,7 @@ static PyObject *__pyx_pf_6libzim_19SuggestionResultSet_5__setstate_cython__(CYT
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_resultset cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__45, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__44, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -19702,7 +19622,7 @@ static PyObject *__pyx_pf_6libzim_19SuggestionResultSet_5__setstate_cython__(CYT
   return __pyx_r;
 }
 
-/* "libzim.pyx":1181
+/* "libzim.pyx":1173
  *     # Factory functions - Currently Cython can't use classmethods
  *     @staticmethod
  *     cdef from_search(zim.SuggestionSearch _search):             # <<<<<<<<<<<<<<
@@ -19720,19 +19640,19 @@ static PyObject *__pyx_f_6libzim_16SuggestionSearch_from_search(wrapper::Suggest
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("from_search", 0);
 
-  /* "libzim.pyx":1192
+  /* "libzim.pyx":1184
  *             Item
  *                 Casted item"""
  *         cdef SuggestionSearch search = SuggestionSearch()             # <<<<<<<<<<<<<<
  *         search.c_search = move(_search)
  *         return search
  */
-  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_SuggestionSearch)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1192, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_CallNoArg(((PyObject *)__pyx_ptype_6libzim_SuggestionSearch)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1184, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_v_search = ((struct __pyx_obj_6libzim_SuggestionSearch *)__pyx_t_1);
   __pyx_t_1 = 0;
 
-  /* "libzim.pyx":1193
+  /* "libzim.pyx":1185
  *                 Casted item"""
  *         cdef SuggestionSearch search = SuggestionSearch()
  *         search.c_search = move(_search)             # <<<<<<<<<<<<<<
@@ -19741,7 +19661,7 @@ static PyObject *__pyx_f_6libzim_16SuggestionSearch_from_search(wrapper::Suggest
  */
   __pyx_v_search->c_search = cython_std::move<wrapper::SuggestionSearch>(__pyx_v__search);
 
-  /* "libzim.pyx":1194
+  /* "libzim.pyx":1186
  *         cdef SuggestionSearch search = SuggestionSearch()
  *         search.c_search = move(_search)
  *         return search             # <<<<<<<<<<<<<<
@@ -19753,7 +19673,7 @@ static PyObject *__pyx_f_6libzim_16SuggestionSearch_from_search(wrapper::Suggest
   __pyx_r = ((PyObject *)__pyx_v_search);
   goto __pyx_L0;
 
-  /* "libzim.pyx":1181
+  /* "libzim.pyx":1173
  *     # Factory functions - Currently Cython can't use classmethods
  *     @staticmethod
  *     cdef from_search(zim.SuggestionSearch _search):             # <<<<<<<<<<<<<<
@@ -19773,7 +19693,7 @@ static PyObject *__pyx_f_6libzim_16SuggestionSearch_from_search(wrapper::Suggest
   return __pyx_r;
 }
 
-/* "libzim.pyx":1196
+/* "libzim.pyx":1188
  *         return search
  * 
  *     def getEstimatedMatches(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -19805,7 +19725,7 @@ static PyObject *__pyx_pf_6libzim_16SuggestionSearch_getEstimatedMatches(struct
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("getEstimatedMatches", 0);
 
-  /* "libzim.pyx":1198
+  /* "libzim.pyx":1190
  *     def getEstimatedMatches(self) -> pyint:
  *         """Estimated number of results in Archive for the suggestion search"""
  *         return self.c_search.getEstimatedMatches()             # <<<<<<<<<<<<<<
@@ -19817,15 +19737,15 @@ static PyObject *__pyx_pf_6libzim_16SuggestionSearch_getEstimatedMatches(struct
     __pyx_t_1 = __pyx_v_self->c_search.getEstimatedMatches();
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 1198, __pyx_L1_error)
+    __PYX_ERR(0, 1190, __pyx_L1_error)
   }
-  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1198, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1190, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_r = __pyx_t_2;
   __pyx_t_2 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":1196
+  /* "libzim.pyx":1188
  *         return search
  * 
  *     def getEstimatedMatches(self) -> pyint:             # <<<<<<<<<<<<<<
@@ -19844,7 +19764,7 @@ static PyObject *__pyx_pf_6libzim_16SuggestionSearch_getEstimatedMatches(struct
   return __pyx_r;
 }
 
-/* "libzim.pyx":1200
+/* "libzim.pyx":1192
  *         return self.c_search.getEstimatedMatches()
  * 
  *     def getResults(self, start: pyint, count: pyint) -> SuggestionResultSet:             # <<<<<<<<<<<<<<
@@ -19887,11 +19807,11 @@ static struct __pyx_obj_6libzim_SuggestionResultSet *__pyx_pw_6libzim_16Suggesti
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_count)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("getResults", 1, 2, 2, 1); __PYX_ERR(0, 1200, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("getResults", 1, 2, 2, 1); __PYX_ERR(0, 1192, __pyx_L3_error)
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "getResults") < 0)) __PYX_ERR(0, 1200, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "getResults") < 0)) __PYX_ERR(0, 1192, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
       goto __pyx_L5_argtuple_error;
@@ -19904,7 +19824,7 @@ static struct __pyx_obj_6libzim_SuggestionResultSet *__pyx_pw_6libzim_16Suggesti
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("getResults", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1200, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("getResults", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1192, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.SuggestionSearch.getResults", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -19929,7 +19849,7 @@ static struct __pyx_obj_6libzim_SuggestionResultSet *__pyx_pf_6libzim_16Suggesti
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("getResults", 0);
 
-  /* "libzim.pyx":1202
+  /* "libzim.pyx":1194
  *     def getResults(self, start: pyint, count: pyint) -> SuggestionResultSet:
  *         """Iterator over Entry paths found in Archive for the suggestion search"""
  *         return SuggestionResultSet.from_resultset(move(self.c_search.getResults(start, count)))             # <<<<<<<<<<<<<<
@@ -19937,22 +19857,22 @@ static struct __pyx_obj_6libzim_SuggestionResultSet *__pyx_pf_6libzim_16Suggesti
  * 
  */
   __Pyx_XDECREF(((PyObject *)__pyx_r));
-  __pyx_t_1 = __Pyx_PyInt_As_int(__pyx_v_start); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1202, __pyx_L1_error)
-  __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_count); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1202, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyInt_As_int(__pyx_v_start); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1194, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_v_count); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1194, __pyx_L1_error)
   try {
     __pyx_t_3 = __pyx_v_self->c_search.getResults(__pyx_t_1, __pyx_t_2);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 1202, __pyx_L1_error)
+    __PYX_ERR(0, 1194, __pyx_L1_error)
   }
-  __pyx_t_4 = __pyx_f_6libzim_19SuggestionResultSet_from_resultset(cython_std::move<wrapper::SuggestionResultSet>(__pyx_t_3)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1202, __pyx_L1_error)
+  __pyx_t_4 = __pyx_f_6libzim_19SuggestionResultSet_from_resultset(cython_std::move<wrapper::SuggestionResultSet>(__pyx_t_3)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1194, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_6libzim_SuggestionResultSet))))) __PYX_ERR(0, 1202, __pyx_L1_error)
+  if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_6libzim_SuggestionResultSet))))) __PYX_ERR(0, 1194, __pyx_L1_error)
   __pyx_r = ((struct __pyx_obj_6libzim_SuggestionResultSet *)__pyx_t_4);
   __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":1200
+  /* "libzim.pyx":1192
  *         return self.c_search.getEstimatedMatches()
  * 
  *     def getResults(self, start: pyint, count: pyint) -> SuggestionResultSet:             # <<<<<<<<<<<<<<
@@ -20005,7 +19925,7 @@ static PyObject *__pyx_pf_6libzim_16SuggestionSearch_4__reduce_cython__(CYTHON_U
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_search cannot be converted to a Python object for pickling")
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__46, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__45, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20061,7 +19981,7 @@ static PyObject *__pyx_pf_6libzim_16SuggestionSearch_6__setstate_cython__(CYTHON
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_search cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__47, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__46, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_Raise(__pyx_t_1, 0, 0, 0);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
@@ -20084,7 +20004,7 @@ static PyObject *__pyx_pf_6libzim_16SuggestionSearch_6__setstate_cython__(CYTHON
   return __pyx_r;
 }
 
-/* "libzim.pyx":1216
+/* "libzim.pyx":1208
  *     cdef zim.SuggestionSearcher c_searcher
  * 
  *     def __cinit__(self, object archive: Archive):             # <<<<<<<<<<<<<<
@@ -20121,7 +20041,7 @@ static int __pyx_pw_6libzim_18SuggestionSearcher_1__cinit__(PyObject *__pyx_v_se
         else goto __pyx_L5_argtuple_error;
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 1216, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 1208, __pyx_L3_error)
       }
     } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
       goto __pyx_L5_argtuple_error;
@@ -20132,13 +20052,13 @@ static int __pyx_pw_6libzim_18SuggestionSearcher_1__cinit__(PyObject *__pyx_v_se
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1216, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1208, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.SuggestionSearcher.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_archive), __pyx_ptype_6libzim_Archive, 1, "archive", 0))) __PYX_ERR(0, 1216, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_archive), __pyx_ptype_6libzim_Archive, 1, "archive", 0))) __PYX_ERR(0, 1208, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_18SuggestionSearcher___cinit__(((struct __pyx_obj_6libzim_SuggestionSearcher *)__pyx_v_self), __pyx_v_archive);
 
   /* function exit code */
@@ -20159,7 +20079,7 @@ static int __pyx_pf_6libzim_18SuggestionSearcher___cinit__(struct __pyx_obj_6lib
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__cinit__", 0);
 
-  /* "libzim.pyx":1224
+  /* "libzim.pyx":1216
  *                 Full path to a zim file"""
  * 
  *         self.c_searcher = move(zim.SuggestionSearcher(archive.c_archive))             # <<<<<<<<<<<<<<
@@ -20170,11 +20090,11 @@ static int __pyx_pf_6libzim_18SuggestionSearcher___cinit__(struct __pyx_obj_6lib
     __pyx_t_1 = wrapper::SuggestionSearcher(__pyx_v_archive->c_archive);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 1224, __pyx_L1_error)
+    __PYX_ERR(0, 1216, __pyx_L1_error)
   }
   __pyx_v_self->c_searcher = cython_std::move<wrapper::SuggestionSearcher>(__pyx_t_1);
 
-  /* "libzim.pyx":1216
+  /* "libzim.pyx":1208
  *     cdef zim.SuggestionSearcher c_searcher
  * 
  *     def __cinit__(self, object archive: Archive):             # <<<<<<<<<<<<<<
@@ -20193,7 +20113,7 @@ static int __pyx_pf_6libzim_18SuggestionSearcher___cinit__(struct __pyx_obj_6lib
   return __pyx_r;
 }
 
-/* "libzim.pyx":1226
+/* "libzim.pyx":1218
  *         self.c_searcher = move(zim.SuggestionSearcher(archive.c_archive))
  * 
  *     def suggest(self, query: str) -> SuggestionSearch:             # <<<<<<<<<<<<<<
@@ -20211,7 +20131,7 @@ static struct __pyx_obj_6libzim_SuggestionSearch *__pyx_pw_6libzim_18SuggestionS
   struct __pyx_obj_6libzim_SuggestionSearch *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("suggest (wrapper)", 0);
-  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_query), (&PyUnicode_Type), 1, "query", 1))) __PYX_ERR(0, 1226, __pyx_L1_error)
+  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_query), (&PyUnicode_Type), 1, "query", 1))) __PYX_ERR(0, 1218, __pyx_L1_error)
   __pyx_r = __pyx_pf_6libzim_18SuggestionSearcher_2suggest(((struct __pyx_obj_6libzim_SuggestionSearcher *)__pyx_v_self), ((PyObject*)__pyx_v_query));
 
   /* function exit code */
@@ -20234,7 +20154,7 @@ static struct __pyx_obj_6libzim_SuggestionSearch *__pyx_pf_6libzim_18SuggestionS
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("suggest", 0);
 
-  /* "libzim.pyx":1228
+  /* "libzim.pyx":1220
  *     def suggest(self, query: str) -> SuggestionSearch:
  *         """SuggestionSearch object for a query of this SuggestionSearcher's ZIM Archive"""
  *         return SuggestionSearch.from_search(move(self.c_searcher.suggest(query.encode('UTF-8'))))             # <<<<<<<<<<<<<<
@@ -20244,26 +20164,26 @@ static struct __pyx_obj_6libzim_SuggestionSearch *__pyx_pf_6libzim_18SuggestionS
   __Pyx_XDECREF(((PyObject *)__pyx_r));
   if (unlikely(__pyx_v_query == Py_None)) {
     PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "encode");
-    __PYX_ERR(0, 1228, __pyx_L1_error)
+    __PYX_ERR(0, 1220, __pyx_L1_error)
   }
-  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_query); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1228, __pyx_L1_error)
+  __pyx_t_1 = PyUnicode_AsUTF8String(__pyx_v_query); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1220, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1228, __pyx_L1_error)
+  __pyx_t_2 = __pyx_convert_string_from_py_std__in_string(__pyx_t_1); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1220, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   try {
     __pyx_t_3 = __pyx_v_self->c_searcher.suggest(__pyx_t_2);
   } catch(...) {
     __Pyx_CppExn2PyErr();
-    __PYX_ERR(0, 1228, __pyx_L1_error)
+    __PYX_ERR(0, 1220, __pyx_L1_error)
   }
-  __pyx_t_1 = __pyx_f_6libzim_16SuggestionSearch_from_search(cython_std::move<wrapper::SuggestionSearch>(__pyx_t_3)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1228, __pyx_L1_error)
+  __pyx_t_1 = __pyx_f_6libzim_16SuggestionSearch_from_search(cython_std::move<wrapper::SuggestionSearch>(__pyx_t_3)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1220, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_6libzim_SuggestionSearch))))) __PYX_ERR(0, 1228, __pyx_L1_error)
+  if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_6libzim_SuggestionSearch))))) __PYX_ERR(0, 1220, __pyx_L1_error)
   __pyx_r = ((struct __pyx_obj_6libzim_SuggestionSearch *)__pyx_t_1);
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":1226
+  /* "libzim.pyx":1218
  *         self.c_searcher = move(zim.SuggestionSearcher(archive.c_archive))
  * 
  *     def suggest(self, query: str) -> SuggestionSearch:             # <<<<<<<<<<<<<<
@@ -20310,92 +20230,679 @@ static PyObject *__pyx_pf_6libzim_18SuggestionSearcher_4__reduce_cython__(CYTHON
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__reduce_cython__", 0);
 
-  /* "(tree fragment)":2
- * def __reduce_cython__(self):
- *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
- * def __setstate_cython__(self, __pyx_state):
- *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
+  /* "(tree fragment)":2
+ * def __reduce_cython__(self):
+ *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
+ * def __setstate_cython__(self, __pyx_state):
+ *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
+ */
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__47, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __PYX_ERR(1, 2, __pyx_L1_error)
+
+  /* "(tree fragment)":1
+ * def __reduce_cython__(self):             # <<<<<<<<<<<<<<
+ *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
+ * def __setstate_cython__(self, __pyx_state):
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("libzim.SuggestionSearcher.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "(tree fragment)":3
+ * def __reduce_cython__(self):
+ *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
+ * def __setstate_cython__(self, __pyx_state):             # <<<<<<<<<<<<<<
+ *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_6libzim_18SuggestionSearcher_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
+static PyObject *__pyx_pw_6libzim_18SuggestionSearcher_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_6libzim_18SuggestionSearcher_6__setstate_cython__(((struct __pyx_obj_6libzim_SuggestionSearcher *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6libzim_18SuggestionSearcher_6__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_6libzim_SuggestionSearcher *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__setstate_cython__", 0);
+
+  /* "(tree fragment)":4
+ *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
+ * def __setstate_cython__(self, __pyx_state):
+ *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
+ */
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__48, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __PYX_ERR(1, 4, __pyx_L1_error)
+
+  /* "(tree fragment)":3
+ * def __reduce_cython__(self):
+ *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
+ * def __setstate_cython__(self, __pyx_state):             # <<<<<<<<<<<<<<
+ *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("libzim.SuggestionSearcher.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "libzim.pyx":1253
+ * 
+ * 
+ * def print_versions(out: Union[sys.stdout, sys.stderr] = sys.stdout):             # <<<<<<<<<<<<<<
+ *     """print libzim and its dependencies list with their versions"""
+ *     for library, version in get_versions().items():
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_6libzim_3print_versions(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6libzim_2print_versions[] = "print libzim and its dependencies list with their versions";
+static PyMethodDef __pyx_mdef_6libzim_3print_versions = {"print_versions", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_6libzim_3print_versions, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6libzim_2print_versions};
+static PyObject *__pyx_pw_6libzim_3print_versions(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_out = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("print_versions (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_out,0};
+    PyObject* values[1] = {0};
+    values[0] = __pyx_k__49;
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        CYTHON_FALLTHROUGH;
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (kw_args > 0) {
+          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_out);
+          if (value) { values[0] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "print_versions") < 0)) __PYX_ERR(0, 1253, __pyx_L3_error)
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        CYTHON_FALLTHROUGH;
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_out = values[0];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("print_versions", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1253, __pyx_L3_error)
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("libzim.print_versions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_6libzim_2print_versions(__pyx_self, __pyx_v_out);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6libzim_2print_versions(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_out) {
+  PyObject *__pyx_v_library = NULL;
+  PyObject *__pyx_v_version = NULL;
+  PyObject *__pyx_v_prefix = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  Py_ssize_t __pyx_t_3;
+  int __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_t_8;
+  int __pyx_t_9;
+  Py_ssize_t __pyx_t_10;
+  Py_UCS4 __pyx_t_11;
+  PyObject *__pyx_t_12 = NULL;
+  PyObject *__pyx_t_13 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("print_versions", 0);
+
+  /* "libzim.pyx":1255
+ * def print_versions(out: Union[sys.stdout, sys.stderr] = sys.stdout):
+ *     """print libzim and its dependencies list with their versions"""
+ *     for library, version in get_versions().items():             # <<<<<<<<<<<<<<
+ *         prefix = "" if library == "libzim" else "+ "
+ *         print(f"{prefix}{library} {version}", file=out or sys.stdout)
+ */
+  __pyx_t_2 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_get_versions); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1255, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_6);
+  __pyx_t_7 = NULL;
+  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) {
+    __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
+    if (likely(__pyx_t_7)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+      __Pyx_INCREF(__pyx_t_7);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_6, function);
+    }
+  }
+  __pyx_t_5 = (__pyx_t_7) ? __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_7) : __Pyx_PyObject_CallNoArg(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+  if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1255, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (unlikely(__pyx_t_5 == Py_None)) {
+    PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "items");
+    __PYX_ERR(0, 1255, __pyx_L1_error)
+  }
+  __pyx_t_6 = __Pyx_dict_iterator(__pyx_t_5, 0, __pyx_n_s_items, (&__pyx_t_3), (&__pyx_t_4)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1255, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_6);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_XDECREF(__pyx_t_1);
+  __pyx_t_1 = __pyx_t_6;
+  __pyx_t_6 = 0;
+  while (1) {
+    __pyx_t_8 = __Pyx_dict_iter_next(__pyx_t_1, __pyx_t_3, &__pyx_t_2, &__pyx_t_6, &__pyx_t_5, NULL, __pyx_t_4);
+    if (unlikely(__pyx_t_8 == 0)) break;
+    if (unlikely(__pyx_t_8 == -1)) __PYX_ERR(0, 1255, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_XDECREF_SET(__pyx_v_library, __pyx_t_6);
+    __pyx_t_6 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_version, __pyx_t_5);
+    __pyx_t_5 = 0;
+
+    /* "libzim.pyx":1256
+ *     """print libzim and its dependencies list with their versions"""
+ *     for library, version in get_versions().items():
+ *         prefix = "" if library == "libzim" else "+ "             # <<<<<<<<<<<<<<
+ *         print(f"{prefix}{library} {version}", file=out or sys.stdout)
+ * 
+ */
+    __pyx_t_9 = (__Pyx_PyUnicode_Equals(__pyx_v_library, __pyx_n_u_libzim, Py_EQ)); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 1256, __pyx_L1_error)
+    if (__pyx_t_9) {
+      __Pyx_INCREF(__pyx_kp_u_);
+      __pyx_t_5 = __pyx_kp_u_;
+    } else {
+      __Pyx_INCREF(__pyx_kp_u__50);
+      __pyx_t_5 = __pyx_kp_u__50;
+    }
+    __Pyx_XDECREF_SET(__pyx_v_prefix, ((PyObject*)__pyx_t_5));
+    __pyx_t_5 = 0;
+
+    /* "libzim.pyx":1257
+ *     for library, version in get_versions().items():
+ *         prefix = "" if library == "libzim" else "+ "
+ *         print(f"{prefix}{library} {version}", file=out or sys.stdout)             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1257, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_10 = 0;
+    __pyx_t_11 = 127;
+    __pyx_t_6 = __Pyx_PyUnicode_Unicode(__pyx_v_prefix); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1257, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_11 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_11) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_11;
+    __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6);
+    __Pyx_GIVEREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6);
+    __pyx_t_6 = 0;
+    __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_library, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1257, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_11 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_11) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_11;
+    __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6);
+    __Pyx_GIVEREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_6);
+    __pyx_t_6 = 0;
+    __Pyx_INCREF(__pyx_kp_u__51);
+    __pyx_t_10 += 1;
+    __Pyx_GIVEREF(__pyx_kp_u__51);
+    PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_kp_u__51);
+    __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_v_version, __pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1257, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_11 = (__Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) > __pyx_t_11) ? __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6) : __pyx_t_11;
+    __pyx_t_10 += __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6);
+    __Pyx_GIVEREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_6);
+    __pyx_t_6 = 0;
+    __pyx_t_6 = __Pyx_PyUnicode_Join(__pyx_t_5, 4, __pyx_t_10, __pyx_t_11); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1257, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 1257, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_GIVEREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6);
+    __pyx_t_6 = 0;
+    __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1257, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_v_out); if (unlikely(__pyx_t_9 < 0)) __PYX_ERR(0, 1257, __pyx_L1_error)
+    if (!__pyx_t_9) {
+    } else {
+      __Pyx_INCREF(__pyx_v_out);
+      __pyx_t_7 = __pyx_v_out;
+      goto __pyx_L5_bool_binop_done;
+    }
+    __Pyx_GetModuleGlobalName(__pyx_t_12, __pyx_n_s_sys); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 1257, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_12);
+    __pyx_t_13 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_n_s_stdout); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 1257, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_13);
+    __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+    __Pyx_INCREF(__pyx_t_13);
+    __pyx_t_7 = __pyx_t_13;
+    __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+    __pyx_L5_bool_binop_done:;
+    if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_file, __pyx_t_7) < 0) __PYX_ERR(0, 1257, __pyx_L1_error)
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1257, __pyx_L1_error)
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "libzim.pyx":1253
+ * 
+ * 
+ * def print_versions(out: Union[sys.stdout, sys.stderr] = sys.stdout):             # <<<<<<<<<<<<<<
+ *     """print libzim and its dependencies list with their versions"""
+ *     for library, version in get_versions().items():
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_12);
+  __Pyx_XDECREF(__pyx_t_13);
+  __Pyx_AddTraceback("libzim.print_versions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_library);
+  __Pyx_XDECREF(__pyx_v_version);
+  __Pyx_XDECREF(__pyx_v_prefix);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "libzim.pyx":1260
+ * 
+ * 
+ * def get_versions() -> OrderedDict[str, str]:             # <<<<<<<<<<<<<<
+ *     """ library: version mapping. Always includes `libzim`"""
+ *     versions = zim.getVersions()
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_6libzim_5get_versions(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6libzim_4get_versions[] = " library: version mapping. Always includes `libzim`";
+static PyMethodDef __pyx_mdef_6libzim_5get_versions = {"get_versions", (PyCFunction)__pyx_pw_6libzim_5get_versions, METH_NOARGS, __pyx_doc_6libzim_4get_versions};
+static PyObject *__pyx_pw_6libzim_5get_versions(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_versions (wrapper)", 0);
+  __pyx_r = __pyx_pf_6libzim_4get_versions(__pyx_self);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6libzim_4get_versions(CYTHON_UNUSED PyObject *__pyx_self) {
+  std::vector<std::pair<std::string,std::string> >  __pyx_v_versions;
+  PyObject *__pyx_8genexpr2__pyx_v_library = NULL;
+  PyObject *__pyx_8genexpr2__pyx_v_version = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  std::vector<std::pair<std::string,std::string> > ::iterator __pyx_t_4;
+  std::pair<std::string,std::string>  __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *(*__pyx_t_10)(PyObject *);
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_versions", 0);
+
+  /* "libzim.pyx":1262
+ * def get_versions() -> OrderedDict[str, str]:
+ *     """ library: version mapping. Always includes `libzim`"""
+ *     versions = zim.getVersions()             # <<<<<<<<<<<<<<
+ *     return OrderedDict({
+ *         library.decode("UTF-8"): version.decode("UTF-8")
+ */
+  __pyx_v_versions = zim::getVersions();
+
+  /* "libzim.pyx":1263
+ *     """ library: version mapping. Always includes `libzim`"""
+ *     versions = zim.getVersions()
+ *     return OrderedDict({             # <<<<<<<<<<<<<<
+ *         library.decode("UTF-8"): version.decode("UTF-8")
+ *         for library, version in versions
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_OrderedDict); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1263, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  { /* enter inner scope */
+    __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1263, __pyx_L5_error)
+    __Pyx_GOTREF(__pyx_t_3);
+
+    /* "libzim.pyx":1265
+ *     return OrderedDict({
+ *         library.decode("UTF-8"): version.decode("UTF-8")
+ *         for library, version in versions             # <<<<<<<<<<<<<<
+ *     })
+ * 
+ */
+    __pyx_t_4 = __pyx_v_versions.begin();
+    for (;;) {
+      if (!(__pyx_t_4 != __pyx_v_versions.end())) break;
+      __pyx_t_5 = *__pyx_t_4;
+      ++__pyx_t_4;
+      __pyx_t_6 = __pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string(__pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1265, __pyx_L5_error)
+      __Pyx_GOTREF(__pyx_t_6);
+      if ((likely(PyTuple_CheckExact(__pyx_t_6))) || (PyList_CheckExact(__pyx_t_6))) {
+        PyObject* sequence = __pyx_t_6;
+        Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
+        if (unlikely(size != 2)) {
+          if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+          else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+          __PYX_ERR(0, 1265, __pyx_L5_error)
+        }
+        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
+        if (likely(PyTuple_CheckExact(sequence))) {
+          __pyx_t_7 = PyTuple_GET_ITEM(sequence, 0); 
+          __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1); 
+        } else {
+          __pyx_t_7 = PyList_GET_ITEM(sequence, 0); 
+          __pyx_t_8 = PyList_GET_ITEM(sequence, 1); 
+        }
+        __Pyx_INCREF(__pyx_t_7);
+        __Pyx_INCREF(__pyx_t_8);
+        #else
+        __pyx_t_7 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1265, __pyx_L5_error)
+        __Pyx_GOTREF(__pyx_t_7);
+        __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1265, __pyx_L5_error)
+        __Pyx_GOTREF(__pyx_t_8);
+        #endif
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      } else {
+        Py_ssize_t index = -1;
+        __pyx_t_9 = PyObject_GetIter(__pyx_t_6); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 1265, __pyx_L5_error)
+        __Pyx_GOTREF(__pyx_t_9);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __pyx_t_10 = Py_TYPE(__pyx_t_9)->tp_iternext;
+        index = 0; __pyx_t_7 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_7)) goto __pyx_L8_unpacking_failed;
+        __Pyx_GOTREF(__pyx_t_7);
+        index = 1; __pyx_t_8 = __pyx_t_10(__pyx_t_9); if (unlikely(!__pyx_t_8)) goto __pyx_L8_unpacking_failed;
+        __Pyx_GOTREF(__pyx_t_8);
+        if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_9), 2) < 0) __PYX_ERR(0, 1265, __pyx_L5_error)
+        __pyx_t_10 = NULL;
+        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+        goto __pyx_L9_unpacking_done;
+        __pyx_L8_unpacking_failed:;
+        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+        __pyx_t_10 = NULL;
+        if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+        __PYX_ERR(0, 1265, __pyx_L5_error)
+        __pyx_L9_unpacking_done:;
+      }
+      __Pyx_XDECREF_SET(__pyx_8genexpr2__pyx_v_library, __pyx_t_7);
+      __pyx_t_7 = 0;
+      __Pyx_XDECREF_SET(__pyx_8genexpr2__pyx_v_version, __pyx_t_8);
+      __pyx_t_8 = 0;
+
+      /* "libzim.pyx":1264
+ *     versions = zim.getVersions()
+ *     return OrderedDict({
+ *         library.decode("UTF-8"): version.decode("UTF-8")             # <<<<<<<<<<<<<<
+ *         for library, version in versions
+ *     })
+ */
+      __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr2__pyx_v_library, __pyx_n_s_decode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1264, __pyx_L5_error)
+      __Pyx_GOTREF(__pyx_t_8);
+      __pyx_t_7 = NULL;
+      if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_8))) {
+        __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_8);
+        if (likely(__pyx_t_7)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+          __Pyx_INCREF(__pyx_t_7);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_8, function);
+        }
+      }
+      __pyx_t_6 = (__pyx_t_7) ? __Pyx_PyObject_Call2Args(__pyx_t_8, __pyx_t_7, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_kp_u_UTF_8);
+      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+      if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 1264, __pyx_L5_error)
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+      __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_8genexpr2__pyx_v_version, __pyx_n_s_decode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1264, __pyx_L5_error)
+      __Pyx_GOTREF(__pyx_t_7);
+      __pyx_t_9 = NULL;
+      if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_7))) {
+        __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_7);
+        if (likely(__pyx_t_9)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+          __Pyx_INCREF(__pyx_t_9);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_7, function);
+        }
+      }
+      __pyx_t_8 = (__pyx_t_9) ? __Pyx_PyObject_Call2Args(__pyx_t_7, __pyx_t_9, __pyx_kp_u_UTF_8) : __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_kp_u_UTF_8);
+      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+      if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1264, __pyx_L5_error)
+      __Pyx_GOTREF(__pyx_t_8);
+      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+      if (unlikely(PyDict_SetItem(__pyx_t_3, (PyObject*)__pyx_t_6, (PyObject*)__pyx_t_8))) __PYX_ERR(0, 1264, __pyx_L5_error)
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+      /* "libzim.pyx":1265
+ *     return OrderedDict({
+ *         library.decode("UTF-8"): version.decode("UTF-8")
+ *         for library, version in versions             # <<<<<<<<<<<<<<
+ *     })
+ * 
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__48, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 2, __pyx_L1_error)
+    }
+    __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_library); __pyx_8genexpr2__pyx_v_library = 0;
+    __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_version); __pyx_8genexpr2__pyx_v_version = 0;
+    goto __pyx_L10_exit_scope;
+    __pyx_L5_error:;
+    __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_library); __pyx_8genexpr2__pyx_v_library = 0;
+    __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_version); __pyx_8genexpr2__pyx_v_version = 0;
+    goto __pyx_L1_error;
+    __pyx_L10_exit_scope:;
+  } /* exit inner scope */
+  __pyx_t_8 = NULL;
+  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_8)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_8);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  __pyx_t_1 = (__pyx_t_8) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_8, __pyx_t_3) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1263, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_Raise(__pyx_t_1, 0, 0, 0);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-  /* "(tree fragment)":1
- * def __reduce_cython__(self):             # <<<<<<<<<<<<<<
- *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
- * def __setstate_cython__(self, __pyx_state):
+  /* "libzim.pyx":1260
+ * 
+ * 
+ * def get_versions() -> OrderedDict[str, str]:             # <<<<<<<<<<<<<<
+ *     """ library: version mapping. Always includes `libzim`"""
+ *     versions = zim.getVersions()
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("libzim.SuggestionSearcher.__reduce_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_AddTraceback("libzim.get_versions", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_library);
+  __Pyx_XDECREF(__pyx_8genexpr2__pyx_v_version);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "(tree fragment)":3
- * def __reduce_cython__(self):
- *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
- * def __setstate_cython__(self, __pyx_state):             # <<<<<<<<<<<<<<
- *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
+/* "libzim.pyx":1268
+ *     })
+ * 
+ * def get_libzim_version() -> str:             # <<<<<<<<<<<<<<
+ *     """libzim version string"""
+ *     return get_versions()["libzim"]
  */
 
 /* Python wrapper */
-static PyObject *__pyx_pw_6libzim_18SuggestionSearcher_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state); /*proto*/
-static PyObject *__pyx_pw_6libzim_18SuggestionSearcher_7__setstate_cython__(PyObject *__pyx_v_self, PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pw_6libzim_7get_libzim_version(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6libzim_6get_libzim_version[] = "libzim version string";
+static PyMethodDef __pyx_mdef_6libzim_7get_libzim_version = {"get_libzim_version", (PyCFunction)__pyx_pw_6libzim_7get_libzim_version, METH_NOARGS, __pyx_doc_6libzim_6get_libzim_version};
+static PyObject *__pyx_pw_6libzim_7get_libzim_version(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused) {
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__setstate_cython__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_6libzim_18SuggestionSearcher_6__setstate_cython__(((struct __pyx_obj_6libzim_SuggestionSearcher *)__pyx_v_self), ((PyObject *)__pyx_v___pyx_state));
+  __Pyx_RefNannySetupContext("get_libzim_version (wrapper)", 0);
+  __pyx_r = __pyx_pf_6libzim_6get_libzim_version(__pyx_self);
 
   /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-static PyObject *__pyx_pf_6libzim_18SuggestionSearcher_6__setstate_cython__(CYTHON_UNUSED struct __pyx_obj_6libzim_SuggestionSearcher *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v___pyx_state) {
+static PyObject *__pyx_pf_6libzim_6get_libzim_version(CYTHON_UNUSED PyObject *__pyx_self) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("__setstate_cython__", 0);
+  __Pyx_RefNannySetupContext("get_libzim_version", 0);
 
-  /* "(tree fragment)":4
- *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
- * def __setstate_cython__(self, __pyx_state):
- *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
+  /* "libzim.pyx":1270
+ * def get_libzim_version() -> str:
+ *     """libzim version string"""
+ *     return get_versions()["libzim"]             # <<<<<<<<<<<<<<
+ * 
+ * version_public_objects = [
  */
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__49, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_get_versions); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1270, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1270, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Dict_GetItem(__pyx_t_1, __pyx_n_u_libzim); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1270, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __PYX_ERR(1, 4, __pyx_L1_error)
+  if (!(likely(PyUnicode_CheckExact(__pyx_t_2))||((__pyx_t_2) == Py_None)||((void)PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "unicode", Py_TYPE(__pyx_t_2)->tp_name), 0))) __PYX_ERR(0, 1270, __pyx_L1_error)
+  __pyx_r = ((PyObject*)__pyx_t_2);
+  __pyx_t_2 = 0;
+  goto __pyx_L0;
 
-  /* "(tree fragment)":3
- * def __reduce_cython__(self):
- *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
- * def __setstate_cython__(self, __pyx_state):             # <<<<<<<<<<<<<<
- *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
+  /* "libzim.pyx":1268
+ *     })
+ * 
+ * def get_libzim_version() -> str:             # <<<<<<<<<<<<<<
+ *     """libzim version string"""
+ *     return get_versions()["libzim"]
  */
 
   /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("libzim.SuggestionSearcher.__setstate_cython__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("libzim.get_libzim_version", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
+  __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "libzim.pyx":1251
+/* "libzim.pyx":1284
  *     # Create our module. Easy, just return the created module
  *     @staticmethod
  *     def create_module(spec):             # <<<<<<<<<<<<<<
@@ -20428,7 +20935,7 @@ static PyObject *__pyx_pf_6libzim_12ModuleLoader_create_module(CYTHON_UNUSED PyO
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("create_module", 0);
 
-  /* "libzim.pyx":1252
+  /* "libzim.pyx":1285
  *     @staticmethod
  *     def create_module(spec):
  *         return {             # <<<<<<<<<<<<<<
@@ -20437,66 +20944,78 @@ static PyObject *__pyx_pf_6libzim_12ModuleLoader_create_module(CYTHON_UNUSED PyO
  */
   __Pyx_XDECREF(__pyx_r);
 
-  /* "libzim.pyx":1253
+  /* "libzim.pyx":1286
  *     def create_module(spec):
  *         return {
  *             'libzim.writer': writer,             # <<<<<<<<<<<<<<
  *             'libzim.reader': reader,
  *             'libzim.search': search,
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1253, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyDict_NewPresized(5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1286, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_writer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1253, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_writer); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1286, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_kp_u_libzim_writer, __pyx_t_2) < 0) __PYX_ERR(0, 1253, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_kp_u_libzim_writer, __pyx_t_2) < 0) __PYX_ERR(0, 1286, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":1254
+  /* "libzim.pyx":1287
  *         return {
  *             'libzim.writer': writer,
  *             'libzim.reader': reader,             # <<<<<<<<<<<<<<
  *             'libzim.search': search,
- *             'libzim.suggestion': suggestion
+ *             'libzim.suggestion': suggestion,
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_reader); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1254, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_reader); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1287, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_kp_u_libzim_reader, __pyx_t_2) < 0) __PYX_ERR(0, 1253, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_kp_u_libzim_reader, __pyx_t_2) < 0) __PYX_ERR(0, 1286, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":1255
+  /* "libzim.pyx":1288
  *             'libzim.writer': writer,
  *             'libzim.reader': reader,
  *             'libzim.search': search,             # <<<<<<<<<<<<<<
- *             'libzim.suggestion': suggestion
- *         }.get(spec.name, None)
+ *             'libzim.suggestion': suggestion,
+ *             'libzim.version': version
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_search); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1255, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_search); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1288, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_kp_u_libzim_search, __pyx_t_2) < 0) __PYX_ERR(0, 1253, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_kp_u_libzim_search, __pyx_t_2) < 0) __PYX_ERR(0, 1286, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":1256
+  /* "libzim.pyx":1289
  *             'libzim.reader': reader,
  *             'libzim.search': search,
- *             'libzim.suggestion': suggestion             # <<<<<<<<<<<<<<
+ *             'libzim.suggestion': suggestion,             # <<<<<<<<<<<<<<
+ *             'libzim.version': version
  *         }.get(spec.name, None)
- * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_suggestion); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1256, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_suggestion); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1289, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_kp_u_libzim_suggestion, __pyx_t_2) < 0) __PYX_ERR(0, 1253, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_1, __pyx_kp_u_libzim_suggestion, __pyx_t_2) < 0) __PYX_ERR(0, 1286, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":1257
+  /* "libzim.pyx":1290
  *             'libzim.search': search,
- *             'libzim.suggestion': suggestion
+ *             'libzim.suggestion': suggestion,
+ *             'libzim.version': version             # <<<<<<<<<<<<<<
+ *         }.get(spec.name, None)
+ * 
+ */
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_version); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1290, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_1, __pyx_kp_u_libzim_version, __pyx_t_2) < 0) __PYX_ERR(0, 1286, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "libzim.pyx":1291
+ *             'libzim.suggestion': suggestion,
+ *             'libzim.version': version
  *         }.get(spec.name, None)             # <<<<<<<<<<<<<<
  * 
  *     @staticmethod
  */
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_spec, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1257, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_spec, __pyx_n_s_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1291, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = __Pyx_PyDict_GetItemDefault(__pyx_t_1, __pyx_t_2, Py_None); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1257, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyDict_GetItemDefault(__pyx_t_1, __pyx_t_2, Py_None); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1291, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
@@ -20504,7 +21023,7 @@ static PyObject *__pyx_pf_6libzim_12ModuleLoader_create_module(CYTHON_UNUSED PyO
   __pyx_t_3 = 0;
   goto __pyx_L0;
 
-  /* "libzim.pyx":1251
+  /* "libzim.pyx":1284
  *     # Create our module. Easy, just return the created module
  *     @staticmethod
  *     def create_module(spec):             # <<<<<<<<<<<<<<
@@ -20525,7 +21044,7 @@ static PyObject *__pyx_pf_6libzim_12ModuleLoader_create_module(CYTHON_UNUSED PyO
   return __pyx_r;
 }
 
-/* "libzim.pyx":1260
+/* "libzim.pyx":1294
  * 
  *     @staticmethod
  *     def exec_module(module):             # <<<<<<<<<<<<<<
@@ -20559,7 +21078,7 @@ static PyObject *__pyx_pf_6libzim_12ModuleLoader_2exec_module(CYTHON_UNUSED PyOb
   return __pyx_r;
 }
 
-/* "libzim.pyx":1266
+/* "libzim.pyx":1300
  * 
  * class ModuleFinder(importlib.abc.MetaPathFinder):
  *     def find_spec(self, fullname, path, target=None):             # <<<<<<<<<<<<<<
@@ -20609,13 +21128,13 @@ static PyObject *__pyx_pw_6libzim_12ModuleFinder_1find_spec(PyObject *__pyx_self
         case  1:
         if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_fullname)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("find_spec", 0, 3, 4, 1); __PYX_ERR(0, 1266, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("find_spec", 0, 3, 4, 1); __PYX_ERR(0, 1300, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  2:
         if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_path)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("find_spec", 0, 3, 4, 2); __PYX_ERR(0, 1266, __pyx_L3_error)
+          __Pyx_RaiseArgtupleInvalid("find_spec", 0, 3, 4, 2); __PYX_ERR(0, 1300, __pyx_L3_error)
         }
         CYTHON_FALLTHROUGH;
         case  3:
@@ -20625,7 +21144,7 @@ static PyObject *__pyx_pw_6libzim_12ModuleFinder_1find_spec(PyObject *__pyx_self
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "find_spec") < 0)) __PYX_ERR(0, 1266, __pyx_L3_error)
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "find_spec") < 0)) __PYX_ERR(0, 1300, __pyx_L3_error)
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -20645,7 +21164,7 @@ static PyObject *__pyx_pw_6libzim_12ModuleFinder_1find_spec(PyObject *__pyx_self
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("find_spec", 0, 3, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1266, __pyx_L3_error)
+  __Pyx_RaiseArgtupleInvalid("find_spec", 0, 3, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 1300, __pyx_L3_error)
   __pyx_L3_error:;
   __Pyx_AddTraceback("libzim.ModuleFinder.find_spec", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
@@ -20673,14 +21192,14 @@ static PyObject *__pyx_pf_6libzim_12ModuleFinder_find_spec(CYTHON_UNUSED PyObjec
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("find_spec", 0);
 
-  /* "libzim.pyx":1267
+  /* "libzim.pyx":1301
  * class ModuleFinder(importlib.abc.MetaPathFinder):
  *     def find_spec(self, fullname, path, target=None):
  *         if fullname.startswith("libzim."):             # <<<<<<<<<<<<<<
  *             return importlib.machinery.ModuleSpec(fullname, ModuleLoader)
  *         # This is not our problem, let import mechanism continue
  */
-  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_fullname, __pyx_n_s_startswith); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1267, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_fullname, __pyx_n_s_startswith); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1301, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __pyx_t_3 = NULL;
   if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
@@ -20694,14 +21213,14 @@ static PyObject *__pyx_pf_6libzim_12ModuleFinder_find_spec(CYTHON_UNUSED PyObjec
   }
   __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_kp_u_libzim_2) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_kp_u_libzim_2);
   __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1267, __pyx_L1_error)
+  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1301, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 1267, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 1301, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   if (__pyx_t_4) {
 
-    /* "libzim.pyx":1268
+    /* "libzim.pyx":1302
  *     def find_spec(self, fullname, path, target=None):
  *         if fullname.startswith("libzim."):
  *             return importlib.machinery.ModuleSpec(fullname, ModuleLoader)             # <<<<<<<<<<<<<<
@@ -20709,15 +21228,15 @@ static PyObject *__pyx_pf_6libzim_12ModuleFinder_find_spec(CYTHON_UNUSED PyObjec
  *         return None
  */
     __Pyx_XDECREF(__pyx_r);
-    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_importlib); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1268, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_importlib); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1302, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_machinery); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1268, __pyx_L1_error)
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_machinery); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1302, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_ModuleSpec); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1268, __pyx_L1_error)
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_ModuleSpec); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1302, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_2);
     __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_ModuleLoader); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1268, __pyx_L1_error)
+    __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_ModuleLoader); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1302, __pyx_L1_error)
     __Pyx_GOTREF(__pyx_t_3);
     __pyx_t_5 = NULL;
     __pyx_t_6 = 0;
@@ -20734,7 +21253,7 @@ static PyObject *__pyx_pf_6libzim_12ModuleFinder_find_spec(CYTHON_UNUSED PyObjec
     #if CYTHON_FAST_PYCALL
     if (PyFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_v_fullname, __pyx_t_3};
-      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1268, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1302, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
@@ -20743,14 +21262,14 @@ static PyObject *__pyx_pf_6libzim_12ModuleFinder_find_spec(CYTHON_UNUSED PyObjec
     #if CYTHON_FAST_PYCCALL
     if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
       PyObject *__pyx_temp[3] = {__pyx_t_5, __pyx_v_fullname, __pyx_t_3};
-      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1268, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_6, 2+__pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1302, __pyx_L1_error)
       __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
     } else
     #endif
     {
-      __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1268, __pyx_L1_error)
+      __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1302, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_7);
       if (__pyx_t_5) {
         __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
@@ -20761,7 +21280,7 @@ static PyObject *__pyx_pf_6libzim_12ModuleFinder_find_spec(CYTHON_UNUSED PyObjec
       __Pyx_GIVEREF(__pyx_t_3);
       PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_3);
       __pyx_t_3 = 0;
-      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1268, __pyx_L1_error)
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1302, __pyx_L1_error)
       __Pyx_GOTREF(__pyx_t_1);
       __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
     }
@@ -20770,7 +21289,7 @@ static PyObject *__pyx_pf_6libzim_12ModuleFinder_find_spec(CYTHON_UNUSED PyObjec
     __pyx_t_1 = 0;
     goto __pyx_L0;
 
-    /* "libzim.pyx":1267
+    /* "libzim.pyx":1301
  * class ModuleFinder(importlib.abc.MetaPathFinder):
  *     def find_spec(self, fullname, path, target=None):
  *         if fullname.startswith("libzim."):             # <<<<<<<<<<<<<<
@@ -20779,7 +21298,7 @@ static PyObject *__pyx_pf_6libzim_12ModuleFinder_find_spec(CYTHON_UNUSED PyObjec
  */
   }
 
-  /* "libzim.pyx":1270
+  /* "libzim.pyx":1304
  *             return importlib.machinery.ModuleSpec(fullname, ModuleLoader)
  *         # This is not our problem, let import mechanism continue
  *         return None             # <<<<<<<<<<<<<<
@@ -20790,7 +21309,7 @@ static PyObject *__pyx_pf_6libzim_12ModuleFinder_find_spec(CYTHON_UNUSED PyObjec
   __pyx_r = Py_None; __Pyx_INCREF(Py_None);
   goto __pyx_L0;
 
-  /* "libzim.pyx":1266
+  /* "libzim.pyx":1300
  * 
  * class ModuleFinder(importlib.abc.MetaPathFinder):
  *     def find_spec(self, fullname, path, target=None):             # <<<<<<<<<<<<<<
@@ -21233,6 +21752,70 @@ static PyObject *__pyx_convert_set_to_py_unsigned_int(std::set<unsigned int>  co
   return __pyx_r;
 }
 
+/* "pair.to_py":158
+ * 
+ * @cname("__pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string")
+ * cdef object __pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string(const pair[X,Y]& p):             # <<<<<<<<<<<<<<
+ *     return p.first, p.second
+ * 
+ */
+
+static PyObject *__pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string(std::pair<std::string,std::string>  const &__pyx_v_p) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string", 0);
+
+  /* "pair.to_py":159
+ * @cname("__pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string")
+ * cdef object __pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string(const pair[X,Y]& p):
+ *     return p.first, p.second             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_p.first); if (unlikely(!__pyx_t_1)) __PYX_ERR(1, 159, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __pyx_convert_PyBytes_string_to_py_std__in_string(__pyx_v_p.second); if (unlikely(!__pyx_t_2)) __PYX_ERR(1, 159, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 159, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
+  __pyx_r = __pyx_t_3;
+  __pyx_t_3 = 0;
+  goto __pyx_L0;
+
+  /* "pair.to_py":158
+ * 
+ * @cname("__pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string")
+ * cdef object __pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string(const pair[X,Y]& p):             # <<<<<<<<<<<<<<
+ *     return p.first, p.second
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("pair.to_py.__pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
 static PyObject *__pyx_tp_new_6libzim_WritingBlob(PyTypeObject *t, PyObject *a, PyObject *k) {
   struct __pyx_obj_6libzim_WritingBlob *p;
   PyObject *o;
@@ -23498,8 +24081,10 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_ModuleLoader_exec_module, __pyx_k_ModuleLoader_exec_module, sizeof(__pyx_k_ModuleLoader_exec_module), 0, 0, 1, 1},
   {&__pyx_n_s_ModuleSpec, __pyx_k_ModuleSpec, sizeof(__pyx_k_ModuleSpec), 0, 0, 1, 1},
   {&__pyx_n_s_ModuleType, __pyx_k_ModuleType, sizeof(__pyx_k_ModuleType), 0, 0, 1, 1},
+  {&__pyx_kp_u_None, __pyx_k_None, sizeof(__pyx_k_None), 0, 1, 0, 0},
   {&__pyx_n_s_NotImplementedError, __pyx_k_NotImplementedError, sizeof(__pyx_k_NotImplementedError), 0, 0, 1, 1},
   {&__pyx_n_s_Optional, __pyx_k_Optional, sizeof(__pyx_k_Optional), 0, 0, 1, 1},
+  {&__pyx_n_s_OrderedDict, __pyx_k_OrderedDict, sizeof(__pyx_k_OrderedDict), 0, 0, 1, 1},
   {&__pyx_n_s_Path, __pyx_k_Path, sizeof(__pyx_k_Path), 0, 0, 1, 1},
   {&__pyx_n_s_Query, __pyx_k_Query, sizeof(__pyx_k_Query), 0, 0, 1, 1},
   {&__pyx_n_s_ReadingBlob, __pyx_k_ReadingBlob, sizeof(__pyx_k_ReadingBlob), 0, 0, 1, 1},
@@ -23529,7 +24114,8 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_u_WritingBlob, __pyx_k_WritingBlob, sizeof(__pyx_k_WritingBlob), 0, 1, 0, 1},
   {&__pyx_kp_u_Y_m_d, __pyx_k_Y_m_d, sizeof(__pyx_k_Y_m_d), 0, 1, 0, 0},
   {&__pyx_kp_u__24, __pyx_k__24, sizeof(__pyx_k__24), 0, 1, 0, 0},
-  {&__pyx_n_u__25, __pyx_k__25, sizeof(__pyx_k__25), 0, 1, 0, 1},
+  {&__pyx_kp_u__50, __pyx_k__50, sizeof(__pyx_k__50), 0, 1, 0, 0},
+  {&__pyx_kp_u__51, __pyx_k__51, sizeof(__pyx_k__51), 0, 1, 0, 0},
   {&__pyx_n_s_abc, __pyx_k_abc, sizeof(__pyx_k_abc), 0, 0, 1, 1},
   {&__pyx_n_s_access, __pyx_k_access, sizeof(__pyx_k_access), 0, 0, 1, 1},
   {&__pyx_n_s_add_metadata, __pyx_k_add_metadata, sizeof(__pyx_k_add_metadata), 0, 0, 1, 1},
@@ -23543,6 +24129,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
   {&__pyx_n_s_cline_in_traceback, __pyx_k_cline_in_traceback, sizeof(__pyx_k_cline_in_traceback), 0, 0, 1, 1},
   {&__pyx_n_s_close, __pyx_k_close, sizeof(__pyx_k_close), 0, 0, 1, 1},
+  {&__pyx_n_s_collections, __pyx_k_collections, sizeof(__pyx_k_collections), 0, 0, 1, 1},
   {&__pyx_n_s_compression, __pyx_k_compression, sizeof(__pyx_k_compression), 0, 0, 1, 1},
   {&__pyx_n_s_config_compression, __pyx_k_config_compression, sizeof(__pyx_k_config_compression), 0, 0, 1, 1},
   {&__pyx_n_s_content, __pyx_k_content, sizeof(__pyx_k_content), 0, 0, 1, 1},
@@ -23550,6 +24137,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_create_module, __pyx_k_create_module, sizeof(__pyx_k_create_module), 0, 0, 1, 1},
   {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
   {&__pyx_n_s_datetime, __pyx_k_datetime, sizeof(__pyx_k_datetime), 0, 0, 1, 1},
+  {&__pyx_n_s_decode, __pyx_k_decode, sizeof(__pyx_k_decode), 0, 0, 1, 1},
   {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1},
   {&__pyx_n_s_doc_2, __pyx_k_doc_2, sizeof(__pyx_k_doc_2), 0, 0, 1, 1},
   {&__pyx_n_s_effective_ids, __pyx_k_effective_ids, sizeof(__pyx_k_effective_ids), 0, 0, 1, 1},
@@ -23564,6 +24152,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_expanduser, __pyx_k_expanduser, sizeof(__pyx_k_expanduser), 0, 0, 1, 1},
   {&__pyx_n_s_feed, __pyx_k_feed, sizeof(__pyx_k_feed), 0, 0, 1, 1},
   {&__pyx_n_s_fh, __pyx_k_fh, sizeof(__pyx_k_fh), 0, 0, 1, 1},
+  {&__pyx_n_s_file, __pyx_k_file, sizeof(__pyx_k_file), 0, 0, 1, 1},
   {&__pyx_n_s_filename, __pyx_k_filename, sizeof(__pyx_k_filename), 0, 0, 1, 1},
   {&__pyx_kp_u_filename_2, __pyx_k_filename_2, sizeof(__pyx_k_filename_2), 0, 1, 0, 0},
   {&__pyx_n_s_filepath, __pyx_k_filepath, sizeof(__pyx_k_filepath), 0, 0, 1, 1},
@@ -23583,6 +24172,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_u_get_hints_must_be_implemented, __pyx_k_get_hints_must_be_implemented, sizeof(__pyx_k_get_hints_must_be_implemented), 0, 1, 0, 0},
   {&__pyx_n_s_get_keywords, __pyx_k_get_keywords, sizeof(__pyx_k_get_keywords), 0, 0, 1, 1},
   {&__pyx_kp_u_get_keywords_must_be_implemented, __pyx_k_get_keywords_must_be_implemented, sizeof(__pyx_k_get_keywords_must_be_implemented), 0, 1, 0, 0},
+  {&__pyx_n_s_get_libzim_version, __pyx_k_get_libzim_version, sizeof(__pyx_k_get_libzim_version), 0, 0, 1, 1},
   {&__pyx_n_s_get_mimetype, __pyx_k_get_mimetype, sizeof(__pyx_k_get_mimetype), 0, 0, 1, 1},
   {&__pyx_kp_u_get_mimetype_must_be_implemented, __pyx_k_get_mimetype_must_be_implemented, sizeof(__pyx_k_get_mimetype_must_be_implemented), 0, 1, 0, 0},
   {&__pyx_n_s_get_path, __pyx_k_get_path, sizeof(__pyx_k_get_path), 0, 0, 1, 1},
@@ -23591,6 +24181,7 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_u_get_size_must_be_implemented, __pyx_k_get_size_must_be_implemented, sizeof(__pyx_k_get_size_must_be_implemented), 0, 1, 0, 0},
   {&__pyx_n_s_get_title, __pyx_k_get_title, sizeof(__pyx_k_get_title), 0, 0, 1, 1},
   {&__pyx_kp_u_get_title_must_be_implemented, __pyx_k_get_title_must_be_implemented, sizeof(__pyx_k_get_title_must_be_implemented), 0, 1, 0, 0},
+  {&__pyx_n_s_get_versions, __pyx_k_get_versions, sizeof(__pyx_k_get_versions), 0, 0, 1, 1},
   {&__pyx_n_s_get_wordcount, __pyx_k_get_wordcount, sizeof(__pyx_k_get_wordcount), 0, 0, 1, 1},
   {&__pyx_kp_u_get_wordcount_must_be_implemente, __pyx_k_get_wordcount_must_be_implemente, sizeof(__pyx_k_get_wordcount_must_be_implemente), 0, 1, 0, 0},
   {&__pyx_n_s_getsize, __pyx_k_getsize, sizeof(__pyx_k_getsize), 0, 0, 1, 1},
@@ -23607,9 +24198,10 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_u_int, __pyx_k_int, sizeof(__pyx_k_int), 0, 1, 0, 1},
   {&__pyx_n_s_items, __pyx_k_items, sizeof(__pyx_k_items), 0, 0, 1, 1},
   {&__pyx_n_s_iter, __pyx_k_iter, sizeof(__pyx_k_iter), 0, 0, 1, 1},
-  {&__pyx_n_s_keyword, __pyx_k_keyword, sizeof(__pyx_k_keyword), 0, 0, 1, 1},
   {&__pyx_n_s_language, __pyx_k_language, sizeof(__pyx_k_language), 0, 0, 1, 1},
+  {&__pyx_n_s_library, __pyx_k_library, sizeof(__pyx_k_library), 0, 0, 1, 1},
   {&__pyx_n_s_libzim, __pyx_k_libzim, sizeof(__pyx_k_libzim), 0, 0, 1, 1},
+  {&__pyx_n_u_libzim, __pyx_k_libzim, sizeof(__pyx_k_libzim), 0, 1, 0, 1},
   {&__pyx_kp_u_libzim_2, __pyx_k_libzim_2, sizeof(__pyx_k_libzim_2), 0, 1, 0, 0},
   {&__pyx_kp_s_libzim_libzim_pyx, __pyx_k_libzim_libzim_pyx, sizeof(__pyx_k_libzim_libzim_pyx), 0, 0, 1, 0},
   {&__pyx_kp_u_libzim_reader, __pyx_k_libzim_reader, sizeof(__pyx_k_libzim_reader), 0, 1, 0, 0},
@@ -23618,6 +24210,8 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_u_libzim_search_module_Query_to_pr, __pyx_k_libzim_search_module_Query_to_pr, sizeof(__pyx_k_libzim_search_module_Query_to_pr), 0, 1, 0, 0},
   {&__pyx_kp_u_libzim_suggestion, __pyx_k_libzim_suggestion, sizeof(__pyx_k_libzim_suggestion), 0, 1, 0, 0},
   {&__pyx_kp_u_libzim_suggestion_module_Suggest, __pyx_k_libzim_suggestion_module_Suggest, sizeof(__pyx_k_libzim_suggestion_module_Suggest), 0, 1, 0, 0},
+  {&__pyx_kp_u_libzim_version, __pyx_k_libzim_version, sizeof(__pyx_k_libzim_version), 0, 1, 0, 0},
+  {&__pyx_kp_u_libzim_version_module_Get_versio, __pyx_k_libzim_version_module_Get_versio, sizeof(__pyx_k_libzim_version_module_Get_versio), 0, 1, 0, 0},
   {&__pyx_kp_u_libzim_writer, __pyx_k_libzim_writer, sizeof(__pyx_k_libzim_writer), 0, 1, 0, 0},
   {&__pyx_kp_u_libzim_writer_module_Creator_to, __pyx_k_libzim_writer_module_Creator_to, sizeof(__pyx_k_libzim_writer_module_Creator_to), 0, 1, 0, 0},
   {&__pyx_n_s_lower, __pyx_k_lower, sizeof(__pyx_k_lower), 0, 0, 1, 1},
@@ -23640,13 +24234,16 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1},
   {&__pyx_n_s_open, __pyx_k_open, sizeof(__pyx_k_open), 0, 0, 1, 1},
   {&__pyx_n_s_os, __pyx_k_os, sizeof(__pyx_k_os), 0, 0, 1, 1},
+  {&__pyx_n_s_out, __pyx_k_out, sizeof(__pyx_k_out), 0, 0, 1, 1},
   {&__pyx_n_s_parent, __pyx_k_parent, sizeof(__pyx_k_parent), 0, 0, 1, 1},
-  {&__pyx_n_s_pascalize, __pyx_k_pascalize, sizeof(__pyx_k_pascalize), 0, 0, 1, 1},
   {&__pyx_n_s_path, __pyx_k_path, sizeof(__pyx_k_path), 0, 0, 1, 1},
   {&__pyx_kp_u_path_2, __pyx_k_path_2, sizeof(__pyx_k_path_2), 0, 1, 0, 0},
   {&__pyx_n_s_path_3, __pyx_k_path_3, sizeof(__pyx_k_path_3), 0, 0, 1, 1},
   {&__pyx_n_s_pathlib, __pyx_k_pathlib, sizeof(__pyx_k_pathlib), 0, 0, 1, 1},
+  {&__pyx_n_s_prefix, __pyx_k_prefix, sizeof(__pyx_k_prefix), 0, 0, 1, 1},
   {&__pyx_n_s_prepare, __pyx_k_prepare, sizeof(__pyx_k_prepare), 0, 0, 1, 1},
+  {&__pyx_n_s_print, __pyx_k_print, sizeof(__pyx_k_print), 0, 0, 1, 1},
+  {&__pyx_n_s_print_versions, __pyx_k_print_versions, sizeof(__pyx_k_print_versions), 0, 0, 1, 1},
   {&__pyx_n_s_pybool, __pyx_k_pybool, sizeof(__pyx_k_pybool), 0, 0, 1, 1},
   {&__pyx_n_s_pyint, __pyx_k_pyint, sizeof(__pyx_k_pyint), 0, 0, 1, 1},
   {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
@@ -23684,10 +24281,10 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_n_s_setstate_cython, __pyx_k_setstate_cython, sizeof(__pyx_k_setstate_cython), 0, 0, 1, 1},
   {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1},
   {&__pyx_n_s_spec, __pyx_k_spec, sizeof(__pyx_k_spec), 0, 0, 1, 1},
-  {&__pyx_n_s_split, __pyx_k_split, sizeof(__pyx_k_split), 0, 0, 1, 1},
   {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
   {&__pyx_n_s_startswith, __pyx_k_startswith, sizeof(__pyx_k_startswith), 0, 0, 1, 1},
   {&__pyx_n_s_staticmethod, __pyx_k_staticmethod, sizeof(__pyx_k_staticmethod), 0, 0, 1, 1},
+  {&__pyx_n_s_stdout, __pyx_k_stdout, sizeof(__pyx_k_stdout), 0, 0, 1, 1},
   {&__pyx_n_s_strftime, __pyx_k_strftime, sizeof(__pyx_k_strftime), 0, 0, 1, 1},
   {&__pyx_n_s_suggestion, __pyx_k_suggestion, sizeof(__pyx_k_suggestion), 0, 0, 1, 1},
   {&__pyx_n_u_suggestion, __pyx_k_suggestion, sizeof(__pyx_k_suggestion), 0, 1, 0, 1},
@@ -23712,6 +24309,13 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {&__pyx_kp_u_url, __pyx_k_url, sizeof(__pyx_k_url), 0, 1, 0, 0},
   {&__pyx_n_s_uuid, __pyx_k_uuid, sizeof(__pyx_k_uuid), 0, 0, 1, 1},
   {&__pyx_n_s_value, __pyx_k_value, sizeof(__pyx_k_value), 0, 0, 1, 1},
+  {&__pyx_n_s_version, __pyx_k_version, sizeof(__pyx_k_version), 0, 0, 1, 1},
+  {&__pyx_n_u_version, __pyx_k_version, sizeof(__pyx_k_version), 0, 1, 0, 1},
+  {&__pyx_kp_u_version_2, __pyx_k_version_2, sizeof(__pyx_k_version_2), 0, 1, 0, 0},
+  {&__pyx_n_s_version_module_doc, __pyx_k_version_module_doc, sizeof(__pyx_k_version_module_doc), 0, 0, 1, 1},
+  {&__pyx_n_s_version_module_name, __pyx_k_version_module_name, sizeof(__pyx_k_version_module_name), 0, 0, 1, 1},
+  {&__pyx_n_s_version_public_objects, __pyx_k_version_public_objects, sizeof(__pyx_k_version_public_objects), 0, 0, 1, 1},
+  {&__pyx_n_s_versions, __pyx_k_versions, sizeof(__pyx_k_versions), 0, 0, 1, 1},
   {&__pyx_n_s_writer, __pyx_k_writer, sizeof(__pyx_k_writer), 0, 0, 1, 1},
   {&__pyx_n_u_writer, __pyx_k_writer, sizeof(__pyx_k_writer), 0, 1, 0, 1},
   {&__pyx_kp_u_writer_2, __pyx_k_writer_2, sizeof(__pyx_k_writer_2), 0, 1, 0, 0},
@@ -23722,16 +24326,17 @@ static __Pyx_StringTabEntry __pyx_string_tab[] = {
   {0, 0, 0, 0, 0, 0, 0}
 };
 static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(void) {
-  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 1250, __pyx_L1_error)
-  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 110, __pyx_L1_error)
+  __pyx_builtin_staticmethod = __Pyx_GetBuiltinName(__pyx_n_s_staticmethod); if (!__pyx_builtin_staticmethod) __PYX_ERR(0, 1283, __pyx_L1_error)
+  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) __PYX_ERR(0, 111, __pyx_L1_error)
   __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(1, 2, __pyx_L1_error)
-  __pyx_builtin_IOError = __Pyx_GetBuiltinName(__pyx_n_s_IOError); if (!__pyx_builtin_IOError) __PYX_ERR(0, 262, __pyx_L1_error)
-  __pyx_builtin_NotImplementedError = __Pyx_GetBuiltinName(__pyx_n_s_NotImplementedError); if (!__pyx_builtin_NotImplementedError) __PYX_ERR(0, 421, __pyx_L1_error)
-  __pyx_builtin_StopIteration = __Pyx_GetBuiltinName(__pyx_n_s_StopIteration); if (!__pyx_builtin_StopIteration) __PYX_ERR(0, 435, __pyx_L1_error)
-  __pyx_builtin_super = __Pyx_GetBuiltinName(__pyx_n_s_super); if (!__pyx_builtin_super) __PYX_ERR(0, 449, __pyx_L1_error)
-  __pyx_builtin_open = __Pyx_GetBuiltinName(__pyx_n_s_open); if (!__pyx_builtin_open) __PYX_ERR(0, 472, __pyx_L1_error)
-  __pyx_builtin_BufferError = __Pyx_GetBuiltinName(__pyx_n_s_BufferError); if (!__pyx_builtin_BufferError) __PYX_ERR(0, 646, __pyx_L1_error)
-  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 848, __pyx_L1_error)
+  __pyx_builtin_IOError = __Pyx_GetBuiltinName(__pyx_n_s_IOError); if (!__pyx_builtin_IOError) __PYX_ERR(0, 263, __pyx_L1_error)
+  __pyx_builtin_NotImplementedError = __Pyx_GetBuiltinName(__pyx_n_s_NotImplementedError); if (!__pyx_builtin_NotImplementedError) __PYX_ERR(0, 422, __pyx_L1_error)
+  __pyx_builtin_StopIteration = __Pyx_GetBuiltinName(__pyx_n_s_StopIteration); if (!__pyx_builtin_StopIteration) __PYX_ERR(0, 436, __pyx_L1_error)
+  __pyx_builtin_super = __Pyx_GetBuiltinName(__pyx_n_s_super); if (!__pyx_builtin_super) __PYX_ERR(0, 450, __pyx_L1_error)
+  __pyx_builtin_open = __Pyx_GetBuiltinName(__pyx_n_s_open); if (!__pyx_builtin_open) __PYX_ERR(0, 473, __pyx_L1_error)
+  __pyx_builtin_BufferError = __Pyx_GetBuiltinName(__pyx_n_s_BufferError); if (!__pyx_builtin_BufferError) __PYX_ERR(0, 638, __pyx_L1_error)
+  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 840, __pyx_L1_error)
+  __pyx_builtin_print = __Pyx_GetBuiltinName(__pyx_n_s_print); if (!__pyx_builtin_print) __PYX_ERR(0, 1257, __pyx_L1_error)
   return 0;
   __pyx_L1_error:;
   return -1;
@@ -23741,25 +24346,25 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
 
-  /* "libzim.pyx":110
+  /* "libzim.pyx":111
  *             blob = call_method(obj, method)
  *             if blob is None:
  *                 raise RuntimeError("Blob is none")             # <<<<<<<<<<<<<<
  *             return move(blob.c_blob)
  *         except Exception as e:
  */
-  __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_u_Blob_is_none); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 110, __pyx_L1_error)
+  __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_u_Blob_is_none); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 111, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__2);
   __Pyx_GIVEREF(__pyx_tuple__2);
 
-  /* "libzim.pyx":122
+  /* "libzim.pyx":123
  *             contentProvider = call_method(obj, method)
  *             if not contentProvider:
  *                 raise RuntimeError("ContentProvider is None")             # <<<<<<<<<<<<<<
  *             return new zim.ContentProviderWrapper(<PyObject*>contentProvider)
  *         except Exception as e:
  */
-  __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_ContentProvider_is_None); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(0, 122, __pyx_L1_error)
+  __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_u_ContentProvider_is_None); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(0, 123, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__3);
   __Pyx_GIVEREF(__pyx_tuple__3);
 
@@ -23782,25 +24387,25 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__5);
   __Pyx_GIVEREF(__pyx_tuple__5);
 
-  /* "libzim.pyx":276
+  /* "libzim.pyx":277
  *         """Set creator verbosity (inside libzim). Default is off"""
  *         if self._started:
  *             raise RuntimeError("Creator started")             # <<<<<<<<<<<<<<
  *         self.c_creator.configVerbose(verbose)
  *         return self
  */
-  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_Creator_started); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(0, 276, __pyx_L1_error)
+  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_Creator_started); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(0, 277, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__6);
   __Pyx_GIVEREF(__pyx_tuple__6);
 
-  /* "libzim.pyx":351
+  /* "libzim.pyx":352
  *                     If the ZimCreator was already finalized"""
  *         if not self._started:
  *             raise RuntimeError("Creator not started")             # <<<<<<<<<<<<<<
  * 
  *         # Make a shared pointer to ZimArticleWrapper from the ZimArticle object
  */
-  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_u_Creator_not_started); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 351, __pyx_L1_error)
+  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_u_Creator_not_started); if (unlikely(!__pyx_tuple__7)) __PYX_ERR(0, 352, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__7);
   __Pyx_GIVEREF(__pyx_tuple__7);
 
@@ -23823,159 +24428,159 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
   __Pyx_GOTREF(__pyx_tuple__9);
   __Pyx_GIVEREF(__pyx_tuple__9);
 
-  /* "libzim.pyx":421
+  /* "libzim.pyx":422
  *     def get_size(self) -> pyint:
  *         """Size of get_data's result in bytes"""
  *         raise NotImplementedError("get_size must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def feed(self) -> WritingBlob:
  */
-  __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_u_get_size_must_be_implemented); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 421, __pyx_L1_error)
+  __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_u_get_size_must_be_implemented); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 422, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__10);
   __Pyx_GIVEREF(__pyx_tuple__10);
 
-  /* "libzim.pyx":436
+  /* "libzim.pyx":437
  *             self._blob = next(self.generator)
  *         except StopIteration:
  *             self._blob = WritingBlob("")             # <<<<<<<<<<<<<<
  * 
  *         return self._blob
  */
-  __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_u_); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(0, 436, __pyx_L1_error)
+  __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_u_); if (unlikely(!__pyx_tuple__11)) __PYX_ERR(0, 437, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__11);
   __Pyx_GIVEREF(__pyx_tuple__11);
 
-  /* "libzim.pyx":442
+  /* "libzim.pyx":443
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:
  *         """Generator yielding blobs for the content of the article"""
  *         raise NotImplementedError("gen_blob (ro feed) must be implemented")             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_u_gen_blob_ro_feed_must_be_impleme); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 442, __pyx_L1_error)
+  __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_u_gen_blob_ro_feed_must_be_impleme); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 443, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__12);
   __Pyx_GIVEREF(__pyx_tuple__12);
 
-  /* "libzim.pyx":472
+  /* "libzim.pyx":473
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:
  *         bsize = 1048576  # 1MiB chunk
  *         with open(self.filepath, "rb") as fh:             # <<<<<<<<<<<<<<
  *             res = fh.read(bsize)
  *             while res:
  */
-  __pyx_tuple__15 = PyTuple_Pack(3, Py_None, Py_None, Py_None); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(0, 472, __pyx_L1_error)
+  __pyx_tuple__15 = PyTuple_Pack(3, Py_None, Py_None, Py_None); if (unlikely(!__pyx_tuple__15)) __PYX_ERR(0, 473, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__15);
   __Pyx_GIVEREF(__pyx_tuple__15);
 
-  /* "libzim.pyx":490
+  /* "libzim.pyx":491
  *     def get_title(self) -> str:
  *         """Title to index. Might be the same as Item.get_title or not"""
  *         raise NotImplementedError("get_title must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_content(self) -> str:
  */
-  __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_u_get_title_must_be_implemented); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(0, 490, __pyx_L1_error)
+  __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_u_get_title_must_be_implemented); if (unlikely(!__pyx_tuple__16)) __PYX_ERR(0, 491, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__16);
   __Pyx_GIVEREF(__pyx_tuple__16);
 
-  /* "libzim.pyx":494
+  /* "libzim.pyx":495
  *     def get_content(self) -> str:
  *         """Content to index. Might be the same as Item.get_title or not"""
  *         raise NotImplementedError("get_content must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_keywords(self) -> str:
  */
-  __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_u_get_content_must_be_implemented); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(0, 494, __pyx_L1_error)
+  __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_u_get_content_must_be_implemented); if (unlikely(!__pyx_tuple__17)) __PYX_ERR(0, 495, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__17);
   __Pyx_GIVEREF(__pyx_tuple__17);
 
-  /* "libzim.pyx":500
+  /* "libzim.pyx":501
  * 
  *         Must be a string containing keywords separated by a space"""
  *         raise NotImplementedError("get_keywords must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_wordcount(self) -> int:
  */
-  __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_u_get_keywords_must_be_implemented); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(0, 500, __pyx_L1_error)
+  __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_u_get_keywords_must_be_implemented); if (unlikely(!__pyx_tuple__18)) __PYX_ERR(0, 501, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__18);
   __Pyx_GIVEREF(__pyx_tuple__18);
 
-  /* "libzim.pyx":504
+  /* "libzim.pyx":505
  *     def get_wordcount(self) -> int:
  *         """Number of word in content"""
  *         raise NotImplementedError("get_wordcount must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_geoposition(self) -> Optional[Tuple[float, float]]:
  */
-  __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_u_get_wordcount_must_be_implemente); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 504, __pyx_L1_error)
+  __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_u_get_wordcount_must_be_implemente); if (unlikely(!__pyx_tuple__19)) __PYX_ERR(0, 505, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__19);
   __Pyx_GIVEREF(__pyx_tuple__19);
 
-  /* "libzim.pyx":524
+  /* "libzim.pyx":525
  *     def get_path(self) -> str:
  *         """Full path of item"""
  *         raise NotImplementedError("get_path must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_title(self) -> str:
  */
-  __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_u_get_path_must_be_implemented); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(0, 524, __pyx_L1_error)
+  __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_u_get_path_must_be_implemented); if (unlikely(!__pyx_tuple__20)) __PYX_ERR(0, 525, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__20);
   __Pyx_GIVEREF(__pyx_tuple__20);
 
-  /* "libzim.pyx":532
+  /* "libzim.pyx":533
  *     def get_mimetype(self) -> str:
  *         """MIME-type of the item's content."""
  *         raise NotImplementedError("get_mimetype must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_contentprovider(self) -> ContentProvider:
  */
-  __pyx_tuple__21 = PyTuple_Pack(1, __pyx_kp_u_get_mimetype_must_be_implemented); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(0, 532, __pyx_L1_error)
+  __pyx_tuple__21 = PyTuple_Pack(1, __pyx_kp_u_get_mimetype_must_be_implemented); if (unlikely(!__pyx_tuple__21)) __PYX_ERR(0, 533, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__21);
   __Pyx_GIVEREF(__pyx_tuple__21);
 
-  /* "libzim.pyx":536
+  /* "libzim.pyx":537
  *     def get_contentprovider(self) -> ContentProvider:
  *         """ContentProvider containing the complete content of the item"""
  *         raise NotImplementedError("get_contentprovider must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def get_hints(self) -> Dict[Hint, pyint]:
  */
-  __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_u_get_contentprovider_must_be_impl); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 536, __pyx_L1_error)
+  __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_u_get_contentprovider_must_be_impl); if (unlikely(!__pyx_tuple__22)) __PYX_ERR(0, 537, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__22);
   __Pyx_GIVEREF(__pyx_tuple__22);
 
-  /* "libzim.pyx":540
+  /* "libzim.pyx":541
  *     def get_hints(self) -> Dict[Hint, pyint]:
  *         """Dict of Hint: value informing Creator how to handle this item"""
  *         raise NotImplementedError("get_hints must be implemented.")             # <<<<<<<<<<<<<<
  * 
  *     def __repr__(self) -> str:
  */
-  __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_u_get_hints_must_be_implemented); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 540, __pyx_L1_error)
+  __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_u_get_hints_must_be_implemented); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 541, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__23);
   __Pyx_GIVEREF(__pyx_tuple__23);
 
-  /* "libzim.pyx":642
+  /* "libzim.pyx":634
  *     def __dealloc__(self):
  *         if self.view_count:
  *             raise RuntimeError("Blob has views")             # <<<<<<<<<<<<<<
  * 
  *     def __getbuffer__(self, Py_buffer *buffer, int flags):
  */
-  __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_u_Blob_has_views); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(0, 642, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__26);
-  __Pyx_GIVEREF(__pyx_tuple__26);
+  __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_u_Blob_has_views); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 634, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__25);
+  __Pyx_GIVEREF(__pyx_tuple__25);
 
-  /* "libzim.pyx":646
+  /* "libzim.pyx":638
  *     def __getbuffer__(self, Py_buffer *buffer, int flags):
  *         if flags&PyBUF_WRITABLE:
  *             raise BufferError("Cannot create writable memoryview on readonly data")             # <<<<<<<<<<<<<<
  *         buffer.obj = self
  *         buffer.buf = <void*>self.c_blob.data()
  */
-  __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_u_Cannot_create_writable_memoryvie); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(0, 646, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__27);
-  __Pyx_GIVEREF(__pyx_tuple__27);
+  __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_u_Cannot_create_writable_memoryvie); if (unlikely(!__pyx_tuple__26)) __PYX_ERR(0, 638, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__26);
+  __Pyx_GIVEREF(__pyx_tuple__26);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -23983,18 +24588,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_blob cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_self_c_blob_cannot_be_converted); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__28);
-  __Pyx_GIVEREF(__pyx_tuple__28);
+  __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_s_self_c_blob_cannot_be_converted); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__27);
+  __Pyx_GIVEREF(__pyx_tuple__27);
 
   /* "(tree fragment)":4
  *     raise TypeError("self.c_blob cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_blob cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_self_c_blob_cannot_be_converted); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__29);
-  __Pyx_GIVEREF(__pyx_tuple__29);
+  __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_self_c_blob_cannot_be_converted); if (unlikely(!__pyx_tuple__28)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__28);
+  __Pyx_GIVEREF(__pyx_tuple__28);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -24002,18 +24607,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_entry cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_self_c_entry_cannot_be_converted); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__30);
-  __Pyx_GIVEREF(__pyx_tuple__30);
+  __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_self_c_entry_cannot_be_converted); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__29);
+  __Pyx_GIVEREF(__pyx_tuple__29);
 
   /* "(tree fragment)":4
  *     raise TypeError("self.c_entry cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_entry cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_self_c_entry_cannot_be_converted); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__31);
-  __Pyx_GIVEREF(__pyx_tuple__31);
+  __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_self_c_entry_cannot_be_converted); if (unlikely(!__pyx_tuple__30)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__30);
+  __Pyx_GIVEREF(__pyx_tuple__30);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -24021,18 +24626,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_item cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__32 = PyTuple_Pack(1, __pyx_kp_s_self_c_item_cannot_be_converted); if (unlikely(!__pyx_tuple__32)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__32);
-  __Pyx_GIVEREF(__pyx_tuple__32);
+  __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_self_c_item_cannot_be_converted); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__31);
+  __Pyx_GIVEREF(__pyx_tuple__31);
 
   /* "(tree fragment)":4
  *     raise TypeError("self.c_item cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_item cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__33 = PyTuple_Pack(1, __pyx_kp_s_self_c_item_cannot_be_converted); if (unlikely(!__pyx_tuple__33)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__33);
-  __Pyx_GIVEREF(__pyx_tuple__33);
+  __pyx_tuple__32 = PyTuple_Pack(1, __pyx_kp_s_self_c_item_cannot_be_converted); if (unlikely(!__pyx_tuple__32)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__32);
+  __Pyx_GIVEREF(__pyx_tuple__32);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -24040,18 +24645,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  */
-  __pyx_tuple__34 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__34)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__34);
-  __Pyx_GIVEREF(__pyx_tuple__34);
+  __pyx_tuple__33 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__33)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__33);
+  __Pyx_GIVEREF(__pyx_tuple__33);
 
   /* "(tree fragment)":4
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__35 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__35)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__35);
-  __Pyx_GIVEREF(__pyx_tuple__35);
+  __pyx_tuple__34 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__34)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__34);
+  __Pyx_GIVEREF(__pyx_tuple__34);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -24059,18 +24664,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_query cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__36 = PyTuple_Pack(1, __pyx_kp_s_self_c_query_cannot_be_converted); if (unlikely(!__pyx_tuple__36)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__36);
-  __Pyx_GIVEREF(__pyx_tuple__36);
+  __pyx_tuple__35 = PyTuple_Pack(1, __pyx_kp_s_self_c_query_cannot_be_converted); if (unlikely(!__pyx_tuple__35)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__35);
+  __Pyx_GIVEREF(__pyx_tuple__35);
 
   /* "(tree fragment)":4
  *     raise TypeError("self.c_query cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_query cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__37 = PyTuple_Pack(1, __pyx_kp_s_self_c_query_cannot_be_converted); if (unlikely(!__pyx_tuple__37)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__37);
-  __Pyx_GIVEREF(__pyx_tuple__37);
+  __pyx_tuple__36 = PyTuple_Pack(1, __pyx_kp_s_self_c_query_cannot_be_converted); if (unlikely(!__pyx_tuple__36)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__36);
+  __Pyx_GIVEREF(__pyx_tuple__36);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -24078,18 +24683,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_resultset cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__38 = PyTuple_Pack(1, __pyx_kp_s_self_c_resultset_cannot_be_conve); if (unlikely(!__pyx_tuple__38)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__38);
-  __Pyx_GIVEREF(__pyx_tuple__38);
+  __pyx_tuple__37 = PyTuple_Pack(1, __pyx_kp_s_self_c_resultset_cannot_be_conve); if (unlikely(!__pyx_tuple__37)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__37);
+  __Pyx_GIVEREF(__pyx_tuple__37);
 
   /* "(tree fragment)":4
  *     raise TypeError("self.c_resultset cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_resultset cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__39 = PyTuple_Pack(1, __pyx_kp_s_self_c_resultset_cannot_be_conve); if (unlikely(!__pyx_tuple__39)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__39);
-  __Pyx_GIVEREF(__pyx_tuple__39);
+  __pyx_tuple__38 = PyTuple_Pack(1, __pyx_kp_s_self_c_resultset_cannot_be_conve); if (unlikely(!__pyx_tuple__38)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__38);
+  __Pyx_GIVEREF(__pyx_tuple__38);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -24097,18 +24702,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_search cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__40 = PyTuple_Pack(1, __pyx_kp_s_self_c_search_cannot_be_converte); if (unlikely(!__pyx_tuple__40)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__40);
-  __Pyx_GIVEREF(__pyx_tuple__40);
+  __pyx_tuple__39 = PyTuple_Pack(1, __pyx_kp_s_self_c_search_cannot_be_converte); if (unlikely(!__pyx_tuple__39)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__39);
+  __Pyx_GIVEREF(__pyx_tuple__39);
 
   /* "(tree fragment)":4
  *     raise TypeError("self.c_search cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_search cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__41 = PyTuple_Pack(1, __pyx_kp_s_self_c_search_cannot_be_converte); if (unlikely(!__pyx_tuple__41)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__41);
-  __Pyx_GIVEREF(__pyx_tuple__41);
+  __pyx_tuple__40 = PyTuple_Pack(1, __pyx_kp_s_self_c_search_cannot_be_converte); if (unlikely(!__pyx_tuple__40)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__40);
+  __Pyx_GIVEREF(__pyx_tuple__40);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -24116,18 +24721,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  */
-  __pyx_tuple__42 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__42)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__42);
-  __Pyx_GIVEREF(__pyx_tuple__42);
+  __pyx_tuple__41 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__41)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__41);
+  __Pyx_GIVEREF(__pyx_tuple__41);
 
   /* "(tree fragment)":4
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__43 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__43)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__43);
-  __Pyx_GIVEREF(__pyx_tuple__43);
+  __pyx_tuple__42 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__42)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__42);
+  __Pyx_GIVEREF(__pyx_tuple__42);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -24135,18 +24740,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_resultset cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__44 = PyTuple_Pack(1, __pyx_kp_s_self_c_resultset_cannot_be_conve); if (unlikely(!__pyx_tuple__44)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__44);
-  __Pyx_GIVEREF(__pyx_tuple__44);
+  __pyx_tuple__43 = PyTuple_Pack(1, __pyx_kp_s_self_c_resultset_cannot_be_conve); if (unlikely(!__pyx_tuple__43)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__43);
+  __Pyx_GIVEREF(__pyx_tuple__43);
 
   /* "(tree fragment)":4
  *     raise TypeError("self.c_resultset cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_resultset cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__45 = PyTuple_Pack(1, __pyx_kp_s_self_c_resultset_cannot_be_conve); if (unlikely(!__pyx_tuple__45)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__45);
-  __Pyx_GIVEREF(__pyx_tuple__45);
+  __pyx_tuple__44 = PyTuple_Pack(1, __pyx_kp_s_self_c_resultset_cannot_be_conve); if (unlikely(!__pyx_tuple__44)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__44);
+  __Pyx_GIVEREF(__pyx_tuple__44);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -24154,18 +24759,18 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_search cannot be converted to a Python object for pickling")
  */
-  __pyx_tuple__46 = PyTuple_Pack(1, __pyx_kp_s_self_c_search_cannot_be_converte); if (unlikely(!__pyx_tuple__46)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__46);
-  __Pyx_GIVEREF(__pyx_tuple__46);
+  __pyx_tuple__45 = PyTuple_Pack(1, __pyx_kp_s_self_c_search_cannot_be_converte); if (unlikely(!__pyx_tuple__45)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__45);
+  __Pyx_GIVEREF(__pyx_tuple__45);
 
   /* "(tree fragment)":4
  *     raise TypeError("self.c_search cannot be converted to a Python object for pickling")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("self.c_search cannot be converted to a Python object for pickling")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__47 = PyTuple_Pack(1, __pyx_kp_s_self_c_search_cannot_be_converte); if (unlikely(!__pyx_tuple__47)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__47);
-  __Pyx_GIVEREF(__pyx_tuple__47);
+  __pyx_tuple__46 = PyTuple_Pack(1, __pyx_kp_s_self_c_search_cannot_be_converte); if (unlikely(!__pyx_tuple__46)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__46);
+  __Pyx_GIVEREF(__pyx_tuple__46);
 
   /* "(tree fragment)":2
  * def __reduce_cython__(self):
@@ -24173,396 +24778,417 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  */
-  __pyx_tuple__48 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__48)) __PYX_ERR(1, 2, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__48);
-  __Pyx_GIVEREF(__pyx_tuple__48);
+  __pyx_tuple__47 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__47)) __PYX_ERR(1, 2, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__47);
+  __Pyx_GIVEREF(__pyx_tuple__47);
 
   /* "(tree fragment)":4
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")
  * def __setstate_cython__(self, __pyx_state):
  *     raise TypeError("no default __reduce__ due to non-trivial __cinit__")             # <<<<<<<<<<<<<<
  */
-  __pyx_tuple__49 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__49)) __PYX_ERR(1, 4, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__49);
-  __Pyx_GIVEREF(__pyx_tuple__49);
+  __pyx_tuple__48 = PyTuple_Pack(1, __pyx_kp_s_no_default___reduce___due_to_non); if (unlikely(!__pyx_tuple__48)) __PYX_ERR(1, 4, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__48);
+  __Pyx_GIVEREF(__pyx_tuple__48);
 
-  /* "libzim.pyx":61
+  /* "libzim.pyx":62
  * pyint = type(1)
  * 
  * def create_module(name, doc, members):             # <<<<<<<<<<<<<<
  *     """Create/define a module for name and docstring, populated by members"""
  *     module = ModuleType(name, doc)
  */
-  __pyx_tuple__50 = PyTuple_Pack(6, __pyx_n_s_name, __pyx_n_s_doc, __pyx_n_s_members, __pyx_n_s_module, __pyx_n_s_all_2, __pyx_n_s_obj); if (unlikely(!__pyx_tuple__50)) __PYX_ERR(0, 61, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__50);
-  __Pyx_GIVEREF(__pyx_tuple__50);
-  __pyx_codeobj__51 = (PyObject*)__Pyx_PyCode_New(3, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__50, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_create_module, 61, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__51)) __PYX_ERR(0, 61, __pyx_L1_error)
+  __pyx_tuple__52 = PyTuple_Pack(6, __pyx_n_s_name, __pyx_n_s_doc, __pyx_n_s_members, __pyx_n_s_module, __pyx_n_s_all_2, __pyx_n_s_obj); if (unlikely(!__pyx_tuple__52)) __PYX_ERR(0, 62, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__52);
+  __Pyx_GIVEREF(__pyx_tuple__52);
+  __pyx_codeobj__53 = (PyObject*)__Pyx_PyCode_New(3, 0, 6, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__52, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_create_module, 62, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__53)) __PYX_ERR(0, 62, __pyx_L1_error)
 
-  /* "libzim.pyx":416
+  /* "libzim.pyx":417
  * class ContentProvider:
  *     __module__ = writer_module_name
  *     def __init__(self):             # <<<<<<<<<<<<<<
  *         self.generator = None
  * 
  */
-  __pyx_tuple__52 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__52)) __PYX_ERR(0, 416, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__52);
-  __Pyx_GIVEREF(__pyx_tuple__52);
-  __pyx_codeobj__53 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__52, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_init, 416, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__53)) __PYX_ERR(0, 416, __pyx_L1_error)
+  __pyx_tuple__54 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__54)) __PYX_ERR(0, 417, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__54);
+  __Pyx_GIVEREF(__pyx_tuple__54);
+  __pyx_codeobj__55 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__54, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_init, 417, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__55)) __PYX_ERR(0, 417, __pyx_L1_error)
 
-  /* "libzim.pyx":419
+  /* "libzim.pyx":420
  *         self.generator = None
  * 
  *     def get_size(self) -> pyint:             # <<<<<<<<<<<<<<
  *         """Size of get_data's result in bytes"""
  *         raise NotImplementedError("get_size must be implemented.")
  */
-  __pyx_tuple__54 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__54)) __PYX_ERR(0, 419, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__54);
-  __Pyx_GIVEREF(__pyx_tuple__54);
-  __pyx_codeobj__55 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__54, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_size, 419, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__55)) __PYX_ERR(0, 419, __pyx_L1_error)
+  __pyx_tuple__56 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__56)) __PYX_ERR(0, 420, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__56);
+  __Pyx_GIVEREF(__pyx_tuple__56);
+  __pyx_codeobj__57 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__56, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_size, 420, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__57)) __PYX_ERR(0, 420, __pyx_L1_error)
 
-  /* "libzim.pyx":423
+  /* "libzim.pyx":424
  *         raise NotImplementedError("get_size must be implemented.")
  * 
  *     def feed(self) -> WritingBlob:             # <<<<<<<<<<<<<<
  *         """Blob(s) containing the complete content of the article.
  *         Must return an empty blob to tell writer no more content has to be written.
  */
-  __pyx_tuple__56 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__56)) __PYX_ERR(0, 423, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__56);
-  __Pyx_GIVEREF(__pyx_tuple__56);
-  __pyx_codeobj__57 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__56, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_feed, 423, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__57)) __PYX_ERR(0, 423, __pyx_L1_error)
+  __pyx_tuple__58 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__58)) __PYX_ERR(0, 424, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__58);
+  __Pyx_GIVEREF(__pyx_tuple__58);
+  __pyx_codeobj__59 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__58, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_feed, 424, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__59)) __PYX_ERR(0, 424, __pyx_L1_error)
 
-  /* "libzim.pyx":440
+  /* "libzim.pyx":441
  *         return self._blob
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
  *         """Generator yielding blobs for the content of the article"""
  *         raise NotImplementedError("gen_blob (ro feed) must be implemented")
  */
-  __pyx_tuple__58 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__58)) __PYX_ERR(0, 440, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__58);
-  __Pyx_GIVEREF(__pyx_tuple__58);
-  __pyx_codeobj__59 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__58, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_gen_blob, 440, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__59)) __PYX_ERR(0, 440, __pyx_L1_error)
+  __pyx_tuple__60 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__60)) __PYX_ERR(0, 441, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__60);
+  __Pyx_GIVEREF(__pyx_tuple__60);
+  __pyx_codeobj__61 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__60, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_gen_blob, 441, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__61)) __PYX_ERR(0, 441, __pyx_L1_error)
 
-  /* "libzim.pyx":448
+  /* "libzim.pyx":449
  *     """ContentProvider for a single encoded-or-not UTF-8 string"""
  *     __module__ = writer_module_name
  *     def __init__(self, content: Union[str, bytes]):             # <<<<<<<<<<<<<<
  *         super().__init__()
  *         self.content = content.encode("UTF-8") if isinstance(content, str) else content
  */
-  __pyx_tuple__60 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_content); if (unlikely(!__pyx_tuple__60)) __PYX_ERR(0, 448, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__60);
-  __Pyx_GIVEREF(__pyx_tuple__60);
-  __pyx_codeobj__61 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__60, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_init, 448, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__61)) __PYX_ERR(0, 448, __pyx_L1_error)
+  __pyx_tuple__62 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_content); if (unlikely(!__pyx_tuple__62)) __PYX_ERR(0, 449, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__62);
+  __Pyx_GIVEREF(__pyx_tuple__62);
+  __pyx_codeobj__63 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__62, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_init, 449, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__63)) __PYX_ERR(0, 449, __pyx_L1_error)
 
-  /* "libzim.pyx":452
+  /* "libzim.pyx":453
  *         self.content = content.encode("UTF-8") if isinstance(content, str) else content
  * 
  *     def get_size(self) -> pyint:             # <<<<<<<<<<<<<<
  *         return len(self.content)
  * 
  */
-  __pyx_tuple__62 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__62)) __PYX_ERR(0, 452, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__62);
-  __Pyx_GIVEREF(__pyx_tuple__62);
-  __pyx_codeobj__63 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__62, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_size, 452, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__63)) __PYX_ERR(0, 452, __pyx_L1_error)
+  __pyx_tuple__64 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__64)) __PYX_ERR(0, 453, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__64);
+  __Pyx_GIVEREF(__pyx_tuple__64);
+  __pyx_codeobj__65 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__64, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_size, 453, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__65)) __PYX_ERR(0, 453, __pyx_L1_error)
 
-  /* "libzim.pyx":455
+  /* "libzim.pyx":456
  *         return len(self.content)
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
  *         yield WritingBlob(self.content)
  * 
  */
-  __pyx_tuple__64 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__64)) __PYX_ERR(0, 455, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__64);
-  __Pyx_GIVEREF(__pyx_tuple__64);
-  __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__64, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_gen_blob, 455, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) __PYX_ERR(0, 455, __pyx_L1_error)
+  __pyx_tuple__66 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__66)) __PYX_ERR(0, 456, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__66);
+  __Pyx_GIVEREF(__pyx_tuple__66);
+  __pyx_codeobj__13 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__66, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_gen_blob, 456, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__13)) __PYX_ERR(0, 456, __pyx_L1_error)
 
-  /* "libzim.pyx":462
+  /* "libzim.pyx":463
  *     """ContentProvider for a file using its local path"""
  *     __module__ = writer_module_name
  *     def __init__(self, filepath: Union[pathlib.Path, str]):             # <<<<<<<<<<<<<<
  *         super().__init__()
  *         self.filepath = filepath
  */
-  __pyx_tuple__65 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_filepath); if (unlikely(!__pyx_tuple__65)) __PYX_ERR(0, 462, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__65);
-  __Pyx_GIVEREF(__pyx_tuple__65);
-  __pyx_codeobj__66 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__65, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_init, 462, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__66)) __PYX_ERR(0, 462, __pyx_L1_error)
+  __pyx_tuple__67 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_filepath); if (unlikely(!__pyx_tuple__67)) __PYX_ERR(0, 463, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__67);
+  __Pyx_GIVEREF(__pyx_tuple__67);
+  __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__67, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_init, 463, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) __PYX_ERR(0, 463, __pyx_L1_error)
 
-  /* "libzim.pyx":467
+  /* "libzim.pyx":468
  *         self.size = os.path.getsize(self.filepath)
  * 
  *     def get_size(self) -> pyint:             # <<<<<<<<<<<<<<
  *         return self.size
  * 
  */
-  __pyx_tuple__67 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__67)) __PYX_ERR(0, 467, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__67);
-  __Pyx_GIVEREF(__pyx_tuple__67);
-  __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__67, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_size, 467, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) __PYX_ERR(0, 467, __pyx_L1_error)
+  __pyx_tuple__69 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 468, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__69);
+  __Pyx_GIVEREF(__pyx_tuple__69);
+  __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_size, 468, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) __PYX_ERR(0, 468, __pyx_L1_error)
 
-  /* "libzim.pyx":470
+  /* "libzim.pyx":471
  *         return self.size
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
  *         bsize = 1048576  # 1MiB chunk
  *         with open(self.filepath, "rb") as fh:
  */
-  __pyx_tuple__69 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_bsize, __pyx_n_s_fh, __pyx_n_s_res); if (unlikely(!__pyx_tuple__69)) __PYX_ERR(0, 470, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__69);
-  __Pyx_GIVEREF(__pyx_tuple__69);
-  __pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(1, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_gen_blob, 470, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) __PYX_ERR(0, 470, __pyx_L1_error)
+  __pyx_tuple__71 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_bsize, __pyx_n_s_fh, __pyx_n_s_res); if (unlikely(!__pyx_tuple__71)) __PYX_ERR(0, 471, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__71);
+  __Pyx_GIVEREF(__pyx_tuple__71);
+  __pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(1, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__71, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_gen_blob, 471, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) __PYX_ERR(0, 471, __pyx_L1_error)
 
-  /* "libzim.pyx":484
+  /* "libzim.pyx":485
  *     __module__ = writer_module_name
  * 
  *     def has_indexdata(self) -> bool:             # <<<<<<<<<<<<<<
  *         """Return true if the IndexData actually contains data"""
  *         return False
  */
-  __pyx_tuple__70 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__70)) __PYX_ERR(0, 484, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__70);
-  __Pyx_GIVEREF(__pyx_tuple__70);
-  __pyx_codeobj__71 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__70, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_has_indexdata, 484, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__71)) __PYX_ERR(0, 484, __pyx_L1_error)
+  __pyx_tuple__72 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__72)) __PYX_ERR(0, 485, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__72);
+  __Pyx_GIVEREF(__pyx_tuple__72);
+  __pyx_codeobj__73 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__72, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_has_indexdata, 485, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__73)) __PYX_ERR(0, 485, __pyx_L1_error)
 
-  /* "libzim.pyx":488
+  /* "libzim.pyx":489
  *         return False
  * 
  *     def get_title(self) -> str:             # <<<<<<<<<<<<<<
  *         """Title to index. Might be the same as Item.get_title or not"""
  *         raise NotImplementedError("get_title must be implemented.")
  */
-  __pyx_tuple__72 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__72)) __PYX_ERR(0, 488, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__72);
-  __Pyx_GIVEREF(__pyx_tuple__72);
-  __pyx_codeobj__73 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__72, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_title, 488, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__73)) __PYX_ERR(0, 488, __pyx_L1_error)
+  __pyx_tuple__74 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__74)) __PYX_ERR(0, 489, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__74);
+  __Pyx_GIVEREF(__pyx_tuple__74);
+  __pyx_codeobj__75 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__74, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_title, 489, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__75)) __PYX_ERR(0, 489, __pyx_L1_error)
 
-  /* "libzim.pyx":492
+  /* "libzim.pyx":493
  *         raise NotImplementedError("get_title must be implemented.")
  * 
  *     def get_content(self) -> str:             # <<<<<<<<<<<<<<
  *         """Content to index. Might be the same as Item.get_title or not"""
  *         raise NotImplementedError("get_content must be implemented.")
  */
-  __pyx_tuple__74 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__74)) __PYX_ERR(0, 492, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__74);
-  __Pyx_GIVEREF(__pyx_tuple__74);
-  __pyx_codeobj__75 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__74, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_content, 492, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__75)) __PYX_ERR(0, 492, __pyx_L1_error)
+  __pyx_tuple__76 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__76)) __PYX_ERR(0, 493, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__76);
+  __Pyx_GIVEREF(__pyx_tuple__76);
+  __pyx_codeobj__77 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__76, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_content, 493, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__77)) __PYX_ERR(0, 493, __pyx_L1_error)
 
-  /* "libzim.pyx":496
+  /* "libzim.pyx":497
  *         raise NotImplementedError("get_content must be implemented.")
  * 
  *     def get_keywords(self) -> str:             # <<<<<<<<<<<<<<
  *         """Keywords used to index the item.
  * 
  */
-  __pyx_tuple__76 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__76)) __PYX_ERR(0, 496, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__76);
-  __Pyx_GIVEREF(__pyx_tuple__76);
-  __pyx_codeobj__77 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__76, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_keywords, 496, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__77)) __PYX_ERR(0, 496, __pyx_L1_error)
+  __pyx_tuple__78 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__78)) __PYX_ERR(0, 497, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__78);
+  __Pyx_GIVEREF(__pyx_tuple__78);
+  __pyx_codeobj__79 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__78, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_keywords, 497, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__79)) __PYX_ERR(0, 497, __pyx_L1_error)
 
-  /* "libzim.pyx":502
+  /* "libzim.pyx":503
  *         raise NotImplementedError("get_keywords must be implemented.")
  * 
  *     def get_wordcount(self) -> int:             # <<<<<<<<<<<<<<
  *         """Number of word in content"""
  *         raise NotImplementedError("get_wordcount must be implemented.")
  */
-  __pyx_tuple__78 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__78)) __PYX_ERR(0, 502, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__78);
-  __Pyx_GIVEREF(__pyx_tuple__78);
-  __pyx_codeobj__79 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__78, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_wordcount, 502, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__79)) __PYX_ERR(0, 502, __pyx_L1_error)
+  __pyx_tuple__80 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__80)) __PYX_ERR(0, 503, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__80);
+  __Pyx_GIVEREF(__pyx_tuple__80);
+  __pyx_codeobj__81 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__80, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_wordcount, 503, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__81)) __PYX_ERR(0, 503, __pyx_L1_error)
 
-  /* "libzim.pyx":506
+  /* "libzim.pyx":507
  *         raise NotImplementedError("get_wordcount must be implemented.")
  * 
  *     def get_geoposition(self) -> Optional[Tuple[float, float]]:             # <<<<<<<<<<<<<<
  *         """GeoPosition used to index the item.
  * 
  */
-  __pyx_tuple__80 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__80)) __PYX_ERR(0, 506, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__80);
-  __Pyx_GIVEREF(__pyx_tuple__80);
-  __pyx_codeobj__81 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__80, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_geoposition, 506, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__81)) __PYX_ERR(0, 506, __pyx_L1_error)
+  __pyx_tuple__82 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__82)) __PYX_ERR(0, 507, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__82);
+  __Pyx_GIVEREF(__pyx_tuple__82);
+  __pyx_codeobj__83 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__82, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_geoposition, 507, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__83)) __PYX_ERR(0, 507, __pyx_L1_error)
 
-  /* "libzim.pyx":519
+  /* "libzim.pyx":520
  *     __module__ = writer_module_name
  * 
  *     def __init__(self):             # <<<<<<<<<<<<<<
  *         self._blob = None
  * 
  */
-  __pyx_tuple__82 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__82)) __PYX_ERR(0, 519, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__82);
-  __Pyx_GIVEREF(__pyx_tuple__82);
-  __pyx_codeobj__83 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__82, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_init, 519, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__83)) __PYX_ERR(0, 519, __pyx_L1_error)
+  __pyx_tuple__84 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__84)) __PYX_ERR(0, 520, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__84);
+  __Pyx_GIVEREF(__pyx_tuple__84);
+  __pyx_codeobj__85 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__84, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_init, 520, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__85)) __PYX_ERR(0, 520, __pyx_L1_error)
 
-  /* "libzim.pyx":522
+  /* "libzim.pyx":523
  *         self._blob = None
  * 
  *     def get_path(self) -> str:             # <<<<<<<<<<<<<<
  *         """Full path of item"""
  *         raise NotImplementedError("get_path must be implemented.")
  */
-  __pyx_tuple__84 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__84)) __PYX_ERR(0, 522, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__84);
-  __Pyx_GIVEREF(__pyx_tuple__84);
-  __pyx_codeobj__85 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__84, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_path, 522, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__85)) __PYX_ERR(0, 522, __pyx_L1_error)
+  __pyx_tuple__86 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__86)) __PYX_ERR(0, 523, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__86);
+  __Pyx_GIVEREF(__pyx_tuple__86);
+  __pyx_codeobj__87 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__86, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_path, 523, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__87)) __PYX_ERR(0, 523, __pyx_L1_error)
 
-  /* "libzim.pyx":526
+  /* "libzim.pyx":527
  *         raise NotImplementedError("get_path must be implemented.")
  * 
  *     def get_title(self) -> str:             # <<<<<<<<<<<<<<
  *         """Item title. Might be indexed and used in suggestions"""
  *         raise NotImplementedError("get_title must be implemented.")
  */
-  __pyx_tuple__86 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__86)) __PYX_ERR(0, 526, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__86);
-  __Pyx_GIVEREF(__pyx_tuple__86);
-  __pyx_codeobj__87 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__86, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_title, 526, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__87)) __PYX_ERR(0, 526, __pyx_L1_error)
+  __pyx_tuple__88 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__88)) __PYX_ERR(0, 527, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__88);
+  __Pyx_GIVEREF(__pyx_tuple__88);
+  __pyx_codeobj__89 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__88, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_title, 527, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__89)) __PYX_ERR(0, 527, __pyx_L1_error)
 
-  /* "libzim.pyx":530
+  /* "libzim.pyx":531
  *         raise NotImplementedError("get_title must be implemented.")
  * 
  *     def get_mimetype(self) -> str:             # <<<<<<<<<<<<<<
  *         """MIME-type of the item's content."""
  *         raise NotImplementedError("get_mimetype must be implemented.")
  */
-  __pyx_tuple__88 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__88)) __PYX_ERR(0, 530, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__88);
-  __Pyx_GIVEREF(__pyx_tuple__88);
-  __pyx_codeobj__89 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__88, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_mimetype, 530, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__89)) __PYX_ERR(0, 530, __pyx_L1_error)
+  __pyx_tuple__90 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__90)) __PYX_ERR(0, 531, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__90);
+  __Pyx_GIVEREF(__pyx_tuple__90);
+  __pyx_codeobj__91 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__90, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_mimetype, 531, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__91)) __PYX_ERR(0, 531, __pyx_L1_error)
 
-  /* "libzim.pyx":534
+  /* "libzim.pyx":535
  *         raise NotImplementedError("get_mimetype must be implemented.")
  * 
  *     def get_contentprovider(self) -> ContentProvider:             # <<<<<<<<<<<<<<
  *         """ContentProvider containing the complete content of the item"""
  *         raise NotImplementedError("get_contentprovider must be implemented.")
  */
-  __pyx_tuple__90 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__90)) __PYX_ERR(0, 534, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__90);
-  __Pyx_GIVEREF(__pyx_tuple__90);
-  __pyx_codeobj__91 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__90, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_contentprovider, 534, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__91)) __PYX_ERR(0, 534, __pyx_L1_error)
+  __pyx_tuple__92 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__92)) __PYX_ERR(0, 535, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__92);
+  __Pyx_GIVEREF(__pyx_tuple__92);
+  __pyx_codeobj__93 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__92, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_contentprovider, 535, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__93)) __PYX_ERR(0, 535, __pyx_L1_error)
 
-  /* "libzim.pyx":538
+  /* "libzim.pyx":539
  *         raise NotImplementedError("get_contentprovider must be implemented.")
  * 
  *     def get_hints(self) -> Dict[Hint, pyint]:             # <<<<<<<<<<<<<<
  *         """Dict of Hint: value informing Creator how to handle this item"""
  *         raise NotImplementedError("get_hints must be implemented.")
  */
-  __pyx_tuple__92 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__92)) __PYX_ERR(0, 538, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__92);
-  __Pyx_GIVEREF(__pyx_tuple__92);
-  __pyx_codeobj__93 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__92, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_hints, 538, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__93)) __PYX_ERR(0, 538, __pyx_L1_error)
+  __pyx_tuple__94 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__94)) __PYX_ERR(0, 539, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__94);
+  __Pyx_GIVEREF(__pyx_tuple__94);
+  __pyx_codeobj__95 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__94, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_hints, 539, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__95)) __PYX_ERR(0, 539, __pyx_L1_error)
 
-  /* "libzim.pyx":542
+  /* "libzim.pyx":543
  *         raise NotImplementedError("get_hints must be implemented.")
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
  *         return (
  *             f"{self.__class__.__name__}(path={self.get_path()}, "
  */
-  __pyx_tuple__94 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__94)) __PYX_ERR(0, 542, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__94);
-  __Pyx_GIVEREF(__pyx_tuple__94);
-  __pyx_codeobj__95 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__94, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_repr, 542, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__95)) __PYX_ERR(0, 542, __pyx_L1_error)
-
-  /* "libzim.pyx":549
- * 
- * 
- * def pascalize(keyword: str):             # <<<<<<<<<<<<<<
- *     """Converts python case to pascal case.
- * 
- */
-  __pyx_tuple__96 = PyTuple_Pack(1, __pyx_n_s_keyword); if (unlikely(!__pyx_tuple__96)) __PYX_ERR(0, 549, __pyx_L1_error)
+  __pyx_tuple__96 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__96)) __PYX_ERR(0, 543, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__96);
   __Pyx_GIVEREF(__pyx_tuple__96);
-  __pyx_codeobj__97 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__96, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_pascalize, 549, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__97)) __PYX_ERR(0, 549, __pyx_L1_error)
+  __pyx_codeobj__97 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__96, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_repr, 543, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__97)) __PYX_ERR(0, 543, __pyx_L1_error)
 
-  /* "libzim.pyx":558
+  /* "libzim.pyx":552
  * class Creator(_Creator):
  *     __module__ = writer_module_name
  *     def config_compression(self, compression: Compression):             # <<<<<<<<<<<<<<
  *         if not isinstance(compression, Compression):
  *             compression = getattr(Compression, compression.lower())
  */
-  __pyx_tuple__98 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_compression); if (unlikely(!__pyx_tuple__98)) __PYX_ERR(0, 558, __pyx_L1_error)
+  __pyx_tuple__98 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_compression); if (unlikely(!__pyx_tuple__98)) __PYX_ERR(0, 552, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__98);
   __Pyx_GIVEREF(__pyx_tuple__98);
-  __pyx_codeobj__99 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__98, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_config_compression, 558, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__99)) __PYX_ERR(0, 558, __pyx_L1_error)
+  __pyx_codeobj__99 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__98, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_config_compression, 552, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__99)) __PYX_ERR(0, 552, __pyx_L1_error)
 
-  /* "libzim.pyx":563
+  /* "libzim.pyx":557
  *         return super().config_compression(compression)
  * 
  *     def add_metadata(             # <<<<<<<<<<<<<<
  *         self, name: str, content: Union[str, bytes, datetime.date, datetime.datetime],
  *         mimetype: str = "text/plain;charset=UTF-8"
  */
-  __pyx_tuple__100 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_name, __pyx_n_s_content, __pyx_n_s_mimetype); if (unlikely(!__pyx_tuple__100)) __PYX_ERR(0, 563, __pyx_L1_error)
+  __pyx_tuple__100 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_name, __pyx_n_s_content, __pyx_n_s_mimetype); if (unlikely(!__pyx_tuple__100)) __PYX_ERR(0, 557, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__100);
   __Pyx_GIVEREF(__pyx_tuple__100);
-  __pyx_codeobj__101 = (PyObject*)__Pyx_PyCode_New(4, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__100, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_add_metadata, 563, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__101)) __PYX_ERR(0, 563, __pyx_L1_error)
-  __pyx_tuple__102 = PyTuple_Pack(1, ((PyObject*)__pyx_kp_u_text_plain_charset_UTF_8)); if (unlikely(!__pyx_tuple__102)) __PYX_ERR(0, 563, __pyx_L1_error)
+  __pyx_codeobj__101 = (PyObject*)__Pyx_PyCode_New(4, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__100, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_add_metadata, 557, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__101)) __PYX_ERR(0, 557, __pyx_L1_error)
+  __pyx_tuple__102 = PyTuple_Pack(1, ((PyObject*)__pyx_kp_u_text_plain_charset_UTF_8)); if (unlikely(!__pyx_tuple__102)) __PYX_ERR(0, 557, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__102);
   __Pyx_GIVEREF(__pyx_tuple__102);
 
-  /* "libzim.pyx":574
+  /* "libzim.pyx":567
  *         super().add_metadata(name=name, content=content, mimetype=mimetype)
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
  *         return f"Creator(filename={self.filename})"
  * 
  */
-  __pyx_tuple__103 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__103)) __PYX_ERR(0, 574, __pyx_L1_error)
+  __pyx_tuple__103 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__103)) __PYX_ERR(0, 567, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_tuple__103);
   __Pyx_GIVEREF(__pyx_tuple__103);
-  __pyx_codeobj__104 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__103, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_repr, 574, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__104)) __PYX_ERR(0, 574, __pyx_L1_error)
+  __pyx_codeobj__104 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__103, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_repr, 567, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__104)) __PYX_ERR(0, 567, __pyx_L1_error)
+
+  /* "libzim.pyx":1253
+ * 
+ * 
+ * def print_versions(out: Union[sys.stdout, sys.stderr] = sys.stdout):             # <<<<<<<<<<<<<<
+ *     """print libzim and its dependencies list with their versions"""
+ *     for library, version in get_versions().items():
+ */
+  __pyx_tuple__105 = PyTuple_Pack(4, __pyx_n_s_out, __pyx_n_s_library, __pyx_n_s_version, __pyx_n_s_prefix); if (unlikely(!__pyx_tuple__105)) __PYX_ERR(0, 1253, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__105);
+  __Pyx_GIVEREF(__pyx_tuple__105);
+  __pyx_codeobj__106 = (PyObject*)__Pyx_PyCode_New(1, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__105, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_print_versions, 1253, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__106)) __PYX_ERR(0, 1253, __pyx_L1_error)
+
+  /* "libzim.pyx":1260
+ * 
+ * 
+ * def get_versions() -> OrderedDict[str, str]:             # <<<<<<<<<<<<<<
+ *     """ library: version mapping. Always includes `libzim`"""
+ *     versions = zim.getVersions()
+ */
+  __pyx_tuple__107 = PyTuple_Pack(3, __pyx_n_s_versions, __pyx_n_s_library, __pyx_n_s_version); if (unlikely(!__pyx_tuple__107)) __PYX_ERR(0, 1260, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__107);
+  __Pyx_GIVEREF(__pyx_tuple__107);
+  __pyx_codeobj__108 = (PyObject*)__Pyx_PyCode_New(0, 0, 3, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__107, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_versions, 1260, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__108)) __PYX_ERR(0, 1260, __pyx_L1_error)
+
+  /* "libzim.pyx":1268
+ *     })
+ * 
+ * def get_libzim_version() -> str:             # <<<<<<<<<<<<<<
+ *     """libzim version string"""
+ *     return get_versions()["libzim"]
+ */
+  __pyx_codeobj__109 = (PyObject*)__Pyx_PyCode_New(0, 0, 0, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_get_libzim_version, 1268, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__109)) __PYX_ERR(0, 1268, __pyx_L1_error)
 
-  /* "libzim.pyx":1251
+  /* "libzim.pyx":1284
  *     # Create our module. Easy, just return the created module
  *     @staticmethod
  *     def create_module(spec):             # <<<<<<<<<<<<<<
  *         return {
  *             'libzim.writer': writer,
  */
-  __pyx_tuple__105 = PyTuple_Pack(1, __pyx_n_s_spec); if (unlikely(!__pyx_tuple__105)) __PYX_ERR(0, 1251, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__105);
-  __Pyx_GIVEREF(__pyx_tuple__105);
-  __pyx_codeobj__106 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__105, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_create_module, 1251, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__106)) __PYX_ERR(0, 1251, __pyx_L1_error)
+  __pyx_tuple__110 = PyTuple_Pack(1, __pyx_n_s_spec); if (unlikely(!__pyx_tuple__110)) __PYX_ERR(0, 1284, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__110);
+  __Pyx_GIVEREF(__pyx_tuple__110);
+  __pyx_codeobj__111 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__110, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_create_module, 1284, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__111)) __PYX_ERR(0, 1284, __pyx_L1_error)
 
-  /* "libzim.pyx":1260
+  /* "libzim.pyx":1294
  * 
  *     @staticmethod
  *     def exec_module(module):             # <<<<<<<<<<<<<<
  *         # Nothing to execute for our already existing module.
  *         # But we need to define exec_module to tell python not use the legacy import system.
  */
-  __pyx_tuple__107 = PyTuple_Pack(1, __pyx_n_s_module); if (unlikely(!__pyx_tuple__107)) __PYX_ERR(0, 1260, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__107);
-  __Pyx_GIVEREF(__pyx_tuple__107);
-  __pyx_codeobj__108 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__107, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_exec_module, 1260, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__108)) __PYX_ERR(0, 1260, __pyx_L1_error)
+  __pyx_tuple__112 = PyTuple_Pack(1, __pyx_n_s_module); if (unlikely(!__pyx_tuple__112)) __PYX_ERR(0, 1294, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__112);
+  __Pyx_GIVEREF(__pyx_tuple__112);
+  __pyx_codeobj__113 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__112, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_exec_module, 1294, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__113)) __PYX_ERR(0, 1294, __pyx_L1_error)
 
-  /* "libzim.pyx":1266
+  /* "libzim.pyx":1300
  * 
  * class ModuleFinder(importlib.abc.MetaPathFinder):
  *     def find_spec(self, fullname, path, target=None):             # <<<<<<<<<<<<<<
  *         if fullname.startswith("libzim."):
  *             return importlib.machinery.ModuleSpec(fullname, ModuleLoader)
  */
-  __pyx_tuple__109 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_fullname, __pyx_n_s_path, __pyx_n_s_target); if (unlikely(!__pyx_tuple__109)) __PYX_ERR(0, 1266, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__109);
-  __Pyx_GIVEREF(__pyx_tuple__109);
-  __pyx_codeobj__110 = (PyObject*)__Pyx_PyCode_New(4, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__109, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_find_spec, 1266, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__110)) __PYX_ERR(0, 1266, __pyx_L1_error)
-  __pyx_tuple__111 = PyTuple_Pack(1, ((PyObject *)Py_None)); if (unlikely(!__pyx_tuple__111)) __PYX_ERR(0, 1266, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_tuple__111);
-  __Pyx_GIVEREF(__pyx_tuple__111);
+  __pyx_tuple__114 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_fullname, __pyx_n_s_path, __pyx_n_s_target); if (unlikely(!__pyx_tuple__114)) __PYX_ERR(0, 1300, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__114);
+  __Pyx_GIVEREF(__pyx_tuple__114);
+  __pyx_codeobj__115 = (PyObject*)__Pyx_PyCode_New(4, 0, 4, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__114, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_libzim_libzim_pyx, __pyx_n_s_find_spec, 1300, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__115)) __PYX_ERR(0, 1300, __pyx_L1_error)
+  __pyx_tuple__116 = PyTuple_Pack(1, ((PyObject *)Py_None)); if (unlikely(!__pyx_tuple__116)) __PYX_ERR(0, 1300, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_tuple__116);
+  __Pyx_GIVEREF(__pyx_tuple__116);
   __Pyx_RefNannyFinishContext();
   return 0;
   __pyx_L1_error:;
@@ -24572,7 +25198,7 @@ static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(void) {
 
 static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void) {
   __pyx_umethod_PyDict_Type_get.type = (PyObject*)&PyDict_Type;
-  if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error);
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) __PYX_ERR(0, 1, __pyx_L1_error)
   __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) __PYX_ERR(0, 1, __pyx_L1_error)
   return 0;
@@ -24636,17 +25262,17 @@ static int __Pyx_modinit_type_init_code(void) {
   int __pyx_clineno = 0;
   __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0);
   /*--- Type init code ---*/
-  if (PyType_Ready(&__pyx_type_6libzim_WritingBlob) < 0) __PYX_ERR(0, 206, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim_WritingBlob) < 0) __PYX_ERR(0, 207, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim_WritingBlob.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_6libzim_WritingBlob.tp_dictoffset && __pyx_type_6libzim_WritingBlob.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_6libzim_WritingBlob.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_WritingBlob, (PyObject *)&__pyx_type_6libzim_WritingBlob) < 0) __PYX_ERR(0, 206, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_WritingBlob) < 0) __PYX_ERR(0, 206, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_WritingBlob, (PyObject *)&__pyx_type_6libzim_WritingBlob) < 0) __PYX_ERR(0, 207, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_WritingBlob) < 0) __PYX_ERR(0, 207, __pyx_L1_error)
   __pyx_ptype_6libzim_WritingBlob = &__pyx_type_6libzim_WritingBlob;
-  if (PyType_Ready(&__pyx_type_6libzim__Creator) < 0) __PYX_ERR(0, 239, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim__Creator) < 0) __PYX_ERR(0, 240, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim__Creator.tp_print = 0;
   #endif
@@ -24655,7 +25281,7 @@ static int __Pyx_modinit_type_init_code(void) {
   }
   #if CYTHON_UPDATE_DESCRIPTOR_DOC
   {
-    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_6libzim__Creator, "__init__"); if (unlikely(!wrapper)) __PYX_ERR(0, 239, __pyx_L1_error)
+    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_6libzim__Creator, "__init__"); if (unlikely(!wrapper)) __PYX_ERR(0, 240, __pyx_L1_error)
     if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
       __pyx_wrapperbase_6libzim_8_Creator_2__init__ = *((PyWrapperDescrObject *)wrapper)->d_base;
       __pyx_wrapperbase_6libzim_8_Creator_2__init__.doc = __pyx_doc_6libzim_8_Creator_2__init__;
@@ -24663,71 +25289,71 @@ static int __Pyx_modinit_type_init_code(void) {
     }
   }
   #endif
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Creator, (PyObject *)&__pyx_type_6libzim__Creator) < 0) __PYX_ERR(0, 239, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim__Creator) < 0) __PYX_ERR(0, 239, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Creator, (PyObject *)&__pyx_type_6libzim__Creator) < 0) __PYX_ERR(0, 240, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim__Creator) < 0) __PYX_ERR(0, 240, __pyx_L1_error)
   __pyx_ptype_6libzim__Creator = &__pyx_type_6libzim__Creator;
   __pyx_vtabptr_6libzim_ReadingBlob = &__pyx_vtable_6libzim_ReadingBlob;
   __pyx_vtable_6libzim_ReadingBlob.from_blob = (PyObject *(*)(wrapper::Blob))__pyx_f_6libzim_11ReadingBlob_from_blob;
-  if (PyType_Ready(&__pyx_type_6libzim_ReadingBlob) < 0) __PYX_ERR(0, 615, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim_ReadingBlob) < 0) __PYX_ERR(0, 607, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim_ReadingBlob.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_6libzim_ReadingBlob.tp_dictoffset && __pyx_type_6libzim_ReadingBlob.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_6libzim_ReadingBlob.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_6libzim_ReadingBlob.tp_dict, __pyx_vtabptr_6libzim_ReadingBlob) < 0) __PYX_ERR(0, 615, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_ReadingBlob, (PyObject *)&__pyx_type_6libzim_ReadingBlob) < 0) __PYX_ERR(0, 615, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_ReadingBlob) < 0) __PYX_ERR(0, 615, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_6libzim_ReadingBlob.tp_dict, __pyx_vtabptr_6libzim_ReadingBlob) < 0) __PYX_ERR(0, 607, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_ReadingBlob, (PyObject *)&__pyx_type_6libzim_ReadingBlob) < 0) __PYX_ERR(0, 607, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_ReadingBlob) < 0) __PYX_ERR(0, 607, __pyx_L1_error)
   __pyx_ptype_6libzim_ReadingBlob = &__pyx_type_6libzim_ReadingBlob;
   __pyx_vtabptr_6libzim_Entry = &__pyx_vtable_6libzim_Entry;
   __pyx_vtable_6libzim_Entry.from_entry = (PyObject *(*)(wrapper::Entry))__pyx_f_6libzim_5Entry_from_entry;
-  if (PyType_Ready(&__pyx_type_6libzim_Entry) < 0) __PYX_ERR(0, 665, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim_Entry) < 0) __PYX_ERR(0, 657, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim_Entry.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_6libzim_Entry.tp_dictoffset && __pyx_type_6libzim_Entry.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_6libzim_Entry.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_6libzim_Entry.tp_dict, __pyx_vtabptr_6libzim_Entry) < 0) __PYX_ERR(0, 665, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Entry, (PyObject *)&__pyx_type_6libzim_Entry) < 0) __PYX_ERR(0, 665, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_Entry) < 0) __PYX_ERR(0, 665, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_6libzim_Entry.tp_dict, __pyx_vtabptr_6libzim_Entry) < 0) __PYX_ERR(0, 657, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Entry, (PyObject *)&__pyx_type_6libzim_Entry) < 0) __PYX_ERR(0, 657, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_Entry) < 0) __PYX_ERR(0, 657, __pyx_L1_error)
   __pyx_ptype_6libzim_Entry = &__pyx_type_6libzim_Entry;
   __pyx_vtabptr_6libzim_Item = &__pyx_vtable_6libzim_Item;
   __pyx_vtable_6libzim_Item.from_item = (PyObject *(*)(wrapper::Item))__pyx_f_6libzim_4Item_from_item;
-  if (PyType_Ready(&__pyx_type_6libzim_Item) < 0) __PYX_ERR(0, 722, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim_Item) < 0) __PYX_ERR(0, 714, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim_Item.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_6libzim_Item.tp_dictoffset && __pyx_type_6libzim_Item.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_6libzim_Item.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_6libzim_Item.tp_dict, __pyx_vtabptr_6libzim_Item) < 0) __PYX_ERR(0, 722, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Item, (PyObject *)&__pyx_type_6libzim_Item) < 0) __PYX_ERR(0, 722, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_Item) < 0) __PYX_ERR(0, 722, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_6libzim_Item.tp_dict, __pyx_vtabptr_6libzim_Item) < 0) __PYX_ERR(0, 714, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Item, (PyObject *)&__pyx_type_6libzim_Item) < 0) __PYX_ERR(0, 714, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_Item) < 0) __PYX_ERR(0, 714, __pyx_L1_error)
   __pyx_ptype_6libzim_Item = &__pyx_type_6libzim_Item;
-  if (PyType_Ready(&__pyx_type_6libzim_Archive) < 0) __PYX_ERR(0, 783, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim_Archive) < 0) __PYX_ERR(0, 775, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim_Archive.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_6libzim_Archive.tp_dictoffset && __pyx_type_6libzim_Archive.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_6libzim_Archive.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Archive, (PyObject *)&__pyx_type_6libzim_Archive) < 0) __PYX_ERR(0, 783, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_Archive) < 0) __PYX_ERR(0, 783, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Archive, (PyObject *)&__pyx_type_6libzim_Archive) < 0) __PYX_ERR(0, 775, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_Archive) < 0) __PYX_ERR(0, 775, __pyx_L1_error)
   __pyx_ptype_6libzim_Archive = &__pyx_type_6libzim_Archive;
-  if (PyType_Ready(&__pyx_type_6libzim_Query) < 0) __PYX_ERR(0, 1045, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim_Query) < 0) __PYX_ERR(0, 1037, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim_Query.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_6libzim_Query.tp_dictoffset && __pyx_type_6libzim_Query.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_6libzim_Query.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Query, (PyObject *)&__pyx_type_6libzim_Query) < 0) __PYX_ERR(0, 1045, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_Query) < 0) __PYX_ERR(0, 1045, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Query, (PyObject *)&__pyx_type_6libzim_Query) < 0) __PYX_ERR(0, 1037, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_Query) < 0) __PYX_ERR(0, 1037, __pyx_L1_error)
   __pyx_ptype_6libzim_Query = &__pyx_type_6libzim_Query;
   __pyx_vtabptr_6libzim_SearchResultSet = &__pyx_vtable_6libzim_SearchResultSet;
   __pyx_vtable_6libzim_SearchResultSet.from_resultset = (PyObject *(*)(wrapper::SearchResultSet))__pyx_f_6libzim_15SearchResultSet_from_resultset;
-  if (PyType_Ready(&__pyx_type_6libzim_SearchResultSet) < 0) __PYX_ERR(0, 1055, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim_SearchResultSet) < 0) __PYX_ERR(0, 1047, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim_SearchResultSet.tp_print = 0;
   #endif
@@ -24736,7 +25362,7 @@ static int __Pyx_modinit_type_init_code(void) {
   }
   #if CYTHON_UPDATE_DESCRIPTOR_DOC
   {
-    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_6libzim_SearchResultSet, "__iter__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1055, __pyx_L1_error)
+    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_6libzim_SearchResultSet, "__iter__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1047, __pyx_L1_error)
     if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
       __pyx_wrapperbase_6libzim_15SearchResultSet___iter__ = *((PyWrapperDescrObject *)wrapper)->d_base;
       __pyx_wrapperbase_6libzim_15SearchResultSet___iter__.doc = __pyx_doc_6libzim_15SearchResultSet___iter__;
@@ -24744,36 +25370,36 @@ static int __Pyx_modinit_type_init_code(void) {
     }
   }
   #endif
-  if (__Pyx_SetVtable(__pyx_type_6libzim_SearchResultSet.tp_dict, __pyx_vtabptr_6libzim_SearchResultSet) < 0) __PYX_ERR(0, 1055, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SearchResultSet, (PyObject *)&__pyx_type_6libzim_SearchResultSet) < 0) __PYX_ERR(0, 1055, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_SearchResultSet) < 0) __PYX_ERR(0, 1055, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_6libzim_SearchResultSet.tp_dict, __pyx_vtabptr_6libzim_SearchResultSet) < 0) __PYX_ERR(0, 1047, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SearchResultSet, (PyObject *)&__pyx_type_6libzim_SearchResultSet) < 0) __PYX_ERR(0, 1047, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_SearchResultSet) < 0) __PYX_ERR(0, 1047, __pyx_L1_error)
   __pyx_ptype_6libzim_SearchResultSet = &__pyx_type_6libzim_SearchResultSet;
   __pyx_vtabptr_6libzim_Search = &__pyx_vtable_6libzim_Search;
   __pyx_vtable_6libzim_Search.from_search = (PyObject *(*)(wrapper::Search))__pyx_f_6libzim_6Search_from_search;
-  if (PyType_Ready(&__pyx_type_6libzim_Search) < 0) __PYX_ERR(0, 1074, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim_Search) < 0) __PYX_ERR(0, 1066, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim_Search.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_6libzim_Search.tp_dictoffset && __pyx_type_6libzim_Search.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_6libzim_Search.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_6libzim_Search.tp_dict, __pyx_vtabptr_6libzim_Search) < 0) __PYX_ERR(0, 1074, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Search, (PyObject *)&__pyx_type_6libzim_Search) < 0) __PYX_ERR(0, 1074, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_Search) < 0) __PYX_ERR(0, 1074, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_6libzim_Search.tp_dict, __pyx_vtabptr_6libzim_Search) < 0) __PYX_ERR(0, 1066, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Search, (PyObject *)&__pyx_type_6libzim_Search) < 0) __PYX_ERR(0, 1066, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_Search) < 0) __PYX_ERR(0, 1066, __pyx_L1_error)
   __pyx_ptype_6libzim_Search = &__pyx_type_6libzim_Search;
-  if (PyType_Ready(&__pyx_type_6libzim_Searcher) < 0) __PYX_ERR(0, 1105, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim_Searcher) < 0) __PYX_ERR(0, 1097, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim_Searcher.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_6libzim_Searcher.tp_dictoffset && __pyx_type_6libzim_Searcher.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_6libzim_Searcher.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Searcher, (PyObject *)&__pyx_type_6libzim_Searcher) < 0) __PYX_ERR(0, 1105, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_Searcher) < 0) __PYX_ERR(0, 1105, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_Searcher, (PyObject *)&__pyx_type_6libzim_Searcher) < 0) __PYX_ERR(0, 1097, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_Searcher) < 0) __PYX_ERR(0, 1097, __pyx_L1_error)
   __pyx_ptype_6libzim_Searcher = &__pyx_type_6libzim_Searcher;
   __pyx_vtabptr_6libzim_SuggestionResultSet = &__pyx_vtable_6libzim_SuggestionResultSet;
   __pyx_vtable_6libzim_SuggestionResultSet.from_resultset = (PyObject *(*)(wrapper::SuggestionResultSet))__pyx_f_6libzim_19SuggestionResultSet_from_resultset;
-  if (PyType_Ready(&__pyx_type_6libzim_SuggestionResultSet) < 0) __PYX_ERR(0, 1156, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim_SuggestionResultSet) < 0) __PYX_ERR(0, 1148, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim_SuggestionResultSet.tp_print = 0;
   #endif
@@ -24782,7 +25408,7 @@ static int __Pyx_modinit_type_init_code(void) {
   }
   #if CYTHON_UPDATE_DESCRIPTOR_DOC
   {
-    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_6libzim_SuggestionResultSet, "__iter__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1156, __pyx_L1_error)
+    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_6libzim_SuggestionResultSet, "__iter__"); if (unlikely(!wrapper)) __PYX_ERR(0, 1148, __pyx_L1_error)
     if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
       __pyx_wrapperbase_6libzim_19SuggestionResultSet___iter__ = *((PyWrapperDescrObject *)wrapper)->d_base;
       __pyx_wrapperbase_6libzim_19SuggestionResultSet___iter__.doc = __pyx_doc_6libzim_19SuggestionResultSet___iter__;
@@ -24790,34 +25416,34 @@ static int __Pyx_modinit_type_init_code(void) {
     }
   }
   #endif
-  if (__Pyx_SetVtable(__pyx_type_6libzim_SuggestionResultSet.tp_dict, __pyx_vtabptr_6libzim_SuggestionResultSet) < 0) __PYX_ERR(0, 1156, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SuggestionResultSet, (PyObject *)&__pyx_type_6libzim_SuggestionResultSet) < 0) __PYX_ERR(0, 1156, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_SuggestionResultSet) < 0) __PYX_ERR(0, 1156, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_6libzim_SuggestionResultSet.tp_dict, __pyx_vtabptr_6libzim_SuggestionResultSet) < 0) __PYX_ERR(0, 1148, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SuggestionResultSet, (PyObject *)&__pyx_type_6libzim_SuggestionResultSet) < 0) __PYX_ERR(0, 1148, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_SuggestionResultSet) < 0) __PYX_ERR(0, 1148, __pyx_L1_error)
   __pyx_ptype_6libzim_SuggestionResultSet = &__pyx_type_6libzim_SuggestionResultSet;
   __pyx_vtabptr_6libzim_SuggestionSearch = &__pyx_vtable_6libzim_SuggestionSearch;
   __pyx_vtable_6libzim_SuggestionSearch.from_search = (PyObject *(*)(wrapper::SuggestionSearch))__pyx_f_6libzim_16SuggestionSearch_from_search;
-  if (PyType_Ready(&__pyx_type_6libzim_SuggestionSearch) < 0) __PYX_ERR(0, 1175, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim_SuggestionSearch) < 0) __PYX_ERR(0, 1167, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim_SuggestionSearch.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_6libzim_SuggestionSearch.tp_dictoffset && __pyx_type_6libzim_SuggestionSearch.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_6libzim_SuggestionSearch.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (__Pyx_SetVtable(__pyx_type_6libzim_SuggestionSearch.tp_dict, __pyx_vtabptr_6libzim_SuggestionSearch) < 0) __PYX_ERR(0, 1175, __pyx_L1_error)
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SuggestionSearch, (PyObject *)&__pyx_type_6libzim_SuggestionSearch) < 0) __PYX_ERR(0, 1175, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_SuggestionSearch) < 0) __PYX_ERR(0, 1175, __pyx_L1_error)
+  if (__Pyx_SetVtable(__pyx_type_6libzim_SuggestionSearch.tp_dict, __pyx_vtabptr_6libzim_SuggestionSearch) < 0) __PYX_ERR(0, 1167, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SuggestionSearch, (PyObject *)&__pyx_type_6libzim_SuggestionSearch) < 0) __PYX_ERR(0, 1167, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_SuggestionSearch) < 0) __PYX_ERR(0, 1167, __pyx_L1_error)
   __pyx_ptype_6libzim_SuggestionSearch = &__pyx_type_6libzim_SuggestionSearch;
-  if (PyType_Ready(&__pyx_type_6libzim_SuggestionSearcher) < 0) __PYX_ERR(0, 1205, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim_SuggestionSearcher) < 0) __PYX_ERR(0, 1197, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim_SuggestionSearcher.tp_print = 0;
   #endif
   if ((CYTHON_USE_TYPE_SLOTS && CYTHON_USE_PYTYPE_LOOKUP) && likely(!__pyx_type_6libzim_SuggestionSearcher.tp_dictoffset && __pyx_type_6libzim_SuggestionSearcher.tp_getattro == PyObject_GenericGetAttr)) {
     __pyx_type_6libzim_SuggestionSearcher.tp_getattro = __Pyx_PyObject_GenericGetAttr;
   }
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SuggestionSearcher, (PyObject *)&__pyx_type_6libzim_SuggestionSearcher) < 0) __PYX_ERR(0, 1205, __pyx_L1_error)
-  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_SuggestionSearcher) < 0) __PYX_ERR(0, 1205, __pyx_L1_error)
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_SuggestionSearcher, (PyObject *)&__pyx_type_6libzim_SuggestionSearcher) < 0) __PYX_ERR(0, 1197, __pyx_L1_error)
+  if (__Pyx_setup_reduce((PyObject*)&__pyx_type_6libzim_SuggestionSearcher) < 0) __PYX_ERR(0, 1197, __pyx_L1_error)
   __pyx_ptype_6libzim_SuggestionSearcher = &__pyx_type_6libzim_SuggestionSearcher;
-  if (PyType_Ready(&__pyx_type_6libzim___pyx_scope_struct__gen_blob) < 0) __PYX_ERR(0, 455, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim___pyx_scope_struct__gen_blob) < 0) __PYX_ERR(0, 456, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim___pyx_scope_struct__gen_blob.tp_print = 0;
   #endif
@@ -24825,7 +25451,7 @@ static int __Pyx_modinit_type_init_code(void) {
     __pyx_type_6libzim___pyx_scope_struct__gen_blob.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
   }
   __pyx_ptype_6libzim___pyx_scope_struct__gen_blob = &__pyx_type_6libzim___pyx_scope_struct__gen_blob;
-  if (PyType_Ready(&__pyx_type_6libzim___pyx_scope_struct_1_gen_blob) < 0) __PYX_ERR(0, 470, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim___pyx_scope_struct_1_gen_blob) < 0) __PYX_ERR(0, 471, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim___pyx_scope_struct_1_gen_blob.tp_print = 0;
   #endif
@@ -24833,7 +25459,7 @@ static int __Pyx_modinit_type_init_code(void) {
     __pyx_type_6libzim___pyx_scope_struct_1_gen_blob.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
   }
   __pyx_ptype_6libzim___pyx_scope_struct_1_gen_blob = &__pyx_type_6libzim___pyx_scope_struct_1_gen_blob;
-  if (PyType_Ready(&__pyx_type_6libzim___pyx_scope_struct_2___iter__) < 0) __PYX_ERR(0, 1066, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim___pyx_scope_struct_2___iter__) < 0) __PYX_ERR(0, 1058, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim___pyx_scope_struct_2___iter__.tp_print = 0;
   #endif
@@ -24841,7 +25467,7 @@ static int __Pyx_modinit_type_init_code(void) {
     __pyx_type_6libzim___pyx_scope_struct_2___iter__.tp_getattro = __Pyx_PyObject_GenericGetAttrNoDict;
   }
   __pyx_ptype_6libzim___pyx_scope_struct_2___iter__ = &__pyx_type_6libzim___pyx_scope_struct_2___iter__;
-  if (PyType_Ready(&__pyx_type_6libzim___pyx_scope_struct_3___iter__) < 0) __PYX_ERR(0, 1167, __pyx_L1_error)
+  if (PyType_Ready(&__pyx_type_6libzim___pyx_scope_struct_3___iter__) < 0) __PYX_ERR(0, 1159, __pyx_L1_error)
   #if PY_VERSION_HEX < 0x030800B1
   __pyx_type_6libzim___pyx_scope_struct_3___iter__.tp_print = 0;
   #endif
@@ -25003,7 +25629,6 @@ static CYTHON_SMALL_CODE int __pyx_pymod_exec_libzim(PyObject *__pyx_pyinit_modu
   PyObject *__pyx_t_8 = NULL;
   PyObject *__pyx_t_9 = NULL;
   PyObject *__pyx_t_10 = NULL;
-  PyObject *__pyx_t_11 = NULL;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
@@ -25075,7 +25700,7 @@ if (!__Pyx_RefNanny) {
   Py_INCREF(__pyx_b);
   __pyx_cython_runtime = PyImport_AddModule((char *) "cython_runtime"); if (unlikely(!__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error)
   Py_INCREF(__pyx_cython_runtime);
-  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error);
+  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   /*--- Initialize various global constants etc. ---*/
   if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error)
   #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
@@ -25198,7 +25823,7 @@ if (!__Pyx_RefNanny) {
  * import pathlib
  * import sys             # <<<<<<<<<<<<<<
  * import traceback
- * from types import ModuleType
+ * from collections import OrderedDict
  */
   __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
@@ -25209,8 +25834,8 @@ if (!__Pyx_RefNanny) {
  * import pathlib
  * import sys
  * import traceback             # <<<<<<<<<<<<<<
+ * from collections import OrderedDict
  * from types import ModuleType
- * from typing import Dict, Generator, Iterator, List, Optional, Set, Tuple, Union
  */
   __pyx_t_1 = __Pyx_Import(__pyx_n_s_traceback, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 41, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
@@ -25220,412 +25845,433 @@ if (!__Pyx_RefNanny) {
   /* "libzim.pyx":42
  * import sys
  * import traceback
- * from types import ModuleType             # <<<<<<<<<<<<<<
+ * from collections import OrderedDict             # <<<<<<<<<<<<<<
+ * from types import ModuleType
  * from typing import Dict, Generator, Iterator, List, Optional, Set, Tuple, Union
- * from uuid import UUID
  */
   __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 42, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_INCREF(__pyx_n_s_ModuleType);
-  __Pyx_GIVEREF(__pyx_n_s_ModuleType);
-  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_ModuleType);
-  __pyx_t_2 = __Pyx_Import(__pyx_n_s_types, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 42, __pyx_L1_error)
+  __Pyx_INCREF(__pyx_n_s_OrderedDict);
+  __Pyx_GIVEREF(__pyx_n_s_OrderedDict);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_OrderedDict);
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_collections, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 42, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_ModuleType); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 42, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_OrderedDict); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 42, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ModuleType, __pyx_t_1) < 0) __PYX_ERR(0, 42, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_OrderedDict, __pyx_t_1) < 0) __PYX_ERR(0, 42, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
   /* "libzim.pyx":43
  * import traceback
+ * from collections import OrderedDict
+ * from types import ModuleType             # <<<<<<<<<<<<<<
+ * from typing import Dict, Generator, Iterator, List, Optional, Set, Tuple, Union
+ * from uuid import UUID
+ */
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_INCREF(__pyx_n_s_ModuleType);
+  __Pyx_GIVEREF(__pyx_n_s_ModuleType);
+  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_ModuleType);
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_types, __pyx_t_2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 43, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_ModuleType); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ModuleType, __pyx_t_2) < 0) __PYX_ERR(0, 43, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "libzim.pyx":44
+ * from collections import OrderedDict
  * from types import ModuleType
  * from typing import Dict, Generator, Iterator, List, Optional, Set, Tuple, Union             # <<<<<<<<<<<<<<
  * from uuid import UUID
  * 
  */
-  __pyx_t_2 = PyList_New(8); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyList_New(8); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(__pyx_n_s_Dict);
   __Pyx_GIVEREF(__pyx_n_s_Dict);
-  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_Dict);
+  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_Dict);
   __Pyx_INCREF(__pyx_n_s_Generator);
   __Pyx_GIVEREF(__pyx_n_s_Generator);
-  PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_s_Generator);
+  PyList_SET_ITEM(__pyx_t_1, 1, __pyx_n_s_Generator);
   __Pyx_INCREF(__pyx_n_s_Iterator);
   __Pyx_GIVEREF(__pyx_n_s_Iterator);
-  PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_s_Iterator);
+  PyList_SET_ITEM(__pyx_t_1, 2, __pyx_n_s_Iterator);
   __Pyx_INCREF(__pyx_n_s_List);
   __Pyx_GIVEREF(__pyx_n_s_List);
-  PyList_SET_ITEM(__pyx_t_2, 3, __pyx_n_s_List);
+  PyList_SET_ITEM(__pyx_t_1, 3, __pyx_n_s_List);
   __Pyx_INCREF(__pyx_n_s_Optional);
   __Pyx_GIVEREF(__pyx_n_s_Optional);
-  PyList_SET_ITEM(__pyx_t_2, 4, __pyx_n_s_Optional);
+  PyList_SET_ITEM(__pyx_t_1, 4, __pyx_n_s_Optional);
   __Pyx_INCREF(__pyx_n_s_Set);
   __Pyx_GIVEREF(__pyx_n_s_Set);
-  PyList_SET_ITEM(__pyx_t_2, 5, __pyx_n_s_Set);
+  PyList_SET_ITEM(__pyx_t_1, 5, __pyx_n_s_Set);
   __Pyx_INCREF(__pyx_n_s_Tuple);
   __Pyx_GIVEREF(__pyx_n_s_Tuple);
-  PyList_SET_ITEM(__pyx_t_2, 6, __pyx_n_s_Tuple);
+  PyList_SET_ITEM(__pyx_t_1, 6, __pyx_n_s_Tuple);
   __Pyx_INCREF(__pyx_n_s_Union);
   __Pyx_GIVEREF(__pyx_n_s_Union);
-  PyList_SET_ITEM(__pyx_t_2, 7, __pyx_n_s_Union);
-  __pyx_t_1 = __Pyx_Import(__pyx_n_s_typing, __pyx_t_2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Dict); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Dict, __pyx_t_2) < 0) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Generator); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Generator, __pyx_t_2) < 0) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Iterator); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Iterator, __pyx_t_2) < 0) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_List); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_List, __pyx_t_2) < 0) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Optional); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Optional, __pyx_t_2) < 0) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Set); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Set, __pyx_t_2) < 0) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Tuple); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Tuple, __pyx_t_2) < 0) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Union); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error)
+  PyList_SET_ITEM(__pyx_t_1, 7, __pyx_n_s_Union);
+  __pyx_t_2 = __Pyx_Import(__pyx_n_s_typing, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Union, __pyx_t_2) < 0) __PYX_ERR(0, 43, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_Dict); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Dict, __pyx_t_1) < 0) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_Generator); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Generator, __pyx_t_1) < 0) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_Iterator); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Iterator, __pyx_t_1) < 0) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_List); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_List, __pyx_t_1) < 0) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_Optional); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Optional, __pyx_t_1) < 0) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_Set); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Set, __pyx_t_1) < 0) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_Tuple); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Tuple, __pyx_t_1) < 0) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_Union); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Union, __pyx_t_1) < 0) __PYX_ERR(0, 44, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":44
+  /* "libzim.pyx":45
  * from types import ModuleType
  * from typing import Dict, Generator, Iterator, List, Optional, Set, Tuple, Union
  * from uuid import UUID             # <<<<<<<<<<<<<<
  * 
  * from cpython.buffer cimport PyBUF_WRITABLE
  */
-  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 45, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(__pyx_n_s_UUID);
   __Pyx_GIVEREF(__pyx_n_s_UUID);
-  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_UUID);
-  __pyx_t_2 = __Pyx_Import(__pyx_n_s_uuid, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_UUID); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 44, __pyx_L1_error)
+  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_UUID);
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_uuid, __pyx_t_2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UUID, __pyx_t_1) < 0) __PYX_ERR(0, 44, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_UUID); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 45, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_UUID, __pyx_t_2) < 0) __PYX_ERR(0, 45, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":58
+  /* "libzim.pyx":59
  * from libcpp.utility cimport move
  * 
  * pybool = type(True)             # <<<<<<<<<<<<<<
  * pyint = type(1)
  * 
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pybool, ((PyObject *)Py_TYPE(Py_True))) < 0) __PYX_ERR(0, 58, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pybool, ((PyObject *)Py_TYPE(Py_True))) < 0) __PYX_ERR(0, 59, __pyx_L1_error)
 
-  /* "libzim.pyx":59
+  /* "libzim.pyx":60
  * 
  * pybool = type(True)
  * pyint = type(1)             # <<<<<<<<<<<<<<
  * 
  * def create_module(name, doc, members):
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyint, ((PyObject *)Py_TYPE(__pyx_int_1))) < 0) __PYX_ERR(0, 59, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pyint, ((PyObject *)Py_TYPE(__pyx_int_1))) < 0) __PYX_ERR(0, 60, __pyx_L1_error)
 
-  /* "libzim.pyx":61
+  /* "libzim.pyx":62
  * pyint = type(1)
  * 
  * def create_module(name, doc, members):             # <<<<<<<<<<<<<<
  *     """Create/define a module for name and docstring, populated by members"""
  *     module = ModuleType(name, doc)
  */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_6libzim_1create_module, NULL, __pyx_n_s_libzim); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 61, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_create_module, __pyx_t_2) < 0) __PYX_ERR(0, 61, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6libzim_1create_module, NULL, __pyx_n_s_libzim); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_create_module, __pyx_t_1) < 0) __PYX_ERR(0, 62, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":204
+  /* "libzim.pyx":205
  * ###############################################################################
  * 
  * writer_module_name = f"{__name__}.writer"             # <<<<<<<<<<<<<<
  * 
  * cdef class WritingBlob:
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 204, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 204, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 205, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_1, __pyx_kp_u_writer_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 204, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_FormatSimple(__pyx_t_1, __pyx_empty_unicode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 205, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_writer_module_name, __pyx_t_2) < 0) __PYX_ERR(0, 204, __pyx_L1_error)
+  __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_t_2, __pyx_kp_u_writer_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 205, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_writer_module_name, __pyx_t_1) < 0) __PYX_ERR(0, 205, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":207
+  /* "libzim.pyx":208
  * 
  * cdef class WritingBlob:
  *     __module__ = writer_module_name             # <<<<<<<<<<<<<<
  *     cdef zim.Blob c_blob
  *     cdef bytes ref_content
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 207, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_WritingBlob->tp_dict, __pyx_n_s_module_2, __pyx_t_2) < 0) __PYX_ERR(0, 207, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 208, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_WritingBlob->tp_dict, __pyx_n_s_module_2, __pyx_t_1) < 0) __PYX_ERR(0, 208, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_6libzim_WritingBlob);
 
-  /* "libzim.pyx":223
+  /* "libzim.pyx":224
  * 
  * 
  * class Compression(enum.Enum):             # <<<<<<<<<<<<<<
  *     """Compression algorithms available to create ZIM files"""
  *     __module__ = writer_module_name
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_enum); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 223, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_Enum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 223, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_enum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 224, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 223, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Enum); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 224, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 223, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 224, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_Compression, __pyx_n_s_Compression, (PyObject *) NULL, __pyx_n_s_libzim, __pyx_kp_s_Compression_algorithms_available); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 223, __pyx_L1_error)
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 224, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_Compression, __pyx_n_s_Compression, (PyObject *) NULL, __pyx_n_s_libzim, __pyx_kp_s_Compression_algorithms_available); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 224, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "libzim.pyx":225
+  /* "libzim.pyx":226
  * class Compression(enum.Enum):
  *     """Compression algorithms available to create ZIM files"""
  *     __module__ = writer_module_name             # <<<<<<<<<<<<<<
  *     # We don't care of the exact value. The function comp_from_int will do the right
  *     # conversion to zim::Compression
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 225, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 226, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_module_2, __pyx_t_4) < 0) __PYX_ERR(0, 225, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_module_2, __pyx_t_4) < 0) __PYX_ERR(0, 226, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "libzim.pyx":228
+  /* "libzim.pyx":229
  *     # We don't care of the exact value. The function comp_from_int will do the right
  *     # conversion to zim::Compression
  *     none = 0             # <<<<<<<<<<<<<<
  *     zstd = 1
  * 
  */
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_none, __pyx_int_0) < 0) __PYX_ERR(0, 228, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_none, __pyx_int_0) < 0) __PYX_ERR(0, 229, __pyx_L1_error)
 
-  /* "libzim.pyx":229
+  /* "libzim.pyx":230
  *     # conversion to zim::Compression
  *     none = 0
  *     zstd = 1             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_zstd, __pyx_int_1) < 0) __PYX_ERR(0, 229, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_zstd, __pyx_int_1) < 0) __PYX_ERR(0, 230, __pyx_L1_error)
 
-  /* "libzim.pyx":223
+  /* "libzim.pyx":224
  * 
  * 
  * class Compression(enum.Enum):             # <<<<<<<<<<<<<<
  *     """Compression algorithms available to create ZIM files"""
  *     __module__ = writer_module_name
  */
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_Compression, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 223, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_Compression, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 224, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Compression, __pyx_t_4) < 0) __PYX_ERR(0, 223, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Compression, __pyx_t_4) < 0) __PYX_ERR(0, 224, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":232
+  /* "libzim.pyx":233
  * 
  * 
  * class Hint(enum.Enum):             # <<<<<<<<<<<<<<
  *     __module__ = writer_module_name
  *     COMPRESS = zim.HintKeys.COMPRESS
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_enum); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_Enum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 232, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_enum); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 233, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_Enum); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 233, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 232, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 233, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_Hint, __pyx_n_s_Hint, (PyObject *) NULL, __pyx_n_s_libzim, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 232, __pyx_L1_error)
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 233, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_Hint, __pyx_n_s_Hint, (PyObject *) NULL, __pyx_n_s_libzim, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 233, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "libzim.pyx":233
+  /* "libzim.pyx":234
  * 
  * class Hint(enum.Enum):
  *     __module__ = writer_module_name             # <<<<<<<<<<<<<<
  *     COMPRESS = zim.HintKeys.COMPRESS
  *     FRONT_ARTICLE = zim.HintKeys.FRONT_ARTICLE
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 233, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 234, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_module_2, __pyx_t_4) < 0) __PYX_ERR(0, 233, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_module_2, __pyx_t_4) < 0) __PYX_ERR(0, 234, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "libzim.pyx":234
+  /* "libzim.pyx":235
  * class Hint(enum.Enum):
  *     __module__ = writer_module_name
  *     COMPRESS = zim.HintKeys.COMPRESS             # <<<<<<<<<<<<<<
  *     FRONT_ARTICLE = zim.HintKeys.FRONT_ARTICLE
  * 
  */
-  __pyx_t_4 = __Pyx_PyInt_From_zim_3a__3a_writer_3a__3a_HintKeys(zim::writer::COMPRESS); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 234, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_zim_3a__3a_writer_3a__3a_HintKeys(zim::writer::COMPRESS); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 235, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_COMPRESS, __pyx_t_4) < 0) __PYX_ERR(0, 234, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_COMPRESS, __pyx_t_4) < 0) __PYX_ERR(0, 235, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "libzim.pyx":235
+  /* "libzim.pyx":236
  *     __module__ = writer_module_name
  *     COMPRESS = zim.HintKeys.COMPRESS
  *     FRONT_ARTICLE = zim.HintKeys.FRONT_ARTICLE             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __pyx_t_4 = __Pyx_PyInt_From_zim_3a__3a_writer_3a__3a_HintKeys(zim::writer::FRONT_ARTICLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 235, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyInt_From_zim_3a__3a_writer_3a__3a_HintKeys(zim::writer::FRONT_ARTICLE); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 236, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_FRONT_ARTICLE, __pyx_t_4) < 0) __PYX_ERR(0, 235, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_FRONT_ARTICLE, __pyx_t_4) < 0) __PYX_ERR(0, 236, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "libzim.pyx":232
+  /* "libzim.pyx":233
  * 
  * 
  * class Hint(enum.Enum):             # <<<<<<<<<<<<<<
  *     __module__ = writer_module_name
  *     COMPRESS = zim.HintKeys.COMPRESS
  */
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_Hint, __pyx_t_2, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 232, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_Hint, __pyx_t_1, __pyx_t_3, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 233, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Hint, __pyx_t_4) < 0) __PYX_ERR(0, 232, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Hint, __pyx_t_4) < 0) __PYX_ERR(0, 233, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":250
+  /* "libzim.pyx":251
  *         _started : bool
  *             flag if the creator has started"""
  *     __module__ = writer_module_name             # <<<<<<<<<<<<<<
  * 
  *     cdef zim.ZimCreator c_creator
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 250, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim__Creator->tp_dict, __pyx_n_s_module_2, __pyx_t_2) < 0) __PYX_ERR(0, 250, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 251, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim__Creator->tp_dict, __pyx_n_s_module_2, __pyx_t_1) < 0) __PYX_ERR(0, 251, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   PyType_Modified(__pyx_ptype_6libzim__Creator);
 
-  /* "libzim.pyx":414
+  /* "libzim.pyx":415
  *         return self._filename
  * 
  * class ContentProvider:             # <<<<<<<<<<<<<<
  *     __module__ = writer_module_name
  *     def __init__(self):
  */
-  __pyx_t_2 = __Pyx_Py3MetaclassPrepare((PyObject *) NULL, __pyx_empty_tuple, __pyx_n_s_ContentProvider, __pyx_n_s_ContentProvider, (PyObject *) NULL, __pyx_n_s_libzim, (PyObject *) NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 414, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_Py3MetaclassPrepare((PyObject *) NULL, __pyx_empty_tuple, __pyx_n_s_ContentProvider, __pyx_n_s_ContentProvider, (PyObject *) NULL, __pyx_n_s_libzim, (PyObject *) NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 415, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "libzim.pyx":415
+  /* "libzim.pyx":416
  * 
  * class ContentProvider:
  *     __module__ = writer_module_name             # <<<<<<<<<<<<<<
  *     def __init__(self):
  *         self.generator = None
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 415, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_module_2, __pyx_t_1) < 0) __PYX_ERR(0, 415, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 416, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_module_2, __pyx_t_2) < 0) __PYX_ERR(0, 416, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":416
+  /* "libzim.pyx":417
  * class ContentProvider:
  *     __module__ = writer_module_name
  *     def __init__(self):             # <<<<<<<<<<<<<<
  *         self.generator = None
  * 
  */
-  __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15ContentProvider_1__init__, 0, __pyx_n_s_ContentProvider___init, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__53)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 416, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_init, __pyx_t_1) < 0) __PYX_ERR(0, 416, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15ContentProvider_1__init__, 0, __pyx_n_s_ContentProvider___init, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__55)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 417, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_init, __pyx_t_2) < 0) __PYX_ERR(0, 417, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":419
+  /* "libzim.pyx":420
  *         self.generator = None
  * 
  *     def get_size(self) -> pyint:             # <<<<<<<<<<<<<<
  *         """Size of get_data's result in bytes"""
  *         raise NotImplementedError("get_size must be implemented.")
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 419, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_pyint); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 419, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 420, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_pyint); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 420, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_return, __pyx_t_3) < 0) __PYX_ERR(0, 419, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_t_3) < 0) __PYX_ERR(0, 420, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15ContentProvider_3get_size, 0, __pyx_n_s_ContentProvider_get_size, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__55)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 419, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15ContentProvider_3get_size, 0, __pyx_n_s_ContentProvider_get_size, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__57)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 420, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_3, __pyx_t_1);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_size, __pyx_t_3) < 0) __PYX_ERR(0, 419, __pyx_L1_error)
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_3, __pyx_t_2);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_size, __pyx_t_3) < 0) __PYX_ERR(0, 420, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "libzim.pyx":423
+  /* "libzim.pyx":424
  *         raise NotImplementedError("get_size must be implemented.")
  * 
  *     def feed(self) -> WritingBlob:             # <<<<<<<<<<<<<<
  *         """Blob(s) containing the complete content of the article.
  *         Must return an empty blob to tell writer no more content has to be written.
  */
-  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 423, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 424, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_return, __pyx_n_u_WritingBlob) < 0) __PYX_ERR(0, 423, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15ContentProvider_5feed, 0, __pyx_n_s_ContentProvider_feed, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__57)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 423, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_1, __pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_return, __pyx_n_u_WritingBlob) < 0) __PYX_ERR(0, 424, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15ContentProvider_5feed, 0, __pyx_n_s_ContentProvider_feed, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__59)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 424, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_3);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_feed, __pyx_t_1) < 0) __PYX_ERR(0, 423, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_feed, __pyx_t_2) < 0) __PYX_ERR(0, 424, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":440
+  /* "libzim.pyx":441
  *         return self._blob
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
  *         """Generator yielding blobs for the content of the article"""
  *         raise NotImplementedError("gen_blob (ro feed) must be implemented")
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 440, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Generator); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 440, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 441, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Generator); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 441, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 440, __pyx_L1_error)
+  __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 441, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_INCREF(((PyObject *)__pyx_ptype_6libzim_WritingBlob));
   __Pyx_GIVEREF(((PyObject *)__pyx_ptype_6libzim_WritingBlob));
@@ -25636,77 +26282,77 @@ if (!__Pyx_RefNanny) {
   __Pyx_INCREF(Py_None);
   __Pyx_GIVEREF(Py_None);
   PyTuple_SET_ITEM(__pyx_t_4, 2, Py_None);
-  __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 440, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 441, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_return, __pyx_t_5) < 0) __PYX_ERR(0, 440, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_t_5) < 0) __PYX_ERR(0, 441, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15ContentProvider_7gen_blob, 0, __pyx_n_s_ContentProvider_gen_blob, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__59)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 440, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15ContentProvider_7gen_blob, 0, __pyx_n_s_ContentProvider_gen_blob, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__61)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 441, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_1);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_gen_blob, __pyx_t_5) < 0) __PYX_ERR(0, 440, __pyx_L1_error)
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_2);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_gen_blob, __pyx_t_5) < 0) __PYX_ERR(0, 441, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-  /* "libzim.pyx":414
+  /* "libzim.pyx":415
  *         return self._filename
  * 
  * class ContentProvider:             # <<<<<<<<<<<<<<
  *     __module__ = writer_module_name
  *     def __init__(self):
  */
-  __pyx_t_5 = __Pyx_Py3ClassCreate(((PyObject*)&__Pyx_DefaultClassType), __pyx_n_s_ContentProvider, __pyx_empty_tuple, __pyx_t_2, NULL, 0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 414, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_Py3ClassCreate(((PyObject*)&__Pyx_DefaultClassType), __pyx_n_s_ContentProvider, __pyx_empty_tuple, __pyx_t_1, NULL, 0, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 415, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ContentProvider, __pyx_t_5) < 0) __PYX_ERR(0, 414, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ContentProvider, __pyx_t_5) < 0) __PYX_ERR(0, 415, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":445
+  /* "libzim.pyx":446
  * 
  * 
  * class StringProvider(ContentProvider):             # <<<<<<<<<<<<<<
  *     """ContentProvider for a single encoded-or-not UTF-8 string"""
  *     __module__ = writer_module_name
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_ContentProvider); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 445, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 445, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_ContentProvider); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 446, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 446, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_GIVEREF(__pyx_t_2);
-  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 445, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_5, __pyx_n_s_StringProvider, __pyx_n_s_StringProvider, (PyObject *) NULL, __pyx_n_s_libzim, __pyx_kp_s_ContentProvider_for_a_single_enc); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 445, __pyx_L1_error)
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
+  __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 446, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 445, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_5, __pyx_n_s_StringProvider, __pyx_n_s_StringProvider, (PyObject *) NULL, __pyx_n_s_libzim, __pyx_kp_s_ContentProvider_for_a_single_enc); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 446, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 446, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
 
-  /* "libzim.pyx":447
+  /* "libzim.pyx":448
  * class StringProvider(ContentProvider):
  *     """ContentProvider for a single encoded-or-not UTF-8 string"""
  *     __module__ = writer_module_name             # <<<<<<<<<<<<<<
  *     def __init__(self, content: Union[str, bytes]):
  *         super().__init__()
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 447, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 448, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_module_2, __pyx_t_3) < 0) __PYX_ERR(0, 447, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_module_2, __pyx_t_3) < 0) __PYX_ERR(0, 448, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "libzim.pyx":448
+  /* "libzim.pyx":449
  *     """ContentProvider for a single encoded-or-not UTF-8 string"""
  *     __module__ = writer_module_name
  *     def __init__(self, content: Union[str, bytes]):             # <<<<<<<<<<<<<<
  *         super().__init__()
  *         self.content = content.encode("UTF-8") if isinstance(content, str) else content
  */
-  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 448, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 449, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_Union); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 448, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_Union); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 449, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 448, __pyx_L1_error)
+  __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 449, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
   __Pyx_INCREF(((PyObject *)(&PyUnicode_Type)));
   __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type)));
@@ -25714,54 +26360,54 @@ if (!__Pyx_RefNanny) {
   __Pyx_INCREF(((PyObject *)(&PyBytes_Type)));
   __Pyx_GIVEREF(((PyObject *)(&PyBytes_Type)));
   PyTuple_SET_ITEM(__pyx_t_7, 1, ((PyObject *)(&PyBytes_Type)));
-  __pyx_t_8 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 448, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_PyObject_GetItem(__pyx_t_6, __pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 449, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_content, __pyx_t_8) < 0) __PYX_ERR(0, 448, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_content, __pyx_t_8) < 0) __PYX_ERR(0, 449, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  __pyx_t_8 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_14StringProvider_1__init__, 0, __pyx_n_s_StringProvider___init, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__61)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 448, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_14StringProvider_1__init__, 0, __pyx_n_s_StringProvider___init, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__63)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 449, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_INCREF(__pyx_t_8);
   PyList_Append(__pyx_t_4, __pyx_t_8);
   __Pyx_GIVEREF(__pyx_t_8);
   __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_8, __pyx_t_3);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_init, __pyx_t_8) < 0) __PYX_ERR(0, 448, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_init, __pyx_t_8) < 0) __PYX_ERR(0, 449, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
 
-  /* "libzim.pyx":452
+  /* "libzim.pyx":453
  *         self.content = content.encode("UTF-8") if isinstance(content, str) else content
  * 
  *     def get_size(self) -> pyint:             # <<<<<<<<<<<<<<
  *         return len(self.content)
  * 
  */
-  __pyx_t_8 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 452, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 453, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_pyint); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 452, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_pyint); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 453, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_return, __pyx_t_3) < 0) __PYX_ERR(0, 452, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_return, __pyx_t_3) < 0) __PYX_ERR(0, 453, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_14StringProvider_3get_size, 0, __pyx_n_s_StringProvider_get_size, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__63)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 452, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_14StringProvider_3get_size, 0, __pyx_n_s_StringProvider_get_size, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__65)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 453, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_3, __pyx_t_8);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_size, __pyx_t_3) < 0) __PYX_ERR(0, 452, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_size, __pyx_t_3) < 0) __PYX_ERR(0, 453, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "libzim.pyx":455
+  /* "libzim.pyx":456
  *         return len(self.content)
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
  *         yield WritingBlob(self.content)
  * 
  */
-  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 455, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 456, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_Generator); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 455, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_Generator); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 456, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
-  __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 455, __pyx_L1_error)
+  __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 456, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
   __Pyx_INCREF(((PyObject *)__pyx_ptype_6libzim_WritingBlob));
   __Pyx_GIVEREF(((PyObject *)__pyx_ptype_6libzim_WritingBlob));
@@ -25772,86 +26418,86 @@ if (!__Pyx_RefNanny) {
   __Pyx_INCREF(Py_None);
   __Pyx_GIVEREF(Py_None);
   PyTuple_SET_ITEM(__pyx_t_7, 2, Py_None);
-  __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 455, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 456, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_return, __pyx_t_6) < 0) __PYX_ERR(0, 455, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_return, __pyx_t_6) < 0) __PYX_ERR(0, 456, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_14StringProvider_5gen_blob, 0, __pyx_n_s_StringProvider_gen_blob, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__13)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 455, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_14StringProvider_5gen_blob, 0, __pyx_n_s_StringProvider_gen_blob, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__13)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 456, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_3);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_gen_blob, __pyx_t_6) < 0) __PYX_ERR(0, 455, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_gen_blob, __pyx_t_6) < 0) __PYX_ERR(0, 456, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-  /* "libzim.pyx":445
+  /* "libzim.pyx":446
  * 
  * 
  * class StringProvider(ContentProvider):             # <<<<<<<<<<<<<<
  *     """ContentProvider for a single encoded-or-not UTF-8 string"""
  *     __module__ = writer_module_name
  */
-  __pyx_t_6 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_StringProvider, __pyx_t_5, __pyx_t_1, NULL, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 445, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_StringProvider, __pyx_t_5, __pyx_t_2, NULL, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 446, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  if (__Pyx_CyFunction_InitClassCell(__pyx_t_4, __pyx_t_6) < 0) __PYX_ERR(0, 445, __pyx_L1_error)
+  if (__Pyx_CyFunction_InitClassCell(__pyx_t_4, __pyx_t_6) < 0) __PYX_ERR(0, 446, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_StringProvider, __pyx_t_6) < 0) __PYX_ERR(0, 445, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_StringProvider, __pyx_t_6) < 0) __PYX_ERR(0, 446, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-  /* "libzim.pyx":459
+  /* "libzim.pyx":460
  * 
  * 
  * class FileProvider(ContentProvider):             # <<<<<<<<<<<<<<
  *     """ContentProvider for a file using its local path"""
  *     __module__ = writer_module_name
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_ContentProvider); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 459, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_ContentProvider); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 460, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 459, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 460, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_5);
-  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_5);
+  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
   __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 459, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 460, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_1 = __Pyx_Py3MetaclassPrepare(__pyx_t_5, __pyx_t_2, __pyx_n_s_FileProvider, __pyx_n_s_FileProvider, (PyObject *) NULL, __pyx_n_s_libzim, __pyx_kp_s_ContentProvider_for_a_file_using); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 459, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 459, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_Py3MetaclassPrepare(__pyx_t_5, __pyx_t_1, __pyx_n_s_FileProvider, __pyx_n_s_FileProvider, (PyObject *) NULL, __pyx_n_s_libzim, __pyx_kp_s_ContentProvider_for_a_file_using); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 460, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 460, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
 
-  /* "libzim.pyx":461
+  /* "libzim.pyx":462
  * class FileProvider(ContentProvider):
  *     """ContentProvider for a file using its local path"""
  *     __module__ = writer_module_name             # <<<<<<<<<<<<<<
  *     def __init__(self, filepath: Union[pathlib.Path, str]):
  *         super().__init__()
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 461, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 462, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_module_2, __pyx_t_4) < 0) __PYX_ERR(0, 461, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_module_2, __pyx_t_4) < 0) __PYX_ERR(0, 462, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "libzim.pyx":462
+  /* "libzim.pyx":463
  *     """ContentProvider for a file using its local path"""
  *     __module__ = writer_module_name
  *     def __init__(self, filepath: Union[pathlib.Path, str]):             # <<<<<<<<<<<<<<
  *         super().__init__()
  *         self.filepath = filepath
  */
-  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 462, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 463, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Union); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 462, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Union); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 463, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_pathlib); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 462, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_pathlib); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 463, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_Path); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 462, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_Path); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 463, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 462, __pyx_L1_error)
+  __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 463, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
   __Pyx_GIVEREF(__pyx_t_8);
   PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_8);
@@ -25859,54 +26505,54 @@ if (!__Pyx_RefNanny) {
   __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type)));
   PyTuple_SET_ITEM(__pyx_t_7, 1, ((PyObject *)(&PyUnicode_Type)));
   __pyx_t_8 = 0;
-  __pyx_t_8 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 462, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 463, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_filepath, __pyx_t_8) < 0) __PYX_ERR(0, 462, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_filepath, __pyx_t_8) < 0) __PYX_ERR(0, 463, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  __pyx_t_8 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_12FileProvider_1__init__, 0, __pyx_n_s_FileProvider___init, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__66)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 462, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_12FileProvider_1__init__, 0, __pyx_n_s_FileProvider___init, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__68)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 463, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_INCREF(__pyx_t_8);
   PyList_Append(__pyx_t_6, __pyx_t_8);
   __Pyx_GIVEREF(__pyx_t_8);
   __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_8, __pyx_t_4);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_init, __pyx_t_8) < 0) __PYX_ERR(0, 462, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_init, __pyx_t_8) < 0) __PYX_ERR(0, 463, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
 
-  /* "libzim.pyx":467
+  /* "libzim.pyx":468
  *         self.size = os.path.getsize(self.filepath)
  * 
  *     def get_size(self) -> pyint:             # <<<<<<<<<<<<<<
  *         return self.size
  * 
  */
-  __pyx_t_8 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 467, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 468, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pyint); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 467, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_pyint); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 468, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_return, __pyx_t_4) < 0) __PYX_ERR(0, 467, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_return, __pyx_t_4) < 0) __PYX_ERR(0, 468, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_12FileProvider_3get_size, 0, __pyx_n_s_FileProvider_get_size, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__68)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 467, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_12FileProvider_3get_size, 0, __pyx_n_s_FileProvider_get_size, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__70)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 468, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_8);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_size, __pyx_t_4) < 0) __PYX_ERR(0, 467, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_size, __pyx_t_4) < 0) __PYX_ERR(0, 468, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "libzim.pyx":470
+  /* "libzim.pyx":471
  *         return self.size
  * 
  *     def gen_blob(self) -> Generator[WritingBlob, None, None]:             # <<<<<<<<<<<<<<
  *         bsize = 1048576  # 1MiB chunk
  *         with open(self.filepath, "rb") as fh:
  */
-  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 470, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 471, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_Generator); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 470, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_Generator); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 471, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
-  __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 470, __pyx_L1_error)
+  __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 471, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
   __Pyx_INCREF(((PyObject *)__pyx_ptype_6libzim_WritingBlob));
   __Pyx_GIVEREF(((PyObject *)__pyx_ptype_6libzim_WritingBlob));
@@ -25917,157 +26563,157 @@ if (!__Pyx_RefNanny) {
   __Pyx_INCREF(Py_None);
   __Pyx_GIVEREF(Py_None);
   PyTuple_SET_ITEM(__pyx_t_7, 2, Py_None);
-  __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 470, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_PyObject_GetItem(__pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 471, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_t_3) < 0) __PYX_ERR(0, 470, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_return, __pyx_t_3) < 0) __PYX_ERR(0, 471, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_12FileProvider_5gen_blob, 0, __pyx_n_s_FileProvider_gen_blob, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__14)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 470, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_12FileProvider_5gen_blob, 0, __pyx_n_s_FileProvider_gen_blob, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__14)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 471, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_3, __pyx_t_4);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_gen_blob, __pyx_t_3) < 0) __PYX_ERR(0, 470, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_gen_blob, __pyx_t_3) < 0) __PYX_ERR(0, 471, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "libzim.pyx":459
+  /* "libzim.pyx":460
  * 
  * 
  * class FileProvider(ContentProvider):             # <<<<<<<<<<<<<<
  *     """ContentProvider for a file using its local path"""
  *     __module__ = writer_module_name
  */
-  __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_5, __pyx_n_s_FileProvider, __pyx_t_2, __pyx_t_1, NULL, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 459, __pyx_L1_error)
+  __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_5, __pyx_n_s_FileProvider, __pyx_t_1, __pyx_t_2, NULL, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 460, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  if (__Pyx_CyFunction_InitClassCell(__pyx_t_6, __pyx_t_3) < 0) __PYX_ERR(0, 459, __pyx_L1_error)
+  if (__Pyx_CyFunction_InitClassCell(__pyx_t_6, __pyx_t_3) < 0) __PYX_ERR(0, 460, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FileProvider, __pyx_t_3) < 0) __PYX_ERR(0, 459, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_FileProvider, __pyx_t_3) < 0) __PYX_ERR(0, 460, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":478
+  /* "libzim.pyx":479
  *                 res = fh.read(bsize)
  * 
  * class IndexData:             # <<<<<<<<<<<<<<
  *     """ IndexData stub to override
  * 
  */
-  __pyx_t_2 = __Pyx_Py3MetaclassPrepare((PyObject *) NULL, __pyx_empty_tuple, __pyx_n_s_IndexData, __pyx_n_s_IndexData, (PyObject *) NULL, __pyx_n_s_libzim, __pyx_kp_s_IndexData_stub_to_override_Retu); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 478, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_Py3MetaclassPrepare((PyObject *) NULL, __pyx_empty_tuple, __pyx_n_s_IndexData, __pyx_n_s_IndexData, (PyObject *) NULL, __pyx_n_s_libzim, __pyx_kp_s_IndexData_stub_to_override_Retu); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 479, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "libzim.pyx":482
+  /* "libzim.pyx":483
  * 
  *     Return a subclass of it in Item.get_indexdata()"""
  *     __module__ = writer_module_name             # <<<<<<<<<<<<<<
  * 
  *     def has_indexdata(self) -> bool:
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 482, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 483, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_module_2, __pyx_t_5) < 0) __PYX_ERR(0, 482, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_module_2, __pyx_t_5) < 0) __PYX_ERR(0, 483, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-  /* "libzim.pyx":484
+  /* "libzim.pyx":485
  *     __module__ = writer_module_name
  * 
  *     def has_indexdata(self) -> bool:             # <<<<<<<<<<<<<<
  *         """Return true if the IndexData actually contains data"""
  *         return False
  */
-  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 484, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 485, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_return, __pyx_n_u_bool) < 0) __PYX_ERR(0, 484, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_9IndexData_1has_indexdata, 0, __pyx_n_s_IndexData_has_indexdata, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__71)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 484, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_1, __pyx_t_5);
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_return, __pyx_n_u_bool) < 0) __PYX_ERR(0, 485, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_9IndexData_1has_indexdata, 0, __pyx_n_s_IndexData_has_indexdata, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__73)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 485, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_5);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_has_indexdata, __pyx_t_1) < 0) __PYX_ERR(0, 484, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_has_indexdata, __pyx_t_2) < 0) __PYX_ERR(0, 485, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":488
+  /* "libzim.pyx":489
  *         return False
  * 
  *     def get_title(self) -> str:             # <<<<<<<<<<<<<<
  *         """Title to index. Might be the same as Item.get_title or not"""
  *         raise NotImplementedError("get_title must be implemented.")
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 488, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 488, __pyx_L1_error)
-  __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_9IndexData_3get_title, 0, __pyx_n_s_IndexData_get_title, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__73)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 488, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 489, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 489, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_9IndexData_3get_title, 0, __pyx_n_s_IndexData_get_title, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__75)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 489, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_1);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_title, __pyx_t_5) < 0) __PYX_ERR(0, 488, __pyx_L1_error)
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_2);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_title, __pyx_t_5) < 0) __PYX_ERR(0, 489, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-  /* "libzim.pyx":492
+  /* "libzim.pyx":493
  *         raise NotImplementedError("get_title must be implemented.")
  * 
  *     def get_content(self) -> str:             # <<<<<<<<<<<<<<
  *         """Content to index. Might be the same as Item.get_title or not"""
  *         raise NotImplementedError("get_content must be implemented.")
  */
-  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 492, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 493, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 492, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_9IndexData_5get_content, 0, __pyx_n_s_IndexData_get_content, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__75)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 492, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_1, __pyx_t_5);
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 493, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_9IndexData_5get_content, 0, __pyx_n_s_IndexData_get_content, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__77)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 493, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_5);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_content, __pyx_t_1) < 0) __PYX_ERR(0, 492, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_content, __pyx_t_2) < 0) __PYX_ERR(0, 493, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":496
+  /* "libzim.pyx":497
  *         raise NotImplementedError("get_content must be implemented.")
  * 
  *     def get_keywords(self) -> str:             # <<<<<<<<<<<<<<
  *         """Keywords used to index the item.
  * 
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 496, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 496, __pyx_L1_error)
-  __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_9IndexData_7get_keywords, 0, __pyx_n_s_IndexData_get_keywords, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__77)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 496, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 497, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 497, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_9IndexData_7get_keywords, 0, __pyx_n_s_IndexData_get_keywords, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__79)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 497, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_1);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_keywords, __pyx_t_5) < 0) __PYX_ERR(0, 496, __pyx_L1_error)
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_2);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_keywords, __pyx_t_5) < 0) __PYX_ERR(0, 497, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-  /* "libzim.pyx":502
+  /* "libzim.pyx":503
  *         raise NotImplementedError("get_keywords must be implemented.")
  * 
  *     def get_wordcount(self) -> int:             # <<<<<<<<<<<<<<
  *         """Number of word in content"""
  *         raise NotImplementedError("get_wordcount must be implemented.")
  */
-  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 502, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 503, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_return, __pyx_n_u_int) < 0) __PYX_ERR(0, 502, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_9IndexData_9get_wordcount, 0, __pyx_n_s_IndexData_get_wordcount, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__79)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 502, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_1, __pyx_t_5);
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_return, __pyx_n_u_int) < 0) __PYX_ERR(0, 503, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_9IndexData_9get_wordcount, 0, __pyx_n_s_IndexData_get_wordcount, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__81)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 503, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_5);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_wordcount, __pyx_t_1) < 0) __PYX_ERR(0, 502, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_wordcount, __pyx_t_2) < 0) __PYX_ERR(0, 503, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":506
+  /* "libzim.pyx":507
  *         raise NotImplementedError("get_wordcount must be implemented.")
  * 
  *     def get_geoposition(self) -> Optional[Tuple[float, float]]:             # <<<<<<<<<<<<<<
  *         """GeoPosition used to index the item.
  * 
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 506, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_Optional); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 506, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 507, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_Optional); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 507, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Tuple); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 506, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_Tuple); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 507, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 506, __pyx_L1_error)
+  __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 507, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
   __Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
@@ -26075,157 +26721,157 @@ if (!__Pyx_RefNanny) {
   __Pyx_INCREF(((PyObject *)(&PyFloat_Type)));
   __Pyx_GIVEREF(((PyObject *)(&PyFloat_Type)));
   PyTuple_SET_ITEM(__pyx_t_6, 1, ((PyObject *)(&PyFloat_Type)));
-  __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 506, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyObject_GetItem(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 507, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 506, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyObject_GetItem(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 507, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_return, __pyx_t_6) < 0) __PYX_ERR(0, 506, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_t_6) < 0) __PYX_ERR(0, 507, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_9IndexData_11get_geoposition, 0, __pyx_n_s_IndexData_get_geoposition, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__81)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 506, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_9IndexData_11get_geoposition, 0, __pyx_n_s_IndexData_get_geoposition, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__83)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 507, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_1);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_geoposition, __pyx_t_6) < 0) __PYX_ERR(0, 506, __pyx_L1_error)
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_2);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_geoposition, __pyx_t_6) < 0) __PYX_ERR(0, 507, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-  /* "libzim.pyx":478
+  /* "libzim.pyx":479
  *                 res = fh.read(bsize)
  * 
  * class IndexData:             # <<<<<<<<<<<<<<
  *     """ IndexData stub to override
  * 
  */
-  __pyx_t_6 = __Pyx_Py3ClassCreate(((PyObject*)&__Pyx_DefaultClassType), __pyx_n_s_IndexData, __pyx_empty_tuple, __pyx_t_2, NULL, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 478, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_Py3ClassCreate(((PyObject*)&__Pyx_DefaultClassType), __pyx_n_s_IndexData, __pyx_empty_tuple, __pyx_t_1, NULL, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 479, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_IndexData, __pyx_t_6) < 0) __PYX_ERR(0, 478, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_IndexData, __pyx_t_6) < 0) __PYX_ERR(0, 479, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":513
+  /* "libzim.pyx":514
  * 
  * 
  * class BaseWritingItem:             # <<<<<<<<<<<<<<
  *     """Item stub to override
  * 
  */
-  __pyx_t_2 = __Pyx_Py3MetaclassPrepare((PyObject *) NULL, __pyx_empty_tuple, __pyx_n_s_BaseWritingItem, __pyx_n_s_BaseWritingItem, (PyObject *) NULL, __pyx_n_s_libzim, __pyx_kp_s_Item_stub_to_override_Pass_a_sub); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 513, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = __Pyx_Py3MetaclassPrepare((PyObject *) NULL, __pyx_empty_tuple, __pyx_n_s_BaseWritingItem, __pyx_n_s_BaseWritingItem, (PyObject *) NULL, __pyx_n_s_libzim, __pyx_kp_s_Item_stub_to_override_Pass_a_sub); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 514, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "libzim.pyx":517
+  /* "libzim.pyx":518
  * 
  *     Pass a subclass of it to Creator.add_item()"""
  *     __module__ = writer_module_name             # <<<<<<<<<<<<<<
  * 
  *     def __init__(self):
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 517, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 518, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_module_2, __pyx_t_6) < 0) __PYX_ERR(0, 517, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_module_2, __pyx_t_6) < 0) __PYX_ERR(0, 518, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-  /* "libzim.pyx":519
+  /* "libzim.pyx":520
  *     __module__ = writer_module_name
  * 
  *     def __init__(self):             # <<<<<<<<<<<<<<
  *         self._blob = None
  * 
  */
-  __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_1__init__, 0, __pyx_n_s_BaseWritingItem___init, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__83)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 519, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_1__init__, 0, __pyx_n_s_BaseWritingItem___init, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__85)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 520, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_init, __pyx_t_6) < 0) __PYX_ERR(0, 519, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_init, __pyx_t_6) < 0) __PYX_ERR(0, 520, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-  /* "libzim.pyx":522
+  /* "libzim.pyx":523
  *         self._blob = None
  * 
  *     def get_path(self) -> str:             # <<<<<<<<<<<<<<
  *         """Full path of item"""
  *         raise NotImplementedError("get_path must be implemented.")
  */
-  __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 522, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 523, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 522, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_3get_path, 0, __pyx_n_s_BaseWritingItem_get_path, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__85)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 522, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_1, __pyx_t_6);
+  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 523, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_3get_path, 0, __pyx_n_s_BaseWritingItem_get_path, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__87)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 523, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_6);
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_path, __pyx_t_1) < 0) __PYX_ERR(0, 522, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_path, __pyx_t_2) < 0) __PYX_ERR(0, 523, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":526
+  /* "libzim.pyx":527
  *         raise NotImplementedError("get_path must be implemented.")
  * 
  *     def get_title(self) -> str:             # <<<<<<<<<<<<<<
  *         """Item title. Might be indexed and used in suggestions"""
  *         raise NotImplementedError("get_title must be implemented.")
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 526, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 526, __pyx_L1_error)
-  __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_5get_title, 0, __pyx_n_s_BaseWritingItem_get_title, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__87)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 526, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 527, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 527, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_5get_title, 0, __pyx_n_s_BaseWritingItem_get_title, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__89)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 527, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_1);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_title, __pyx_t_6) < 0) __PYX_ERR(0, 526, __pyx_L1_error)
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_2);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_title, __pyx_t_6) < 0) __PYX_ERR(0, 527, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-  /* "libzim.pyx":530
+  /* "libzim.pyx":531
  *         raise NotImplementedError("get_title must be implemented.")
  * 
  *     def get_mimetype(self) -> str:             # <<<<<<<<<<<<<<
  *         """MIME-type of the item's content."""
  *         raise NotImplementedError("get_mimetype must be implemented.")
  */
-  __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 530, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 531, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 530, __pyx_L1_error)
-  __pyx_t_1 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_7get_mimetype, 0, __pyx_n_s_BaseWritingItem_get_mimetype, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__89)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 530, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_1, __pyx_t_6);
+  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 531, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_7get_mimetype, 0, __pyx_n_s_BaseWritingItem_get_mimetype, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__91)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 531, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_6);
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_mimetype, __pyx_t_1) < 0) __PYX_ERR(0, 530, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_mimetype, __pyx_t_2) < 0) __PYX_ERR(0, 531, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":534
+  /* "libzim.pyx":535
  *         raise NotImplementedError("get_mimetype must be implemented.")
  * 
  *     def get_contentprovider(self) -> ContentProvider:             # <<<<<<<<<<<<<<
  *         """ContentProvider containing the complete content of the item"""
  *         raise NotImplementedError("get_contentprovider must be implemented.")
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 534, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_ContentProvider); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 534, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 535, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_ContentProvider); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 535, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_return, __pyx_t_6) < 0) __PYX_ERR(0, 534, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_return, __pyx_t_6) < 0) __PYX_ERR(0, 535, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_9get_contentprovider, 0, __pyx_n_s_BaseWritingItem_get_contentprovi, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__91)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 534, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_9get_contentprovider, 0, __pyx_n_s_BaseWritingItem_get_contentprovi, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__93)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 535, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_1);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_contentprovider, __pyx_t_6) < 0) __PYX_ERR(0, 534, __pyx_L1_error)
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_2);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_contentprovider, __pyx_t_6) < 0) __PYX_ERR(0, 535, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-  /* "libzim.pyx":538
+  /* "libzim.pyx":539
  *         raise NotImplementedError("get_contentprovider must be implemented.")
  * 
  *     def get_hints(self) -> Dict[Hint, pyint]:             # <<<<<<<<<<<<<<
  *         """Dict of Hint: value informing Creator how to handle this item"""
  *         raise NotImplementedError("get_hints must be implemented.")
  */
-  __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 538, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 539, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Dict); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 538, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_Hint); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 538, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_Dict); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 539, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_Hint); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 539, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_pyint); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 538, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_pyint); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 539, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 538, __pyx_L1_error)
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 539, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_4);
   PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
@@ -26233,146 +26879,134 @@ if (!__Pyx_RefNanny) {
   PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_5);
   __pyx_t_4 = 0;
   __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 538, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 539, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_return, __pyx_t_5) < 0) __PYX_ERR(0, 538, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_return, __pyx_t_5) < 0) __PYX_ERR(0, 539, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_11get_hints, 0, __pyx_n_s_BaseWritingItem_get_hints, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__93)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 538, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_11get_hints, 0, __pyx_n_s_BaseWritingItem_get_hints, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__95)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 539, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_6);
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_get_hints, __pyx_t_5) < 0) __PYX_ERR(0, 538, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_get_hints, __pyx_t_5) < 0) __PYX_ERR(0, 539, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
 
-  /* "libzim.pyx":542
+  /* "libzim.pyx":543
  *         raise NotImplementedError("get_hints must be implemented.")
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
  *         return (
  *             f"{self.__class__.__name__}(path={self.get_path()}, "
  */
-  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 542, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 543, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 542, __pyx_L1_error)
-  __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_13__repr__, 0, __pyx_n_s_BaseWritingItem___repr, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__95)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 542, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 543, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_15BaseWritingItem_13__repr__, 0, __pyx_n_s_BaseWritingItem___repr, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__97)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 543, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
   __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_6, __pyx_t_5);
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_repr, __pyx_t_6) < 0) __PYX_ERR(0, 542, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_1, __pyx_n_s_repr, __pyx_t_6) < 0) __PYX_ERR(0, 543, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
 
-  /* "libzim.pyx":513
+  /* "libzim.pyx":514
  * 
  * 
  * class BaseWritingItem:             # <<<<<<<<<<<<<<
  *     """Item stub to override
  * 
  */
-  __pyx_t_6 = __Pyx_Py3ClassCreate(((PyObject*)&__Pyx_DefaultClassType), __pyx_n_s_BaseWritingItem, __pyx_empty_tuple, __pyx_t_2, NULL, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 513, __pyx_L1_error)
+  __pyx_t_6 = __Pyx_Py3ClassCreate(((PyObject*)&__Pyx_DefaultClassType), __pyx_n_s_BaseWritingItem, __pyx_empty_tuple, __pyx_t_1, NULL, 0, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 514, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BaseWritingItem, __pyx_t_6) < 0) __PYX_ERR(0, 513, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_BaseWritingItem, __pyx_t_6) < 0) __PYX_ERR(0, 514, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "libzim.pyx":549
- * 
- * 
- * def pascalize(keyword: str):             # <<<<<<<<<<<<<<
- *     """Converts python case to pascal case.
- * 
- */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_6libzim_3pascalize, NULL, __pyx_n_s_libzim); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 549, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pascalize, __pyx_t_2) < 0) __PYX_ERR(0, 549, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":556
+  /* "libzim.pyx":550
  * 
  * 
  * class Creator(_Creator):             # <<<<<<<<<<<<<<
  *     __module__ = writer_module_name
  *     def config_compression(self, compression: Compression):
  */
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 556, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 550, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
   __Pyx_INCREF(((PyObject *)__pyx_ptype_6libzim__Creator));
   __Pyx_GIVEREF(((PyObject *)__pyx_ptype_6libzim__Creator));
-  PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_ptype_6libzim__Creator));
-  __pyx_t_6 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 556, __pyx_L1_error)
+  PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_ptype_6libzim__Creator));
+  __pyx_t_6 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 550, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
-  __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_6, __pyx_t_2, __pyx_n_s_Creator_2, __pyx_n_s_Creator_2, (PyObject *) NULL, __pyx_n_s_libzim, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 556, __pyx_L1_error)
+  __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_6, __pyx_t_1, __pyx_n_s_Creator_2, __pyx_n_s_Creator_2, (PyObject *) NULL, __pyx_n_s_libzim, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 550, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
-  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 556, __pyx_L1_error)
+  __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 550, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "libzim.pyx":557
+  /* "libzim.pyx":551
  * 
  * class Creator(_Creator):
  *     __module__ = writer_module_name             # <<<<<<<<<<<<<<
  *     def config_compression(self, compression: Compression):
  *         if not isinstance(compression, Compression):
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 557, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (__Pyx_SetNameInClass(__pyx_t_5, __pyx_n_s_module_2, __pyx_t_1) < 0) __PYX_ERR(0, 557, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 551, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (__Pyx_SetNameInClass(__pyx_t_5, __pyx_n_s_module_2, __pyx_t_2) < 0) __PYX_ERR(0, 551, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":558
+  /* "libzim.pyx":552
  * class Creator(_Creator):
  *     __module__ = writer_module_name
  *     def config_compression(self, compression: Compression):             # <<<<<<<<<<<<<<
  *         if not isinstance(compression, Compression):
  *             compression = getattr(Compression, compression.lower())
  */
-  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 558, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_Compression); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 558, __pyx_L1_error)
+  __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 552, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_Compression); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 552, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_compression, __pyx_t_4) < 0) __PYX_ERR(0, 558, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_compression, __pyx_t_4) < 0) __PYX_ERR(0, 552, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_7Creator_1config_compression, 0, __pyx_n_s_Creator_config_compression, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__99)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 558, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_7Creator_1config_compression, 0, __pyx_n_s_Creator_config_compression, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__99)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 552, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_INCREF(__pyx_t_4);
   PyList_Append(__pyx_t_3, __pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_4);
-  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_1);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_5, __pyx_n_s_config_compression, __pyx_t_4) < 0) __PYX_ERR(0, 558, __pyx_L1_error)
+  __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_2);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_5, __pyx_n_s_config_compression, __pyx_t_4) < 0) __PYX_ERR(0, 552, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "libzim.pyx":563
+  /* "libzim.pyx":557
  *         return super().config_compression(compression)
  * 
  *     def add_metadata(             # <<<<<<<<<<<<<<
  *         self, name: str, content: Union[str, bytes, datetime.date, datetime.datetime],
  *         mimetype: str = "text/plain;charset=UTF-8"
  */
-  __pyx_t_4 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 563, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 557, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_name, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 563, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_name, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 557, __pyx_L1_error)
 
-  /* "libzim.pyx":564
+  /* "libzim.pyx":558
  * 
  *     def add_metadata(
  *         self, name: str, content: Union[str, bytes, datetime.date, datetime.datetime],             # <<<<<<<<<<<<<<
  *         mimetype: str = "text/plain;charset=UTF-8"
  *     ):
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Union); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 564, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_datetime); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 564, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_Union); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 558, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_datetime); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 558, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_date); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 564, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_date); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 558, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_datetime); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 564, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_datetime); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 558, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_datetime); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 564, __pyx_L1_error)
+  __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_datetime); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 558, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_9);
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __pyx_t_7 = PyTuple_New(4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 564, __pyx_L1_error)
+  __pyx_t_7 = PyTuple_New(4); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 558, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
   __Pyx_INCREF(((PyObject *)(&PyUnicode_Type)));
   __Pyx_GIVEREF(((PyObject *)(&PyUnicode_Type)));
@@ -26386,22 +27020,22 @@ if (!__Pyx_RefNanny) {
   PyTuple_SET_ITEM(__pyx_t_7, 3, __pyx_t_9);
   __pyx_t_8 = 0;
   __pyx_t_9 = 0;
-  __pyx_t_9 = __Pyx_PyObject_GetItem(__pyx_t_1, __pyx_t_7); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 564, __pyx_L1_error)
+  __pyx_t_9 = __Pyx_PyObject_GetItem(__pyx_t_2, __pyx_t_7); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 558, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_9);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_content, __pyx_t_9) < 0) __PYX_ERR(0, 563, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_content, __pyx_t_9) < 0) __PYX_ERR(0, 557, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_mimetype, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 563, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_mimetype, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 557, __pyx_L1_error)
 
-  /* "libzim.pyx":563
+  /* "libzim.pyx":557
  *         return super().config_compression(compression)
  * 
  *     def add_metadata(             # <<<<<<<<<<<<<<
  *         self, name: str, content: Union[str, bytes, datetime.date, datetime.datetime],
  *         mimetype: str = "text/plain;charset=UTF-8"
  */
-  __pyx_t_9 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_7Creator_3add_metadata, 0, __pyx_n_s_Creator_add_metadata, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__101)); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 563, __pyx_L1_error)
+  __pyx_t_9 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_7Creator_3add_metadata, 0, __pyx_n_s_Creator_add_metadata, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__101)); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 557, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_9);
   __Pyx_INCREF(__pyx_t_9);
   PyList_Append(__pyx_t_3, __pyx_t_9);
@@ -26409,80 +27043,80 @@ if (!__Pyx_RefNanny) {
   __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_9, __pyx_tuple__102);
   __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_9, __pyx_t_4);
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_5, __pyx_n_s_add_metadata, __pyx_t_9) < 0) __PYX_ERR(0, 563, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_5, __pyx_n_s_add_metadata, __pyx_t_9) < 0) __PYX_ERR(0, 557, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-  /* "libzim.pyx":574
+  /* "libzim.pyx":567
  *         super().add_metadata(name=name, content=content, mimetype=mimetype)
  * 
  *     def __repr__(self) -> str:             # <<<<<<<<<<<<<<
  *         return f"Creator(filename={self.filename})"
  * 
  */
-  __pyx_t_9 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 574, __pyx_L1_error)
+  __pyx_t_9 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 567, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_9);
-  if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 574, __pyx_L1_error)
-  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_7Creator_5__repr__, 0, __pyx_n_s_Creator___repr, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__104)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 574, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_return, __pyx_n_u_unicode) < 0) __PYX_ERR(0, 567, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_7Creator_5__repr__, 0, __pyx_n_s_Creator___repr, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__104)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 567, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
   __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_9);
   __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_5, __pyx_n_s_repr, __pyx_t_4) < 0) __PYX_ERR(0, 574, __pyx_L1_error)
+  if (__Pyx_SetNameInClass(__pyx_t_5, __pyx_n_s_repr, __pyx_t_4) < 0) __PYX_ERR(0, 567, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-  /* "libzim.pyx":556
+  /* "libzim.pyx":550
  * 
  * 
  * class Creator(_Creator):             # <<<<<<<<<<<<<<
  *     __module__ = writer_module_name
  *     def config_compression(self, compression: Compression):
  */
-  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_6, __pyx_n_s_Creator_2, __pyx_t_2, __pyx_t_5, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 556, __pyx_L1_error)
+  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_6, __pyx_n_s_Creator_2, __pyx_t_1, __pyx_t_5, NULL, 0, 0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 550, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
-  if (__Pyx_CyFunction_InitClassCell(__pyx_t_3, __pyx_t_4) < 0) __PYX_ERR(0, 556, __pyx_L1_error)
+  if (__Pyx_CyFunction_InitClassCell(__pyx_t_3, __pyx_t_4) < 0) __PYX_ERR(0, 550, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Creator_2, __pyx_t_4) < 0) __PYX_ERR(0, 556, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Creator_2, __pyx_t_4) < 0) __PYX_ERR(0, 550, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
   __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
   __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":577
+  /* "libzim.pyx":570
  *         return f"Creator(filename={self.filename})"
  * 
  * writer_module_doc = """libzim writer module             # <<<<<<<<<<<<<<
  * - Creator to create ZIM files
  * - Item to store ZIM articles metadata
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_writer_module_doc, __pyx_kp_u_libzim_writer_module_Creator_to) < 0) __PYX_ERR(0, 577, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_writer_module_doc, __pyx_kp_u_libzim_writer_module_Creator_to) < 0) __PYX_ERR(0, 570, __pyx_L1_error)
 
-  /* "libzim.pyx":594
+  /* "libzim.pyx":587
  *     creator.set_mainpath(path)"""
  * writer_public_objects = [
  *     Creator,             # <<<<<<<<<<<<<<
  *     Compression,
  *     ('Blob', WritingBlob),
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_Creator_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 594, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_Creator_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 587, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "libzim.pyx":595
+  /* "libzim.pyx":588
  * writer_public_objects = [
  *     Creator,
  *     Compression,             # <<<<<<<<<<<<<<
  *     ('Blob', WritingBlob),
  *     Hint,
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_Compression); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 595, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_n_s_Compression); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 588, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_6);
 
-  /* "libzim.pyx":596
+  /* "libzim.pyx":589
  *     Creator,
  *     Compression,
  *     ('Blob', WritingBlob),             # <<<<<<<<<<<<<<
  *     Hint,
  *     ('Item', BaseWritingItem),
  */
-  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 596, __pyx_L1_error)
+  __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 589, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_5);
   __Pyx_INCREF(__pyx_n_u_Blob);
   __Pyx_GIVEREF(__pyx_n_u_Blob);
@@ -26491,26 +27125,26 @@ if (!__Pyx_RefNanny) {
   __Pyx_GIVEREF(((PyObject *)__pyx_ptype_6libzim_WritingBlob));
   PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_ptype_6libzim_WritingBlob));
 
-  /* "libzim.pyx":597
+  /* "libzim.pyx":590
  *     Compression,
  *     ('Blob', WritingBlob),
  *     Hint,             # <<<<<<<<<<<<<<
  *     ('Item', BaseWritingItem),
  *     ContentProvider,
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_Hint); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 597, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_Hint); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 590, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_4);
 
-  /* "libzim.pyx":598
+  /* "libzim.pyx":591
  *     ('Blob', WritingBlob),
  *     Hint,
  *     ('Item', BaseWritingItem),             # <<<<<<<<<<<<<<
  *     ContentProvider,
  *     FileProvider,
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_BaseWritingItem); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 598, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_BaseWritingItem); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 591, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 598, __pyx_L1_error)
+  __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 591, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_9);
   __Pyx_INCREF(__pyx_n_u_Item);
   __Pyx_GIVEREF(__pyx_n_u_Item);
@@ -26519,150 +27153,137 @@ if (!__Pyx_RefNanny) {
   PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_3);
   __pyx_t_3 = 0;
 
-  /* "libzim.pyx":599
+  /* "libzim.pyx":592
  *     Hint,
  *     ('Item', BaseWritingItem),
  *     ContentProvider,             # <<<<<<<<<<<<<<
  *     FileProvider,
  *     StringProvider,
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_ContentProvider); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 599, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_ContentProvider); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 592, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_3);
 
-  /* "libzim.pyx":600
+  /* "libzim.pyx":593
  *     ('Item', BaseWritingItem),
  *     ContentProvider,
  *     FileProvider,             # <<<<<<<<<<<<<<
  *     StringProvider,
- *     IndexData,
+ *     IndexData
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_FileProvider); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 600, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_FileProvider); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 593, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
 
-  /* "libzim.pyx":601
+  /* "libzim.pyx":594
  *     ContentProvider,
  *     FileProvider,
  *     StringProvider,             # <<<<<<<<<<<<<<
- *     IndexData,
- *     pascalize
- */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_StringProvider); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 601, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-
-  /* "libzim.pyx":602
- *     FileProvider,
- *     StringProvider,
- *     IndexData,             # <<<<<<<<<<<<<<
- *     pascalize
+ *     IndexData
  * ]
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_IndexData); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 602, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_StringProvider); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 594, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "libzim.pyx":603
+  /* "libzim.pyx":595
+ *     FileProvider,
  *     StringProvider,
- *     IndexData,
- *     pascalize             # <<<<<<<<<<<<<<
+ *     IndexData             # <<<<<<<<<<<<<<
  * ]
  * writer = create_module(writer_module_name, writer_module_doc, writer_public_objects)
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_pascalize); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 603, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_IndexData); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 595, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
 
-  /* "libzim.pyx":593
+  /* "libzim.pyx":586
  *     creator.add_item(MyItemSubclass(path, title, mimetype, content)
  *     creator.set_mainpath(path)"""
  * writer_public_objects = [             # <<<<<<<<<<<<<<
  *     Creator,
  *     Compression,
  */
-  __pyx_t_11 = PyList_New(10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 593, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  __Pyx_GIVEREF(__pyx_t_2);
-  PyList_SET_ITEM(__pyx_t_11, 0, __pyx_t_2);
+  __pyx_t_10 = PyList_New(9); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 586, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyList_SET_ITEM(__pyx_t_10, 0, __pyx_t_1);
   __Pyx_GIVEREF(__pyx_t_6);
-  PyList_SET_ITEM(__pyx_t_11, 1, __pyx_t_6);
+  PyList_SET_ITEM(__pyx_t_10, 1, __pyx_t_6);
   __Pyx_GIVEREF(__pyx_t_5);
-  PyList_SET_ITEM(__pyx_t_11, 2, __pyx_t_5);
+  PyList_SET_ITEM(__pyx_t_10, 2, __pyx_t_5);
   __Pyx_GIVEREF(__pyx_t_4);
-  PyList_SET_ITEM(__pyx_t_11, 3, __pyx_t_4);
+  PyList_SET_ITEM(__pyx_t_10, 3, __pyx_t_4);
   __Pyx_GIVEREF(__pyx_t_9);
-  PyList_SET_ITEM(__pyx_t_11, 4, __pyx_t_9);
+  PyList_SET_ITEM(__pyx_t_10, 4, __pyx_t_9);
   __Pyx_GIVEREF(__pyx_t_3);
-  PyList_SET_ITEM(__pyx_t_11, 5, __pyx_t_3);
+  PyList_SET_ITEM(__pyx_t_10, 5, __pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_7);
-  PyList_SET_ITEM(__pyx_t_11, 6, __pyx_t_7);
-  __Pyx_GIVEREF(__pyx_t_1);
-  PyList_SET_ITEM(__pyx_t_11, 7, __pyx_t_1);
+  PyList_SET_ITEM(__pyx_t_10, 6, __pyx_t_7);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyList_SET_ITEM(__pyx_t_10, 7, __pyx_t_2);
   __Pyx_GIVEREF(__pyx_t_8);
-  PyList_SET_ITEM(__pyx_t_11, 8, __pyx_t_8);
-  __Pyx_GIVEREF(__pyx_t_10);
-  PyList_SET_ITEM(__pyx_t_11, 9, __pyx_t_10);
-  __pyx_t_2 = 0;
+  PyList_SET_ITEM(__pyx_t_10, 8, __pyx_t_8);
+  __pyx_t_1 = 0;
   __pyx_t_6 = 0;
   __pyx_t_5 = 0;
   __pyx_t_4 = 0;
   __pyx_t_9 = 0;
   __pyx_t_3 = 0;
   __pyx_t_7 = 0;
-  __pyx_t_1 = 0;
+  __pyx_t_2 = 0;
   __pyx_t_8 = 0;
-  __pyx_t_10 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_writer_public_objects, __pyx_t_11) < 0) __PYX_ERR(0, 593, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_writer_public_objects, __pyx_t_10) < 0) __PYX_ERR(0, 586, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 
-  /* "libzim.pyx":605
- *     pascalize
+  /* "libzim.pyx":597
+ *     IndexData
  * ]
  * writer = create_module(writer_module_name, writer_module_doc, writer_public_objects)             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_create_module); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 605, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 605, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_create_module); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 597, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_10);
-  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_writer_module_doc); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 605, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_writer_module_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 597, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_writer_public_objects); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 605, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 605, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_writer_module_doc); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 597, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_writer_public_objects); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 597, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_GIVEREF(__pyx_t_10);
-  PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_10);
+  __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 597, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
   __Pyx_GIVEREF(__pyx_t_8);
-  PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_8);
-  __Pyx_GIVEREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_t_1);
-  __pyx_t_10 = 0;
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_7);
+  PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_7);
   __pyx_t_8 = 0;
-  __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 605, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_7 = 0;
+  __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_3, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 597, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_writer, __pyx_t_7) < 0) __PYX_ERR(0, 597, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_writer, __pyx_t_1) < 0) __PYX_ERR(0, 605, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":612
+  /* "libzim.pyx":604
  * ###############################################################################
  * 
  * reader_module_name = f"{__name__}.reader"             # <<<<<<<<<<<<<<
  * cdef Py_ssize_t itemsize = 1
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 612, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_7 = __Pyx_PyObject_FormatSimple(__pyx_t_1, __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 612, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_name_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 604, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_t_7, __pyx_kp_u_reader_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 612, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_t_7, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 604, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __pyx_t_7 = __Pyx_PyUnicode_Concat(__pyx_t_3, __pyx_kp_u_reader_2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 604, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_reader_module_name, __pyx_t_7) < 0) __PYX_ERR(0, 604, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_reader_module_name, __pyx_t_1) < 0) __PYX_ERR(0, 612, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":613
+  /* "libzim.pyx":605
  * 
  * reader_module_name = f"{__name__}.reader"
  * cdef Py_ssize_t itemsize = 1             # <<<<<<<<<<<<<<
@@ -26671,577 +27292,735 @@ if (!__Pyx_RefNanny) {
  */
   __pyx_v_6libzim_itemsize = 1;
 
-  /* "libzim.pyx":616
+  /* "libzim.pyx":608
  * 
  * cdef class ReadingBlob:
  *     __module__ = reader_module_name             # <<<<<<<<<<<<<<
  *     cdef zim.Blob c_blob
  *     cdef Py_ssize_t size
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_reader_module_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 616, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_ReadingBlob->tp_dict, __pyx_n_s_module_2, __pyx_t_1) < 0) __PYX_ERR(0, 616, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_reader_module_name); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 608, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_ReadingBlob->tp_dict, __pyx_n_s_module_2, __pyx_t_7) < 0) __PYX_ERR(0, 608, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   PyType_Modified(__pyx_ptype_6libzim_ReadingBlob);
 
-  /* "libzim.pyx":672
+  /* "libzim.pyx":664
  *         *c_entry : Entry (zim::)
  *             a pointer to the C++ entry object"""
  *     __module__ = reader_module_name             # <<<<<<<<<<<<<<
  *     cdef zim.Entry c_entry
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_reader_module_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 672, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_Entry->tp_dict, __pyx_n_s_module_2, __pyx_t_1) < 0) __PYX_ERR(0, 672, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_reader_module_name); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 664, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_Entry->tp_dict, __pyx_n_s_module_2, __pyx_t_7) < 0) __PYX_ERR(0, 664, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   PyType_Modified(__pyx_ptype_6libzim_Entry);
 
-  /* "libzim.pyx":729
+  /* "libzim.pyx":721
  *         *c_entry : Entry (zim::)
  *             a pointer to the C++ entry object"""
  *     __module__ = reader_module_name             # <<<<<<<<<<<<<<
  *     cdef zim.Item c_item
  *     cdef ReadingBlob _blob
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_reader_module_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 729, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_Item->tp_dict, __pyx_n_s_module_2, __pyx_t_1) < 0) __PYX_ERR(0, 729, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_reader_module_name); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 721, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_Item->tp_dict, __pyx_n_s_module_2, __pyx_t_7) < 0) __PYX_ERR(0, 721, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   PyType_Modified(__pyx_ptype_6libzim_Item);
 
-  /* "libzim.pyx":793
+  /* "libzim.pyx":785
  *             the file name of the Archive Reader object"""
  * 
  *     __module__ = reader_module_name             # <<<<<<<<<<<<<<
  *     cdef zim.Archive c_archive
  *     cdef object _filename
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_reader_module_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 793, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_Archive->tp_dict, __pyx_n_s_module_2, __pyx_t_1) < 0) __PYX_ERR(0, 793, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_reader_module_name); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 785, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_Archive->tp_dict, __pyx_n_s_module_2, __pyx_t_7) < 0) __PYX_ERR(0, 785, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   PyType_Modified(__pyx_ptype_6libzim_Archive);
 
-  /* "libzim.pyx":1019
+  /* "libzim.pyx":1011
  *         return f"{self.__class__.__name__}(filename={self.filename})"
  * 
  * reader_module_doc = """libzim reader module             # <<<<<<<<<<<<<<
  * 
  * - Archive to open and read ZIM files (gives access to all `Entry`)
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_reader_module_doc, __pyx_kp_u_libzim_reader_module_Archive_to) < 0) __PYX_ERR(0, 1019, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_reader_module_doc, __pyx_kp_u_libzim_reader_module_Archive_to) < 0) __PYX_ERR(0, 1011, __pyx_L1_error)
 
-  /* "libzim.pyx":1031
+  /* "libzim.pyx":1023
  *     print(f"Article {entry.title} at {entry.path} is "
  *           f"{entry.get_item().content.nbytes}b")"""
  * reader_public_objects = [             # <<<<<<<<<<<<<<
  *     Archive,
  *     Entry,
  */
-  __pyx_t_1 = PyList_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1031, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_7 = PyList_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1023, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
   __Pyx_INCREF(((PyObject *)__pyx_ptype_6libzim_Archive));
   __Pyx_GIVEREF(((PyObject *)__pyx_ptype_6libzim_Archive));
-  PyList_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_ptype_6libzim_Archive));
+  PyList_SET_ITEM(__pyx_t_7, 0, ((PyObject *)__pyx_ptype_6libzim_Archive));
   __Pyx_INCREF(((PyObject *)__pyx_ptype_6libzim_Entry));
   __Pyx_GIVEREF(((PyObject *)__pyx_ptype_6libzim_Entry));
-  PyList_SET_ITEM(__pyx_t_1, 1, ((PyObject *)__pyx_ptype_6libzim_Entry));
+  PyList_SET_ITEM(__pyx_t_7, 1, ((PyObject *)__pyx_ptype_6libzim_Entry));
   __Pyx_INCREF(((PyObject *)__pyx_ptype_6libzim_Item));
   __Pyx_GIVEREF(((PyObject *)__pyx_ptype_6libzim_Item));
-  PyList_SET_ITEM(__pyx_t_1, 2, ((PyObject *)__pyx_ptype_6libzim_Item));
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_reader_public_objects, __pyx_t_1) < 0) __PYX_ERR(0, 1031, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  PyList_SET_ITEM(__pyx_t_7, 2, ((PyObject *)__pyx_ptype_6libzim_Item));
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_reader_public_objects, __pyx_t_7) < 0) __PYX_ERR(0, 1023, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
 
-  /* "libzim.pyx":1036
+  /* "libzim.pyx":1028
  *     Item,
  * ]
  * reader = create_module(reader_module_name, reader_module_doc, reader_public_objects)             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_create_module); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1036, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_reader_module_name); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1036, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_create_module); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1028, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_reader_module_doc); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1036, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_reader_public_objects); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1036, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
-  __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1036, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_reader_module_name); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1028, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_reader_module_doc); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1028, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_10);
-  __Pyx_GIVEREF(__pyx_t_7);
-  PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
-  __Pyx_GIVEREF(__pyx_t_11);
-  PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_11);
-  __Pyx_GIVEREF(__pyx_t_8);
-  PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_t_8);
-  __pyx_t_7 = 0;
-  __pyx_t_11 = 0;
-  __pyx_t_8 = 0;
-  __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_10, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1036, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_reader_public_objects); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1028, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1028, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_reader, __pyx_t_8) < 0) __PYX_ERR(0, 1036, __pyx_L1_error)
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_10);
+  PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_10);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_2);
+  __pyx_t_3 = 0;
+  __pyx_t_10 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1028, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_reader, __pyx_t_2) < 0) __PYX_ERR(0, 1028, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":1043
+  /* "libzim.pyx":1035
  * ###############################################################################
  * 
  * search_module_name = f"{__name__}.search"             # <<<<<<<<<<<<<<
  * 
  * cdef class Query:
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_name_2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1043, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
-  __pyx_t_10 = __Pyx_PyObject_FormatSimple(__pyx_t_8, __pyx_empty_unicode); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1043, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_10);
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  __pyx_t_8 = __Pyx_PyUnicode_Concat(__pyx_t_10, __pyx_kp_u_search_2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1043, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1035, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_8 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1035, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_search_module_name, __pyx_t_8) < 0) __PYX_ERR(0, 1043, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_8, __pyx_kp_u_search_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1035, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_search_module_name, __pyx_t_2) < 0) __PYX_ERR(0, 1035, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":1047
+  /* "libzim.pyx":1039
  * cdef class Query:
  *     """ZIM agnostic Query-builder to use with a Searcher"""
  *     __module__ = search_module_name             # <<<<<<<<<<<<<<
  *     cdef zim.Query c_query
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_search_module_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1047, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_Query->tp_dict, __pyx_n_s_module_2, __pyx_t_8) < 0) __PYX_ERR(0, 1047, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_search_module_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1039, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_Query->tp_dict, __pyx_n_s_module_2, __pyx_t_2) < 0) __PYX_ERR(0, 1039, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_6libzim_Query);
 
-  /* "libzim.pyx":1057
+  /* "libzim.pyx":1049
  * cdef class SearchResultSet:
  *     """Iterator over a Search result: entry paths"""
  *     __module__ = search_module_name             # <<<<<<<<<<<<<<
  *     cdef zim.SearchResultSet c_resultset
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_search_module_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1057, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_SearchResultSet->tp_dict, __pyx_n_s_module_2, __pyx_t_8) < 0) __PYX_ERR(0, 1057, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_search_module_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1049, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_SearchResultSet->tp_dict, __pyx_n_s_module_2, __pyx_t_2) < 0) __PYX_ERR(0, 1049, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_6libzim_SearchResultSet);
 
-  /* "libzim.pyx":1076
+  /* "libzim.pyx":1068
  * cdef class Search:
  *     """Search request over a ZIM Archive"""
  *     __module__ = search_module_name             # <<<<<<<<<<<<<<
  *     cdef zim.Search c_search
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_search_module_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1076, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_Search->tp_dict, __pyx_n_s_module_2, __pyx_t_8) < 0) __PYX_ERR(0, 1076, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_search_module_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1068, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_Search->tp_dict, __pyx_n_s_module_2, __pyx_t_2) < 0) __PYX_ERR(0, 1068, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_6libzim_Search);
 
-  /* "libzim.pyx":1112
+  /* "libzim.pyx":1104
  *         *c_archive : Searcher
  *             a pointer to a C++ Searcher object"""
  *     __module__ = search_module_name             # <<<<<<<<<<<<<<
  * 
  *     cdef zim.Searcher c_searcher
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_search_module_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1112, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_Searcher->tp_dict, __pyx_n_s_module_2, __pyx_t_8) < 0) __PYX_ERR(0, 1112, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_search_module_name); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1104, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_Searcher->tp_dict, __pyx_n_s_module_2, __pyx_t_2) < 0) __PYX_ERR(0, 1104, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   PyType_Modified(__pyx_ptype_6libzim_Searcher);
 
-  /* "libzim.pyx":1130
+  /* "libzim.pyx":1122
  *         return Search.from_search(move(self.c_searcher.search(query.c_query)))
  * 
  * search_module_doc = """libzim search module             # <<<<<<<<<<<<<<
  * 
  * - Query to prepare a query from a string
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_search_module_doc, __pyx_kp_u_libzim_search_module_Query_to_pr) < 0) __PYX_ERR(0, 1130, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_search_module_doc, __pyx_kp_u_libzim_search_module_Query_to_pr) < 0) __PYX_ERR(0, 1122, __pyx_L1_error)
 
-  /* "libzim.pyx":1143
+  /* "libzim.pyx":1135
  * for path in search.getResult(10, 10) # get result from 10 to 20 (10 results)
  *     print(path, archive.get_entry_by_path(path).title)"""
  * search_public_objects = [             # <<<<<<<<<<<<<<
  *     Searcher,
  *     Query
  */
-  __pyx_t_8 = PyList_New(2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1143, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_2 = PyList_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1135, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(((PyObject *)__pyx_ptype_6libzim_Searcher));
   __Pyx_GIVEREF(((PyObject *)__pyx_ptype_6libzim_Searcher));
-  PyList_SET_ITEM(__pyx_t_8, 0, ((PyObject *)__pyx_ptype_6libzim_Searcher));
+  PyList_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_ptype_6libzim_Searcher));
   __Pyx_INCREF(((PyObject *)__pyx_ptype_6libzim_Query));
   __Pyx_GIVEREF(((PyObject *)__pyx_ptype_6libzim_Query));
-  PyList_SET_ITEM(__pyx_t_8, 1, ((PyObject *)__pyx_ptype_6libzim_Query));
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_search_public_objects, __pyx_t_8) < 0) __PYX_ERR(0, 1143, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  PyList_SET_ITEM(__pyx_t_2, 1, ((PyObject *)__pyx_ptype_6libzim_Query));
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_search_public_objects, __pyx_t_2) < 0) __PYX_ERR(0, 1135, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":1147
+  /* "libzim.pyx":1139
  *     Query
  * ]
  * search = create_module(search_module_name, search_module_doc, search_public_objects)             # <<<<<<<<<<<<<<
  * 
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_create_module); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1147, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_create_module); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1139, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_search_module_name); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1139, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
-  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_search_module_name); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1147, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_10);
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_search_module_doc); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1147, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_search_public_objects); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1147, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1147, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_search_module_doc); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1139, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_search_public_objects); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1139, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
+  __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1139, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_8);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_7);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_7);
   __Pyx_GIVEREF(__pyx_t_10);
-  PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_10);
-  __Pyx_GIVEREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_11);
-  PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_t_11);
+  PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_10);
+  __pyx_t_8 = 0;
+  __pyx_t_7 = 0;
   __pyx_t_10 = 0;
-  __pyx_t_1 = 0;
-  __pyx_t_11 = 0;
-  __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_7, NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1147, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_search, __pyx_t_11) < 0) __PYX_ERR(0, 1147, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1139, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_search, __pyx_t_10) < 0) __PYX_ERR(0, 1139, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 
-  /* "libzim.pyx":1154
+  /* "libzim.pyx":1146
  * ###############################################################################
  * 
  * suggestion_module_name = f"{__name__}.suggestion"             # <<<<<<<<<<<<<<
  * 
  * cdef class SuggestionResultSet:
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_name_2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1154, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  __pyx_t_7 = __Pyx_PyObject_FormatSimple(__pyx_t_11, __pyx_empty_unicode); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1154, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-  __pyx_t_11 = __Pyx_PyUnicode_Concat(__pyx_t_7, __pyx_kp_u_suggestion_2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1154, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_suggestion_module_name, __pyx_t_11) < 0) __PYX_ERR(0, 1154, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_name_2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1146, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
+  __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_t_10, __pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1146, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __pyx_t_10 = __Pyx_PyUnicode_Concat(__pyx_t_3, __pyx_kp_u_suggestion_2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1146, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_suggestion_module_name, __pyx_t_10) < 0) __PYX_ERR(0, 1146, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 
-  /* "libzim.pyx":1158
+  /* "libzim.pyx":1150
  * cdef class SuggestionResultSet:
  *     """Iterator over a SuggestionSearch result: entry paths"""
  *     __module__ = suggestion_module_name             # <<<<<<<<<<<<<<
  *     cdef zim.SuggestionResultSet c_resultset
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_suggestion_module_name); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1158, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_SuggestionResultSet->tp_dict, __pyx_n_s_module_2, __pyx_t_11) < 0) __PYX_ERR(0, 1158, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_suggestion_module_name); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1150, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_SuggestionResultSet->tp_dict, __pyx_n_s_module_2, __pyx_t_10) < 0) __PYX_ERR(0, 1150, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
   PyType_Modified(__pyx_ptype_6libzim_SuggestionResultSet);
 
-  /* "libzim.pyx":1176
+  /* "libzim.pyx":1168
  * 
  * cdef class SuggestionSearch:
  *     __module__ = suggestion_module_name             # <<<<<<<<<<<<<<
  *     cdef zim.SuggestionSearch c_search
  * 
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_suggestion_module_name); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1176, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_SuggestionSearch->tp_dict, __pyx_n_s_module_2, __pyx_t_11) < 0) __PYX_ERR(0, 1176, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_suggestion_module_name); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1168, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_SuggestionSearch->tp_dict, __pyx_n_s_module_2, __pyx_t_10) < 0) __PYX_ERR(0, 1168, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
   PyType_Modified(__pyx_ptype_6libzim_SuggestionSearch);
 
-  /* "libzim.pyx":1212
+  /* "libzim.pyx":1204
  *         *c_archive : Searcher
  *             a pointer to a C++ Searcher object"""
  *     __module__ = suggestion_module_name             # <<<<<<<<<<<<<<
  * 
  *     cdef zim.SuggestionSearcher c_searcher
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_suggestion_module_name); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1212, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_SuggestionSearcher->tp_dict, __pyx_n_s_module_2, __pyx_t_11) < 0) __PYX_ERR(0, 1212, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_suggestion_module_name); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1204, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6libzim_SuggestionSearcher->tp_dict, __pyx_n_s_module_2, __pyx_t_10) < 0) __PYX_ERR(0, 1204, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
   PyType_Modified(__pyx_ptype_6libzim_SuggestionSearcher);
 
-  /* "libzim.pyx":1230
+  /* "libzim.pyx":1222
  *         return SuggestionSearch.from_search(move(self.c_searcher.suggest(query.encode('UTF-8'))))
  * 
  * suggestion_module_doc = """libzim suggestion module             # <<<<<<<<<<<<<<
  * 
  * - SuggestionSearcher to perform a suggestion search over a libzim.reader.Archive
  */
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_suggestion_module_doc, __pyx_kp_u_libzim_suggestion_module_Suggest) < 0) __PYX_ERR(0, 1230, __pyx_L1_error)
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_suggestion_module_doc, __pyx_kp_u_libzim_suggestion_module_Suggest) < 0) __PYX_ERR(0, 1222, __pyx_L1_error)
 
-  /* "libzim.pyx":1241
+  /* "libzim.pyx":1233
  * for path in suggestion.getResult(10, 10) # get result from 10 to 20 (10 results)
  *     print(path, archive.get_entry_by_path(path).title)"""
  * suggestion_public_objects = [             # <<<<<<<<<<<<<<
  *     SuggestionSearcher
  * ]
  */
-  __pyx_t_11 = PyList_New(1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1241, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
+  __pyx_t_10 = PyList_New(1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1233, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
   __Pyx_INCREF(((PyObject *)__pyx_ptype_6libzim_SuggestionSearcher));
   __Pyx_GIVEREF(((PyObject *)__pyx_ptype_6libzim_SuggestionSearcher));
-  PyList_SET_ITEM(__pyx_t_11, 0, ((PyObject *)__pyx_ptype_6libzim_SuggestionSearcher));
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_suggestion_public_objects, __pyx_t_11) < 0) __PYX_ERR(0, 1241, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  PyList_SET_ITEM(__pyx_t_10, 0, ((PyObject *)__pyx_ptype_6libzim_SuggestionSearcher));
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_suggestion_public_objects, __pyx_t_10) < 0) __PYX_ERR(0, 1233, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 
-  /* "libzim.pyx":1244
+  /* "libzim.pyx":1236
  *     SuggestionSearcher
  * ]
  * suggestion = create_module(suggestion_module_name, suggestion_module_doc, suggestion_public_objects)             # <<<<<<<<<<<<<<
  * 
+ * version_module_doc = """libzim version module
+ */
+  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_create_module); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1236, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_suggestion_module_name); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1236, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_suggestion_module_doc); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1236, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_suggestion_public_objects); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1236, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1236, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_7);
+  PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7);
+  __pyx_t_3 = 0;
+  __pyx_t_2 = 0;
+  __pyx_t_7 = 0;
+  __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1236, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_suggestion, __pyx_t_7) < 0) __PYX_ERR(0, 1236, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+  /* "libzim.pyx":1238
+ * suggestion = create_module(suggestion_module_name, suggestion_module_doc, suggestion_public_objects)
+ * 
+ * version_module_doc = """libzim version module             # <<<<<<<<<<<<<<
+ * - Get version of libzim and its dependencies
+ * - Print version of libzim and its dependencies
+ */
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_version_module_doc, __pyx_kp_u_libzim_version_module_Get_versio) < 0) __PYX_ERR(0, 1238, __pyx_L1_error)
+
+  /* "libzim.pyx":1253
+ * 
  * 
+ * def print_versions(out: Union[sys.stdout, sys.stderr] = sys.stdout):             # <<<<<<<<<<<<<<
+ *     """print libzim and its dependencies list with their versions"""
+ *     for library, version in get_versions().items():
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_n_s_create_module); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1244, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_suggestion_module_name); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1244, __pyx_L1_error)
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_sys); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1253, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_suggestion_module_doc); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1244, __pyx_L1_error)
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_stdout); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1253, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_8);
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_suggestion_public_objects); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1244, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_10 = PyTuple_New(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1244, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __pyx_k__49 = __pyx_t_8;
+  __Pyx_GIVEREF(__pyx_t_8);
+  __pyx_t_8 = 0;
+  __pyx_t_8 = PyCFunction_NewEx(&__pyx_mdef_6libzim_3print_versions, NULL, __pyx_n_s_libzim); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1253, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_print_versions, __pyx_t_8) < 0) __PYX_ERR(0, 1253, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+  /* "libzim.pyx":1260
+ * 
+ * 
+ * def get_versions() -> OrderedDict[str, str]:             # <<<<<<<<<<<<<<
+ *     """ library: version mapping. Always includes `libzim`"""
+ *     versions = zim.getVersions()
+ */
+  __pyx_t_8 = PyCFunction_NewEx(&__pyx_mdef_6libzim_5get_versions, NULL, __pyx_n_s_libzim); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1260, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_get_versions, __pyx_t_8) < 0) __PYX_ERR(0, 1260, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+  /* "libzim.pyx":1268
+ *     })
+ * 
+ * def get_libzim_version() -> str:             # <<<<<<<<<<<<<<
+ *     """libzim version string"""
+ *     return get_versions()["libzim"]
+ */
+  __pyx_t_8 = PyCFunction_NewEx(&__pyx_mdef_6libzim_7get_libzim_version, NULL, __pyx_n_s_libzim); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1268, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_get_libzim_version, __pyx_t_8) < 0) __PYX_ERR(0, 1268, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+  /* "libzim.pyx":1273
+ * 
+ * version_public_objects = [
+ *     get_libzim_version,             # <<<<<<<<<<<<<<
+ *     get_versions,
+ *     print_versions,
+ */
+  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_get_libzim_version); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1273, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+
+  /* "libzim.pyx":1274
+ * version_public_objects = [
+ *     get_libzim_version,
+ *     get_versions,             # <<<<<<<<<<<<<<
+ *     print_versions,
+ * ]
+ */
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_get_versions); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1274, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+
+  /* "libzim.pyx":1275
+ *     get_libzim_version,
+ *     get_versions,
+ *     print_versions,             # <<<<<<<<<<<<<<
+ * ]
+ * version_module_name = f"{__name__}.version"
+ */
+  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_print_versions); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1275, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
+
+  /* "libzim.pyx":1272
+ *     return get_versions()["libzim"]
+ * 
+ * version_public_objects = [             # <<<<<<<<<<<<<<
+ *     get_libzim_version,
+ *     get_versions,
+ */
+  __pyx_t_2 = PyList_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1272, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_8);
+  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_7);
+  PyList_SET_ITEM(__pyx_t_2, 1, __pyx_t_7);
+  __Pyx_GIVEREF(__pyx_t_10);
+  PyList_SET_ITEM(__pyx_t_2, 2, __pyx_t_10);
+  __pyx_t_8 = 0;
+  __pyx_t_7 = 0;
+  __pyx_t_10 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_version_public_objects, __pyx_t_2) < 0) __PYX_ERR(0, 1272, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "libzim.pyx":1277
+ *     print_versions,
+ * ]
+ * version_module_name = f"{__name__}.version"             # <<<<<<<<<<<<<<
+ * version = create_module(version_module_name, version_module_doc, version_public_objects)
+ * 
+ */
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1277, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_10 = __Pyx_PyObject_FormatSimple(__pyx_t_2, __pyx_empty_unicode); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1277, __pyx_L1_error)
   __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyUnicode_Concat(__pyx_t_10, __pyx_kp_u_version_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1277, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_version_module_name, __pyx_t_2) < 0) __PYX_ERR(0, 1277, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "libzim.pyx":1278
+ * ]
+ * version_module_name = f"{__name__}.version"
+ * version = create_module(version_module_name, version_module_doc, version_public_objects)             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_create_module); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1278, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_version_module_name); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1278, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_n_s_version_module_doc); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1278, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_version_public_objects); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1278, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1278, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_10);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_10);
   __Pyx_GIVEREF(__pyx_t_7);
-  PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_7);
   __Pyx_GIVEREF(__pyx_t_8);
-  PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_8);
-  __Pyx_GIVEREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_10, 2, __pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_8);
+  __pyx_t_10 = 0;
   __pyx_t_7 = 0;
   __pyx_t_8 = 0;
-  __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_10, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1244, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_suggestion, __pyx_t_1) < 0) __PYX_ERR(0, 1244, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1278, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_version, __pyx_t_8) < 0) __PYX_ERR(0, 1278, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
 
-  /* "libzim.pyx":1248
+  /* "libzim.pyx":1281
  * 
  * 
  * class ModuleLoader(importlib.abc.Loader):             # <<<<<<<<<<<<<<
  *     # Create our module. Easy, just return the created module
  *     @staticmethod
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_importlib); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1248, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_abc); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1248, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_10);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_Loader); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1248, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1248, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_10);
-  __Pyx_GIVEREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_10); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1248, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_11 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_10, __pyx_n_s_ModuleLoader, __pyx_n_s_ModuleLoader, (PyObject *) NULL, __pyx_n_s_libzim, (PyObject *) NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1248, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
+  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_importlib); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1281, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_abc); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1281, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_Loader); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1281, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1281, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_8);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_8);
+  __pyx_t_8 = 0;
+  __pyx_t_8 = __Pyx_CalculateMetaclass(NULL, __pyx_t_3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1281, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_2 = __Pyx_Py3MetaclassPrepare(__pyx_t_8, __pyx_t_3, __pyx_n_s_ModuleLoader, __pyx_n_s_ModuleLoader, (PyObject *) NULL, __pyx_n_s_libzim, (PyObject *) NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1281, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "libzim.pyx":1251
+  /* "libzim.pyx":1284
  *     # Create our module. Easy, just return the created module
  *     @staticmethod
  *     def create_module(spec):             # <<<<<<<<<<<<<<
  *         return {
  *             'libzim.writer': writer,
  */
-  __pyx_t_8 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_12ModuleLoader_1create_module, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_ModuleLoader_create_module, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__106)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1251, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_12ModuleLoader_1create_module, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_ModuleLoader_create_module, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__111)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1284, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
 
-  /* "libzim.pyx":1250
+  /* "libzim.pyx":1283
  * class ModuleLoader(importlib.abc.Loader):
  *     # Create our module. Easy, just return the created module
  *     @staticmethod             # <<<<<<<<<<<<<<
  *     def create_module(spec):
  *         return {
  */
-  __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_8); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1250, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_11, __pyx_n_s_create_module, __pyx_t_7) < 0) __PYX_ERR(0, 1251, __pyx_L1_error)
+  __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_7); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1283, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_create_module, __pyx_t_10) < 0) __PYX_ERR(0, 1284, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 
-  /* "libzim.pyx":1260
+  /* "libzim.pyx":1294
  * 
  *     @staticmethod
  *     def exec_module(module):             # <<<<<<<<<<<<<<
  *         # Nothing to execute for our already existing module.
  *         # But we need to define exec_module to tell python not use the legacy import system.
  */
-  __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_12ModuleLoader_3exec_module, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_ModuleLoader_exec_module, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__108)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1260, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_7);
+  __pyx_t_10 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_12ModuleLoader_3exec_module, __Pyx_CYFUNCTION_STATICMETHOD, __pyx_n_s_ModuleLoader_exec_module, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__113)); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1294, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_10);
 
-  /* "libzim.pyx":1259
+  /* "libzim.pyx":1293
  *         }.get(spec.name, None)
  * 
  *     @staticmethod             # <<<<<<<<<<<<<<
  *     def exec_module(module):
  *         # Nothing to execute for our already existing module.
  */
-  __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_7); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1259, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_builtin_staticmethod, __pyx_t_10); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1293, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_exec_module, __pyx_t_7) < 0) __PYX_ERR(0, 1294, __pyx_L1_error)
   __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  if (__Pyx_SetNameInClass(__pyx_t_11, __pyx_n_s_exec_module, __pyx_t_8) < 0) __PYX_ERR(0, 1260, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
 
-  /* "libzim.pyx":1248
+  /* "libzim.pyx":1281
  * 
  * 
  * class ModuleLoader(importlib.abc.Loader):             # <<<<<<<<<<<<<<
  *     # Create our module. Easy, just return the created module
  *     @staticmethod
  */
-  __pyx_t_8 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_ModuleLoader, __pyx_t_10, __pyx_t_11, NULL, 0, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1248, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ModuleLoader, __pyx_t_8) < 0) __PYX_ERR(0, 1248, __pyx_L1_error)
+  __pyx_t_7 = __Pyx_Py3ClassCreate(__pyx_t_8, __pyx_n_s_ModuleLoader, __pyx_t_3, __pyx_t_2, NULL, 0, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1281, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ModuleLoader, __pyx_t_7) < 0) __PYX_ERR(0, 1281, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "libzim.pyx":1265
+  /* "libzim.pyx":1299
  *         pass
  * 
  * class ModuleFinder(importlib.abc.MetaPathFinder):             # <<<<<<<<<<<<<<
  *     def find_spec(self, fullname, path, target=None):
  *         if fullname.startswith("libzim."):
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_importlib); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1265, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_10);
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_abc); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1265, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_MetaPathFinder); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1265, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_10);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1265, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_10);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_10);
-  __pyx_t_10 = 0;
-  __pyx_t_10 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1265, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_10);
-  __pyx_t_11 = __Pyx_Py3MetaclassPrepare(__pyx_t_10, __pyx_t_1, __pyx_n_s_ModuleFinder, __pyx_n_s_ModuleFinder, (PyObject *) NULL, __pyx_n_s_libzim, (PyObject *) NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1265, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_importlib); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1299, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_abc); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1299, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_MetaPathFinder); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1299, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1299, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_3);
+  __pyx_t_3 = 0;
+  __pyx_t_3 = __Pyx_CalculateMetaclass(NULL, __pyx_t_8); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1299, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = __Pyx_Py3MetaclassPrepare(__pyx_t_3, __pyx_t_8, __pyx_n_s_ModuleFinder, __pyx_n_s_ModuleFinder, (PyObject *) NULL, __pyx_n_s_libzim, (PyObject *) NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1299, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "libzim.pyx":1266
+  /* "libzim.pyx":1300
  * 
  * class ModuleFinder(importlib.abc.MetaPathFinder):
  *     def find_spec(self, fullname, path, target=None):             # <<<<<<<<<<<<<<
  *         if fullname.startswith("libzim."):
  *             return importlib.machinery.ModuleSpec(fullname, ModuleLoader)
  */
-  __pyx_t_8 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_12ModuleFinder_1find_spec, 0, __pyx_n_s_ModuleFinder_find_spec, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__110)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1266, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
-  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_8, __pyx_tuple__111);
-  if (__Pyx_SetNameInClass(__pyx_t_11, __pyx_n_s_find_spec, __pyx_t_8) < 0) __PYX_ERR(0, 1266, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __pyx_t_7 = __Pyx_CyFunction_New(&__pyx_mdef_6libzim_12ModuleFinder_1find_spec, 0, __pyx_n_s_ModuleFinder_find_spec, NULL, __pyx_n_s_libzim, __pyx_d, ((PyObject *)__pyx_codeobj__115)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1300, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_7, __pyx_tuple__116);
+  if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_n_s_find_spec, __pyx_t_7) < 0) __PYX_ERR(0, 1300, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
 
-  /* "libzim.pyx":1265
+  /* "libzim.pyx":1299
  *         pass
  * 
  * class ModuleFinder(importlib.abc.MetaPathFinder):             # <<<<<<<<<<<<<<
  *     def find_spec(self, fullname, path, target=None):
  *         if fullname.startswith("libzim."):
  */
-  __pyx_t_8 = __Pyx_Py3ClassCreate(__pyx_t_10, __pyx_n_s_ModuleFinder, __pyx_t_1, __pyx_t_11, NULL, 0, 0); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1265, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_8);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ModuleFinder, __pyx_t_8) < 0) __PYX_ERR(0, 1265, __pyx_L1_error)
+  __pyx_t_7 = __Pyx_Py3ClassCreate(__pyx_t_3, __pyx_n_s_ModuleFinder, __pyx_t_8, __pyx_t_2, NULL, 0, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 1299, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_7);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_ModuleFinder, __pyx_t_7) < 0) __PYX_ERR(0, 1299, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "libzim.pyx":1273
+  /* "libzim.pyx":1307
  * 
  * # register finder for our submodules
  * sys.meta_path.insert(0, ModuleFinder())             # <<<<<<<<<<<<<<
  * 
- * __all__ = ["writer", "reader", "search", "suggestion"]
+ * __all__ = ["writer", "reader", "search", "suggestion", "version"]
  */
-  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_sys); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1273, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_meta_path); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1273, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_10);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_insert); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1273, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_n_s_ModuleFinder); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1273, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_10);
-  __pyx_t_11 = __Pyx_PyObject_CallNoArg(__pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1273, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 1273, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_GetModuleGlobalName(__pyx_t_8, __pyx_n_s_sys); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1307, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_meta_path); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1307, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_insert); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 1307, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_n_s_ModuleFinder); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1307, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1307, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 1307, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_3);
   __Pyx_INCREF(__pyx_int_0);
   __Pyx_GIVEREF(__pyx_int_0);
-  PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_int_0);
-  __Pyx_GIVEREF(__pyx_t_11);
-  PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_11);
-  __pyx_t_11 = 0;
-  __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_10, NULL); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1273, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_int_0);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1307, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "libzim.pyx":1275
+  /* "libzim.pyx":1309
  * sys.meta_path.insert(0, ModuleFinder())
  * 
- * __all__ = ["writer", "reader", "search", "suggestion"]             # <<<<<<<<<<<<<<
+ * __all__ = ["writer", "reader", "search", "suggestion", "version"]             # <<<<<<<<<<<<<<
  * 
  */
-  __pyx_t_11 = PyList_New(4); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1275, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
+  __pyx_t_2 = PyList_New(5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1309, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
   __Pyx_INCREF(__pyx_n_u_writer);
   __Pyx_GIVEREF(__pyx_n_u_writer);
-  PyList_SET_ITEM(__pyx_t_11, 0, __pyx_n_u_writer);
+  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_u_writer);
   __Pyx_INCREF(__pyx_n_u_reader);
   __Pyx_GIVEREF(__pyx_n_u_reader);
-  PyList_SET_ITEM(__pyx_t_11, 1, __pyx_n_u_reader);
+  PyList_SET_ITEM(__pyx_t_2, 1, __pyx_n_u_reader);
   __Pyx_INCREF(__pyx_n_u_search);
   __Pyx_GIVEREF(__pyx_n_u_search);
-  PyList_SET_ITEM(__pyx_t_11, 2, __pyx_n_u_search);
+  PyList_SET_ITEM(__pyx_t_2, 2, __pyx_n_u_search);
   __Pyx_INCREF(__pyx_n_u_suggestion);
   __Pyx_GIVEREF(__pyx_n_u_suggestion);
-  PyList_SET_ITEM(__pyx_t_11, 3, __pyx_n_u_suggestion);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_all, __pyx_t_11) < 0) __PYX_ERR(0, 1275, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  PyList_SET_ITEM(__pyx_t_2, 3, __pyx_n_u_suggestion);
+  __Pyx_INCREF(__pyx_n_u_version);
+  __Pyx_GIVEREF(__pyx_n_u_version);
+  PyList_SET_ITEM(__pyx_t_2, 4, __pyx_n_u_version);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_all, __pyx_t_2) < 0) __PYX_ERR(0, 1309, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
   /* "libzim.pyx":1
  * # This file is part of python-libzim             # <<<<<<<<<<<<<<
  * # (see https://github.com/libzim/python-libzim)
  * #
  */
-  __pyx_t_11 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 1, __pyx_L1_error)
-  __Pyx_GOTREF(__pyx_t_11);
-  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_11) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
-  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error)
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "set.to_py":129
+  /* "pair.to_py":158
+ * 
+ * @cname("__pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string")
+ * cdef object __pyx_convert_pair_to_py_std_3a__3a_string____std_3a__3a_string(const pair[X,Y]& p):             # <<<<<<<<<<<<<<
+ *     return p.first, p.second
  * 
- * @cname("__pyx_convert_set_to_py_unsigned_int")
- * cdef object __pyx_convert_set_to_py_unsigned_int(const cpp_set[X]& s):             # <<<<<<<<<<<<<<
- *     o = set()
- *     cdef cpp_set[X].const_iterator iter = s.begin()
  */
 
   /*--- Wrapped vars code ---*/
@@ -27258,7 +28037,6 @@ if (!__Pyx_RefNanny) {
   __Pyx_XDECREF(__pyx_t_8);
   __Pyx_XDECREF(__pyx_t_9);
   __Pyx_XDECREF(__pyx_t_10);
-  __Pyx_XDECREF(__pyx_t_11);
   if (__pyx_m) {
     if (__pyx_d) {
       __Pyx_AddTraceback("init libzim", __pyx_clineno, __pyx_lineno, __pyx_filename);
@@ -27858,7 +28636,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
         return __Pyx_PyFunction_FastCall(func, NULL, 0);
     }
 #endif
-#ifdef __Pyx_CyFunction_USED
+#if defined(__Pyx_CyFunction_USED) && defined(NDEBUG)
     if (likely(PyCFunction_Check(func) || __Pyx_CyFunction_Check(func)))
 #else
     if (likely(PyCFunction_Check(func)))
@@ -27965,9 +28743,7 @@ static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
     PyGILState_STATE state;
     if (nogil)
         state = PyGILState_Ensure();
-#ifdef _MSC_VER
-    else state = (PyGILState_STATE)-1;
-#endif
+    else state = (PyGILState_STATE)0;
 #endif
     __Pyx_PyThreadState_assign
     __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
@@ -28553,10 +29329,8 @@ static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
         Py_DECREF(retval);
         __Pyx_RaiseTooManyValuesError(expected);
         return -1;
-    } else {
-        return __Pyx_IterFinish();
     }
-    return 0;
+    return __Pyx_IterFinish();
 }
 
 /* RaiseNoneIterError */
@@ -29027,6 +29801,37 @@ return_ne:
 #endif
 }
 
+/* PyUnicode_Unicode */
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Unicode(PyObject *obj) {
+    if (unlikely(obj == Py_None))
+        obj = __pyx_kp_u_None;
+    return __Pyx_NewRef(obj);
+}
+
+/* DictGetItem */
+#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY
+static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
+    PyObject *value;
+    value = PyDict_GetItemWithError(d, key);
+    if (unlikely(!value)) {
+        if (!PyErr_Occurred()) {
+            if (unlikely(PyTuple_Check(key))) {
+                PyObject* args = PyTuple_Pack(1, key);
+                if (likely(args)) {
+                    PyErr_SetObject(PyExc_KeyError, args);
+                    Py_DECREF(args);
+                }
+            } else {
+                PyErr_SetObject(PyExc_KeyError, key);
+            }
+        }
+        return NULL;
+    }
+    Py_INCREF(value);
+    return value;
+}
+#endif
+
 /* UnpackUnboundCMethod */
 static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) {
     PyObject *method;
@@ -29055,11 +29860,11 @@ static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction*
         if (flag == METH_O) {
             return (*(cfunc->func))(self, arg);
         } else if (PY_VERSION_HEX >= 0x030600B1 && flag == METH_FASTCALL) {
-            if (PY_VERSION_HEX >= 0x030700A0) {
+            #if PY_VERSION_HEX >= 0x030700A0
                 return (*(__Pyx_PyCFunctionFast)(void*)(PyCFunction)cfunc->func)(self, &arg, 1);
-            } else {
+            #else
                 return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, &arg, 1, NULL);
-            }
+            #endif
         } else if (PY_VERSION_HEX >= 0x030700A0 && flag == (METH_FASTCALL | METH_KEYWORDS)) {
             return (*(__Pyx_PyCFunctionFastWithKeywords)(void*)(PyCFunction)cfunc->func)(self, &arg, 1, NULL);
         }
@@ -30161,9 +30966,14 @@ static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, P
         self = PyTuple_GetItem(args, 0);
         if (unlikely(!self)) {
             Py_DECREF(new_args);
+#if PY_MAJOR_VERSION > 2
             PyErr_Format(PyExc_TypeError,
                          "unbound method %.200S() needs an argument",
                          cyfunc->func_qualname);
+#else
+            PyErr_SetString(PyExc_TypeError,
+                            "unbound method needs an argument");
+#endif
             return NULL;
         }
         result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw);
@@ -30291,7 +31101,7 @@ static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qual
 /* ObjectGetItem */
 #if CYTHON_USE_TYPE_SLOTS
 static PyObject *__Pyx_PyObject_GetIndex(PyObject *obj, PyObject* index) {
-    PyObject *runerr;
+    PyObject *runerr = NULL;
     Py_ssize_t key_value;
     PySequenceMethods *m = Py_TYPE(obj)->tp_as_sequence;
     if (unlikely(!(m && m->sq_item))) {
@@ -30340,7 +31150,7 @@ static int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *class
 
 /* CLineInTraceback */
 #ifndef CYTHON_CLINE_IN_TRACEBACK
-static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int c_line) {
+static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_line) {
     PyObject *use_cline;
     PyObject *ptype, *pvalue, *ptraceback;
 #if CYTHON_COMPILING_IN_CPYTHON
diff --git a/libzim/libzim.h b/libzim/libzim.h
index c98a88a..c85701e 100644
--- a/libzim/libzim.h
+++ b/libzim/libzim.h
@@ -1,4 +1,4 @@
-/* Generated by Cython 0.29.32 */
+/* Generated by Cython 0.29.33 */
 
 #ifndef __PYX_HAVE__libzim
 #define __PYX_HAVE__libzim
diff --git a/libzim/libzim.pyx b/libzim/libzim.pyx
index 508380f..120c457 100644
--- a/libzim/libzim.pyx
+++ b/libzim/libzim.pyx
@@ -39,6 +39,7 @@ import os
 import pathlib
 import sys
 import traceback
+from collections import OrderedDict
 from types import ModuleType
 from typing import Dict, Generator, Iterator, List, Optional, Set, Tuple, Union
 from uuid import UUID
@@ -546,13 +547,6 @@ class BaseWritingItem:
         )
 
 
-def pascalize(keyword: str):
-    """Converts python case to pascal case.
-
-    example: long_description -> LongDescription"""
-    return "".join(keyword.title().split("_"))
-
-
 class Creator(_Creator):
     __module__ = writer_module_name
     def config_compression(self, compression: Compression):
@@ -564,7 +558,6 @@ class Creator(_Creator):
         self, name: str, content: Union[str, bytes, datetime.date, datetime.datetime],
         mimetype: str = "text/plain;charset=UTF-8"
     ):
-        name = pascalize(name)
         if name == "Date" and isinstance(content, (datetime.date, datetime.datetime)):
             content = content.strftime("%Y-%m-%d").encode("UTF-8")
         if isinstance(content, str):
@@ -599,8 +592,7 @@ writer_public_objects = [
     ContentProvider,
     FileProvider,
     StringProvider,
-    IndexData,
-    pascalize
+    IndexData
 ]
 writer = create_module(writer_module_name, writer_module_doc, writer_public_objects)
 
@@ -1243,6 +1235,47 @@ suggestion_public_objects = [
 ]
 suggestion = create_module(suggestion_module_name, suggestion_module_doc, suggestion_public_objects)
 
+version_module_doc = """libzim version module
+- Get version of libzim and its dependencies
+- Print version of libzim and its dependencies
+- Get libzim version
+
+Usage:
+    from libzim.version import get_libzim_version, get_versions, print_versions
+    major, minor, patch = get_libzim_version().split(".", 2)
+
+    for dependency, version in get_versions().items():
+        print(f"- {dependency}={version}")
+
+    print_versions()"""
+
+
+def print_versions(out: Union[sys.stdout, sys.stderr] = sys.stdout):
+    """print libzim and its dependencies list with their versions"""
+    for library, version in get_versions().items():
+        prefix = "" if library == "libzim" else "+ "
+        print(f"{prefix}{library} {version}", file=out or sys.stdout)
+
+
+def get_versions() -> OrderedDict[str, str]:
+    """ library: version mapping. Always includes `libzim`"""
+    versions = zim.getVersions()
+    return OrderedDict({
+        library.decode("UTF-8"): version.decode("UTF-8")
+        for library, version in versions
+    })
+
+def get_libzim_version() -> str:
+    """libzim version string"""
+    return get_versions()["libzim"]
+
+version_public_objects = [
+    get_libzim_version,
+    get_versions,
+    print_versions,
+]
+version_module_name = f"{__name__}.version"
+version = create_module(version_module_name, version_module_doc, version_public_objects)
 
 
 class ModuleLoader(importlib.abc.Loader):
@@ -1253,7 +1286,8 @@ class ModuleLoader(importlib.abc.Loader):
             'libzim.writer': writer,
             'libzim.reader': reader,
             'libzim.search': search,
-            'libzim.suggestion': suggestion
+            'libzim.suggestion': suggestion,
+            'libzim.version': version 
         }.get(spec.name, None)
 
     @staticmethod
@@ -1272,5 +1306,5 @@ class ModuleFinder(importlib.abc.MetaPathFinder):
 # register finder for our submodules
 sys.meta_path.insert(0, ModuleFinder())
 
-__all__ = ["writer", "reader", "search", "suggestion"]
+__all__ = ["writer", "reader", "search", "suggestion", "version"]
 
diff --git a/libzim/libzim_api.h b/libzim/libzim_api.h
index 766700e..cafb914 100644
--- a/libzim/libzim_api.h
+++ b/libzim/libzim_api.h
@@ -1,4 +1,4 @@
-/* Generated by Cython 0.29.32 */
+/* Generated by Cython 0.29.33 */
 
 #ifndef __PYX_HAVE_API__libzim
 #define __PYX_HAVE_API__libzim
diff --git a/libzim/zim.pxd b/libzim/zim.pxd
index 23df91d..578912f 100644
--- a/libzim/zim.pxd
+++ b/libzim/zim.pxd
@@ -22,6 +22,7 @@ from libc.stdint cimport uint32_t, uint64_t
 from libcpp cimport bool
 from libcpp.map cimport map
 from libcpp.memory cimport shared_ptr
+from libcpp.pair cimport pair
 from libcpp.set cimport set
 from libcpp.string cimport string
 from libcpp.vector cimport vector
@@ -218,3 +219,6 @@ cdef extern from "libwrapper.h" namespace "wrapper":
         SuggestionIterator begin()
         SuggestionIterator end()
         int size()
+
+cdef extern from "zim/version.h" namespace "zim":
+    cdef vector[pair[string, string]] getVersions()
diff --git a/setup.cfg b/setup.cfg
index 428a86d..f181a6c 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
 [metadata]
 name = libzim
-version = 2.1.0
+version = 3.0.0
 url = https://github.com/openzim/python-libzim
 project_urls = 
 	Donate = https://www.kiwix.org/en/support-us/
diff --git a/tests/test_libzim_creator.py b/tests/test_libzim_creator.py
index 62552e3..164f38c 100644
--- a/tests/test_libzim_creator.py
+++ b/tests/test_libzim_creator.py
@@ -135,12 +135,6 @@ def test_imports():
     assert libzim.writer.Creator  # noqa
 
 
-def test_pascalize():
-    assert libzim.writer.pascalize("title") == "Title"
-    assert libzim.writer.pascalize("my man") == "My Man"
-    assert libzim.writer.pascalize("THATisBAD") == "Thatisbad"
-
-
 def test_creator_filename(fpath):
     with Creator(fpath) as c:
         assert c.filename == fpath
diff --git a/tests/test_libzim_reader.py b/tests/test_libzim_reader.py
index 0516c35..6763cd0 100644
--- a/tests/test_libzim_reader.py
+++ b/tests/test_libzim_reader.py
@@ -147,52 +147,47 @@ ZIMS_DATA = {
         "test_content_includes": "looking forward to your contributions.",
         "test_redirect": None,
     },
-    "corner_cases.zim": {
-        "filename": "corner_cases.zim",
-        "filesize": 75741,
-        "new_ns": False,
+    "corner_cases%23%26.zim": {
+        "filename": "corner_cases%23%26.zim",
+        "filesize": 35991,
+        "new_ns": True,
         "mutlipart": False,
-        "zim_uuid": "9150439f963dff9ec91ca09a41962d71",
+        "zim_uuid": "702abcbe6fe926152f5d451af7986437",
         "metadata_keys": [
             "Counter",
-            "Creator",
             "Date",
-            "Description",
-            "Flavour",
+            "Illustration_48x48@1",
             "Language",
-            "Name",
-            "Publisher",
             "Scraper",
-            "Source",
             "Tags",
             "Title",
         ],
         "test_metadata": "Title",
-        "test_metadata_value": "=ZIM corner cases",
+        "test_metadata_value": "ZIM corner cases",
         "has_main_entry": True,
         "has_favicon_entry": True,
-        "has_fulltext_index": True,
+        "has_fulltext_index": False,
         "has_title_index": True,
         "has_checksum": True,
         "checksum": None,
         "is_valid": True,
-        "entry_count": 19,
-        "all_entry_count": 19,
-        "article_count": 1,
+        "entry_count": 7,
+        "all_entry_count": 18,
+        "article_count": 2,
         "media_count": 1,
-        "suggestion_string": "empty",
+        "suggestion_string": "c#",
         "suggestion_count": 1,
-        "suggestion_result": ["A/empty.html"],
-        "search_string": "empty",
-        "search_count": 1,
-        "search_result": ["A/empty.html"],
-        "test_path": "A/empty.html",
-        "test_title": "empty",
+        "suggestion_result": ["c#.html"],
+        "search_string": None,
+        "search_count": 0,
+        "search_result": [],
+        "test_path": "empty.html",
+        "test_title": "empty.html",
         "test_mimetype": "text/html",
         "test_size": 0,
         "test_content_includes": "",
-        "test_redirect": "-/favicon",
-        "test_redirect_to": "I/empty.png",
+        "test_redirect": None,
+        "test_redirect_to": None,
     },
     "small.zim": {
         "filename": "small.zim",
@@ -271,8 +266,8 @@ def all_zims(tmpdir_factory):
     temp_dir = tmpdir_factory.mktemp("data")
 
     libzim_urls = [
-        f"https://github.com/kiwix/libkiwix/raw/master/test/data/{name}"
-        for name in ("zimfile.zim", "example.zim", "corner_cases.zim")
+        f"https://github.com/kiwix/libkiwix/raw/main/test/data/{name}"
+        for name in ("zimfile.zim", "example.zim", "corner_cases%23%26.zim")
     ] + ["https://github.com/openzim/zim-testing-suite/raw/main/data/nons/small.zim"]
 
     # download libzim tests
@@ -335,6 +330,7 @@ def test_content_ref_keep(all_zims):
 )
 def test_reader_archive(all_zims, filename, filesize, new_ns, mutlipart, zim_uuid):
     fpath = all_zims / filename
+
     zim = Archive(fpath)
 
     # check externaly verifiable data
@@ -370,7 +366,7 @@ def test_reader_metadata(
     if test_metadata:
         assert zim.get_metadata(test_metadata).decode("UTF-8") == test_metadata_value
         item = zim.get_metadata_item(test_metadata)
-        assert item.mimetype == "text/plain"
+        assert item.mimetype in ("text/plain", "text/plain;charset=utf-8")  # newer
         assert item.size > 1
 
 
@@ -444,6 +440,7 @@ def test_reader_checksum(all_zims, filename, has_checksum, is_valid):
             "all_entry_count",
             "article_count",
             "media_count",
+            "has_fulltext_index",
             "suggestion_string",
             "suggestion_count",
             "suggestion_result",
@@ -460,6 +457,7 @@ def test_reader_suggest_search(
     all_entry_count,
     article_count,
     media_count,
+    has_fulltext_index,
     suggestion_string,
     suggestion_count,
     suggestion_result,
@@ -475,7 +473,7 @@ def test_reader_suggest_search(
     assert zim.article_count == article_count
     assert zim.media_count == media_count
 
-    if search_string is not None:
+    if has_fulltext_index and search_string is not None:
         query = Query().set_query(search_string)
         searcher = Searcher(zim)
         search = searcher.search(query)
diff --git a/tests/test_libzim_version.py b/tests/test_libzim_version.py
new file mode 100644
index 0000000..cf06cf9
--- /dev/null
+++ b/tests/test_libzim_version.py
@@ -0,0 +1,33 @@
+import re
+import sys
+
+from libzim.version import get_libzim_version, get_versions, print_versions
+
+
+def test_version_print_version_with_stdout(capsys):
+    print_versions()
+    print("", file=sys.stdout, flush=True)
+    stdout, stderr = capsys.readouterr()
+    assert len(stdout) != 0
+
+
+def test_version_print_version_with_stderr(capsys):
+    print_versions(sys.stderr)
+    print("", file=sys.stderr, flush=True)
+    stdout, stderr = capsys.readouterr()
+    assert len(stderr) != 0
+
+
+def test_get_versions():
+    versions = get_versions()
+    assert versions
+    assert "libzim" in versions
+    assert len(versions.keys()) > 1
+    for library, version in versions.items():
+        assert isinstance(library, str)
+        assert isinstance(version, str)
+
+
+def test_get_libzim_version():
+    # libzim uses semantic versioning
+    assert re.match(r"\d+\.\d+\.\d+", get_libzim_version())

More details

Full run details

Historical runs