Merge branch 'master' into master
diff --git a/python/_brotli.c b/python/_brotli.c
index 9f6c017..bdc24a1 100644
--- a/python/_brotli.c
+++ b/python/_brotli.c
@@ -18,7 +18,53 @@
 #define Py_ARRAY_LENGTH(array)  (sizeof(array) / sizeof((array)[0]))
 #endif
 
-static PyObject *BrotliError;
+/* Forward declaration for module definition */
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef brotli_module;
+#endif
+
+/* Module state for multi-phase initialization */
+typedef struct {
+    PyObject *BrotliError;
+} brotli_module_state;
+
+#if PY_MAJOR_VERSION >= 3
+static brotli_module_state *
+get_brotli_state(PyObject *module)
+{
+    void *state = PyModule_GetState(module);
+    assert(state != NULL);
+    return (brotli_module_state *)state;
+}
+#endif
+
+static void set_brotli_exception(const char *message) {
+#if PY_MAJOR_VERSION >= 3
+  PyObject *module = PyImport_ImportModule("_brotli");
+  if (module == NULL) {
+      PyErr_SetString(PyExc_RuntimeError, "Module not found");
+      return;
+  }
+  brotli_module_state *state = get_brotli_state(module);
+  PyErr_SetString(state->BrotliError, message);
+#else
+  /* For Python 2, use static global */
+  static PyObject *brotli_error = NULL;
+  if (brotli_error == NULL) {
+      PyObject *module_dict = PyImport_GetModuleDict();
+      PyObject *module = PyDict_GetItemString(module_dict, "_brotli");
+      if (module != NULL) {
+          brotli_error = PyObject_GetAttrString(module, "error");
+      }
+  }
+  if (brotli_error != NULL) {
+      PyErr_SetString(brotli_error, message);
+  } else {
+      PyErr_SetString(PyExc_RuntimeError, message);
+  }
+#endif
+}
+
 
 /* -----------------------------------
      BlocksOutputBuffer code
@@ -236,20 +282,20 @@
 
 static int mode_convertor(PyObject *o, BrotliEncoderMode *mode) {
   if (!PyInt_Check(o)) {
-    PyErr_SetString(BrotliError, "Invalid mode");
+    set_brotli_exception("Invalid mode");
     return 0;
   }
 
   int mode_value = -1;
   if (!as_bounded_int(o, &mode_value, 0, 255)) {
-    PyErr_SetString(BrotliError, "Invalid mode");
+    set_brotli_exception("Invalid mode");
     return 0;
   }
   *mode = (BrotliEncoderMode) mode_value;
   if (*mode != BROTLI_MODE_GENERIC &&
       *mode != BROTLI_MODE_TEXT &&
       *mode != BROTLI_MODE_FONT) {
-    PyErr_SetString(BrotliError, "Invalid mode");
+    set_brotli_exception("Invalid mode");
     return 0;
   }
 
@@ -258,12 +304,12 @@
 
 static int quality_convertor(PyObject *o, int *quality) {
   if (!PyInt_Check(o)) {
-    PyErr_SetString(BrotliError, "Invalid quality");
+    set_brotli_exception("Invalid quality");
     return 0;
   }
 
   if (!as_bounded_int(o, quality, 0, 11)) {
-    PyErr_SetString(BrotliError, "Invalid quality. Range is 0 to 11.");
+    set_brotli_exception("Invalid quality. Range is 0 to 11.");
     return 0;
   }
 
@@ -272,12 +318,12 @@
 
 static int lgwin_convertor(PyObject *o, int *lgwin) {
   if (!PyInt_Check(o)) {
-    PyErr_SetString(BrotliError, "Invalid lgwin");
+    set_brotli_exception("Invalid lgwin");
     return 0;
   }
 
   if (!as_bounded_int(o, lgwin, 10, 24)) {
-    PyErr_SetString(BrotliError, "Invalid lgwin. Range is 10 to 24.");
+    set_brotli_exception("Invalid lgwin. Range is 10 to 24.");
     return 0;
   }
 
@@ -286,12 +332,12 @@
 
 static int lgblock_convertor(PyObject *o, int *lgblock) {
   if (!PyInt_Check(o)) {
-    PyErr_SetString(BrotliError, "Invalid lgblock");
+    set_brotli_exception("Invalid lgblock");
     return 0;
   }
 
   if (!as_bounded_int(o, lgblock, 0, 24) || (*lgblock != 0 && *lgblock < 16)) {
-    PyErr_SetString(BrotliError, "Invalid lgblock. Can be 0 or in range 16 to 24.");
+    set_brotli_exception("Invalid lgblock. Can be 0 or in range 16 to 24.");
     return 0;
   }
 
@@ -470,8 +516,7 @@
   }
 
 error:
-  PyErr_SetString(BrotliError,
-                  "BrotliEncoderCompressStream failed while processing the stream");
+  set_brotli_exception("BrotliEncoderCompressStream failed while processing the stream");
   ret = NULL;
 
 finally:
@@ -507,8 +552,7 @@
   }
 
 error:
-  PyErr_SetString(BrotliError,
-                  "BrotliEncoderCompressStream failed while flushing the stream");
+  set_brotli_exception("BrotliEncoderCompressStream failed while flushing the stream");
   ret = NULL;
 finally:
   return ret;
@@ -547,8 +591,7 @@
   goto finally;
 
 error:
-  PyErr_SetString(BrotliError,
-                  "BrotliEncoderCompressStream failed while finishing the stream");
+  set_brotli_exception("BrotliEncoderCompressStream failed while finishing the stream");
   ret = NULL;
 finally:
   return ret;
@@ -791,7 +834,7 @@
 
   if (self->unconsumed_data_length > 0) {
     if (input.len > 0) {
-      PyErr_SetString(BrotliError, "process called with data when accept_more_data is False");
+      set_brotli_exception("process called with data when accept_more_data is False");
       ret = NULL;
       goto finally;
     }
@@ -808,8 +851,7 @@
   }
 
 error:
-  PyErr_SetString(BrotliError,
-                  "BrotliDecoderDecompressStream failed while processing the stream");
+  set_brotli_exception("BrotliDecoderDecompressStream failed while processing the stream");
   ret = NULL;
 
 finally:
@@ -833,7 +875,7 @@
 
 static PyObject* brotli_Decompressor_is_finished(brotli_Decompressor *self) {
   if (!self->dec) {
-    PyErr_SetString(BrotliError, "BrotliDecoderState is NULL while checking is_finished");
+    set_brotli_exception("BrotliDecoderState is NULL while checking is_finished");
     return NULL;
   }
 
@@ -1003,7 +1045,7 @@
 
 error:
   BlocksOutputBuffer_OnError(&buffer);
-  PyErr_SetString(BrotliError, "BrotliDecompress failed");
+  set_brotli_exception("BrotliDecompress failed");
   ret = NULL;
 
 finally:
@@ -1019,47 +1061,34 @@
 
 PyDoc_STRVAR(brotli_doc, "Implementation module for the Brotli library.");
 
+static int init_brotli_mod(PyObject *m) {
 #if PY_MAJOR_VERSION >= 3
-#define INIT_BROTLI   PyInit__brotli
-#define CREATE_BROTLI PyModule_Create(&brotli_module)
-#define RETURN_BROTLI return m
-#define RETURN_NULL return NULL
-
-static struct PyModuleDef brotli_module = {
-  PyModuleDef_HEAD_INIT,
-  "_brotli",      /* m_name */
-  brotli_doc,     /* m_doc */
-  0,              /* m_size */
-  brotli_methods, /* m_methods */
-  NULL,           /* m_reload */
-  NULL,           /* m_traverse */
-  NULL,           /* m_clear */
-  NULL            /* m_free */
-};
+  brotli_module_state *state = get_brotli_state(m);
+  state->BrotliError = PyErr_NewException("brotli.error", NULL, NULL);
+  if (state->BrotliError == NULL) {
+    return -1;
+  }
+  Py_INCREF(state->BrotliError);
+  if (PyModule_AddObject(m, "error", state->BrotliError) < 0) {
+    Py_DECREF(state->BrotliError);
+    return -1;
+  }
 #else
-#define INIT_BROTLI   init_brotli
-#define CREATE_BROTLI Py_InitModule3("_brotli", brotli_methods, brotli_doc)
-#define RETURN_BROTLI return
-#define RETURN_NULL return
+  PyObject* err = PyErr_NewException("brotli.error", NULL, NULL);
+  if (err != NULL) {
+    Py_INCREF(err);
+    PyModule_AddObject(m, "error", err);
+  }
 #endif
 
-PyMODINIT_FUNC INIT_BROTLI(void) {
-  PyObject *m = CREATE_BROTLI;
-
-  BrotliError = PyErr_NewException((char*) "brotli.error", NULL, NULL);
-  if (BrotliError != NULL) {
-    Py_INCREF(BrotliError);
-    PyModule_AddObject(m, "error", BrotliError);
-  }
-
   if (PyType_Ready(&brotli_CompressorType) < 0) {
-    RETURN_NULL;
+    return -1;
   }
   Py_INCREF(&brotli_CompressorType);
   PyModule_AddObject(m, "Compressor", (PyObject *)&brotli_CompressorType);
 
   if (PyType_Ready(&brotli_DecompressorType) < 0) {
-    RETURN_NULL;
+    return -1;
   }
   Py_INCREF(&brotli_DecompressorType);
   PyModule_AddObject(m, "Decompressor", (PyObject *)&brotli_DecompressorType);
@@ -1074,5 +1103,56 @@
       decoderVersion >> 24, (decoderVersion >> 12) & 0xFFF, decoderVersion & 0xFFF);
   PyModule_AddStringConstant(m, "__version__", version);
 
-  RETURN_BROTLI;
+  return 0;
 }
+
+#if PY_MAJOR_VERSION >= 3
+
+static PyModuleDef_Slot brotli_mod_slots[] = {
+  {Py_mod_exec, init_brotli_mod},
+  #if PY_MINOR_VERSION >= 12
+  {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
+  #endif
+  {0, NULL}
+};
+
+static int
+brotli_traverse(PyObject *m, visitproc visit, void *arg)
+{
+    brotli_module_state *state = get_brotli_state(m);
+    Py_VISIT(state->BrotliError);
+    return 0;
+}
+
+static int
+brotli_clear(PyObject *m)
+{
+    brotli_module_state *state = get_brotli_state(m);
+    Py_CLEAR(state->BrotliError);
+    return 0;
+}
+
+static struct PyModuleDef brotli_module = {
+  PyModuleDef_HEAD_INIT,
+  "_brotli",          /* m_name */
+  brotli_doc,         /* m_doc */
+  sizeof(brotli_module_state),  /* m_size */
+  brotli_methods,     /* m_methods */
+  brotli_mod_slots,   /* m_slots */
+  brotli_traverse,    /* m_traverse */
+  brotli_clear,       /* m_clear */
+  NULL                /* m_free */
+};
+
+PyMODINIT_FUNC PyInit__brotli(void){
+  return PyModuleDef_Init(&brotli_module);
+}
+
+#else
+
+PyMODINIT_FUNC init_brotli(void) {
+  PyObject *m = Py_InitModule3("_brotli", brotli_methods, brotli_doc);
+  init_brotli_mod(m);
+}
+
+#endif
diff --git a/setup.py b/setup.py
index 17b6167..2bb0e8a 100644
--- a/setup.py
+++ b/setup.py
@@ -36,35 +36,33 @@
 
 
 def read_define(path, macro):
-    """ Return macro value from the given file. """
-    with open(path, 'r') as f:
+    """Return macro value from the given file."""
+    with open(path, "r") as f:
         for line in f:
-            m = re.match(rf'#define\s{macro}\s+(.+)', line)
+            m = re.match(r"#define\s{}\s+(.+)".format(macro), line)
             if m:
                 return m.group(1)
-
-    return ''
+    return ""
 
 
 def get_version():
-    """ Return library version string from 'common/version.h' file. """
-    version_file_path = os.path.join(CURR_DIR, 'c', 'common', 'version.h')
-    major = read_define(version_file_path, 'BROTLI_VERSION_MAJOR')
-    minor = read_define(version_file_path, 'BROTLI_VERSION_MINOR')
-    patch = read_define(version_file_path, 'BROTLI_VERSION_PATCH')
+    """Return library version string from 'common/version.h' file."""
+    version_file_path = os.path.join(CURR_DIR, "c", "common", "version.h")
+    major = read_define(version_file_path, "BROTLI_VERSION_MAJOR")
+    minor = read_define(version_file_path, "BROTLI_VERSION_MINOR")
+    patch = read_define(version_file_path, "BROTLI_VERSION_PATCH")
     if not major or not minor or not patch:
-        return ''
-    return f'{major}.{minor}.{patch}'
+        return ""
+    return "{}.{}.{}".format(major, minor, patch)
 
 
 def get_test_suite():
     test_loader = unittest.TestLoader()
-    test_suite = test_loader.discover('python', pattern='*_test.py')
+    test_suite = test_loader.discover("python", pattern="*_test.py")
     return test_suite
 
 
 class BuildExt(build_ext):
-
     def get_source_files(self):
         filenames = build_ext.get_source_files(self)
         for ext in self.extensions:
@@ -74,13 +72,14 @@
     def build_extension(self, ext):
         if ext.sources is None or not isinstance(ext.sources, (list, tuple)):
             raise errors.DistutilsSetupError(
-            "in 'ext_modules' option (extension '%s'), "
-            "'sources' must be present and must be "
-            "a list of source filenames" % ext.name)
+                "in 'ext_modules' option (extension '%s'), "
+                "'sources' must be present and must be "
+                "a list of source filenames" % ext.name
+            )
 
         ext_path = self.get_ext_fullpath(ext.name)
         depends = ext.sources + ext.depends
-        if not (self.force or dep_util.newer_group(depends, ext_path, 'newer')):
+        if not (self.force or dep_util.newer_group(depends, ext_path, "newer")):
             log.debug("skipping '%s' extension (up-to-date)", ext.name)
             return
         else:
@@ -88,20 +87,20 @@
 
         c_sources = []
         for source in ext.sources:
-            if source.endswith('.c'):
-                 c_sources.append(source)
+            if source.endswith(".c"):
+                c_sources.append(source)
         extra_args = ext.extra_compile_args or []
 
         objects = []
 
         macros = ext.define_macros[:]
-        if platform.system() == 'Darwin':
-            macros.append(('OS_MACOSX', '1'))
-        elif self.compiler.compiler_type == 'mingw32':
+        if platform.system() == "Darwin":
+            macros.append(("OS_MACOSX", "1"))
+        elif self.compiler.compiler_type == "mingw32":
             # On Windows Python 2.7, pyconfig.h defines "hypot" as "_hypot",
             # This clashes with GCC's cmath, and causes compilation errors when
             # building under MinGW: http://bugs.python.org/issue11566
-            macros.append(('_hypot', 'hypot'))
+            macros.append(("_hypot", "hypot"))
         for undef in ext.undef_macros:
             macros.append((undef,))
 
@@ -112,7 +111,8 @@
             include_dirs=ext.include_dirs,
             debug=self.debug,
             extra_postargs=extra_args,
-            depends=ext.depends)
+            depends=ext.depends,
+        )
         objects.extend(objs)
 
         self._built_objects = objects[:]
@@ -121,8 +121,8 @@
         extra_args = ext.extra_link_args or []
         # when using GCC on Windows, we statically link libgcc and libstdc++,
         # so that we don't need to package extra DLLs
-        if self.compiler.compiler_type == 'mingw32':
-            extra_args.extend(['-static-libgcc', '-static-libstdc++'])
+        if self.compiler.compiler_type == "mingw32":
+            extra_args.extend(["-static-libgcc", "-static-libstdc++"])
 
         ext_path = self.get_ext_fullpath(ext.name)
         # Detect target language, if not provided
@@ -138,54 +138,55 @@
             export_symbols=self.get_export_symbols(ext),
             debug=self.debug,
             build_temp=self.build_temp,
-            target_lang=language)
+            target_lang=language,
+        )
 
 
-NAME = 'Brotli'
+NAME = "Brotli"
 
 VERSION = get_version()
 
-URL = 'https://github.com/google/brotli'
+URL = "https://github.com/google/brotli"
 
-DESCRIPTION = 'Python bindings for the Brotli compression library'
+DESCRIPTION = "Python bindings for the Brotli compression library"
 
-AUTHOR = 'The Brotli Authors'
+AUTHOR = "The Brotli Authors"
 
-LICENSE = 'MIT'
+LICENSE = "MIT"
 
-PLATFORMS = ['Posix', 'MacOS X', 'Windows']
+PLATFORMS = ["Posix", "MacOS X", "Windows"]
 
 CLASSIFIERS = [
-    'Development Status :: 4 - Beta',
-    'Environment :: Console',
-    'Intended Audience :: Developers',
-    'License :: OSI Approved :: MIT License',
-    'Operating System :: MacOS :: MacOS X',
-    'Operating System :: Microsoft :: Windows',
-    'Operating System :: POSIX :: Linux',
-    'Programming Language :: C',
-    'Programming Language :: C++',
-    'Programming Language :: Python',
-    'Programming Language :: Python :: 2',
-    'Programming Language :: Python :: 2.7',
-    'Programming Language :: Python :: 3',
-    'Programming Language :: Python :: 3.3',
-    'Programming Language :: Python :: 3.4',
-    'Programming Language :: Python :: 3.5',
-    'Programming Language :: Unix Shell',
-    'Topic :: Software Development :: Libraries',
-    'Topic :: Software Development :: Libraries :: Python Modules',
-    'Topic :: System :: Archiving',
-    'Topic :: System :: Archiving :: Compression',
-    'Topic :: Text Processing :: Fonts',
-    'Topic :: Utilities',
+    "Development Status :: 4 - Beta",
+    "Environment :: Console",
+    "Intended Audience :: Developers",
+    "License :: OSI Approved :: MIT License",
+    "Operating System :: MacOS :: MacOS X",
+    "Operating System :: Microsoft :: Windows",
+    "Operating System :: POSIX :: Linux",
+    "Programming Language :: C",
+    "Programming Language :: C++",
+    "Programming Language :: Python",
+    "Programming Language :: Python :: 2",
+    "Programming Language :: Python :: 2.7",
+    "Programming Language :: Python :: 3",
+    "Programming Language :: Python :: 3.3",
+    "Programming Language :: Python :: 3.4",
+    "Programming Language :: Python :: 3.5",
+    "Programming Language :: Unix Shell",
+    "Topic :: Software Development :: Libraries",
+    "Topic :: Software Development :: Libraries :: Python Modules",
+    "Topic :: System :: Archiving",
+    "Topic :: System :: Archiving :: Compression",
+    "Topic :: Text Processing :: Fonts",
+    "Topic :: Utilities",
 ]
 
-PACKAGE_DIR = {'': 'python'}
+PACKAGE_DIR = {"": "python"}
 
-PY_MODULES = ['brotli']
+PY_MODULES = ["brotli"]
 
-USE_SYSTEM_BROTLI = bool_from_environ('USE_SYSTEM_BROTLI')
+USE_SYSTEM_BROTLI = bool_from_environ("USE_SYSTEM_BROTLI")
 
 if USE_SYSTEM_BROTLI:
     import pkgconfig
@@ -221,109 +222,109 @@
 else:
     EXT_MODULES = [
         Extension(
-            '_brotli',
+            "_brotli",
             sources=[
-                'python/_brotli.c',
-                'c/common/constants.c',
-                'c/common/context.c',
-                'c/common/dictionary.c',
-                'c/common/platform.c',
-                'c/common/shared_dictionary.c',
-                'c/common/transform.c',
-                'c/dec/bit_reader.c',
-                'c/dec/decode.c',
-                'c/dec/huffman.c',
-                'c/dec/state.c',
-                'c/enc/backward_references.c',
-                'c/enc/backward_references_hq.c',
-                'c/enc/bit_cost.c',
-                'c/enc/block_splitter.c',
-                'c/enc/brotli_bit_stream.c',
-                'c/enc/cluster.c',
-                'c/enc/command.c',
-                'c/enc/compound_dictionary.c',
-                'c/enc/compress_fragment.c',
-                'c/enc/compress_fragment_two_pass.c',
-                'c/enc/dictionary_hash.c',
-                'c/enc/encode.c',
-                'c/enc/encoder_dict.c',
-                'c/enc/entropy_encode.c',
-                'c/enc/fast_log.c',
-                'c/enc/histogram.c',
-                'c/enc/literal_cost.c',
-                'c/enc/memory.c',
-                'c/enc/metablock.c',
-                'c/enc/static_dict.c',
-                'c/enc/static_dict_lut.c',
-                'c/enc/static_init.c',
-                'c/enc/utf8_util.c',
+                "python/_brotli.c",
+                "c/common/constants.c",
+                "c/common/context.c",
+                "c/common/dictionary.c",
+                "c/common/platform.c",
+                "c/common/shared_dictionary.c",
+                "c/common/transform.c",
+                "c/dec/bit_reader.c",
+                "c/dec/decode.c",
+                "c/dec/huffman.c",
+                "c/dec/state.c",
+                "c/enc/backward_references.c",
+                "c/enc/backward_references_hq.c",
+                "c/enc/bit_cost.c",
+                "c/enc/block_splitter.c",
+                "c/enc/brotli_bit_stream.c",
+                "c/enc/cluster.c",
+                "c/enc/command.c",
+                "c/enc/compound_dictionary.c",
+                "c/enc/compress_fragment.c",
+                "c/enc/compress_fragment_two_pass.c",
+                "c/enc/dictionary_hash.c",
+                "c/enc/encode.c",
+                "c/enc/encoder_dict.c",
+                "c/enc/entropy_encode.c",
+                "c/enc/fast_log.c",
+                "c/enc/histogram.c",
+                "c/enc/literal_cost.c",
+                "c/enc/memory.c",
+                "c/enc/metablock.c",
+                "c/enc/static_dict.c",
+                "c/enc/static_dict_lut.c",
+                "c/enc/static_init.c",
+                "c/enc/utf8_util.c",
             ],
             depends=[
-                'c/common/constants.h',
-                'c/common/context.h',
-                'c/common/dictionary.h',
-                'c/common/platform.h',
-                'c/common/shared_dictionary_internal.h',
-                'c/common/transform.h',
-                'c/common/version.h',
-                'c/dec/bit_reader.h',
-                'c/dec/huffman.h',
-                'c/dec/prefix.h',
-                'c/dec/state.h',
-                'c/enc/backward_references.h',
-                'c/enc/backward_references_hq.h',
-                'c/enc/backward_references_inc.h',
-                'c/enc/bit_cost.h',
-                'c/enc/bit_cost_inc.h',
-                'c/enc/block_encoder_inc.h',
-                'c/enc/block_splitter.h',
-                'c/enc/block_splitter_inc.h',
-                'c/enc/brotli_bit_stream.h',
-                'c/enc/cluster.h',
-                'c/enc/cluster_inc.h',
-                'c/enc/command.h',
-                'c/enc/compound_dictionary.h',
-                'c/enc/compress_fragment.h',
-                'c/enc/compress_fragment_two_pass.h',
-                'c/enc/dictionary_hash.h',
-                'c/enc/encoder_dict.h',
-                'c/enc/entropy_encode.h',
-                'c/enc/entropy_encode_static.h',
-                'c/enc/fast_log.h',
-                'c/enc/find_match_length.h',
-                'c/enc/hash.h',
-                'c/enc/hash_composite_inc.h',
-                'c/enc/hash_forgetful_chain_inc.h',
-                'c/enc/hash_longest_match64_inc.h',
-                'c/enc/hash_longest_match_inc.h',
-                'c/enc/hash_longest_match_quickly_inc.h',
-                'c/enc/hash_rolling_inc.h',
-                'c/enc/hash_to_binary_tree_inc.h',
-                'c/enc/histogram.h',
-                'c/enc/histogram_inc.h',
-                'c/enc/literal_cost.h',
-                'c/enc/memory.h',
-                'c/enc/metablock.h',
-                'c/enc/metablock_inc.h',
-                'c/enc/params.h',
-                'c/enc/prefix.h',
-                'c/enc/quality.h',
-                'c/enc/ringbuffer.h',
-                'c/enc/static_dict.h',
-                'c/enc/static_dict_lut.h',
-                'c/enc/static_init.h',
-                'c/enc/utf8_util.h',
-                'c/enc/write_bits.h',
+                "c/common/constants.h",
+                "c/common/context.h",
+                "c/common/dictionary.h",
+                "c/common/platform.h",
+                "c/common/shared_dictionary_internal.h",
+                "c/common/transform.h",
+                "c/common/version.h",
+                "c/dec/bit_reader.h",
+                "c/dec/huffman.h",
+                "c/dec/prefix.h",
+                "c/dec/state.h",
+                "c/enc/backward_references.h",
+                "c/enc/backward_references_hq.h",
+                "c/enc/backward_references_inc.h",
+                "c/enc/bit_cost.h",
+                "c/enc/bit_cost_inc.h",
+                "c/enc/block_encoder_inc.h",
+                "c/enc/block_splitter.h",
+                "c/enc/block_splitter_inc.h",
+                "c/enc/brotli_bit_stream.h",
+                "c/enc/cluster.h",
+                "c/enc/cluster_inc.h",
+                "c/enc/command.h",
+                "c/enc/compound_dictionary.h",
+                "c/enc/compress_fragment.h",
+                "c/enc/compress_fragment_two_pass.h",
+                "c/enc/dictionary_hash.h",
+                "c/enc/encoder_dict.h",
+                "c/enc/entropy_encode.h",
+                "c/enc/entropy_encode_static.h",
+                "c/enc/fast_log.h",
+                "c/enc/find_match_length.h",
+                "c/enc/hash.h",
+                "c/enc/hash_composite_inc.h",
+                "c/enc/hash_forgetful_chain_inc.h",
+                "c/enc/hash_longest_match64_inc.h",
+                "c/enc/hash_longest_match_inc.h",
+                "c/enc/hash_longest_match_quickly_inc.h",
+                "c/enc/hash_rolling_inc.h",
+                "c/enc/hash_to_binary_tree_inc.h",
+                "c/enc/histogram.h",
+                "c/enc/histogram_inc.h",
+                "c/enc/literal_cost.h",
+                "c/enc/memory.h",
+                "c/enc/metablock.h",
+                "c/enc/metablock_inc.h",
+                "c/enc/params.h",
+                "c/enc/prefix.h",
+                "c/enc/quality.h",
+                "c/enc/ringbuffer.h",
+                "c/enc/static_dict.h",
+                "c/enc/static_dict_lut.h",
+                "c/enc/static_init.h",
+                "c/enc/utf8_util.h",
+                "c/enc/write_bits.h",
             ],
             include_dirs=[
-                'c/include',
+                "c/include",
             ]),
     ]
 
-TEST_SUITE = 'setup.get_test_suite'
+TEST_SUITE = "setup.get_test_suite"
 
 CMD_CLASS = {
-    'build_ext': BuildExt,
+    "build_ext": BuildExt,
 }
 
 with open("README.md", "r") as f:
@@ -344,4 +345,5 @@
     py_modules=PY_MODULES,
     ext_modules=EXT_MODULES,
     test_suite=TEST_SUITE,
-    cmdclass=CMD_CLASS)
+    cmdclass=CMD_CLASS,
+)