Skip to content

Commit f0edc90

Browse files
authored
Merge pull request #267 from maxmind/greg/eng-3216-pep489
Implement PEP 489 + other modernizations
2 parents 2299949 + a4db64a commit f0edc90

File tree

12 files changed

+370
-245
lines changed

12 files changed

+370
-245
lines changed

HISTORY.rst

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
History
44
-------
55

6-
2.9.0
6+
3.0.0
77
++++++++++++++++++
88

99
* IMPORTANT: Python 3.10 or greater is required. If you are using an older
@@ -15,6 +15,29 @@ History
1515
thread-safe for concurrent reads on platforms with pthread support (such as
1616
Linux and macOS) and Windows. On other platforms, the extension will use
1717
GIL-based protection.
18+
* The C extension now uses PEP 489 multi-phase initialization, enabling
19+
proper subinterpreter support and module isolation for Python 3.12+. This
20+
modernizes the extension to use heap types instead of static types and
21+
implements per-module state management. Key benefits include support for
22+
Python 3.12+ isolated subinterpreters, multiple independent module
23+
instances, and future-proofing for Python 3.14's InterpreterPoolExecutor.
24+
Requested by R. Christian McDonald in GitHub #105.
25+
* **BREAKING**: The pure Python ``maxminddb.reader.Metadata`` class has been
26+
converted to a frozen dataclass. The ``__repr__`` format has changed from
27+
``maxminddb.reader.Metadata(...)`` to ``Metadata(...)``. More importantly,
28+
all Metadata attributes are now readonly and cannot be modified after
29+
creation. If you were modifying metadata attributes after object creation,
30+
you will need to update your code. All functionality remains the same,
31+
including the ``node_byte_size`` and ``search_tree_size`` properties. Note:
32+
The C extension's Metadata class has always been readonly, so this change
33+
brings the pure Python implementation into consistency with the C extension.
34+
* MODE constants have been converted to an ``IntEnum`` (``maxminddb.const.Mode``).
35+
The old constants (``MODE_AUTO``, ``MODE_FILE``, etc.) remain available for
36+
backward compatibility and are now aliases to the enum members. This provides
37+
better IDE support and type safety while maintaining full backward
38+
compatibility. You can now use either ``Mode.FILE`` or ``MODE_FILE`` - both
39+
work identically. Since ``IntEnum`` is int-compatible, existing code using
40+
the constants will continue to work without modification.
1841

1942
2.8.2 (2025-07-25)
2043
++++++++++++++++++

README.rst

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,19 @@ provide `free GeoLite2 databases
3939
files must be decompressed with ``gunzip``.
4040

4141
After you have obtained a database and imported the module, call
42-
``open_database`` with a path, or file descriptor (in the case of ``MODE_FD``),
42+
``open_database`` with a path, or file descriptor (in the case of ``Mode.FD``),
4343
to the database as the first argument. Optionally, you may pass a mode as the
44-
second argument. The modes are exported from ``maxminddb``. Valid modes are:
45-
46-
* ``MODE_MMAP_EXT`` - use the C extension with memory map.
47-
* ``MODE_MMAP`` - read from memory map. Pure Python.
48-
* ``MODE_FILE`` - read database as standard file. Pure Python.
49-
* ``MODE_MEMORY`` - load database into memory. Pure Python.
50-
* ``MODE_FD`` - load database into memory from a file descriptor. Pure Python.
51-
* ``MODE_AUTO`` - try ``MODE_MMAP_EXT``, ``MODE_MMAP``, ``MODE_FILE`` in that
44+
second argument. The modes are available from ``maxminddb.Mode``. Valid modes are:
45+
46+
* ``Mode.MMAP_EXT`` - use the C extension with memory map.
47+
* ``Mode.MMAP`` - read from memory map. Pure Python.
48+
* ``Mode.FILE`` - read database as standard file. Pure Python.
49+
* ``Mode.MEMORY`` - load database into memory. Pure Python.
50+
* ``Mode.FD`` - load database into memory from a file descriptor. Pure Python.
51+
* ``Mode.AUTO`` - try ``Mode.MMAP_EXT``, ``Mode.MMAP``, ``Mode.FILE`` in that
5252
order. Default.
5353

54-
**NOTE**: When using ``MODE_FD``, it is the *caller's* responsibility to be
54+
**NOTE**: When using ``Mode.FD``, it is the *caller's* responsibility to be
5555
sure that the file descriptor gets closed properly. The caller may close the
5656
file descriptor immediately after the ``Reader`` object is created.
5757

dev-bin/release.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ if [ -n "$(git status --porcelain)" ]; then
3333
exit 1
3434
fi
3535

36-
perl -pi -e "s/(?<=__version__ = \").+?(?=\")/$version/gsm" maxminddb/__init__.py
3736
perl -pi -e "s/(?<=^version = \").+?(?=\")/$version/gsm" pyproject.toml
3837

3938
echo $"Test results:"

0 commit comments

Comments
 (0)