Skip to content

Commit e633b9a

Browse files
authored
Merge pull request #67 from maxmind/greg/py3
Drop Python 2 support
2 parents a4b31a3 + 38ca1f7 commit e633b9a

File tree

18 files changed

+181
-233
lines changed

18 files changed

+181
-233
lines changed

.pylintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[MESSAGES CONTROL]
2-
disable=C0330,R0201,R0205,W0105
2+
disable=C0330
33

44
[BASIC]
55

.travis.yml

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
11
language: python
22
matrix:
33
include:
4-
- python: 2.7
5-
dist: trusty
6-
env: RUN_SNYK=1
7-
- python: 3.5
8-
dist: trusty
94
- python: 3.6
10-
dist: trusty
115
- python: 3.7
12-
dist: xenial
136
- python: 3.8
14-
dist: xenial
157
env: RUN_LINTER=1
168
- python: nightly
17-
dist: xenial
18-
- python: pypy
19-
dist: trusty
209
allow_failures:
2110
- python: nightly
2211

@@ -31,17 +20,17 @@ before_install:
3120
- sudo ldconfig
3221
- cd ..
3322
- pip install coverage coveralls
34-
- if [[ $RUN_LINTER ]]; then pip install pylint black; fi
23+
- if [[ $RUN_LINTER ]]; then pip install pylint black mypy; fi
3524
- |
3625
if [[ $RUN_SNYK && $SNYK_TOKEN ]]; then
3726
sudo apt-get install -y nodejs;
3827
npm install -g snyk;
3928
fi
4029
4130
script:
42-
- if [[ $TRAVIS_PYTHON_VERSION != 'pypy' ]]; then export MM_FORCE_EXT_TESTS=1; fi
43-
- CFLAGS="-Werror -Wall -Wextra" coverage run --source maxminddb setup.py test
31+
- MM_FORCE_EXT_TESTS=1 CFLAGS="-Werror -Wall -Wextra" coverage run --source maxminddb setup.py test
4432
- if [[ $RUN_SNYK && $SNYK_TOKEN ]]; then snyk test --org=maxmind --file=requirements.txt; fi
33+
- if [[ $RUN_LINTER ]]; then mypy maxminddb tests; fi
4534
- if [[ $RUN_LINTER ]]; then pylint --rcfile .pylintrc maxminddb/*.py; fi
4635
- if [[ $RUN_LINTER ]]; then ./.travis-black.sh; fi
4736

HISTORY.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
History
44
-------
55

6+
2.0.0
7+
++++++++++++++++++
8+
9+
* IMPORTANT: Python 3.6 or greater is required. If you are using an older
10+
version, please use a 1.x.x release.
11+
* Type hints have been added to the pure Python implementation.
12+
613
1.5.4 (2020-05-05)
714
++++++++++++++++++
815

README.rst

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,8 @@ invalid IP address or an IPv6 address in an IPv4 database.
9393
Requirements
9494
------------
9595

96-
This code requires Python 2.7+ or 3.5+. Older versions are not supported. The C
97-
extension requires CPython. The pure Python implementation has been tested with
98-
PyPy.
99-
100-
On Python 2, the `ipaddress module <https://pypi.python.org/pypi/ipaddress>`_ is
101-
required.
96+
This code requires Python 3.6+. Older versions are not supported. The C
97+
extension requires CPython.
10298

10399
Versioning
104100
----------

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353

5454
# General information about the project.
5555
project = "maxminddb"
56-
copyright = "2013-2019, MaxMind, Inc."
56+
copyright = "2013-2020, MaxMind, Inc."
5757

5858
# The version info for the project you're documenting, acts as replacement for
5959
# |version| and |release|, also used in various other places throughout the

docs/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ Indices and tables
3535
* :ref:`modindex`
3636
* :ref:`search`
3737

38-
:copyright: (c) 2013-2019 by MaxMind, Inc.
38+
:copyright: (c) 2013-2020 by MaxMind, Inc.
3939
:license: Apache License, Version 2.0
4040

examples/benchmark.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
#!/usr/bin/python
22
# -*- coding: utf-8 -*-
33

4-
from __future__ import print_function
5-
64
import argparse
75
import maxminddb
86
import random

extension/maxminddb.c

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,6 @@ static PyObject *from_array(MMDB_entry_data_list_s **entry_data_list);
4141
static PyObject *from_uint128(const MMDB_entry_data_list_s *entry_data_list);
4242
static int ip_converter(PyObject *obj, struct sockaddr_storage *ip_address);
4343

44-
#if PY_MAJOR_VERSION >= 3
45-
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
46-
#define RETURN_MOD_INIT(m) return (m)
47-
#define FILE_NOT_FOUND_ERROR PyExc_FileNotFoundError
48-
#else
49-
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
50-
#define RETURN_MOD_INIT(m) return
51-
#define PyInt_FromLong PyLong_FromLong
52-
#define FILE_NOT_FOUND_ERROR PyExc_IOError
53-
#endif
54-
5544
#ifdef __GNUC__
5645
#define UNUSED(x) UNUSED_##x __attribute__((__unused__))
5746
#else
@@ -78,8 +67,9 @@ static int Reader_init(PyObject *self, PyObject *args, PyObject *kwds) {
7867
}
7968

8069
if (0 != access(filename, R_OK)) {
81-
PyErr_Format(
82-
FILE_NOT_FOUND_ERROR, "No such file or directory: '%s'", filename);
70+
PyErr_Format(PyExc_FileNotFoundError,
71+
"No such file or directory: '%s'",
72+
filename);
8373
return -1;
8474
}
8575

@@ -213,17 +203,10 @@ static int get_record(PyObject *self, PyObject *args, PyObject **record) {
213203
}
214204

215205
static int ip_converter(PyObject *obj, struct sockaddr_storage *ip_address) {
216-
#if PY_MAJOR_VERSION >= 3
217206
if (PyUnicode_Check(obj)) {
218207
Py_ssize_t len;
219208
const char *ipstr = PyUnicode_AsUTF8AndSize(obj, &len);
220-
#else
221-
if (PyUnicode_Check(obj) || PyString_Check(obj)) {
222-
// Although this should work on Python 3, we will hopefully delete
223-
// this soon and the Python 3 version is cleaner.
224-
const char *ipstr = PyString_AsString(obj);
225-
Py_ssize_t len = PyString_Size(obj);
226-
#endif
209+
227210
if (!ipstr) {
228211
PyErr_SetString(PyExc_TypeError,
229212
"argument 1 contains an invalid string");
@@ -713,57 +696,51 @@ static PyTypeObject Metadata_Type = {
713696

714697
static PyMethodDef MaxMindDB_methods[] = {{NULL, NULL, 0, NULL}};
715698

716-
#if PY_MAJOR_VERSION >= 3
717699
static struct PyModuleDef MaxMindDB_module = {
718700
PyModuleDef_HEAD_INIT,
719701
.m_name = "extension",
720702
.m_doc = "This is a C extension to read MaxMind DB file format",
721703
.m_methods = MaxMindDB_methods,
722704
};
723-
#endif
724705

725-
MOD_INIT(extension) {
706+
PyMODINIT_FUNC PyInit_extension(void) {
726707
PyObject *m;
727708

728-
#if PY_MAJOR_VERSION >= 3
729709
m = PyModule_Create(&MaxMindDB_module);
730-
#else
731-
m = Py_InitModule("extension", MaxMindDB_methods);
732-
#endif
733710

734711
if (!m) {
735-
RETURN_MOD_INIT(NULL);
712+
return NULL;
736713
}
737714

738715
Reader_Type.tp_new = PyType_GenericNew;
739716
if (PyType_Ready(&Reader_Type)) {
740-
RETURN_MOD_INIT(NULL);
717+
return NULL;
741718
}
742719
Py_INCREF(&Reader_Type);
743720
PyModule_AddObject(m, "Reader", (PyObject *)&Reader_Type);
744721

745722
Metadata_Type.tp_new = PyType_GenericNew;
746723
if (PyType_Ready(&Metadata_Type)) {
747-
RETURN_MOD_INIT(NULL);
724+
return NULL;
748725
}
749726
PyModule_AddObject(m, "extension", (PyObject *)&Metadata_Type);
750727

751728
PyObject *error_mod = PyImport_ImportModule("maxminddb.errors");
752729
if (error_mod == NULL) {
753-
RETURN_MOD_INIT(NULL);
730+
return NULL;
754731
}
755732

756733
MaxMindDB_error = PyObject_GetAttrString(error_mod, "InvalidDatabaseError");
757734
Py_DECREF(error_mod);
758735

759736
if (MaxMindDB_error == NULL) {
760-
RETURN_MOD_INIT(NULL);
737+
return NULL;
761738
}
762739

763740
Py_INCREF(MaxMindDB_error);
764741

765742
/* We primarily add it to the module for backwards compatibility */
766743
PyModule_AddObject(m, "InvalidDatabaseError", MaxMindDB_error);
767744

768-
RETURN_MOD_INIT(m);
745+
return m;
769746
}

maxminddb/__init__.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# pylint:disable=C0111
22
import os
3+
from typing import AnyStr, IO, Union
34

45
import maxminddb.reader
56

67
try:
78
import maxminddb.extension
89
except ImportError:
9-
maxminddb.extension = None
10+
maxminddb.extension = None # type: ignore
1011

1112
from maxminddb.const import (
1213
MODE_AUTO,
@@ -17,10 +18,13 @@
1718
MODE_FD,
1819
)
1920
from maxminddb.decoder import InvalidDatabaseError
21+
from maxminddb.reader import Reader as PyReader
2022

2123

22-
def open_database(database, mode=MODE_AUTO):
23-
"""Open a Maxmind DB database
24+
def open_database(
25+
database: Union[AnyStr, int, os.PathLike, IO], mode: int = MODE_AUTO
26+
) -> Union[PyReader, "maxminddb.extension.Reader"]:
27+
"""Open a MaxMind DB database
2428
2529
Arguments:
2630
database -- A path to a valid MaxMind DB file such as a GeoIP2 database
@@ -43,7 +47,7 @@ def open_database(database, mode=MODE_AUTO):
4347
)
4448
return maxminddb.extension.Reader(database)
4549
if mode in (MODE_AUTO, MODE_MMAP, MODE_FILE, MODE_MEMORY, MODE_FD):
46-
return maxminddb.reader.Reader(database, mode)
50+
return PyReader(database, mode)
4751
raise ValueError("Unsupported open mode: {0}".format(mode))
4852

4953

@@ -56,4 +60,4 @@ def Reader(database): # pylint: disable=invalid-name
5660
__version__ = "1.5.4"
5761
__author__ = "Gregory Oschwald"
5862
__license__ = "Apache License, Version 2.0"
59-
__copyright__ = "Copyright 2013-2019 Maxmind, Inc."
63+
__copyright__ = "Copyright 2013-2020 MaxMind, Inc."

maxminddb/compat.py

Lines changed: 0 additions & 40 deletions
This file was deleted.

0 commit comments

Comments
 (0)