Merge ~ahasenack/ubuntu/+source/python-maxminddb:groovy-python-maxminddb-1.5.4 into ubuntu/+source/python-maxminddb:ubuntu/devel
- Git
- lp:~ahasenack/ubuntu/+source/python-maxminddb
- groovy-python-maxminddb-1.5.4
- Merge into ubuntu/devel
Status: | Merged |
---|---|
Approved by: | Andreas Hasenack |
Approved revision: | b084998c9d7d6f2acf9b4c3fc8eb5f5d46b33a24 |
Merged at revision: | b084998c9d7d6f2acf9b4c3fc8eb5f5d46b33a24 |
Proposed branch: | ~ahasenack/ubuntu/+source/python-maxminddb:groovy-python-maxminddb-1.5.4 |
Merge into: | ubuntu/+source/python-maxminddb:ubuntu/devel |
Diff against target: |
2949 lines (+787/-667) 31 files modified
HISTORY.rst (+12/-0) MANIFEST.in (+2/-1) PKG-INFO (+1/-1) debian/changelog (+7/-0) debian/patches/rebuild-sphinx-docs.patch (+67/-65) docs/html/.buildinfo (+1/-1) docs/html/_static/basic.css (+1/-1) docs/html/_static/doctools.js (+4/-3) docs/html/_static/documentation_options.js (+2/-1) docs/html/_static/language_data.js (+1/-1) docs/html/_static/searchtools.js (+17/-8) docs/html/_static/sphinxdoc.css (+1/-1) docs/html/genindex.html (+40/-14) docs/html/index.html (+36/-36) docs/html/py-modindex.html (+10/-10) docs/html/search.html (+14/-16) docs/html/searchindex.js (+1/-1) extension/maxminddb.c (+10/-0) maxminddb.egg-info/PKG-INFO (+1/-1) maxminddb.egg-info/SOURCES.txt (+11/-0) maxminddb/__init__.py (+15/-10) maxminddb/compat.py (+1/-1) maxminddb/decoder.py (+26/-24) maxminddb/file.py (+4/-3) maxminddb/reader.py (+43/-46) setup.py (+80/-73) tests/data/bad-data/maxminddb-golang/invalid-bytes-length.mmdb (+1/-0) tests/data/bad-data/maxminddb-golang/invalid-string-length.mmdb (+1/-0) tests/data/bad-data/maxminddb-golang/metadata-is-an-uint128.mmdb (+1/-0) tests/decoder_test.py (+89/-110) tests/reader_test.py (+287/-239) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Christian Ehrhardt (community) | Approve | ||
Canonical Server | Pending | ||
Review via email: mp+385185@code.launchpad.net |
Commit message
Description of the change
Version update to 1.5.4. Debian is still behind. The sphinx patch update is just cosmetic changes.
Andreas Hasenack (ahasenack) wrote : | # |
Thanks, tagging and uploading b084998c9d7d6f2
$ git push pkg upload/
Enumerating objects: 158, done.
Counting objects: 100% (158/158), done.
Delta compression using up to 4 threads
Compressing objects: 100% (84/84), done.
Writing objects: 100% (91/91), 36.44 KiB | 5.21 MiB/s, done.
Total 91 (delta 62), reused 3 (delta 3)
To ssh://git.
* [new tag] upload/
$ dput ubuntu ../python-
Checking signature on .changes
gpg: ../python-
Checking signature on .dsc
gpg: ../python-
Uploading to ubuntu (via ftp to upload.ubuntu.com):
Uploading python-
Uploading python-
Uploading python-
Uploading python-
Uploading python-
Successfully uploaded packages.
Andreas Hasenack (ahasenack) wrote : | # |
I'll wait for this to build in proposed and then upload bind9
Preview Diff
1 | diff --git a/HISTORY.rst b/HISTORY.rst |
2 | index 5784604..389aa54 100644 |
3 | --- a/HISTORY.rst |
4 | +++ b/HISTORY.rst |
5 | @@ -3,6 +3,18 @@ |
6 | History |
7 | ------- |
8 | |
9 | +1.5.4 (2020-05-05) |
10 | +++++++++++++++++++ |
11 | + |
12 | +* 1.5.3 was missing a test database. This release adds the test file. |
13 | + There are no other changes. Reported by Lumír 'Frenzy' Balhar. GitHub #60. |
14 | + |
15 | +1.5.3 (2020-05-04) |
16 | +++++++++++++++++++ |
17 | + |
18 | +* Fix a segfault when decoding a database with a corrupt data section. |
19 | + Reported by Robert Scott. GitHub #58. |
20 | + |
21 | 1.5.2 (2019-12-20) |
22 | ++++++++++++++++++ |
23 | |
24 | diff --git a/MANIFEST.in b/MANIFEST.in |
25 | index 3658f4c..06b2c18 100644 |
26 | --- a/MANIFEST.in |
27 | +++ b/MANIFEST.in |
28 | @@ -1,2 +1,3 @@ |
29 | -include HISTORY.rst README.rst LICENSE tests/*.py tests/data/test-data/*.mmdb tests/data/test-data/*.raw |
30 | +include HISTORY.rst README.rst LICENSE |
31 | +recursive-include tests/ *.mmdb *.py *.raw |
32 | graft docs/html |
33 | diff --git a/PKG-INFO b/PKG-INFO |
34 | index 1a961e9..e8709ed 100644 |
35 | --- a/PKG-INFO |
36 | +++ b/PKG-INFO |
37 | @@ -1,6 +1,6 @@ |
38 | Metadata-Version: 1.2 |
39 | Name: maxminddb |
40 | -Version: 1.5.2 |
41 | +Version: 1.5.4 |
42 | Summary: Reader for the MaxMind DB format |
43 | Home-page: http://www.maxmind.com/ |
44 | Author: Gregory Oschwald |
45 | diff --git a/debian/changelog b/debian/changelog |
46 | index d333eda..6b22a46 100644 |
47 | --- a/debian/changelog |
48 | +++ b/debian/changelog |
49 | @@ -1,3 +1,10 @@ |
50 | +python-maxminddb (1.5.4-0ubuntu1) groovy; urgency=medium |
51 | + |
52 | + * New upstream release: 1.5.4 |
53 | + * d/p/rebuild-sphinx-docs.patch: update from upstream's 1.5.4 |
54 | + |
55 | + -- Andreas Hasenack <andreas@canonical.com> Tue, 02 Jun 2020 17:00:28 -0300 |
56 | + |
57 | python-maxminddb (1.5.2-0ubuntu1) focal; urgency=medium |
58 | |
59 | * New upstream release: 1.5.2 (LP: #1867919) |
60 | diff --git a/debian/patches/rebuild-sphinx-docs.patch b/debian/patches/rebuild-sphinx-docs.patch |
61 | index bbce8e6..3fe26a2 100644 |
62 | --- a/debian/patches/rebuild-sphinx-docs.patch |
63 | +++ b/debian/patches/rebuild-sphinx-docs.patch |
64 | @@ -27,12 +27,9 @@ Forwarded: not-needed |
65 | Last-Update: 2020-03-18 |
66 | --- |
67 | This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
68 | -diff --git a/docs-source/conf.py b/docs-source/conf.py |
69 | -new file mode 100644 |
70 | -index 0000000..f0ae2c9 |
71 | --- /dev/null |
72 | +++ b/docs-source/conf.py |
73 | -@@ -0,0 +1,248 @@ |
74 | +@@ -0,0 +1,253 @@ |
75 | +#!/usr/bin/env python3 |
76 | +# -*- coding: utf-8 -*- |
77 | +# |
78 | @@ -50,7 +47,7 @@ index 0000000..f0ae2c9 |
79 | +import sys |
80 | +import os |
81 | + |
82 | -+sys.path.insert(0, os.path.abspath('..')) |
83 | ++sys.path.insert(0, os.path.abspath("..")) |
84 | +import maxminddb |
85 | + |
86 | +__version__ = maxminddb.__version__ |
87 | @@ -58,35 +55,37 @@ index 0000000..f0ae2c9 |
88 | +# If extensions (or modules to document with autodoc) are in another directory, |
89 | +# add these directories to sys.path here. If the directory is relative to the |
90 | +# documentation root, use os.path.abspath to make it absolute, like shown here. |
91 | -+sys.path.insert(0, os.path.abspath('..')) |
92 | ++sys.path.insert(0, os.path.abspath("..")) |
93 | + |
94 | +# -- General configuration ----------------------------------------------- |
95 | + |
96 | +# If your documentation needs a minimal Sphinx version, state it here. |
97 | -+#needs_sphinx = '1.0' |
98 | ++# needs_sphinx = '1.0' |
99 | + |
100 | +# Add any Sphinx extension module names here, as strings. They can be extensions |
101 | +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. |
102 | +extensions = [ |
103 | -+ 'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', |
104 | -+ 'sphinx.ext.coverage' |
105 | ++ "sphinx.ext.autodoc", |
106 | ++ "sphinx.ext.doctest", |
107 | ++ "sphinx.ext.intersphinx", |
108 | ++ "sphinx.ext.coverage", |
109 | +] |
110 | + |
111 | +# Add any paths that contain templates here, relative to this directory. |
112 | -+templates_path = ['_templates'] |
113 | ++templates_path = ["_templates"] |
114 | + |
115 | +# The suffix of source filenames. |
116 | -+source_suffix = '.rst' |
117 | ++source_suffix = ".rst" |
118 | + |
119 | +# The encoding of source files. |
120 | -+#source_encoding = 'utf-8-sig' |
121 | ++# source_encoding = 'utf-8-sig' |
122 | + |
123 | +# The master toctree document. |
124 | -+master_doc = 'index' |
125 | ++master_doc = "index" |
126 | + |
127 | +# General information about the project. |
128 | -+project = 'maxminddb' |
129 | -+copyright = '2013-2019, MaxMind, Inc.' |
130 | ++project = "maxminddb" |
131 | ++copyright = "2013-2019, MaxMind, Inc." |
132 | + |
133 | +# The version info for the project you're documenting, acts as replacement for |
134 | +# |version| and |release|, also used in various other places throughout the |
135 | @@ -99,126 +98,124 @@ index 0000000..f0ae2c9 |
136 | + |
137 | +# The language for content autogenerated by Sphinx. Refer to documentation |
138 | +# for a list of supported languages. |
139 | -+#language = None |
140 | ++# language = None |
141 | + |
142 | +# There are two options for replacing |today|: either, you set today to some |
143 | +# non-false value, then it is used: |
144 | -+#today = '' |
145 | ++# today = '' |
146 | +# Else, today_fmt is used as the format for a strftime call. |
147 | -+#today_fmt = '%B %d, %Y' |
148 | ++# today_fmt = '%B %d, %Y' |
149 | + |
150 | +# List of patterns, relative to source directory, that match files and |
151 | +# directories to ignore when looking for source files. |
152 | -+exclude_patterns = ['_build'] |
153 | ++exclude_patterns = ["_build"] |
154 | + |
155 | +# The reST default role (used for this markup: `text`) to use for all documents. |
156 | -+#default_role = None |
157 | ++# default_role = None |
158 | + |
159 | +# If true, '()' will be appended to :func: etc. cross-reference text. |
160 | -+#add_function_parentheses = True |
161 | ++# add_function_parentheses = True |
162 | + |
163 | +# If true, the current module name will be prepended to all description |
164 | +# unit titles (such as .. function::). |
165 | -+#add_module_names = True |
166 | ++# add_module_names = True |
167 | + |
168 | +# If true, sectionauthor and moduleauthor directives will be shown in the |
169 | +# output. They are ignored by default. |
170 | -+#show_authors = False |
171 | ++# show_authors = False |
172 | + |
173 | +# The name of the Pygments (syntax highlighting) style to use. |
174 | -+pygments_style = 'sphinx' |
175 | ++pygments_style = "sphinx" |
176 | + |
177 | +# A list of ignored prefixes for module index sorting. |
178 | -+#modindex_common_prefix = [] |
179 | ++# modindex_common_prefix = [] |
180 | + |
181 | +# -- Options for HTML output --------------------------------------------- |
182 | + |
183 | +# The theme to use for HTML and HTML Help pages. See the documentation for |
184 | +# a list of builtin themes. |
185 | -+html_theme = 'sphinxdoc' |
186 | ++html_theme = "sphinxdoc" |
187 | + |
188 | +# Theme options are theme-specific and customize the look and feel of a theme |
189 | +# further. For a list of options available for each theme, see the |
190 | +# documentation. |
191 | -+#html_theme_options = {} |
192 | ++# html_theme_options = {} |
193 | + |
194 | +# Add any paths that contain custom themes here, relative to this directory. |
195 | -+#html_theme_path = [] |
196 | ++# html_theme_path = [] |
197 | + |
198 | +# The name for this set of Sphinx documents. If None, it defaults to |
199 | +# "<project> v<release> documentation". |
200 | -+#html_title = None |
201 | ++# html_title = None |
202 | + |
203 | +# A shorter title for the navigation bar. Default is the same as html_title. |
204 | -+#html_short_title = None |
205 | ++# html_short_title = None |
206 | + |
207 | +# The name of an image file (relative to this directory) to place at the top |
208 | +# of the sidebar. |
209 | -+#html_logo = None |
210 | ++# html_logo = None |
211 | + |
212 | +# The name of an image file (within the static path) to use as favicon of the |
213 | +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 |
214 | +# pixels large. |
215 | -+#html_favicon = None |
216 | ++# html_favicon = None |
217 | + |
218 | +# Add any paths that contain custom static files (such as style sheets) here, |
219 | +# relative to this directory. They are copied after the builtin static files, |
220 | +# so a file named "default.css" will overwrite the builtin "default.css". |
221 | -+html_static_path = ['_static'] |
222 | ++html_static_path = ["_static"] |
223 | + |
224 | +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, |
225 | +# using the given strftime format. |
226 | -+#html_last_updated_fmt = '%b %d, %Y' |
227 | ++# html_last_updated_fmt = '%b %d, %Y' |
228 | + |
229 | +# If true, SmartyPants will be used to convert quotes and dashes to |
230 | +# typographically correct entities. |
231 | -+#html_use_smartypants = True |
232 | ++# html_use_smartypants = True |
233 | + |
234 | +# Custom sidebar templates, maps document names to template names. |
235 | -+#html_sidebars = {} |
236 | ++# html_sidebars = {} |
237 | + |
238 | +# Additional templates that should be rendered to pages, maps page names to |
239 | +# template names. |
240 | -+#html_additional_pages = {} |
241 | ++# html_additional_pages = {} |
242 | + |
243 | +# If false, no module index is generated. |
244 | -+#html_domain_indices = True |
245 | ++# html_domain_indices = True |
246 | + |
247 | +# If false, no index is generated. |
248 | -+#html_use_index = True |
249 | ++# html_use_index = True |
250 | + |
251 | +# If true, the index is split into individual pages for each letter. |
252 | -+#html_split_index = False |
253 | ++# html_split_index = False |
254 | + |
255 | +# If true, links to the reST sources are added to the pages. |
256 | -+#html_show_sourcelink = True |
257 | ++# html_show_sourcelink = True |
258 | + |
259 | +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. |
260 | -+#html_show_sphinx = True |
261 | ++# html_show_sphinx = True |
262 | + |
263 | +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. |
264 | -+#html_show_copyright = True |
265 | ++# html_show_copyright = True |
266 | + |
267 | +# If true, an OpenSearch description file will be output, and all pages will |
268 | +# contain a <link> tag referring to it. The value of this option must be the |
269 | +# base URL from which the finished HTML is served. |
270 | -+#html_use_opensearch = '' |
271 | ++# html_use_opensearch = '' |
272 | + |
273 | +# This is the file name suffix for HTML files (e.g. ".xhtml"). |
274 | -+#html_file_suffix = None |
275 | ++# html_file_suffix = None |
276 | + |
277 | +# Output file base name for HTML help builder. |
278 | -+htmlhelp_basename = 'maxminddbdoc' |
279 | ++htmlhelp_basename = "maxminddbdoc" |
280 | + |
281 | +# -- Options for LaTeX output -------------------------------------------- |
282 | + |
283 | +latex_elements = { |
284 | + # The paper size ('letterpaper' or 'a4paper'). |
285 | + #'papersize': 'letterpaper', |
286 | -+ |
287 | + # The font size ('10pt', '11pt' or '12pt'). |
288 | + #'pointsize': '10pt', |
289 | -+ |
290 | + # Additional stuff for the LaTeX preamble. |
291 | + #'preamble': '', |
292 | +} |
293 | @@ -226,39 +223,37 @@ index 0000000..f0ae2c9 |
294 | +# Grouping the document tree into LaTeX files. List of tuples |
295 | +# (source start file, target name, title, author, documentclass [howto/manual]). |
296 | +latex_documents = [ |
297 | -+ ('index', 'maxminddb.tex', 'maxminddb Documentation', 'Gregory Oschwald', |
298 | -+ 'manual'), |
299 | ++ ("index", "maxminddb.tex", "maxminddb Documentation", "Gregory Oschwald", "manual"), |
300 | +] |
301 | + |
302 | +# The name of an image file (relative to this directory) to place at the top of |
303 | +# the title page. |
304 | -+#latex_logo = None |
305 | ++# latex_logo = None |
306 | + |
307 | +# For "manual" documents, if this is true, then toplevel headings are parts, |
308 | +# not chapters. |
309 | -+#latex_use_parts = False |
310 | ++# latex_use_parts = False |
311 | + |
312 | +# If true, show page references after internal links. |
313 | -+#latex_show_pagerefs = False |
314 | ++# latex_show_pagerefs = False |
315 | + |
316 | +# If true, show URL addresses after external links. |
317 | -+#latex_show_urls = False |
318 | ++# latex_show_urls = False |
319 | + |
320 | +# Documents to append as an appendix to all manuals. |
321 | -+#latex_appendices = [] |
322 | ++# latex_appendices = [] |
323 | + |
324 | +# If false, no module index is generated. |
325 | -+#latex_domain_indices = True |
326 | ++# latex_domain_indices = True |
327 | + |
328 | +# -- Options for manual page output -------------------------------------- |
329 | + |
330 | +# One entry per manual page. List of tuples |
331 | +# (source start file, name, description, authors, manual section). |
332 | -+man_pages = [('index', 'maxminddb', 'maxminddb Documentation', |
333 | -+ ['Gregory Oschwald'], 1)] |
334 | ++man_pages = [("index", "maxminddb", "maxminddb Documentation", ["Gregory Oschwald"], 1)] |
335 | + |
336 | +# If true, show URL addresses after external links. |
337 | -+#man_show_urls = False |
338 | ++# man_show_urls = False |
339 | + |
340 | +# -- Options for Texinfo output ------------------------------------------ |
341 | + |
342 | @@ -266,18 +261,25 @@ index 0000000..f0ae2c9 |
343 | +# (source start file, target name, title, author, |
344 | +# dir menu entry, description, category) |
345 | +texinfo_documents = [ |
346 | -+ ('index', 'maxminddb', 'maxminddb Documentation', 'Gregory Oschwald', |
347 | -+ 'maxminddb', 'MaxMind DB Reader', 'Miscellaneous'), |
348 | ++ ( |
349 | ++ "index", |
350 | ++ "maxminddb", |
351 | ++ "maxminddb Documentation", |
352 | ++ "Gregory Oschwald", |
353 | ++ "maxminddb", |
354 | ++ "MaxMind DB Reader", |
355 | ++ "Miscellaneous", |
356 | ++ ), |
357 | +] |
358 | + |
359 | +# Documents to append as an appendix to all manuals. |
360 | -+#texinfo_appendices = [] |
361 | ++# texinfo_appendices = [] |
362 | + |
363 | +# If false, no module index is generated. |
364 | -+#texinfo_domain_indices = True |
365 | ++# texinfo_domain_indices = True |
366 | + |
367 | +# How to display URL addresses: 'footnote', 'no', or 'inline'. |
368 | -+#texinfo_show_urls = 'footnote' |
369 | ++# texinfo_show_urls = 'footnote' |
370 | + |
371 | +# Example configuration for intersphinx: refer to the Python standard library. |
372 | -+intersphinx_mapping = {'http://docs.python.org/': None} |
373 | ++intersphinx_mapping = {"http://docs.python.org/": None} |
374 | diff --git a/docs/html/.buildinfo b/docs/html/.buildinfo |
375 | index 5e0172d..f487e9a 100644 |
376 | --- a/docs/html/.buildinfo |
377 | +++ b/docs/html/.buildinfo |
378 | @@ -1,4 +1,4 @@ |
379 | # Sphinx build info version 1 |
380 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. |
381 | -config: f4b35ba4b456e07a1fe93fc0f298d57b |
382 | +config: d833e7ff76f25fea37f13f0af124f5fd |
383 | tags: 645f666f9bcd5a90fca523b33c5a78b7 |
384 | diff --git a/docs/html/_static/basic.css b/docs/html/_static/basic.css |
385 | index b04360d..0119285 100644 |
386 | --- a/docs/html/_static/basic.css |
387 | +++ b/docs/html/_static/basic.css |
388 | @@ -4,7 +4,7 @@ |
389 | * |
390 | * Sphinx stylesheet -- basic theme. |
391 | * |
392 | - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. |
393 | + * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. |
394 | * :license: BSD, see LICENSE for details. |
395 | * |
396 | */ |
397 | diff --git a/docs/html/_static/doctools.js b/docs/html/_static/doctools.js |
398 | index b33f87f..daccd20 100644 |
399 | --- a/docs/html/_static/doctools.js |
400 | +++ b/docs/html/_static/doctools.js |
401 | @@ -4,7 +4,7 @@ |
402 | * |
403 | * Sphinx JavaScript utilities for all documentation. |
404 | * |
405 | - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. |
406 | + * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. |
407 | * :license: BSD, see LICENSE for details. |
408 | * |
409 | */ |
410 | @@ -283,10 +283,11 @@ var Documentation = { |
411 | }, |
412 | |
413 | initOnKeyListeners: function() { |
414 | - $(document).keyup(function(event) { |
415 | + $(document).keydown(function(event) { |
416 | var activeElementType = document.activeElement.tagName; |
417 | // don't navigate when in search box or textarea |
418 | - if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { |
419 | + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' |
420 | + && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) { |
421 | switch (event.keyCode) { |
422 | case 37: // left |
423 | var prevHref = $('link[rel="prev"]').prop('href'); |
424 | diff --git a/docs/html/_static/documentation_options.js b/docs/html/_static/documentation_options.js |
425 | index 375482b..a815b52 100644 |
426 | --- a/docs/html/_static/documentation_options.js |
427 | +++ b/docs/html/_static/documentation_options.js |
428 | @@ -1,10 +1,11 @@ |
429 | var DOCUMENTATION_OPTIONS = { |
430 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), |
431 | - VERSION: '1.5.2', |
432 | + VERSION: '1.5.4', |
433 | LANGUAGE: 'None', |
434 | COLLAPSE_INDEX: false, |
435 | BUILDER: 'html', |
436 | FILE_SUFFIX: '.html', |
437 | + LINK_SUFFIX: '.html', |
438 | HAS_SOURCE: true, |
439 | SOURCELINK_SUFFIX: '.txt', |
440 | NAVIGATION_WITH_KEYS: false |
441 | diff --git a/docs/html/_static/language_data.js b/docs/html/_static/language_data.js |
442 | index 5266fb1..d2b4ee9 100644 |
443 | --- a/docs/html/_static/language_data.js |
444 | +++ b/docs/html/_static/language_data.js |
445 | @@ -5,7 +5,7 @@ |
446 | * This script contains the language-specific data used by searchtools.js, |
447 | * namely the list of stopwords, stemmer, scorer and splitter. |
448 | * |
449 | - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. |
450 | + * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. |
451 | * :license: BSD, see LICENSE for details. |
452 | * |
453 | */ |
454 | diff --git a/docs/html/_static/searchtools.js b/docs/html/_static/searchtools.js |
455 | index ad84587..ab56499 100644 |
456 | --- a/docs/html/_static/searchtools.js |
457 | +++ b/docs/html/_static/searchtools.js |
458 | @@ -4,7 +4,7 @@ |
459 | * |
460 | * Sphinx JavaScript utilities for the full-text search. |
461 | * |
462 | - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. |
463 | + * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. |
464 | * :license: BSD, see LICENSE for details. |
465 | * |
466 | */ |
467 | @@ -63,6 +63,11 @@ var Search = { |
468 | htmlElement.innerHTML = htmlString; |
469 | $(htmlElement).find('.headerlink').remove(); |
470 | docContent = $(htmlElement).find('[role=main]')[0]; |
471 | + if(docContent === undefined) { |
472 | + console.warn("Content block not found. Sphinx search tries to obtain it " + |
473 | + "via '[role=main]'. Could you check your theme or template."); |
474 | + return ""; |
475 | + } |
476 | return docContent.textContent || docContent.innerText; |
477 | }, |
478 | |
479 | @@ -245,6 +250,8 @@ var Search = { |
480 | if (results.length) { |
481 | var item = results.pop(); |
482 | var listItem = $('<li style="display:none"></li>'); |
483 | + var requestUrl = ""; |
484 | + var linkUrl = ""; |
485 | if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') { |
486 | // dirhtml builder |
487 | var dirname = item[0] + '/'; |
488 | @@ -253,15 +260,17 @@ var Search = { |
489 | } else if (dirname == 'index/') { |
490 | dirname = ''; |
491 | } |
492 | - listItem.append($('<a/>').attr('href', |
493 | - DOCUMENTATION_OPTIONS.URL_ROOT + dirname + |
494 | - highlightstring + item[2]).html(item[1])); |
495 | + requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + dirname; |
496 | + linkUrl = requestUrl; |
497 | + |
498 | } else { |
499 | // normal html builders |
500 | - listItem.append($('<a/>').attr('href', |
501 | - item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX + |
502 | - highlightstring + item[2]).html(item[1])); |
503 | + requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX; |
504 | + linkUrl = item[0] + DOCUMENTATION_OPTIONS.LINK_SUFFIX; |
505 | } |
506 | + listItem.append($('<a/>').attr('href', |
507 | + linkUrl + |
508 | + highlightstring + item[2]).html(item[1])); |
509 | if (item[3]) { |
510 | listItem.append($('<span> (' + item[3] + ')</span>')); |
511 | Search.output.append(listItem); |
512 | @@ -269,7 +278,7 @@ var Search = { |
513 | displayNextItem(); |
514 | }); |
515 | } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) { |
516 | - $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX, |
517 | + $.ajax({url: requestUrl, |
518 | dataType: "text", |
519 | complete: function(jqxhr, textstatus) { |
520 | var data = jqxhr.responseText; |
521 | diff --git a/docs/html/_static/sphinxdoc.css b/docs/html/_static/sphinxdoc.css |
522 | index 1224733..8c762aa 100644 |
523 | --- a/docs/html/_static/sphinxdoc.css |
524 | +++ b/docs/html/_static/sphinxdoc.css |
525 | @@ -5,7 +5,7 @@ |
526 | * Sphinx stylesheet -- sphinxdoc theme. Originally created by |
527 | * Armin Ronacher for Werkzeug. |
528 | * |
529 | - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. |
530 | + * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. |
531 | * :license: BSD, see LICENSE for details. |
532 | * |
533 | */ |
534 | diff --git a/docs/html/genindex.html b/docs/html/genindex.html |
535 | index 8e58ab8..2b9c62e 100644 |
536 | --- a/docs/html/genindex.html |
537 | +++ b/docs/html/genindex.html |
538 | @@ -5,14 +5,14 @@ |
539 | <html xmlns="http://www.w3.org/1999/xhtml"> |
540 | <head> |
541 | <meta charset="utf-8" /> |
542 | - <title>Index — maxminddb 1.5.2 documentation</title> |
543 | + <title>Index — maxminddb 1.5.4 documentation</title> |
544 | <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" /> |
545 | <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> |
546 | - <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> |
547 | - <script type="text/javascript" src="_static/jquery.js"></script> |
548 | - <script type="text/javascript" src="_static/underscore.js"></script> |
549 | - <script type="text/javascript" src="_static/doctools.js"></script> |
550 | - <script type="text/javascript" src="_static/language_data.js"></script> |
551 | + <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> |
552 | + <script src="_static/jquery.js"></script> |
553 | + <script src="_static/underscore.js"></script> |
554 | + <script src="_static/doctools.js"></script> |
555 | + <script src="_static/language_data.js"></script> |
556 | <link rel="index" title="Index" href="#" /> |
557 | <link rel="search" title="Search" href="search.html" /> |
558 | </head><body> |
559 | @@ -25,7 +25,7 @@ |
560 | <li class="right" > |
561 | <a href="py-modindex.html" title="Python Module Index" |
562 | >modules</a> |</li> |
563 | - <li class="nav-item nav-item-0"><a href="index.html">maxminddb 1.5.2 documentation</a> »</li> |
564 | + <li class="nav-item nav-item-0"><a href="index.html">maxminddb 1.5.4 documentation</a> »</li> |
565 | </ul> |
566 | </div> |
567 | <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> |
568 | @@ -39,7 +39,7 @@ |
569 | </form> |
570 | </div> |
571 | </div> |
572 | -<script type="text/javascript">$('#searchbox').show(0);</script> |
573 | +<script>$('#searchbox').show(0);</script> |
574 | </div> |
575 | </div> |
576 | |
577 | @@ -134,18 +134,44 @@ |
578 | <h2 id="M">M</h2> |
579 | <table style="width: 100%" class="indextable genindextable"><tr> |
580 | <td style="width: 33%; vertical-align: top;"><ul> |
581 | - <li><a href="index.html#module-maxminddb">maxminddb (module)</a> |
582 | + <li> |
583 | + maxminddb |
584 | + |
585 | + <ul> |
586 | + <li><a href="index.html#module-maxminddb">module</a> |
587 | </li> |
588 | - <li><a href="index.html#module-maxminddb.errors">maxminddb.errors (module)</a> |
589 | + </ul></li> |
590 | + <li> |
591 | + maxminddb.errors |
592 | + |
593 | + <ul> |
594 | + <li><a href="index.html#module-maxminddb.errors">module</a> |
595 | +</li> |
596 | + </ul></li> |
597 | + <li> |
598 | + maxminddb.reader |
599 | + |
600 | + <ul> |
601 | + <li><a href="index.html#module-maxminddb.reader">module</a> |
602 | </li> |
603 | + </ul></li> |
604 | </ul></td> |
605 | <td style="width: 33%; vertical-align: top;"><ul> |
606 | - <li><a href="index.html#module-maxminddb.reader">maxminddb.reader (module)</a> |
607 | -</li> |
608 | <li><a href="index.html#maxminddb.reader.Metadata">Metadata (class in maxminddb.reader)</a> |
609 | </li> |
610 | <li><a href="index.html#maxminddb.reader.Reader.metadata">metadata() (maxminddb.reader.Reader method)</a> |
611 | </li> |
612 | + <li> |
613 | + module |
614 | + |
615 | + <ul> |
616 | + <li><a href="index.html#module-maxminddb">maxminddb</a> |
617 | +</li> |
618 | + <li><a href="index.html#module-maxminddb.errors">maxminddb.errors</a> |
619 | +</li> |
620 | + <li><a href="index.html#module-maxminddb.reader">maxminddb.reader</a> |
621 | +</li> |
622 | + </ul></li> |
623 | </ul></td> |
624 | </tr></table> |
625 | |
626 | @@ -207,12 +233,12 @@ |
627 | <li class="right" > |
628 | <a href="py-modindex.html" title="Python Module Index" |
629 | >modules</a> |</li> |
630 | - <li class="nav-item nav-item-0"><a href="index.html">maxminddb 1.5.2 documentation</a> »</li> |
631 | + <li class="nav-item nav-item-0"><a href="index.html">maxminddb 1.5.4 documentation</a> »</li> |
632 | </ul> |
633 | </div> |
634 | <div class="footer" role="contentinfo"> |
635 | © Copyright 2013-2019, MaxMind, Inc.. |
636 | - Created using <a href="http://sphinx-doc.org/">Sphinx</a> 2.3.0. |
637 | + Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.0. |
638 | </div> |
639 | </body> |
640 | </html> |
641 | \ No newline at end of file |
642 | diff --git a/docs/html/index.html b/docs/html/index.html |
643 | index b9b2187..967c00d 100644 |
644 | --- a/docs/html/index.html |
645 | +++ b/docs/html/index.html |
646 | @@ -4,14 +4,14 @@ |
647 | <html xmlns="http://www.w3.org/1999/xhtml"> |
648 | <head> |
649 | <meta charset="utf-8" /> |
650 | - <title>MaxMind DB Python Module — maxminddb 1.5.2 documentation</title> |
651 | + <title>MaxMind DB Python Module — maxminddb 1.5.4 documentation</title> |
652 | <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" /> |
653 | <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> |
654 | - <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> |
655 | - <script type="text/javascript" src="_static/jquery.js"></script> |
656 | - <script type="text/javascript" src="_static/underscore.js"></script> |
657 | - <script type="text/javascript" src="_static/doctools.js"></script> |
658 | - <script type="text/javascript" src="_static/language_data.js"></script> |
659 | + <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> |
660 | + <script src="_static/jquery.js"></script> |
661 | + <script src="_static/underscore.js"></script> |
662 | + <script src="_static/doctools.js"></script> |
663 | + <script src="_static/language_data.js"></script> |
664 | <link rel="index" title="Index" href="genindex.html" /> |
665 | <link rel="search" title="Search" href="search.html" /> |
666 | </head><body> |
667 | @@ -24,7 +24,7 @@ |
668 | <li class="right" > |
669 | <a href="py-modindex.html" title="Python Module Index" |
670 | >modules</a> |</li> |
671 | - <li class="nav-item nav-item-0"><a href="#">maxminddb 1.5.2 documentation</a> »</li> |
672 | + <li class="nav-item nav-item-0"><a href="#">maxminddb 1.5.4 documentation</a> »</li> |
673 | </ul> |
674 | </div> |
675 | <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> |
676 | @@ -66,7 +66,7 @@ |
677 | </form> |
678 | </div> |
679 | </div> |
680 | -<script type="text/javascript">$('#searchbox').show(0);</script> |
681 | +<script>$('#searchbox').show(0);</script> |
682 | </div> |
683 | </div> |
684 | |
685 | @@ -174,15 +174,15 @@ assistance.</p> |
686 | </div> |
687 | <div class="section" id="module-maxminddb"> |
688 | <span id="modules"></span><h1>Modules<a class="headerlink" href="#module-maxminddb" title="Permalink to this headline">¶</a></h1> |
689 | -<dl class="function"> |
690 | +<dl class="py function"> |
691 | <dt id="maxminddb.Reader"> |
692 | -<code class="sig-prename descclassname">maxminddb.</code><code class="sig-name descname">Reader</code><span class="sig-paren">(</span><em class="sig-param">database</em><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.Reader" title="Permalink to this definition">¶</a></dt> |
693 | +<code class="sig-prename descclassname">maxminddb.</code><code class="sig-name descname">Reader</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">database</span></em><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.Reader" title="Permalink to this definition">¶</a></dt> |
694 | <dd><p>This exists for backwards compatibility. Use open_database instead</p> |
695 | </dd></dl> |
696 | |
697 | -<dl class="function"> |
698 | +<dl class="py function"> |
699 | <dt id="maxminddb.open_database"> |
700 | -<code class="sig-prename descclassname">maxminddb.</code><code class="sig-name descname">open_database</code><span class="sig-paren">(</span><em class="sig-param">database</em>, <em class="sig-param">mode=0</em><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.open_database" title="Permalink to this definition">¶</a></dt> |
701 | +<code class="sig-prename descclassname">maxminddb.</code><code class="sig-name descname">open_database</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">database</span></em>, <em class="sig-param"><span class="n">mode</span><span class="o">=</span><span class="default_value">0</span></em><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.open_database" title="Permalink to this definition">¶</a></dt> |
702 | <dd><p>Open a Maxmind DB database</p> |
703 | <dl class="simple"> |
704 | <dt>Arguments:</dt><dd><dl class="simple"> |
705 | @@ -213,7 +213,7 @@ assistance.</p> |
706 | <span class="target" id="module-maxminddb.errors"></span><div class="section" id="maxminddb-errors"> |
707 | <h2>maxminddb.errors<a class="headerlink" href="#maxminddb-errors" title="Permalink to this headline">¶</a></h2> |
708 | <p>This module contains custom errors for the MaxMind DB reader</p> |
709 | -<dl class="exception"> |
710 | +<dl class="py exception"> |
711 | <dt id="maxminddb.errors.InvalidDatabaseError"> |
712 | <em class="property">exception </em><code class="sig-prename descclassname">maxminddb.errors.</code><code class="sig-name descname">InvalidDatabaseError</code><a class="headerlink" href="#maxminddb.errors.InvalidDatabaseError" title="Permalink to this definition">¶</a></dt> |
713 | <dd><p>Bases: <a class="reference external" href="https://docs.python.org/3/library/exceptions.html#RuntimeError" title="(in Python v3.8)"><code class="xref py py-class docutils literal notranslate"><span class="pre">RuntimeError</span></code></a></p> |
714 | @@ -224,12 +224,12 @@ assistance.</p> |
715 | <span class="target" id="module-maxminddb.reader"></span><div class="section" id="maxminddb-reader"> |
716 | <h2>maxminddb.reader<a class="headerlink" href="#maxminddb-reader" title="Permalink to this headline">¶</a></h2> |
717 | <p>This module contains the pure Python database reader and related classes.</p> |
718 | -<dl class="class"> |
719 | +<dl class="py class"> |
720 | <dt id="maxminddb.reader.Metadata"> |
721 | -<em class="property">class </em><code class="sig-prename descclassname">maxminddb.reader.</code><code class="sig-name descname">Metadata</code><span class="sig-paren">(</span><em class="sig-param">**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.reader.Metadata" title="Permalink to this definition">¶</a></dt> |
722 | +<em class="property">class </em><code class="sig-prename descclassname">maxminddb.reader.</code><code class="sig-name descname">Metadata</code><span class="sig-paren">(</span><em class="sig-param"><span class="o">**</span><span class="n">kwargs</span></em><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.reader.Metadata" title="Permalink to this definition">¶</a></dt> |
723 | <dd><p>Bases: <a class="reference external" href="https://docs.python.org/3/library/functions.html#object" title="(in Python v3.8)"><code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></a></p> |
724 | <p>Metadata for the MaxMind DB reader</p> |
725 | -<dl class="attribute"> |
726 | +<dl class="py attribute"> |
727 | <dt id="maxminddb.reader.Metadata.binary_format_major_version"> |
728 | <code class="sig-name descname">binary_format_major_version</code><a class="headerlink" href="#maxminddb.reader.Metadata.binary_format_major_version" title="Permalink to this definition">¶</a></dt> |
729 | <dd><p>The major version number of the binary format used when creating the |
730 | @@ -241,7 +241,7 @@ database.</p> |
731 | </dl> |
732 | </dd></dl> |
733 | |
734 | -<dl class="attribute"> |
735 | +<dl class="py attribute"> |
736 | <dt id="maxminddb.reader.Metadata.binary_format_minor_version"> |
737 | <code class="sig-name descname">binary_format_minor_version</code><a class="headerlink" href="#maxminddb.reader.Metadata.binary_format_minor_version" title="Permalink to this definition">¶</a></dt> |
738 | <dd><p>The minor version number of the binary format used when creating the |
739 | @@ -253,7 +253,7 @@ database.</p> |
740 | </dl> |
741 | </dd></dl> |
742 | |
743 | -<dl class="attribute"> |
744 | +<dl class="py attribute"> |
745 | <dt id="maxminddb.reader.Metadata.build_epoch"> |
746 | <code class="sig-name descname">build_epoch</code><a class="headerlink" href="#maxminddb.reader.Metadata.build_epoch" title="Permalink to this definition">¶</a></dt> |
747 | <dd><p>The Unix epoch for the build time of the database.</p> |
748 | @@ -264,7 +264,7 @@ database.</p> |
749 | </dl> |
750 | </dd></dl> |
751 | |
752 | -<dl class="attribute"> |
753 | +<dl class="py attribute"> |
754 | <dt id="maxminddb.reader.Metadata.database_type"> |
755 | <code class="sig-name descname">database_type</code><a class="headerlink" href="#maxminddb.reader.Metadata.database_type" title="Permalink to this definition">¶</a></dt> |
756 | <dd><p>A string identifying the database type, e.g., “GeoIP2-City”.</p> |
757 | @@ -275,7 +275,7 @@ database.</p> |
758 | </dl> |
759 | </dd></dl> |
760 | |
761 | -<dl class="attribute"> |
762 | +<dl class="py attribute"> |
763 | <dt id="maxminddb.reader.Metadata.description"> |
764 | <code class="sig-name descname">description</code><a class="headerlink" href="#maxminddb.reader.Metadata.description" title="Permalink to this definition">¶</a></dt> |
765 | <dd><p>A map from locales to text descriptions of the database.</p> |
766 | @@ -286,7 +286,7 @@ database.</p> |
767 | </dl> |
768 | </dd></dl> |
769 | |
770 | -<dl class="attribute"> |
771 | +<dl class="py attribute"> |
772 | <dt id="maxminddb.reader.Metadata.ip_version"> |
773 | <code class="sig-name descname">ip_version</code><a class="headerlink" href="#maxminddb.reader.Metadata.ip_version" title="Permalink to this definition">¶</a></dt> |
774 | <dd><p>The IP version of the data in a database. A value of “4” means the |
775 | @@ -299,7 +299,7 @@ both IPv4 and IPv6 lookups.</p> |
776 | </dl> |
777 | </dd></dl> |
778 | |
779 | -<dl class="attribute"> |
780 | +<dl class="py attribute"> |
781 | <dt id="maxminddb.reader.Metadata.languages"> |
782 | <code class="sig-name descname">languages</code><a class="headerlink" href="#maxminddb.reader.Metadata.languages" title="Permalink to this definition">¶</a></dt> |
783 | <dd><p>A list of locale codes supported by the databse.</p> |
784 | @@ -310,7 +310,7 @@ both IPv4 and IPv6 lookups.</p> |
785 | </dl> |
786 | </dd></dl> |
787 | |
788 | -<dl class="attribute"> |
789 | +<dl class="py attribute"> |
790 | <dt id="maxminddb.reader.Metadata.node_count"> |
791 | <code class="sig-name descname">node_count</code><a class="headerlink" href="#maxminddb.reader.Metadata.node_count" title="Permalink to this definition">¶</a></dt> |
792 | <dd><p>The number of nodes in the database.</p> |
793 | @@ -321,7 +321,7 @@ both IPv4 and IPv6 lookups.</p> |
794 | </dl> |
795 | </dd></dl> |
796 | |
797 | -<dl class="attribute"> |
798 | +<dl class="py attribute"> |
799 | <dt id="maxminddb.reader.Metadata.record_size"> |
800 | <code class="sig-name descname">record_size</code><a class="headerlink" href="#maxminddb.reader.Metadata.record_size" title="Permalink to this definition">¶</a></dt> |
801 | <dd><p>The bit size of a record in the search tree.</p> |
802 | @@ -332,7 +332,7 @@ both IPv4 and IPv6 lookups.</p> |
803 | </dl> |
804 | </dd></dl> |
805 | |
806 | -<dl class="method"> |
807 | +<dl class="py method"> |
808 | <dt id="maxminddb.reader.Metadata.node_byte_size"> |
809 | <em class="property">property </em><code class="sig-name descname">node_byte_size</code><a class="headerlink" href="#maxminddb.reader.Metadata.node_byte_size" title="Permalink to this definition">¶</a></dt> |
810 | <dd><p>The size of a node in bytes</p> |
811 | @@ -343,7 +343,7 @@ both IPv4 and IPv6 lookups.</p> |
812 | </dl> |
813 | </dd></dl> |
814 | |
815 | -<dl class="method"> |
816 | +<dl class="py method"> |
817 | <dt id="maxminddb.reader.Metadata.search_tree_size"> |
818 | <em class="property">property </em><code class="sig-name descname">search_tree_size</code><a class="headerlink" href="#maxminddb.reader.Metadata.search_tree_size" title="Permalink to this definition">¶</a></dt> |
819 | <dd><p>The size of the search tree</p> |
820 | @@ -356,35 +356,35 @@ both IPv4 and IPv6 lookups.</p> |
821 | |
822 | </dd></dl> |
823 | |
824 | -<dl class="class"> |
825 | +<dl class="py class"> |
826 | <dt id="maxminddb.reader.Reader"> |
827 | -<em class="property">class </em><code class="sig-prename descclassname">maxminddb.reader.</code><code class="sig-name descname">Reader</code><span class="sig-paren">(</span><em class="sig-param">database</em>, <em class="sig-param">mode=0</em><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.reader.Reader" title="Permalink to this definition">¶</a></dt> |
828 | +<em class="property">class </em><code class="sig-prename descclassname">maxminddb.reader.</code><code class="sig-name descname">Reader</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">database</span></em>, <em class="sig-param"><span class="n">mode</span><span class="o">=</span><span class="default_value">0</span></em><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.reader.Reader" title="Permalink to this definition">¶</a></dt> |
829 | <dd><p>Bases: <a class="reference external" href="https://docs.python.org/3/library/functions.html#object" title="(in Python v3.8)"><code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></a></p> |
830 | <p>Instances of this class provide a reader for the MaxMind DB format. IP |
831 | addresses can be looked up using the <code class="docutils literal notranslate"><span class="pre">get</span></code> method.</p> |
832 | -<dl class="method"> |
833 | +<dl class="py method"> |
834 | <dt id="maxminddb.reader.Reader.close"> |
835 | <code class="sig-name descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.reader.Reader.close" title="Permalink to this definition">¶</a></dt> |
836 | <dd><p>Closes the MaxMind DB file and returns the resources to the system</p> |
837 | </dd></dl> |
838 | |
839 | -<dl class="method"> |
840 | +<dl class="py method"> |
841 | <dt id="maxminddb.reader.Reader.get"> |
842 | -<code class="sig-name descname">get</code><span class="sig-paren">(</span><em class="sig-param">ip_address</em><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.reader.Reader.get" title="Permalink to this definition">¶</a></dt> |
843 | +<code class="sig-name descname">get</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">ip_address</span></em><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.reader.Reader.get" title="Permalink to this definition">¶</a></dt> |
844 | <dd><p>Return the record for the ip_address in the MaxMind DB</p> |
845 | <p>Arguments: |
846 | ip_address – an IP address in the standard string notation</p> |
847 | </dd></dl> |
848 | |
849 | -<dl class="method"> |
850 | +<dl class="py method"> |
851 | <dt id="maxminddb.reader.Reader.get_with_prefix_len"> |
852 | -<code class="sig-name descname">get_with_prefix_len</code><span class="sig-paren">(</span><em class="sig-param">ip_address</em><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.reader.Reader.get_with_prefix_len" title="Permalink to this definition">¶</a></dt> |
853 | +<code class="sig-name descname">get_with_prefix_len</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">ip_address</span></em><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.reader.Reader.get_with_prefix_len" title="Permalink to this definition">¶</a></dt> |
854 | <dd><p>Return a tuple with the record and the associated prefix length</p> |
855 | <p>Arguments: |
856 | ip_address – an IP address in the standard string notation</p> |
857 | </dd></dl> |
858 | |
859 | -<dl class="method"> |
860 | +<dl class="py method"> |
861 | <dt id="maxminddb.reader.Reader.metadata"> |
862 | <code class="sig-name descname">metadata</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#maxminddb.reader.Reader.metadata" title="Permalink to this definition">¶</a></dt> |
863 | <dd><p>Return the metadata associated with the MaxMind DB file</p> |
864 | @@ -428,12 +428,12 @@ ip_address – an IP address in the standard string notation</p> |
865 | <li class="right" > |
866 | <a href="py-modindex.html" title="Python Module Index" |
867 | >modules</a> |</li> |
868 | - <li class="nav-item nav-item-0"><a href="#">maxminddb 1.5.2 documentation</a> »</li> |
869 | + <li class="nav-item nav-item-0"><a href="#">maxminddb 1.5.4 documentation</a> »</li> |
870 | </ul> |
871 | </div> |
872 | <div class="footer" role="contentinfo"> |
873 | © Copyright 2013-2019, MaxMind, Inc.. |
874 | - Created using <a href="http://sphinx-doc.org/">Sphinx</a> 2.3.0. |
875 | + Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.0. |
876 | </div> |
877 | </body> |
878 | </html> |
879 | \ No newline at end of file |
880 | diff --git a/docs/html/objects.inv b/docs/html/objects.inv |
881 | index 9a9ceeb..8874aae 100644 |
882 | Binary files a/docs/html/objects.inv and b/docs/html/objects.inv differ |
883 | diff --git a/docs/html/py-modindex.html b/docs/html/py-modindex.html |
884 | index a8537d3..f8ad535 100644 |
885 | --- a/docs/html/py-modindex.html |
886 | +++ b/docs/html/py-modindex.html |
887 | @@ -4,14 +4,14 @@ |
888 | <html xmlns="http://www.w3.org/1999/xhtml"> |
889 | <head> |
890 | <meta charset="utf-8" /> |
891 | - <title>Python Module Index — maxminddb 1.5.2 documentation</title> |
892 | + <title>Python Module Index — maxminddb 1.5.4 documentation</title> |
893 | <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" /> |
894 | <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> |
895 | - <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> |
896 | - <script type="text/javascript" src="_static/jquery.js"></script> |
897 | - <script type="text/javascript" src="_static/underscore.js"></script> |
898 | - <script type="text/javascript" src="_static/doctools.js"></script> |
899 | - <script type="text/javascript" src="_static/language_data.js"></script> |
900 | + <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> |
901 | + <script src="_static/jquery.js"></script> |
902 | + <script src="_static/underscore.js"></script> |
903 | + <script src="_static/doctools.js"></script> |
904 | + <script src="_static/language_data.js"></script> |
905 | <link rel="index" title="Index" href="genindex.html" /> |
906 | <link rel="search" title="Search" href="search.html" /> |
907 | |
908 | @@ -27,7 +27,7 @@ |
909 | <li class="right" > |
910 | <a href="#" title="Python Module Index" |
911 | >modules</a> |</li> |
912 | - <li class="nav-item nav-item-0"><a href="index.html">maxminddb 1.5.2 documentation</a> »</li> |
913 | + <li class="nav-item nav-item-0"><a href="index.html">maxminddb 1.5.4 documentation</a> »</li> |
914 | </ul> |
915 | </div> |
916 | <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> |
917 | @@ -41,7 +41,7 @@ |
918 | </form> |
919 | </div> |
920 | </div> |
921 | -<script type="text/javascript">$('#searchbox').show(0);</script> |
922 | +<script>$('#searchbox').show(0);</script> |
923 | </div> |
924 | </div> |
925 | |
926 | @@ -94,12 +94,12 @@ |
927 | <li class="right" > |
928 | <a href="#" title="Python Module Index" |
929 | >modules</a> |</li> |
930 | - <li class="nav-item nav-item-0"><a href="index.html">maxminddb 1.5.2 documentation</a> »</li> |
931 | + <li class="nav-item nav-item-0"><a href="index.html">maxminddb 1.5.4 documentation</a> »</li> |
932 | </ul> |
933 | </div> |
934 | <div class="footer" role="contentinfo"> |
935 | © Copyright 2013-2019, MaxMind, Inc.. |
936 | - Created using <a href="http://sphinx-doc.org/">Sphinx</a> 2.3.0. |
937 | + Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.0. |
938 | </div> |
939 | </body> |
940 | </html> |
941 | \ No newline at end of file |
942 | diff --git a/docs/html/search.html b/docs/html/search.html |
943 | index ddd6a1a..c29f498 100644 |
944 | --- a/docs/html/search.html |
945 | +++ b/docs/html/search.html |
946 | @@ -4,19 +4,19 @@ |
947 | <html xmlns="http://www.w3.org/1999/xhtml"> |
948 | <head> |
949 | <meta charset="utf-8" /> |
950 | - <title>Search — maxminddb 1.5.2 documentation</title> |
951 | + <title>Search — maxminddb 1.5.4 documentation</title> |
952 | <link rel="stylesheet" href="_static/sphinxdoc.css" type="text/css" /> |
953 | <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> |
954 | |
955 | - <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> |
956 | - <script type="text/javascript" src="_static/jquery.js"></script> |
957 | - <script type="text/javascript" src="_static/underscore.js"></script> |
958 | - <script type="text/javascript" src="_static/doctools.js"></script> |
959 | - <script type="text/javascript" src="_static/language_data.js"></script> |
960 | - <script type="text/javascript" src="_static/searchtools.js"></script> |
961 | + <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script> |
962 | + <script src="_static/jquery.js"></script> |
963 | + <script src="_static/underscore.js"></script> |
964 | + <script src="_static/doctools.js"></script> |
965 | + <script src="_static/language_data.js"></script> |
966 | + <script src="_static/searchtools.js"></script> |
967 | <link rel="index" title="Index" href="genindex.html" /> |
968 | <link rel="search" title="Search" href="#" /> |
969 | - <script type="text/javascript" src="searchindex.js" defer></script> |
970 | + <script src="searchindex.js" defer></script> |
971 | |
972 | |
973 | </head><body> |
974 | @@ -29,7 +29,7 @@ |
975 | <li class="right" > |
976 | <a href="py-modindex.html" title="Python Module Index" |
977 | >modules</a> |</li> |
978 | - <li class="nav-item nav-item-0"><a href="index.html">maxminddb 1.5.2 documentation</a> »</li> |
979 | + <li class="nav-item nav-item-0"><a href="index.html">maxminddb 1.5.4 documentation</a> »</li> |
980 | </ul> |
981 | </div> |
982 | <div class="sphinxsidebar" role="navigation" aria-label="main navigation"> |
983 | @@ -44,17 +44,15 @@ |
984 | |
985 | <h1 id="search-documentation">Search</h1> |
986 | <div id="fallback" class="admonition warning"> |
987 | - <script type="text/javascript">$('#fallback').hide();</script> |
988 | + <script>$('#fallback').hide();</script> |
989 | <p> |
990 | Please activate JavaScript to enable the search |
991 | functionality. |
992 | </p> |
993 | </div> |
994 | <p> |
995 | - From here you can search these documents. Enter your search |
996 | - words into the box below and click "search". Note that the search |
997 | - function will automatically search for all of the words. Pages |
998 | - containing fewer words won't appear in the result list. |
999 | + Searching for multiple words only shows matches that contain |
1000 | + all words. |
1001 | </p> |
1002 | <form action="" method="get"> |
1003 | <input type="text" name="q" aria-labelledby="search-documentation" value="" /> |
1004 | @@ -80,12 +78,12 @@ |
1005 | <li class="right" > |
1006 | <a href="py-modindex.html" title="Python Module Index" |
1007 | >modules</a> |</li> |
1008 | - <li class="nav-item nav-item-0"><a href="index.html">maxminddb 1.5.2 documentation</a> »</li> |
1009 | + <li class="nav-item nav-item-0"><a href="index.html">maxminddb 1.5.4 documentation</a> »</li> |
1010 | </ul> |
1011 | </div> |
1012 | <div class="footer" role="contentinfo"> |
1013 | © Copyright 2013-2019, MaxMind, Inc.. |
1014 | - Created using <a href="http://sphinx-doc.org/">Sphinx</a> 2.3.0. |
1015 | + Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.0. |
1016 | </div> |
1017 | </body> |
1018 | </html> |
1019 | \ No newline at end of file |
1020 | diff --git a/docs/html/searchindex.js b/docs/html/searchindex.js |
1021 | index bcebefe..999a308 100644 |
1022 | --- a/docs/html/searchindex.js |
1023 | +++ b/docs/html/searchindex.js |
1024 | @@ -1 +1 @@ |
1025 | -Search.setIndex({docnames:["index"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,"sphinx.ext.intersphinx":1,sphinx:56},filenames:["index.rst"],objects:{"":{maxminddb:[0,0,0,"-"]},"maxminddb.errors":{InvalidDatabaseError:[0,2,1,""]},"maxminddb.reader":{Metadata:[0,3,1,""],Reader:[0,3,1,""]},"maxminddb.reader.Metadata":{binary_format_major_version:[0,4,1,""],binary_format_minor_version:[0,4,1,""],build_epoch:[0,4,1,""],database_type:[0,4,1,""],description:[0,4,1,""],ip_version:[0,4,1,""],languages:[0,4,1,""],node_byte_size:[0,5,1,""],node_count:[0,4,1,""],record_size:[0,4,1,""],search_tree_size:[0,5,1,""]},"maxminddb.reader.Reader":{close:[0,5,1,""],get:[0,5,1,""],get_with_prefix_len:[0,5,1,""],metadata:[0,5,1,""]},maxminddb:{Reader:[0,1,1,""],errors:[0,0,0,"-"],open_database:[0,1,1,""],reader:[0,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","exception","Python exception"],"3":["py","class","Python class"],"4":["py","attribute","Python attribute"],"5":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:function","2":"py:exception","3":"py:class","4":"py:attribute","5":"py:method"},terms:{"byte":0,"case":0,"class":0,"default":0,"export":0,"function":0,"import":0,"int":0,"return":0,"try":0,The:0,These:0,Use:0,abl:0,address:0,after:0,all:0,also:0,apach:0,api:0,argument:0,assist:0,associ:0,avail:0,back:0,backward:0,base:0,been:0,befor:0,binari:0,binary_format_major_vers:0,binary_format_minor_vers:0,bit:0,both:0,build:0,build_epoch:0,call:0,caller:0,can:0,citi:0,close:0,code:0,compat:0,contact:0,contain:0,copyright:0,correspond:0,corrupt:0,countri:0,cpython:0,creat:0,custom:0,data:0,databas:0,database_typ:0,databs:0,decompress:0,descriptor:0,dict:0,dictionari:0,directori:0,doe:0,download:0,easy_instal:0,epoch:0,exist:0,extens:0,fall:0,file:0,first:0,follow:0,format:0,found:0,free:0,from:0,geoip2:0,geolite2:0,get:0,get_with_prefix_len:0,github:0,gunzip:0,has:0,have:0,identifi:0,immedi:0,implement:0,impli:0,inc:0,includ:0,index:0,instanc:0,instead:0,invalid:0,invaliddatabaseerror:0,ip_address:0,ip_vers:0,ipaddress:0,ipv4:0,ipv6:0,issu:0,kwarg:0,languag:0,length:0,libmaxminddb:0,librari:0,licens:0,list:0,load:0,local:0,look:0,lookup:0,mai:0,major:0,map:0,mean:0,memori:0,metadata:0,method:0,minor:0,mmdb:0,mode:0,mode_auto:0,mode_fd:0,mode_fil:0,mode_memori:0,mode_mmap:0,mode_mmap_ext:0,must:0,network:0,node:0,node_byte_s:0,node_count:0,none:0,notat:0,note:0,number:0,object:0,obtain:0,older:0,onli:0,open:0,open_databas:0,option:0,order:0,otherwis:0,page:0,param:0,pass:0,path:0,pip:0,pleas:0,prefix:0,properli:0,properti:0,provid:0,pure:0,pypi:0,read:0,record:0,record_s:0,relat:0,report:0,resourc:0,respons:0,retriev:0,runtimeerror:0,search:0,search_tree_s:0,second:0,semant:0,servic:0,size:0,sourc:0,specif:0,standard:0,store:0,str:0,string:0,subnet:0,sure:0,system:0,test:0,text:0,thi:0,thrown:0,time:0,tracker:0,tree:0,tri:0,tupl:0,type:0,unexpect:0,unix:0,use:0,used:0,uses:0,using:0,valid:0,valu:0,valueerror:0,via:0,want:0,when:0,wish:0,you:0},titles:["MaxMind DB Python Module"],titleterms:{descript:0,error:0,exampl:0,except:0,indic:0,instal:0,maxmind:0,maxminddb:0,modul:0,python:0,reader:0,requir:0,support:0,tabl:0,usag:0,version:0}}) |
1026 | \ No newline at end of file |
1027 | +Search.setIndex({docnames:["index"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":2,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.intersphinx":1,sphinx:56},filenames:["index.rst"],objects:{"":{maxminddb:[0,0,0,"-"]},"maxminddb.errors":{InvalidDatabaseError:[0,2,1,""]},"maxminddb.reader":{Metadata:[0,3,1,""],Reader:[0,3,1,""]},"maxminddb.reader.Metadata":{binary_format_major_version:[0,4,1,""],binary_format_minor_version:[0,4,1,""],build_epoch:[0,4,1,""],database_type:[0,4,1,""],description:[0,4,1,""],ip_version:[0,4,1,""],languages:[0,4,1,""],node_byte_size:[0,5,1,""],node_count:[0,4,1,""],record_size:[0,4,1,""],search_tree_size:[0,5,1,""]},"maxminddb.reader.Reader":{close:[0,5,1,""],get:[0,5,1,""],get_with_prefix_len:[0,5,1,""],metadata:[0,5,1,""]},maxminddb:{Reader:[0,1,1,""],errors:[0,0,0,"-"],open_database:[0,1,1,""],reader:[0,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","exception","Python exception"],"3":["py","class","Python class"],"4":["py","attribute","Python attribute"],"5":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:function","2":"py:exception","3":"py:class","4":"py:attribute","5":"py:method"},terms:{"byte":0,"case":0,"class":0,"default":0,"export":0,"function":0,"import":0,"int":0,"return":0,"try":0,The:0,These:0,Use:0,abl:0,address:0,after:0,all:0,also:0,apach:0,api:0,argument:0,assist:0,associ:0,avail:0,back:0,backward:0,base:0,been:0,befor:0,binari:0,binary_format_major_vers:0,binary_format_minor_vers:0,bit:0,both:0,build:0,build_epoch:0,call:0,caller:0,can:0,citi:0,close:0,code:0,compat:0,contact:0,contain:0,copyright:0,correspond:0,corrupt:0,countri:0,cpython:0,creat:0,custom:0,data:0,databas:0,database_typ:0,databs:0,decompress:0,descriptor:0,dict:0,dictionari:0,directori:0,doe:0,download:0,easy_instal:0,epoch:0,exist:0,extens:0,fall:0,file:0,first:0,follow:0,format:0,found:0,free:0,from:0,geoip2:0,geolite2:0,get:0,get_with_prefix_len:0,github:0,gunzip:0,has:0,have:0,identifi:0,immedi:0,implement:0,impli:0,inc:0,includ:0,index:0,instanc:0,instead:0,invalid:0,invaliddatabaseerror:0,ip_address:0,ip_vers:0,ipaddress:0,ipv4:0,ipv6:0,issu:0,kwarg:0,languag:0,length:0,libmaxminddb:0,librari:0,licens:0,list:0,load:0,local:0,look:0,lookup:0,mai:0,major:0,map:0,mean:0,memori:0,metadata:0,method:0,minor:0,mmdb:0,mode:0,mode_auto:0,mode_fd:0,mode_fil:0,mode_memori:0,mode_mmap:0,mode_mmap_ext:0,must:0,network:0,node:0,node_byte_s:0,node_count:0,none:0,notat:0,note:0,number:0,object:0,obtain:0,older:0,onli:0,open:0,open_databas:0,option:0,order:0,otherwis:0,page:0,param:0,pass:0,path:0,pip:0,pleas:0,prefix:0,properli:0,properti:0,provid:0,pure:0,pypi:0,read:0,record:0,record_s:0,relat:0,report:0,resourc:0,respons:0,retriev:0,runtimeerror:0,search:0,search_tree_s:0,second:0,semant:0,servic:0,size:0,sourc:0,specif:0,standard:0,store:0,str:0,string:0,subnet:0,sure:0,system:0,test:0,text:0,thi:0,thrown:0,time:0,tracker:0,tree:0,tri:0,tupl:0,type:0,unexpect:0,unix:0,use:0,used:0,uses:0,using:0,valid:0,valu:0,valueerror:0,via:0,want:0,when:0,wish:0,you:0},titles:["MaxMind DB Python Module"],titleterms:{descript:0,error:0,exampl:0,except:0,indic:0,instal:0,maxmind:0,maxminddb:0,modul:0,python:0,reader:0,requir:0,support:0,tabl:0,usag:0,version:0}}) |
1028 | \ No newline at end of file |
1029 | diff --git a/extension/maxminddb.c b/extension/maxminddb.c |
1030 | index 69f18c5..a464200 100644 |
1031 | --- a/extension/maxminddb.c |
1032 | +++ b/extension/maxminddb.c |
1033 | @@ -204,6 +204,11 @@ static int get_record(PyObject *self, PyObject *args, PyObject **record) { |
1034 | *record = from_entry_data_list(&entry_data_list); |
1035 | MMDB_free_entry_data_list(original_entry_data_list); |
1036 | |
1037 | + // from_entry_data_list will return NULL on errors. |
1038 | + if (*record == NULL) { |
1039 | + return -1; |
1040 | + } |
1041 | + |
1042 | return prefix_len; |
1043 | } |
1044 | |
1045 | @@ -526,6 +531,11 @@ static PyObject *from_map(MMDB_entry_data_list_s **entry_data_list) { |
1046 | PyObject *key = PyUnicode_FromStringAndSize( |
1047 | (char *)(*entry_data_list)->entry_data.utf8_string, |
1048 | (*entry_data_list)->entry_data.data_size); |
1049 | + if (!key) { |
1050 | + // PyUnicode_FromStringAndSize will set an appropriate exception |
1051 | + // in this case. |
1052 | + return NULL; |
1053 | + } |
1054 | |
1055 | *entry_data_list = (*entry_data_list)->next; |
1056 | |
1057 | diff --git a/maxminddb.egg-info/PKG-INFO b/maxminddb.egg-info/PKG-INFO |
1058 | index 1a961e9..e8709ed 100644 |
1059 | --- a/maxminddb.egg-info/PKG-INFO |
1060 | +++ b/maxminddb.egg-info/PKG-INFO |
1061 | @@ -1,6 +1,6 @@ |
1062 | Metadata-Version: 1.2 |
1063 | Name: maxminddb |
1064 | -Version: 1.5.2 |
1065 | +Version: 1.5.4 |
1066 | Summary: Reader for the MaxMind DB format |
1067 | Home-page: http://www.maxmind.com/ |
1068 | Author: Gregory Oschwald |
1069 | diff --git a/maxminddb.egg-info/SOURCES.txt b/maxminddb.egg-info/SOURCES.txt |
1070 | index e1b82e1..6bd54af 100644 |
1071 | --- a/maxminddb.egg-info/SOURCES.txt |
1072 | +++ b/maxminddb.egg-info/SOURCES.txt |
1073 | @@ -42,6 +42,16 @@ maxminddb.egg-info/dependency_links.txt |
1074 | maxminddb.egg-info/top_level.txt |
1075 | tests/decoder_test.py |
1076 | tests/reader_test.py |
1077 | +tests/data/MaxMind-DB-test-metadata-pointers.mmdb |
1078 | +tests/data/bad-data/libmaxminddb/libmaxminddb-offset-integer-overflow.mmdb |
1079 | +tests/data/bad-data/maxminddb-golang/cyclic-data-structure.mmdb |
1080 | +tests/data/bad-data/maxminddb-golang/invalid-bytes-length.mmdb |
1081 | +tests/data/bad-data/maxminddb-golang/invalid-data-record-offset.mmdb |
1082 | +tests/data/bad-data/maxminddb-golang/invalid-map-key-length.mmdb |
1083 | +tests/data/bad-data/maxminddb-golang/invalid-string-length.mmdb |
1084 | +tests/data/bad-data/maxminddb-golang/metadata-is-an-uint128.mmdb |
1085 | +tests/data/bad-data/maxminddb-golang/unexpected-bytes.mmdb |
1086 | +tests/data/bad-data/maxminddb-python/bad-unicode-in-map-key.mmdb |
1087 | tests/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb |
1088 | tests/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb |
1089 | tests/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb |
1090 | @@ -53,6 +63,7 @@ tests/data/test-data/GeoIP2-Domain-Test.mmdb |
1091 | tests/data/test-data/GeoIP2-Enterprise-Test.mmdb |
1092 | tests/data/test-data/GeoIP2-ISP-Test.mmdb |
1093 | tests/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb |
1094 | +tests/data/test-data/GeoIP2-Static-IP-Score-Test.mmdb |
1095 | tests/data/test-data/GeoIP2-User-Count-Test.mmdb |
1096 | tests/data/test-data/GeoLite2-ASN-Test.mmdb |
1097 | tests/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb |
1098 | diff --git a/maxminddb/__init__.py b/maxminddb/__init__.py |
1099 | index dadd6fe..7ad56be 100644 |
1100 | --- a/maxminddb/__init__.py |
1101 | +++ b/maxminddb/__init__.py |
1102 | @@ -8,8 +8,14 @@ try: |
1103 | except ImportError: |
1104 | maxminddb.extension = None |
1105 | |
1106 | -from maxminddb.const import (MODE_AUTO, MODE_MMAP, MODE_MMAP_EXT, MODE_FILE, |
1107 | - MODE_MEMORY, MODE_FD) |
1108 | +from maxminddb.const import ( |
1109 | + MODE_AUTO, |
1110 | + MODE_MMAP, |
1111 | + MODE_MMAP_EXT, |
1112 | + MODE_FILE, |
1113 | + MODE_MEMORY, |
1114 | + MODE_FD, |
1115 | +) |
1116 | from maxminddb.decoder import InvalidDatabaseError |
1117 | |
1118 | |
1119 | @@ -29,8 +35,7 @@ def open_database(database, mode=MODE_AUTO): |
1120 | * MODE_AUTO - tries MODE_MMAP_EXT, MODE_MMAP, MODE_FILE in that |
1121 | order. Default mode. |
1122 | """ |
1123 | - has_extension = maxminddb.extension and hasattr(maxminddb.extension, |
1124 | - 'Reader') |
1125 | + has_extension = maxminddb.extension and hasattr(maxminddb.extension, "Reader") |
1126 | if (mode == MODE_AUTO and has_extension) or mode == MODE_MMAP_EXT: |
1127 | if not has_extension: |
1128 | raise ValueError( |
1129 | @@ -39,7 +44,7 @@ def open_database(database, mode=MODE_AUTO): |
1130 | return maxminddb.extension.Reader(database) |
1131 | if mode in (MODE_AUTO, MODE_MMAP, MODE_FILE, MODE_MEMORY, MODE_FD): |
1132 | return maxminddb.reader.Reader(database, mode) |
1133 | - raise ValueError('Unsupported open mode: {0}'.format(mode)) |
1134 | + raise ValueError("Unsupported open mode: {0}".format(mode)) |
1135 | |
1136 | |
1137 | def Reader(database): # pylint: disable=invalid-name |
1138 | @@ -47,8 +52,8 @@ def Reader(database): # pylint: disable=invalid-name |
1139 | return open_database(database) |
1140 | |
1141 | |
1142 | -__title__ = 'maxminddb' |
1143 | -__version__ = '1.5.2' |
1144 | -__author__ = 'Gregory Oschwald' |
1145 | -__license__ = 'Apache License, Version 2.0' |
1146 | -__copyright__ = 'Copyright 2013-2019 Maxmind, Inc.' |
1147 | +__title__ = "maxminddb" |
1148 | +__version__ = "1.5.4" |
1149 | +__author__ = "Gregory Oschwald" |
1150 | +__license__ = "Apache License, Version 2.0" |
1151 | +__copyright__ = "Copyright 2013-2019 Maxmind, Inc." |
1152 | diff --git a/maxminddb/compat.py b/maxminddb/compat.py |
1153 | index 118a2a1..5935d99 100644 |
1154 | --- a/maxminddb/compat.py |
1155 | +++ b/maxminddb/compat.py |
1156 | @@ -33,7 +33,7 @@ else: |
1157 | |
1158 | FileNotFoundError = FileNotFoundError |
1159 | |
1160 | - int_from_bytes = lambda x: int.from_bytes(x, 'big') |
1161 | + int_from_bytes = lambda x: int.from_bytes(x, "big") |
1162 | |
1163 | byte_from_int = lambda x: bytes([x]) |
1164 | |
1165 | diff --git a/maxminddb/decoder.py b/maxminddb/decoder.py |
1166 | index 3d51e25..71dc4a0 100644 |
1167 | --- a/maxminddb/decoder.py |
1168 | +++ b/maxminddb/decoder.py |
1169 | @@ -15,6 +15,7 @@ from maxminddb.errors import InvalidDatabaseError |
1170 | |
1171 | class Decoder(object): # pylint: disable=too-few-public-methods |
1172 | """Decoder for the data section of the MaxMind DB""" |
1173 | + |
1174 | def __init__(self, database_buffer, pointer_base=0, pointer_test=False): |
1175 | """Created a Decoder for a MaxMind DB |
1176 | |
1177 | @@ -45,14 +46,14 @@ class Decoder(object): # pylint: disable=too-few-public-methods |
1178 | self._verify_size(size, 8) |
1179 | new_offset = offset + size |
1180 | packed_bytes = self._buffer[offset:new_offset] |
1181 | - (value, ) = struct.unpack(b'!d', packed_bytes) |
1182 | + (value,) = struct.unpack(b"!d", packed_bytes) |
1183 | return value, new_offset |
1184 | |
1185 | def _decode_float(self, size, offset): |
1186 | self._verify_size(size, 4) |
1187 | new_offset = offset + size |
1188 | packed_bytes = self._buffer[offset:new_offset] |
1189 | - (value, ) = struct.unpack(b'!f', packed_bytes) |
1190 | + (value,) = struct.unpack(b"!f", packed_bytes) |
1191 | return value, new_offset |
1192 | |
1193 | def _decode_int32(self, size, offset): |
1194 | @@ -62,8 +63,8 @@ class Decoder(object): # pylint: disable=too-few-public-methods |
1195 | packed_bytes = self._buffer[offset:new_offset] |
1196 | |
1197 | if size != 4: |
1198 | - packed_bytes = packed_bytes.rjust(4, b'\x00') |
1199 | - (value, ) = struct.unpack(b'!i', packed_bytes) |
1200 | + packed_bytes = packed_bytes.rjust(4, b"\x00") |
1201 | + (value,) = struct.unpack(b"!i", packed_bytes) |
1202 | return value, new_offset |
1203 | |
1204 | def _decode_map(self, size, offset): |
1205 | @@ -77,21 +78,20 @@ class Decoder(object): # pylint: disable=too-few-public-methods |
1206 | def _decode_pointer(self, size, offset): |
1207 | pointer_size = (size >> 3) + 1 |
1208 | |
1209 | - buf = self._buffer[offset:offset + pointer_size] |
1210 | + buf = self._buffer[offset : offset + pointer_size] |
1211 | new_offset = offset + pointer_size |
1212 | |
1213 | if pointer_size == 1: |
1214 | buf = byte_from_int(size & 0x7) + buf |
1215 | - pointer = struct.unpack(b'!H', buf)[0] + self._pointer_base |
1216 | + pointer = struct.unpack(b"!H", buf)[0] + self._pointer_base |
1217 | elif pointer_size == 2: |
1218 | - buf = b'\x00' + byte_from_int(size & 0x7) + buf |
1219 | - pointer = struct.unpack(b'!I', buf)[0] + 2048 + self._pointer_base |
1220 | + buf = b"\x00" + byte_from_int(size & 0x7) + buf |
1221 | + pointer = struct.unpack(b"!I", buf)[0] + 2048 + self._pointer_base |
1222 | elif pointer_size == 3: |
1223 | buf = byte_from_int(size & 0x7) + buf |
1224 | - pointer = struct.unpack(b'!I', |
1225 | - buf)[0] + 526336 + self._pointer_base |
1226 | + pointer = struct.unpack(b"!I", buf)[0] + 526336 + self._pointer_base |
1227 | else: |
1228 | - pointer = struct.unpack(b'!I', buf)[0] + self._pointer_base |
1229 | + pointer = struct.unpack(b"!I", buf)[0] + self._pointer_base |
1230 | |
1231 | if self._pointer_test: |
1232 | return pointer, new_offset |
1233 | @@ -105,7 +105,7 @@ class Decoder(object): # pylint: disable=too-few-public-methods |
1234 | |
1235 | def _decode_utf8_string(self, size, offset): |
1236 | new_offset = offset + size |
1237 | - return self._buffer[offset:new_offset].decode('utf-8'), new_offset |
1238 | + return self._buffer[offset:new_offset].decode("utf-8"), new_offset |
1239 | |
1240 | _type_decoder = { |
1241 | 1: _decode_pointer, |
1242 | @@ -139,11 +139,11 @@ class Decoder(object): # pylint: disable=too-few-public-methods |
1243 | try: |
1244 | decoder = self._type_decoder[type_num] |
1245 | except KeyError: |
1246 | - raise InvalidDatabaseError('Unexpected type number ({type}) ' |
1247 | - 'encountered'.format(type=type_num)) |
1248 | + raise InvalidDatabaseError( |
1249 | + "Unexpected type number ({type}) " "encountered".format(type=type_num) |
1250 | + ) |
1251 | |
1252 | - (size, new_offset) = self._size_from_ctrl_byte(ctrl_byte, new_offset, |
1253 | - type_num) |
1254 | + (size, new_offset) = self._size_from_ctrl_byte(ctrl_byte, new_offset, type_num) |
1255 | return decoder(self, size, new_offset) |
1256 | |
1257 | def _read_extended(self, offset): |
1258 | @@ -151,19 +151,21 @@ class Decoder(object): # pylint: disable=too-few-public-methods |
1259 | type_num = next_byte + 7 |
1260 | if type_num < 7: |
1261 | raise InvalidDatabaseError( |
1262 | - 'Something went horribly wrong in the decoder. An ' |
1263 | - 'extended type resolved to a type number < 8 ' |
1264 | - '({type})'.format(type=type_num)) |
1265 | + "Something went horribly wrong in the decoder. An " |
1266 | + "extended type resolved to a type number < 8 " |
1267 | + "({type})".format(type=type_num) |
1268 | + ) |
1269 | return type_num, offset + 1 |
1270 | |
1271 | def _verify_size(self, expected, actual): |
1272 | if expected != actual: |
1273 | raise InvalidDatabaseError( |
1274 | - 'The MaxMind DB file\'s data section contains bad data ' |
1275 | - '(unknown data type or corrupt data)') |
1276 | + "The MaxMind DB file's data section contains bad data " |
1277 | + "(unknown data type or corrupt data)" |
1278 | + ) |
1279 | |
1280 | def _size_from_ctrl_byte(self, ctrl_byte, offset, type_num): |
1281 | - size = ctrl_byte & 0x1f |
1282 | + size = ctrl_byte & 0x1F |
1283 | if type_num == 1 or size < 29: |
1284 | return size, offset |
1285 | |
1286 | @@ -176,10 +178,10 @@ class Decoder(object): # pylint: disable=too-few-public-methods |
1287 | if size == 30: |
1288 | new_offset = offset + 2 |
1289 | size_bytes = self._buffer[offset:new_offset] |
1290 | - size = 285 + struct.unpack(b'!H', size_bytes)[0] |
1291 | + size = 285 + struct.unpack(b"!H", size_bytes)[0] |
1292 | return size, new_offset |
1293 | |
1294 | new_offset = offset + 3 |
1295 | size_bytes = self._buffer[offset:new_offset] |
1296 | - size = struct.unpack(b'!I', b'\x00' + size_bytes)[0] + 65821 |
1297 | + size = struct.unpack(b"!I", b"\x00" + size_bytes)[0] + 65821 |
1298 | return size, new_offset |
1299 | diff --git a/maxminddb/file.py b/maxminddb/file.py |
1300 | index 0019e4f..736d99d 100644 |
1301 | --- a/maxminddb/file.py |
1302 | +++ b/maxminddb/file.py |
1303 | @@ -11,10 +11,11 @@ except ImportError: |
1304 | |
1305 | class FileBuffer(object): |
1306 | """A slice-able file reader""" |
1307 | + |
1308 | def __init__(self, database): |
1309 | - self._handle = open(database, 'rb') |
1310 | + self._handle = open(database, "rb") |
1311 | self._size = os.fstat(self._handle.fileno()).st_size |
1312 | - if not hasattr(os, 'pread'): |
1313 | + if not hasattr(os, "pread"): |
1314 | self._lock = Lock() |
1315 | |
1316 | def __getitem__(self, key): |
1317 | @@ -39,7 +40,7 @@ class FileBuffer(object): |
1318 | """Close file""" |
1319 | self._handle.close() |
1320 | |
1321 | - if hasattr(os, 'pread'): |
1322 | + if hasattr(os, "pread"): |
1323 | |
1324 | def _read(self, buffersize, offset): |
1325 | """read that uses pread""" |
1326 | diff --git a/maxminddb/reader.py b/maxminddb/reader.py |
1327 | index 9d924f3..e3cd32f 100644 |
1328 | --- a/maxminddb/reader.py |
1329 | +++ b/maxminddb/reader.py |
1330 | @@ -48,10 +48,8 @@ class Reader(object): |
1331 | a path. This mode implies MODE_MEMORY. |
1332 | """ |
1333 | if (mode == MODE_AUTO and mmap) or mode == MODE_MMAP: |
1334 | - with open(database, 'rb') as db_file: |
1335 | - self._buffer = mmap.mmap(db_file.fileno(), |
1336 | - 0, |
1337 | - access=mmap.ACCESS_READ) |
1338 | + with open(database, "rb") as db_file: |
1339 | + self._buffer = mmap.mmap(db_file.fileno(), 0, access=mmap.ACCESS_READ) |
1340 | self._buffer_size = self._buffer.size() |
1341 | filename = database |
1342 | elif mode in (MODE_AUTO, MODE_FILE): |
1343 | @@ -59,7 +57,7 @@ class Reader(object): |
1344 | self._buffer_size = self._buffer.size() |
1345 | filename = database |
1346 | elif mode == MODE_MEMORY: |
1347 | - with open(database, 'rb') as db_file: |
1348 | + with open(database, "rb") as db_file: |
1349 | self._buffer = db_file.read() |
1350 | self._buffer_size = len(self._buffer) |
1351 | filename = database |
1352 | @@ -69,19 +67,22 @@ class Reader(object): |
1353 | filename = database.name |
1354 | else: |
1355 | raise ValueError( |
1356 | - 'Unsupported open mode ({0}). Only MODE_AUTO, MODE_FILE, ' |
1357 | - 'MODE_MEMORY and MODE_FD are supported by the pure Python ' |
1358 | - 'Reader'.format(mode)) |
1359 | + "Unsupported open mode ({0}). Only MODE_AUTO, MODE_FILE, " |
1360 | + "MODE_MEMORY and MODE_FD are supported by the pure Python " |
1361 | + "Reader".format(mode) |
1362 | + ) |
1363 | |
1364 | metadata_start = self._buffer.rfind( |
1365 | - self._METADATA_START_MARKER, max(0, |
1366 | - self._buffer_size - 128 * 1024)) |
1367 | + self._METADATA_START_MARKER, max(0, self._buffer_size - 128 * 1024) |
1368 | + ) |
1369 | |
1370 | if metadata_start == -1: |
1371 | self.close() |
1372 | - raise InvalidDatabaseError('Error opening database file ({0}). ' |
1373 | - 'Is this a valid MaxMind DB file?' |
1374 | - ''.format(filename)) |
1375 | + raise InvalidDatabaseError( |
1376 | + "Error opening database file ({0}). " |
1377 | + "Is this a valid MaxMind DB file?" |
1378 | + "".format(filename) |
1379 | + ) |
1380 | |
1381 | metadata_start += len(self._METADATA_START_MARKER) |
1382 | metadata_decoder = Decoder(self._buffer, metadata_start) |
1383 | @@ -89,8 +90,9 @@ class Reader(object): |
1384 | self._metadata = Metadata(**metadata) # pylint: disable=bad-option-value |
1385 | |
1386 | self._decoder = Decoder( |
1387 | - self._buffer, self._metadata.search_tree_size + |
1388 | - self._DATA_SECTION_SEPARATOR_SIZE) |
1389 | + self._buffer, |
1390 | + self._metadata.search_tree_size + self._DATA_SECTION_SEPARATOR_SIZE, |
1391 | + ) |
1392 | self.closed = False |
1393 | |
1394 | def metadata(self): |
1395 | @@ -122,12 +124,13 @@ class Reader(object): |
1396 | try: |
1397 | packed_address = bytearray(address.packed) |
1398 | except AttributeError: |
1399 | - raise TypeError('argument 1 must be a string or ipaddress object') |
1400 | + raise TypeError("argument 1 must be a string or ipaddress object") |
1401 | |
1402 | if address.version == 6 and self._metadata.ip_version == 4: |
1403 | raise ValueError( |
1404 | - 'Error looking up {0}. You attempted to look up ' |
1405 | - 'an IPv6 address in an IPv4-only database.'.format(ip_address)) |
1406 | + "Error looking up {0}. You attempted to look up " |
1407 | + "an IPv6 address in an IPv4-only database.".format(ip_address) |
1408 | + ) |
1409 | |
1410 | (pointer, prefix_len) = self._find_address_in_tree(packed_address) |
1411 | |
1412 | @@ -152,7 +155,7 @@ class Reader(object): |
1413 | if node > node_count: |
1414 | return node, i |
1415 | |
1416 | - raise InvalidDatabaseError('Invalid node in search tree') |
1417 | + raise InvalidDatabaseError("Invalid node in search tree") |
1418 | |
1419 | def _start_node(self, length): |
1420 | if self._metadata.ip_version != 6 or length == 128: |
1421 | @@ -177,10 +180,10 @@ class Reader(object): |
1422 | record_size = self._metadata.record_size |
1423 | if record_size == 24: |
1424 | offset = base_offset + index * 3 |
1425 | - node_bytes = b'\x00' + self._buffer[offset:offset + 3] |
1426 | + node_bytes = b"\x00" + self._buffer[offset : offset + 3] |
1427 | elif record_size == 28: |
1428 | offset = base_offset + 3 * index |
1429 | - node_bytes = bytearray(self._buffer[offset:offset + 4]) |
1430 | + node_bytes = bytearray(self._buffer[offset : offset + 4]) |
1431 | if index: |
1432 | node_bytes[0] = 0x0F & node_bytes[0] |
1433 | else: |
1434 | @@ -188,19 +191,16 @@ class Reader(object): |
1435 | node_bytes.insert(0, middle) |
1436 | elif record_size == 32: |
1437 | offset = base_offset + index * 4 |
1438 | - node_bytes = self._buffer[offset:offset + 4] |
1439 | + node_bytes = self._buffer[offset : offset + 4] |
1440 | else: |
1441 | - raise InvalidDatabaseError( |
1442 | - 'Unknown record size: {0}'.format(record_size)) |
1443 | - return struct.unpack(b'!I', node_bytes)[0] |
1444 | + raise InvalidDatabaseError("Unknown record size: {0}".format(record_size)) |
1445 | + return struct.unpack(b"!I", node_bytes)[0] |
1446 | |
1447 | def _resolve_data_pointer(self, pointer): |
1448 | - resolved = pointer - self._metadata.node_count + \ |
1449 | - self._metadata.search_tree_size |
1450 | + resolved = pointer - self._metadata.node_count + self._metadata.search_tree_size |
1451 | |
1452 | if resolved >= self._buffer_size: |
1453 | - raise InvalidDatabaseError( |
1454 | - "The MaxMind DB file's search tree is corrupt") |
1455 | + raise InvalidDatabaseError("The MaxMind DB file's search tree is corrupt") |
1456 | |
1457 | (data, _) = self._decoder.decode(resolved) |
1458 | return data |
1459 | @@ -217,7 +217,7 @@ class Reader(object): |
1460 | |
1461 | def __enter__(self): |
1462 | if self.closed: |
1463 | - raise ValueError('Attempt to reopen a closed MaxMind DB') |
1464 | + raise ValueError("Attempt to reopen a closed MaxMind DB") |
1465 | return self |
1466 | |
1467 | |
1468 | @@ -290,17 +290,15 @@ class Metadata(object): |
1469 | """Creates new Metadata object. kwargs are key/value pairs from spec""" |
1470 | # Although I could just update __dict__, that is less obvious and it |
1471 | # doesn't work well with static analysis tools and some IDEs |
1472 | - self.node_count = kwargs['node_count'] |
1473 | - self.record_size = kwargs['record_size'] |
1474 | - self.ip_version = kwargs['ip_version'] |
1475 | - self.database_type = kwargs['database_type'] |
1476 | - self.languages = kwargs['languages'] |
1477 | - self.binary_format_major_version = kwargs[ |
1478 | - 'binary_format_major_version'] |
1479 | - self.binary_format_minor_version = kwargs[ |
1480 | - 'binary_format_minor_version'] |
1481 | - self.build_epoch = kwargs['build_epoch'] |
1482 | - self.description = kwargs['description'] |
1483 | + self.node_count = kwargs["node_count"] |
1484 | + self.record_size = kwargs["record_size"] |
1485 | + self.ip_version = kwargs["ip_version"] |
1486 | + self.database_type = kwargs["database_type"] |
1487 | + self.languages = kwargs["languages"] |
1488 | + self.binary_format_major_version = kwargs["binary_format_major_version"] |
1489 | + self.binary_format_minor_version = kwargs["binary_format_minor_version"] |
1490 | + self.build_epoch = kwargs["build_epoch"] |
1491 | + self.description = kwargs["description"] |
1492 | |
1493 | @property |
1494 | def node_byte_size(self): |
1495 | @@ -319,8 +317,7 @@ class Metadata(object): |
1496 | return self.node_count * self.node_byte_size |
1497 | |
1498 | def __repr__(self): |
1499 | - args = ', '.join('%s=%r' % x for x in self.__dict__.items()) |
1500 | - return '{module}.{class_name}({data})'.format( |
1501 | - module=self.__module__, |
1502 | - class_name=self.__class__.__name__, |
1503 | - data=args) |
1504 | + args = ", ".join("%s=%r" % x for x in self.__dict__.items()) |
1505 | + return "{module}.{class_name}({data})".format( |
1506 | + module=self.__module__, class_name=self.__class__.__name__, data=args |
1507 | + ) |
1508 | diff --git a/setup.py b/setup.py |
1509 | index 73f74ba..ca9838f 100644 |
1510 | --- a/setup.py |
1511 | +++ b/setup.py |
1512 | @@ -6,34 +6,32 @@ import sys |
1513 | import multiprocessing |
1514 | |
1515 | from distutils.command.build_ext import build_ext |
1516 | -from distutils.errors import (CCompilerError, DistutilsExecError, |
1517 | - DistutilsPlatformError) |
1518 | +from distutils.errors import CCompilerError, DistutilsExecError, DistutilsPlatformError |
1519 | |
1520 | from setuptools import setup, Extension |
1521 | |
1522 | cmdclass = {} |
1523 | -PYPY = hasattr(sys, 'pypy_version_info') |
1524 | -JYTHON = sys.platform.startswith('java') |
1525 | +PYPY = hasattr(sys, "pypy_version_info") |
1526 | +JYTHON = sys.platform.startswith("java") |
1527 | requirements = [] |
1528 | |
1529 | -if sys.version_info[0] == 2 or (sys.version_info[0] == 3 |
1530 | - and sys.version_info[1] < 3): |
1531 | - requirements.append('ipaddress') |
1532 | - if os.environ.get('SNYK_TOKEN'): |
1533 | - with open('requirements.txt', 'w') as f: |
1534 | +if sys.version_info[0] == 2 or (sys.version_info[0] == 3 and sys.version_info[1] < 3): |
1535 | + requirements.append("ipaddress") |
1536 | + if os.environ.get("SNYK_TOKEN"): |
1537 | + with open("requirements.txt", "w") as f: |
1538 | for r in requirements: |
1539 | - f.write(r + '\n') |
1540 | + f.write(r + "\n") |
1541 | |
1542 | -compile_args = ['-Wall', '-Wextra'] |
1543 | +compile_args = ["-Wall", "-Wextra"] |
1544 | |
1545 | if sys.version_info[0] == 2: |
1546 | - compile_args.append('-fno-strict-aliasing') |
1547 | + compile_args.append("-fno-strict-aliasing") |
1548 | |
1549 | ext_module = [ |
1550 | Extension( |
1551 | - 'maxminddb.extension', |
1552 | - libraries=['maxminddb'], |
1553 | - sources=['extension/maxminddb.c'], |
1554 | + "maxminddb.extension", |
1555 | + libraries=["maxminddb"], |
1556 | + sources=["extension/maxminddb.c"], |
1557 | extra_compile_args=compile_args, |
1558 | ) |
1559 | ] |
1560 | @@ -69,37 +67,38 @@ class ve_build_ext(build_ext): |
1561 | raise |
1562 | |
1563 | |
1564 | -cmdclass['build_ext'] = ve_build_ext |
1565 | +cmdclass["build_ext"] = ve_build_ext |
1566 | |
1567 | # |
1568 | |
1569 | ROOT = os.path.dirname(__file__) |
1570 | |
1571 | -with open(os.path.join(ROOT, 'README.rst'), 'rb') as fd: |
1572 | - README = fd.read().decode('utf8') |
1573 | +with open(os.path.join(ROOT, "README.rst"), "rb") as fd: |
1574 | + README = fd.read().decode("utf8") |
1575 | |
1576 | -with open(os.path.join(ROOT, 'maxminddb', '__init__.py'), 'rb') as fd: |
1577 | - maxminddb_text = fd.read().decode('utf8') |
1578 | - LICENSE = re.compile(r".*__license__ = '(.*?)'", |
1579 | - re.S).match(maxminddb_text).group(1) |
1580 | - VERSION = re.compile(r".*__version__ = '(.*?)'", |
1581 | - re.S).match(maxminddb_text).group(1) |
1582 | +with open(os.path.join(ROOT, "maxminddb", "__init__.py"), "rb") as fd: |
1583 | + maxminddb_text = fd.read().decode("utf8") |
1584 | + LICENSE = ( |
1585 | + re.compile(r".*__license__ = \"(.*?)\"", re.S).match(maxminddb_text).group(1) |
1586 | + ) |
1587 | + VERSION = ( |
1588 | + re.compile(r".*__version__ = \"(.*?)\"", re.S).match(maxminddb_text).group(1) |
1589 | + ) |
1590 | |
1591 | |
1592 | def status_msgs(*msgs): |
1593 | - print('*' * 75) |
1594 | + print("*" * 75) |
1595 | for msg in msgs: |
1596 | print(msg) |
1597 | - print('*' * 75) |
1598 | + print("*" * 75) |
1599 | |
1600 | |
1601 | def find_packages(location): |
1602 | packages = [] |
1603 | - for pkg in ['maxminddb']: |
1604 | - for _dir, subdirectories, files in (os.walk(os.path.join( |
1605 | - location, pkg))): |
1606 | - if '__init__.py' in files: |
1607 | - tokens = _dir.split(os.sep)[len(location.split(os.sep)):] |
1608 | + for pkg in ["maxminddb"]: |
1609 | + for _dir, subdirectories, files in os.walk(os.path.join(location, pkg)): |
1610 | + if "__init__.py" in files: |
1611 | + tokens = _dir.split(os.sep)[len(location.split(os.sep)) :] |
1612 | packages.append(".".join(tokens)) |
1613 | return packages |
1614 | |
1615 | @@ -107,59 +106,67 @@ def find_packages(location): |
1616 | def run_setup(with_cext): |
1617 | kwargs = {} |
1618 | if with_cext: |
1619 | - kwargs['ext_modules'] = ext_module |
1620 | - |
1621 | - setup(name='maxminddb', |
1622 | - version=VERSION, |
1623 | - author='Gregory Oschwald', |
1624 | - author_email='goschwald@maxmind.com', |
1625 | - description='Reader for the MaxMind DB format', |
1626 | - long_description=README, |
1627 | - url='http://www.maxmind.com/', |
1628 | - packages=find_packages('.'), |
1629 | - package_data={'': ['LICENSE']}, |
1630 | - package_dir={'maxminddb': 'maxminddb'}, |
1631 | - python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', |
1632 | - include_package_data=True, |
1633 | - install_requires=requirements, |
1634 | - tests_require=['nose'], |
1635 | - test_suite='nose.collector', |
1636 | - license=LICENSE, |
1637 | - cmdclass=cmdclass, |
1638 | - classifiers=[ |
1639 | - 'Development Status :: 5 - Production/Stable', |
1640 | - 'Environment :: Web Environment', |
1641 | - 'Intended Audience :: Developers', |
1642 | - 'Intended Audience :: System Administrators', |
1643 | - 'License :: OSI Approved :: Apache Software License', |
1644 | - 'Programming Language :: Python :: 2.7', |
1645 | - 'Programming Language :: Python :: 3', |
1646 | - 'Programming Language :: Python :: 3.5', |
1647 | - 'Programming Language :: Python :: 3.6', |
1648 | - 'Programming Language :: Python :: 3.7', |
1649 | - 'Programming Language :: Python', |
1650 | - 'Topic :: Internet :: Proxy Servers', |
1651 | - 'Topic :: Internet', |
1652 | - ], |
1653 | - **kwargs) |
1654 | + kwargs["ext_modules"] = ext_module |
1655 | + |
1656 | + setup( |
1657 | + name="maxminddb", |
1658 | + version=VERSION, |
1659 | + author="Gregory Oschwald", |
1660 | + author_email="goschwald@maxmind.com", |
1661 | + description="Reader for the MaxMind DB format", |
1662 | + long_description=README, |
1663 | + url="http://www.maxmind.com/", |
1664 | + packages=find_packages("."), |
1665 | + package_data={"": ["LICENSE"]}, |
1666 | + package_dir={"maxminddb": "maxminddb"}, |
1667 | + python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*", |
1668 | + include_package_data=True, |
1669 | + install_requires=requirements, |
1670 | + tests_require=["nose"], |
1671 | + test_suite="nose.collector", |
1672 | + license=LICENSE, |
1673 | + cmdclass=cmdclass, |
1674 | + classifiers=[ |
1675 | + "Development Status :: 5 - Production/Stable", |
1676 | + "Environment :: Web Environment", |
1677 | + "Intended Audience :: Developers", |
1678 | + "Intended Audience :: System Administrators", |
1679 | + "License :: OSI Approved :: Apache Software License", |
1680 | + "Programming Language :: Python :: 2.7", |
1681 | + "Programming Language :: Python :: 3", |
1682 | + "Programming Language :: Python :: 3.5", |
1683 | + "Programming Language :: Python :: 3.6", |
1684 | + "Programming Language :: Python :: 3.7", |
1685 | + "Programming Language :: Python", |
1686 | + "Topic :: Internet :: Proxy Servers", |
1687 | + "Topic :: Internet", |
1688 | + ], |
1689 | + **kwargs |
1690 | + ) |
1691 | |
1692 | |
1693 | if PYPY or JYTHON: |
1694 | run_setup(False) |
1695 | - status_msgs("WARNING: Disabling C extension due to Python platform.", |
1696 | - "Plain-Python build succeeded.") |
1697 | + status_msgs( |
1698 | + "WARNING: Disabling C extension due to Python platform.", |
1699 | + "Plain-Python build succeeded.", |
1700 | + ) |
1701 | else: |
1702 | try: |
1703 | run_setup(True) |
1704 | except BuildFailed as exc: |
1705 | status_msgs( |
1706 | - exc.cause, "WARNING: The C extension could not be compiled, " + |
1707 | - "speedups are not enabled.", |
1708 | + exc.cause, |
1709 | + "WARNING: The C extension could not be compiled, " |
1710 | + + "speedups are not enabled.", |
1711 | "Failure information, if any, is above.", |
1712 | - "Retrying the build without the C extension now.") |
1713 | + "Retrying the build without the C extension now.", |
1714 | + ) |
1715 | |
1716 | run_setup(False) |
1717 | |
1718 | status_msgs( |
1719 | - "WARNING: The C extension could not be compiled, " + |
1720 | - "speedups are not enabled.", "Plain-Python build succeeded.") |
1721 | + "WARNING: The C extension could not be compiled, " |
1722 | + + "speedups are not enabled.", |
1723 | + "Plain-Python build succeeded.", |
1724 | + ) |
1725 | diff --git a/tests/data/MaxMind-DB-test-metadata-pointers.mmdb b/tests/data/MaxMind-DB-test-metadata-pointers.mmdb |
1726 | new file mode 100644 |
1727 | index 0000000..9a9f625 |
1728 | Binary files /dev/null and b/tests/data/MaxMind-DB-test-metadata-pointers.mmdb differ |
1729 | diff --git a/tests/data/bad-data/libmaxminddb/libmaxminddb-offset-integer-overflow.mmdb b/tests/data/bad-data/libmaxminddb/libmaxminddb-offset-integer-overflow.mmdb |
1730 | new file mode 100644 |
1731 | index 0000000..b76f354 |
1732 | Binary files /dev/null and b/tests/data/bad-data/libmaxminddb/libmaxminddb-offset-integer-overflow.mmdb differ |
1733 | diff --git a/tests/data/bad-data/maxminddb-golang/cyclic-data-structure.mmdb b/tests/data/bad-data/maxminddb-golang/cyclic-data-structure.mmdb |
1734 | new file mode 100644 |
1735 | index 0000000..1015cbe |
1736 | Binary files /dev/null and b/tests/data/bad-data/maxminddb-golang/cyclic-data-structure.mmdb differ |
1737 | diff --git a/tests/data/bad-data/maxminddb-golang/invalid-bytes-length.mmdb b/tests/data/bad-data/maxminddb-golang/invalid-bytes-length.mmdb |
1738 | new file mode 100644 |
1739 | index 0000000..8c13018 |
1740 | --- /dev/null |
1741 | +++ b/tests/data/bad-data/maxminddb-golang/invalid-bytes-length.mmdb |
1742 | @@ -0,0 +1 @@ |
1743 | +���MaxMind.com�Kdescription�Ben� |
1744 | \ No newline at end of file |
1745 | diff --git a/tests/data/bad-data/maxminddb-golang/invalid-data-record-offset.mmdb b/tests/data/bad-data/maxminddb-golang/invalid-data-record-offset.mmdb |
1746 | new file mode 100644 |
1747 | index 0000000..228294e |
1748 | Binary files /dev/null and b/tests/data/bad-data/maxminddb-golang/invalid-data-record-offset.mmdb differ |
1749 | diff --git a/tests/data/bad-data/maxminddb-golang/invalid-map-key-length.mmdb b/tests/data/bad-data/maxminddb-golang/invalid-map-key-length.mmdb |
1750 | new file mode 100644 |
1751 | index 0000000..23e5906 |
1752 | Binary files /dev/null and b/tests/data/bad-data/maxminddb-golang/invalid-map-key-length.mmdb differ |
1753 | diff --git a/tests/data/bad-data/maxminddb-golang/invalid-string-length.mmdb b/tests/data/bad-data/maxminddb-golang/invalid-string-length.mmdb |
1754 | new file mode 100644 |
1755 | index 0000000..c073c77 |
1756 | --- /dev/null |
1757 | +++ b/tests/data/bad-data/maxminddb-golang/invalid-string-length.mmdb |
1758 | @@ -0,0 +1 @@ |
1759 | +Dmap2�Earray�Dmap3�Aa�Ab�Ac����MaxMind.com�[binary_format_major_version�[binary_format_minor_version�Kbuild_epochX�2|Mdatabase_type]MaxMind DB Nested Data StructuresKdescription |
1760 | \ No newline at end of file |
1761 | diff --git a/tests/data/bad-data/maxminddb-golang/metadata-is-an-uint128.mmdb b/tests/data/bad-data/maxminddb-golang/metadata-is-an-uint128.mmdb |
1762 | new file mode 100644 |
1763 | index 0000000..4000d97 |
1764 | --- /dev/null |
1765 | +++ b/tests/data/bad-data/maxminddb-golang/metadata-is-an-uint128.mmdb |
1766 | @@ -0,0 +1 @@ |
1767 | +���MaxMind.com |
1768 | \ No newline at end of file |
1769 | diff --git a/tests/data/bad-data/maxminddb-golang/unexpected-bytes.mmdb b/tests/data/bad-data/maxminddb-golang/unexpected-bytes.mmdb |
1770 | new file mode 100644 |
1771 | index 0000000..29b3bc3 |
1772 | Binary files /dev/null and b/tests/data/bad-data/maxminddb-golang/unexpected-bytes.mmdb differ |
1773 | diff --git a/tests/data/bad-data/maxminddb-python/bad-unicode-in-map-key.mmdb b/tests/data/bad-data/maxminddb-python/bad-unicode-in-map-key.mmdb |
1774 | new file mode 100644 |
1775 | index 0000000..37cec83 |
1776 | Binary files /dev/null and b/tests/data/bad-data/maxminddb-python/bad-unicode-in-map-key.mmdb differ |
1777 | diff --git a/tests/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb b/tests/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb |
1778 | index f1e7e6c..e051118 100644 |
1779 | Binary files a/tests/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb and b/tests/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb differ |
1780 | diff --git a/tests/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb b/tests/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb |
1781 | index 317bb43..a6519b8 100644 |
1782 | Binary files a/tests/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb and b/tests/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb differ |
1783 | diff --git a/tests/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb b/tests/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb |
1784 | index 09973d3..e245431 100644 |
1785 | Binary files a/tests/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb and b/tests/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb differ |
1786 | diff --git a/tests/data/test-data/GeoIP2-City-Test.mmdb b/tests/data/test-data/GeoIP2-City-Test.mmdb |
1787 | index 85f4540..993d89c 100644 |
1788 | Binary files a/tests/data/test-data/GeoIP2-City-Test.mmdb and b/tests/data/test-data/GeoIP2-City-Test.mmdb differ |
1789 | diff --git a/tests/data/test-data/GeoIP2-Connection-Type-Test.mmdb b/tests/data/test-data/GeoIP2-Connection-Type-Test.mmdb |
1790 | index 8b22aef..7601a6f 100644 |
1791 | Binary files a/tests/data/test-data/GeoIP2-Connection-Type-Test.mmdb and b/tests/data/test-data/GeoIP2-Connection-Type-Test.mmdb differ |
1792 | diff --git a/tests/data/test-data/GeoIP2-Country-Test.mmdb b/tests/data/test-data/GeoIP2-Country-Test.mmdb |
1793 | index 2b3bdbf..5624cb1 100644 |
1794 | Binary files a/tests/data/test-data/GeoIP2-Country-Test.mmdb and b/tests/data/test-data/GeoIP2-Country-Test.mmdb differ |
1795 | diff --git a/tests/data/test-data/GeoIP2-DensityIncome-Test.mmdb b/tests/data/test-data/GeoIP2-DensityIncome-Test.mmdb |
1796 | index f474846..caf2996 100644 |
1797 | Binary files a/tests/data/test-data/GeoIP2-DensityIncome-Test.mmdb and b/tests/data/test-data/GeoIP2-DensityIncome-Test.mmdb differ |
1798 | diff --git a/tests/data/test-data/GeoIP2-Domain-Test.mmdb b/tests/data/test-data/GeoIP2-Domain-Test.mmdb |
1799 | index 9504984..89532cb 100644 |
1800 | Binary files a/tests/data/test-data/GeoIP2-Domain-Test.mmdb and b/tests/data/test-data/GeoIP2-Domain-Test.mmdb differ |
1801 | diff --git a/tests/data/test-data/GeoIP2-Enterprise-Test.mmdb b/tests/data/test-data/GeoIP2-Enterprise-Test.mmdb |
1802 | index 71f28a1..e8ea1e1 100644 |
1803 | Binary files a/tests/data/test-data/GeoIP2-Enterprise-Test.mmdb and b/tests/data/test-data/GeoIP2-Enterprise-Test.mmdb differ |
1804 | diff --git a/tests/data/test-data/GeoIP2-ISP-Test.mmdb b/tests/data/test-data/GeoIP2-ISP-Test.mmdb |
1805 | index 1ec5070..6f2d714 100644 |
1806 | Binary files a/tests/data/test-data/GeoIP2-ISP-Test.mmdb and b/tests/data/test-data/GeoIP2-ISP-Test.mmdb differ |
1807 | diff --git a/tests/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb b/tests/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb |
1808 | index 6fd5391..a7b8da7 100644 |
1809 | Binary files a/tests/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb and b/tests/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb differ |
1810 | diff --git a/tests/data/test-data/GeoIP2-Static-IP-Score-Test.mmdb b/tests/data/test-data/GeoIP2-Static-IP-Score-Test.mmdb |
1811 | new file mode 100644 |
1812 | index 0000000..cf7d26f |
1813 | Binary files /dev/null and b/tests/data/test-data/GeoIP2-Static-IP-Score-Test.mmdb differ |
1814 | diff --git a/tests/data/test-data/GeoIP2-User-Count-Test.mmdb b/tests/data/test-data/GeoIP2-User-Count-Test.mmdb |
1815 | index fe751d2..0b19ae8 100644 |
1816 | Binary files a/tests/data/test-data/GeoIP2-User-Count-Test.mmdb and b/tests/data/test-data/GeoIP2-User-Count-Test.mmdb differ |
1817 | diff --git a/tests/data/test-data/GeoLite2-ASN-Test.mmdb b/tests/data/test-data/GeoLite2-ASN-Test.mmdb |
1818 | index 6867459..bbf6bf2 100644 |
1819 | Binary files a/tests/data/test-data/GeoLite2-ASN-Test.mmdb and b/tests/data/test-data/GeoLite2-ASN-Test.mmdb differ |
1820 | diff --git a/tests/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb b/tests/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb |
1821 | index 5b38bfa..7310a54 100644 |
1822 | Binary files a/tests/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb and b/tests/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb differ |
1823 | diff --git a/tests/data/test-data/MaxMind-DB-string-value-entries.mmdb b/tests/data/test-data/MaxMind-DB-string-value-entries.mmdb |
1824 | index 725ed14..6454f17 100644 |
1825 | Binary files a/tests/data/test-data/MaxMind-DB-string-value-entries.mmdb and b/tests/data/test-data/MaxMind-DB-string-value-entries.mmdb differ |
1826 | diff --git a/tests/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb b/tests/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb |
1827 | index 45124c3..7c36926 100644 |
1828 | Binary files a/tests/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb and b/tests/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb differ |
1829 | diff --git a/tests/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb b/tests/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb |
1830 | index df69bcb..b35e91b 100644 |
1831 | Binary files a/tests/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb and b/tests/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb differ |
1832 | diff --git a/tests/data/test-data/MaxMind-DB-test-decoder.mmdb b/tests/data/test-data/MaxMind-DB-test-decoder.mmdb |
1833 | index 5a4a155..64a147f 100644 |
1834 | Binary files a/tests/data/test-data/MaxMind-DB-test-decoder.mmdb and b/tests/data/test-data/MaxMind-DB-test-decoder.mmdb differ |
1835 | diff --git a/tests/data/test-data/MaxMind-DB-test-ipv4-24.mmdb b/tests/data/test-data/MaxMind-DB-test-ipv4-24.mmdb |
1836 | index 2decb0d..d33ba90 100644 |
1837 | Binary files a/tests/data/test-data/MaxMind-DB-test-ipv4-24.mmdb and b/tests/data/test-data/MaxMind-DB-test-ipv4-24.mmdb differ |
1838 | diff --git a/tests/data/test-data/MaxMind-DB-test-ipv4-28.mmdb b/tests/data/test-data/MaxMind-DB-test-ipv4-28.mmdb |
1839 | index ac9870b..0a3c8b9 100644 |
1840 | Binary files a/tests/data/test-data/MaxMind-DB-test-ipv4-28.mmdb and b/tests/data/test-data/MaxMind-DB-test-ipv4-28.mmdb differ |
1841 | diff --git a/tests/data/test-data/MaxMind-DB-test-ipv4-32.mmdb b/tests/data/test-data/MaxMind-DB-test-ipv4-32.mmdb |
1842 | index 1352aec..1c328ba 100644 |
1843 | Binary files a/tests/data/test-data/MaxMind-DB-test-ipv4-32.mmdb and b/tests/data/test-data/MaxMind-DB-test-ipv4-32.mmdb differ |
1844 | diff --git a/tests/data/test-data/MaxMind-DB-test-ipv6-24.mmdb b/tests/data/test-data/MaxMind-DB-test-ipv6-24.mmdb |
1845 | index 73cec25..6530c41 100644 |
1846 | Binary files a/tests/data/test-data/MaxMind-DB-test-ipv6-24.mmdb and b/tests/data/test-data/MaxMind-DB-test-ipv6-24.mmdb differ |
1847 | diff --git a/tests/data/test-data/MaxMind-DB-test-ipv6-28.mmdb b/tests/data/test-data/MaxMind-DB-test-ipv6-28.mmdb |
1848 | index 5a9d19e..1ea130b 100644 |
1849 | Binary files a/tests/data/test-data/MaxMind-DB-test-ipv6-28.mmdb and b/tests/data/test-data/MaxMind-DB-test-ipv6-28.mmdb differ |
1850 | diff --git a/tests/data/test-data/MaxMind-DB-test-ipv6-32.mmdb b/tests/data/test-data/MaxMind-DB-test-ipv6-32.mmdb |
1851 | index 86ce484..2da6950 100644 |
1852 | Binary files a/tests/data/test-data/MaxMind-DB-test-ipv6-32.mmdb and b/tests/data/test-data/MaxMind-DB-test-ipv6-32.mmdb differ |
1853 | diff --git a/tests/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb b/tests/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb |
1854 | index f38e14a..9602af8 100644 |
1855 | Binary files a/tests/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb and b/tests/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb differ |
1856 | diff --git a/tests/data/test-data/MaxMind-DB-test-mixed-24.mmdb b/tests/data/test-data/MaxMind-DB-test-mixed-24.mmdb |
1857 | index 17a8f25..868fcd2 100644 |
1858 | Binary files a/tests/data/test-data/MaxMind-DB-test-mixed-24.mmdb and b/tests/data/test-data/MaxMind-DB-test-mixed-24.mmdb differ |
1859 | diff --git a/tests/data/test-data/MaxMind-DB-test-mixed-28.mmdb b/tests/data/test-data/MaxMind-DB-test-mixed-28.mmdb |
1860 | index 0ab56de..3901eec 100644 |
1861 | Binary files a/tests/data/test-data/MaxMind-DB-test-mixed-28.mmdb and b/tests/data/test-data/MaxMind-DB-test-mixed-28.mmdb differ |
1862 | diff --git a/tests/data/test-data/MaxMind-DB-test-mixed-32.mmdb b/tests/data/test-data/MaxMind-DB-test-mixed-32.mmdb |
1863 | index b4a43e6..5cc031a 100644 |
1864 | Binary files a/tests/data/test-data/MaxMind-DB-test-mixed-32.mmdb and b/tests/data/test-data/MaxMind-DB-test-mixed-32.mmdb differ |
1865 | diff --git a/tests/data/test-data/MaxMind-DB-test-nested.mmdb b/tests/data/test-data/MaxMind-DB-test-nested.mmdb |
1866 | index 7fc3d6d..629b2e5 100644 |
1867 | Binary files a/tests/data/test-data/MaxMind-DB-test-nested.mmdb and b/tests/data/test-data/MaxMind-DB-test-nested.mmdb differ |
1868 | diff --git a/tests/decoder_test.py b/tests/decoder_test.py |
1869 | index 3c9dbe3..6cb695d 100644 |
1870 | --- a/tests/decoder_test.py |
1871 | +++ b/tests/decoder_test.py |
1872 | @@ -19,18 +19,18 @@ if sys.version_info[0] == 2: |
1873 | class TestDecoder(unittest.TestCase): |
1874 | def test_arrays(self): |
1875 | arrays = { |
1876 | - b'\x00\x04': [], |
1877 | - b'\x01\x04\x43\x46\x6f\x6f': ['Foo'], |
1878 | - b'\x02\x04\x43\x46\x6f\x6f\x43\xe4\xba\xba': ['Foo', '人'], |
1879 | + b"\x00\x04": [], |
1880 | + b"\x01\x04\x43\x46\x6f\x6f": ["Foo"], |
1881 | + b"\x02\x04\x43\x46\x6f\x6f\x43\xe4\xba\xba": ["Foo", "人"], |
1882 | } |
1883 | - self.validate_type_decoding('arrays', arrays) |
1884 | + self.validate_type_decoding("arrays", arrays) |
1885 | |
1886 | def test_boolean(self): |
1887 | booleans = { |
1888 | b"\x00\x07": False, |
1889 | b"\x01\x07": True, |
1890 | } |
1891 | - self.validate_type_decoding('booleans', booleans) |
1892 | + self.validate_type_decoding("booleans", booleans) |
1893 | |
1894 | def test_double(self): |
1895 | doubles = { |
1896 | @@ -43,7 +43,7 @@ class TestDecoder(unittest.TestCase): |
1897 | b"\x68\xC0\x09\x21\xFB\x54\x44\x2E\xEA": -3.14159265359, |
1898 | b"\x68\xC1\xD0\x00\x00\x00\x07\xF8\xF4": -1073741824.12457, |
1899 | } |
1900 | - self.validate_type_decoding('double', doubles) |
1901 | + self.validate_type_decoding("double", doubles) |
1902 | |
1903 | def test_float(self): |
1904 | floats = { |
1905 | @@ -55,9 +55,9 @@ class TestDecoder(unittest.TestCase): |
1906 | b"\x04\x08\xBF\x80\x00\x00": -1.0, |
1907 | b"\x04\x08\xBF\x8C\xCC\xCD": -1.1, |
1908 | b"\x04\x08\xC0\x48\xF5\xC3": -3.14, |
1909 | - b"\x04\x08\xC6\x1C\x3F\xF6": -9999.99 |
1910 | + b"\x04\x08\xC6\x1C\x3F\xF6": -9999.99, |
1911 | } |
1912 | - self.validate_type_decoding('float', floats) |
1913 | + self.validate_type_decoding("float", floats) |
1914 | |
1915 | def test_int32(self): |
1916 | int32 = { |
1917 | @@ -74,90 +74,85 @@ class TestDecoder(unittest.TestCase): |
1918 | b"\x04\x01\x7f\xff\xff\xff": 2147483647, |
1919 | b"\x04\x01\x80\x00\x00\x01": -2147483647, |
1920 | } |
1921 | - self.validate_type_decoding('int32', int32) |
1922 | + self.validate_type_decoding("int32", int32) |
1923 | |
1924 | def test_map(self): |
1925 | maps = { |
1926 | - b'\xe0': {}, |
1927 | - b'\xe1\x42\x65\x6e\x43\x46\x6f\x6f': { |
1928 | - 'en': 'Foo' |
1929 | - }, |
1930 | - b'\xe2\x42\x65\x6e\x43\x46\x6f\x6f\x42\x7a\x68\x43\xe4\xba\xba': { |
1931 | - 'en': 'Foo', |
1932 | - 'zh': '人' |
1933 | - }, |
1934 | - (b'\xe1\x44\x6e\x61\x6d\x65\xe2\x42\x65\x6e' |
1935 | - b'\x43\x46\x6f\x6f\x42\x7a\x68\x43\xe4\xba\xba'): { |
1936 | - 'name': { |
1937 | - 'en': 'Foo', |
1938 | - 'zh': '人' |
1939 | - } |
1940 | - }, |
1941 | - (b'\xe1\x49\x6c\x61\x6e\x67\x75\x61\x67\x65\x73' |
1942 | - b'\x02\x04\x42\x65\x6e\x42\x7a\x68'): { |
1943 | - 'languages': ['en', 'zh'] |
1944 | + b"\xe0": {}, |
1945 | + b"\xe1\x42\x65\x6e\x43\x46\x6f\x6f": {"en": "Foo"}, |
1946 | + b"\xe2\x42\x65\x6e\x43\x46\x6f\x6f\x42\x7a\x68\x43\xe4\xba\xba": { |
1947 | + "en": "Foo", |
1948 | + "zh": "人", |
1949 | }, |
1950 | + ( |
1951 | + b"\xe1\x44\x6e\x61\x6d\x65\xe2\x42\x65\x6e" |
1952 | + b"\x43\x46\x6f\x6f\x42\x7a\x68\x43\xe4\xba\xba" |
1953 | + ): {"name": {"en": "Foo", "zh": "人"}}, |
1954 | + ( |
1955 | + b"\xe1\x49\x6c\x61\x6e\x67\x75\x61\x67\x65\x73" |
1956 | + b"\x02\x04\x42\x65\x6e\x42\x7a\x68" |
1957 | + ): {"languages": ["en", "zh"]}, |
1958 | } |
1959 | - self.validate_type_decoding('maps', maps) |
1960 | + self.validate_type_decoding("maps", maps) |
1961 | |
1962 | def test_pointer(self): |
1963 | pointers = { |
1964 | - b'\x20\x00': 0, |
1965 | - b'\x20\x05': 5, |
1966 | - b'\x20\x0a': 10, |
1967 | - b'\x23\xff': 1023, |
1968 | - b'\x28\x03\xc9': 3017, |
1969 | - b'\x2f\xf7\xfb': 524283, |
1970 | - b'\x2f\xff\xff': 526335, |
1971 | - b'\x37\xf7\xf7\xfe': 134217726, |
1972 | - b'\x37\xff\xff\xff': 134744063, |
1973 | - b'\x38\x7f\xff\xff\xff': 2147483647, |
1974 | - b'\x38\xff\xff\xff\xff': 4294967295, |
1975 | + b"\x20\x00": 0, |
1976 | + b"\x20\x05": 5, |
1977 | + b"\x20\x0a": 10, |
1978 | + b"\x23\xff": 1023, |
1979 | + b"\x28\x03\xc9": 3017, |
1980 | + b"\x2f\xf7\xfb": 524283, |
1981 | + b"\x2f\xff\xff": 526335, |
1982 | + b"\x37\xf7\xf7\xfe": 134217726, |
1983 | + b"\x37\xff\xff\xff": 134744063, |
1984 | + b"\x38\x7f\xff\xff\xff": 2147483647, |
1985 | + b"\x38\xff\xff\xff\xff": 4294967295, |
1986 | } |
1987 | - self.validate_type_decoding('pointers', pointers) |
1988 | + self.validate_type_decoding("pointers", pointers) |
1989 | |
1990 | strings = { |
1991 | - b"\x40": |
1992 | - '', |
1993 | - b"\x41\x31": |
1994 | - '1', |
1995 | - b"\x43\xE4\xBA\xBA": |
1996 | - '人', |
1997 | - (b"\x5b\x31\x32\x33\x34" |
1998 | - b"\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35" |
1999 | - b"\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37"): |
2000 | - '123456789012345678901234567', |
2001 | - (b"\x5c\x31\x32\x33\x34" |
2002 | - b"\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35" |
2003 | - b"\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36" |
2004 | - b"\x37\x38"): |
2005 | - '1234567890123456789012345678', |
2006 | - (b"\x5d\x00\x31\x32\x33" |
2007 | - b"\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34" |
2008 | - b"\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35" |
2009 | - b"\x36\x37\x38\x39"): |
2010 | - '12345678901234567890123456789', |
2011 | - (b"\x5d\x01\x31\x32\x33" |
2012 | - b"\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34" |
2013 | - b"\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35" |
2014 | - b"\x36\x37\x38\x39\x30"): |
2015 | - '123456789012345678901234567890', |
2016 | - b'\x5e\x00\xd7' + 500 * b'\x78': |
2017 | - 'x' * 500, |
2018 | - b'\x5e\x06\xb3' + 2000 * b'\x78': |
2019 | - 'x' * 2000, |
2020 | - b'\x5f\x00\x10\x53' + 70000 * b'\x78': |
2021 | - 'x' * 70000, |
2022 | + b"\x40": "", |
2023 | + b"\x41\x31": "1", |
2024 | + b"\x43\xE4\xBA\xBA": "人", |
2025 | + ( |
2026 | + b"\x5b\x31\x32\x33\x34" |
2027 | + b"\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35" |
2028 | + b"\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36\x37" |
2029 | + ): "123456789012345678901234567", |
2030 | + ( |
2031 | + b"\x5c\x31\x32\x33\x34" |
2032 | + b"\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35" |
2033 | + b"\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35\x36" |
2034 | + b"\x37\x38" |
2035 | + ): "1234567890123456789012345678", |
2036 | + ( |
2037 | + b"\x5d\x00\x31\x32\x33" |
2038 | + b"\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34" |
2039 | + b"\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35" |
2040 | + b"\x36\x37\x38\x39" |
2041 | + ): "12345678901234567890123456789", |
2042 | + ( |
2043 | + b"\x5d\x01\x31\x32\x33" |
2044 | + b"\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34" |
2045 | + b"\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35" |
2046 | + b"\x36\x37\x38\x39\x30" |
2047 | + ): "123456789012345678901234567890", |
2048 | + b"\x5e\x00\xd7" + 500 * b"\x78": "x" * 500, |
2049 | + b"\x5e\x06\xb3" + 2000 * b"\x78": "x" * 2000, |
2050 | + b"\x5f\x00\x10\x53" + 70000 * b"\x78": "x" * 70000, |
2051 | } |
2052 | |
2053 | def test_string(self): |
2054 | - self.validate_type_decoding('string', self.strings) |
2055 | + self.validate_type_decoding("string", self.strings) |
2056 | |
2057 | def test_byte(self): |
2058 | # Python 2.6 doesn't support dictionary comprehension |
2059 | - b = dict((byte_from_int(0xc0 ^ int_from_byte(k[0])) + k[1:], |
2060 | - v.encode('utf-8')) for k, v in self.strings.items()) |
2061 | - self.validate_type_decoding('byte', b) |
2062 | + b = dict( |
2063 | + (byte_from_int(0xC0 ^ int_from_byte(k[0])) + k[1:], v.encode("utf-8")) |
2064 | + for k, v in self.strings.items() |
2065 | + ) |
2066 | + self.validate_type_decoding("byte", b) |
2067 | |
2068 | def test_uint16(self): |
2069 | uint16 = { |
2070 | @@ -167,7 +162,7 @@ class TestDecoder(unittest.TestCase): |
2071 | b"\xa2\x2a\x78": 10872, |
2072 | b"\xa2\xff\xff": 65535, |
2073 | } |
2074 | - self.validate_type_decoding('uint16', uint16) |
2075 | + self.validate_type_decoding("uint16", uint16) |
2076 | |
2077 | def test_uint32(self): |
2078 | uint32 = { |
2079 | @@ -179,26 +174,26 @@ class TestDecoder(unittest.TestCase): |
2080 | b"\xc3\xff\xff\xff": 16777215, |
2081 | b"\xc4\xff\xff\xff\xff": 4294967295, |
2082 | } |
2083 | - self.validate_type_decoding('uint32', uint32) |
2084 | + self.validate_type_decoding("uint32", uint32) |
2085 | |
2086 | def generate_large_uint(self, bits): |
2087 | - ctrl_byte = b'\x02' if bits == 64 else b'\x03' |
2088 | + ctrl_byte = b"\x02" if bits == 64 else b"\x03" |
2089 | uints = { |
2090 | - b'\x00' + ctrl_byte: 0, |
2091 | - b'\x02' + ctrl_byte + b'\x01\xf4': 500, |
2092 | - b'\x02' + ctrl_byte + b'\x2a\x78': 10872, |
2093 | + b"\x00" + ctrl_byte: 0, |
2094 | + b"\x02" + ctrl_byte + b"\x01\xf4": 500, |
2095 | + b"\x02" + ctrl_byte + b"\x2a\x78": 10872, |
2096 | } |
2097 | for power in range(bits // 8 + 1): |
2098 | - expected = 2**(8 * power) - 1 |
2099 | - input = byte_from_int(power) + ctrl_byte + (b'\xff' * power) |
2100 | + expected = 2 ** (8 * power) - 1 |
2101 | + input = byte_from_int(power) + ctrl_byte + (b"\xff" * power) |
2102 | uints[input] = expected |
2103 | return uints |
2104 | |
2105 | def test_uint64(self): |
2106 | - self.validate_type_decoding('uint64', self.generate_large_uint(64)) |
2107 | + self.validate_type_decoding("uint64", self.generate_large_uint(64)) |
2108 | |
2109 | def test_uint128(self): |
2110 | - self.validate_type_decoding('uint128', self.generate_large_uint(128)) |
2111 | + self.validate_type_decoding("uint128", self.generate_large_uint(128)) |
2112 | |
2113 | def validate_type_decoding(self, type, tests): |
2114 | for input, expected in tests.items(): |
2115 | @@ -211,44 +206,28 @@ class TestDecoder(unittest.TestCase): |
2116 | db.write(input) |
2117 | |
2118 | decoder = Decoder(db, pointer_test=True) |
2119 | - ( |
2120 | - actual, |
2121 | - _, |
2122 | - ) = decoder.decode(0) |
2123 | + (actual, _,) = decoder.decode(0) |
2124 | |
2125 | - if type in ('float', 'double'): |
2126 | + if type in ("float", "double"): |
2127 | self.assertAlmostEqual(expected, actual, places=3, msg=type) |
2128 | else: |
2129 | self.assertEqual(expected, actual, type) |
2130 | |
2131 | def test_real_pointers(self): |
2132 | - with open('tests/data/test-data/maps-with-pointers.raw', |
2133 | - 'r+b') as db_file: |
2134 | + with open("tests/data/test-data/maps-with-pointers.raw", "r+b") as db_file: |
2135 | mm = mmap.mmap(db_file.fileno(), 0) |
2136 | decoder = Decoder(mm, 0) |
2137 | |
2138 | - self.assertEqual(({ |
2139 | - 'long_key': 'long_value1' |
2140 | - }, 22), decoder.decode(0)) |
2141 | + self.assertEqual(({"long_key": "long_value1"}, 22), decoder.decode(0)) |
2142 | |
2143 | - self.assertEqual(({ |
2144 | - 'long_key': 'long_value2' |
2145 | - }, 37), decoder.decode(22)) |
2146 | + self.assertEqual(({"long_key": "long_value2"}, 37), decoder.decode(22)) |
2147 | |
2148 | - self.assertEqual(({ |
2149 | - 'long_key2': 'long_value1' |
2150 | - }, 50), decoder.decode(37)) |
2151 | + self.assertEqual(({"long_key2": "long_value1"}, 50), decoder.decode(37)) |
2152 | |
2153 | - self.assertEqual(({ |
2154 | - 'long_key2': 'long_value2' |
2155 | - }, 55), decoder.decode(50)) |
2156 | + self.assertEqual(({"long_key2": "long_value2"}, 55), decoder.decode(50)) |
2157 | |
2158 | - self.assertEqual(({ |
2159 | - 'long_key': 'long_value1' |
2160 | - }, 57), decoder.decode(55)) |
2161 | + self.assertEqual(({"long_key": "long_value1"}, 57), decoder.decode(55)) |
2162 | |
2163 | - self.assertEqual(({ |
2164 | - 'long_key2': 'long_value2' |
2165 | - }, 59), decoder.decode(57)) |
2166 | + self.assertEqual(({"long_key2": "long_value2"}, 59), decoder.decode(57)) |
2167 | |
2168 | mm.close() |
2169 | diff --git a/tests/reader_test.py b/tests/reader_test.py |
2170 | index e2b4fc7..8510bd0 100644 |
2171 | --- a/tests/reader_test.py |
2172 | +++ b/tests/reader_test.py |
2173 | @@ -20,8 +20,14 @@ except ImportError: |
2174 | |
2175 | from maxminddb import open_database, InvalidDatabaseError |
2176 | from maxminddb.compat import FileNotFoundError |
2177 | -from maxminddb.const import (MODE_AUTO, MODE_MMAP_EXT, MODE_MMAP, MODE_FILE, |
2178 | - MODE_MEMORY, MODE_FD) |
2179 | +from maxminddb.const import ( |
2180 | + MODE_AUTO, |
2181 | + MODE_MMAP_EXT, |
2182 | + MODE_MMAP, |
2183 | + MODE_FILE, |
2184 | + MODE_MEMORY, |
2185 | + MODE_FD, |
2186 | +) |
2187 | |
2188 | if sys.version_info[:2] == (2, 6): |
2189 | import unittest2 as unittest |
2190 | @@ -36,7 +42,7 @@ if sys.version_info[0] == 2: |
2191 | def get_reader_from_file_descriptor(filepath, mode): |
2192 | """Patches open_database() for class TestFDReader().""" |
2193 | if mode == MODE_FD: |
2194 | - with open(filepath, 'rb') as mmdb_fh: |
2195 | + with open(filepath, "rb") as mmdb_fh: |
2196 | return maxminddb.open_database(mmdb_fh, mode) |
2197 | else: |
2198 | # There are a few cases where mode is statically defined in |
2199 | @@ -56,9 +62,13 @@ class BaseTestReader(object): |
2200 | def test_reader(self): |
2201 | for record_size in [24, 28, 32]: |
2202 | for ip_version in [4, 6]: |
2203 | - file_name = ('tests/data/test-data/MaxMind-DB-test-ipv' + |
2204 | - str(ip_version) + '-' + str(record_size) + |
2205 | - '.mmdb') |
2206 | + file_name = ( |
2207 | + "tests/data/test-data/MaxMind-DB-test-ipv" |
2208 | + + str(ip_version) |
2209 | + + "-" |
2210 | + + str(record_size) |
2211 | + + ".mmdb" |
2212 | + ) |
2213 | reader = open_database(file_name, self.mode) |
2214 | |
2215 | self._check_metadata(reader, ip_version, record_size) |
2216 | @@ -73,16 +83,11 @@ class BaseTestReader(object): |
2217 | decoder_record = { |
2218 | "array": [1, 2, 3], |
2219 | "boolean": True, |
2220 | - "bytes": b'\x00\x00\x00*', |
2221 | + "bytes": b"\x00\x00\x00*", |
2222 | "double": 42.123456, |
2223 | "float": 1.100000023841858, |
2224 | "int32": -268435456, |
2225 | - "map": { |
2226 | - "mapX": { |
2227 | - "arrayX": [7, 8, 9], |
2228 | - "utf8_stringX": "hello", |
2229 | - }, |
2230 | - }, |
2231 | + "map": {"mapX": {"arrayX": [7, 8, 9], "utf8_stringX": "hello",},}, |
2232 | "uint128": 1329227995784915872903807060280344576, |
2233 | "uint16": 0x64, |
2234 | "uint32": 0x10000000, |
2235 | @@ -90,278 +95,313 @@ class BaseTestReader(object): |
2236 | "utf8_string": "unicode! ☯ - ♫", |
2237 | } |
2238 | |
2239 | - tests = [{ |
2240 | - 'ip': '1.1.1.1', |
2241 | - 'file_name': 'MaxMind-DB-test-ipv6-32.mmdb', |
2242 | - 'expected_prefix_len': 8, |
2243 | - 'expected_record': None, |
2244 | - }, { |
2245 | - 'ip': '::1:ffff:ffff', |
2246 | - 'file_name': 'MaxMind-DB-test-ipv6-24.mmdb', |
2247 | - 'expected_prefix_len': 128, |
2248 | - 'expected_record': { |
2249 | - "ip": "::1:ffff:ffff" |
2250 | + tests = [ |
2251 | + { |
2252 | + "ip": "1.1.1.1", |
2253 | + "file_name": "MaxMind-DB-test-ipv6-32.mmdb", |
2254 | + "expected_prefix_len": 8, |
2255 | + "expected_record": None, |
2256 | + }, |
2257 | + { |
2258 | + "ip": "::1:ffff:ffff", |
2259 | + "file_name": "MaxMind-DB-test-ipv6-24.mmdb", |
2260 | + "expected_prefix_len": 128, |
2261 | + "expected_record": {"ip": "::1:ffff:ffff"}, |
2262 | + }, |
2263 | + { |
2264 | + "ip": "::2:0:1", |
2265 | + "file_name": "MaxMind-DB-test-ipv6-24.mmdb", |
2266 | + "expected_prefix_len": 122, |
2267 | + "expected_record": {"ip": "::2:0:0"}, |
2268 | + }, |
2269 | + { |
2270 | + "ip": "1.1.1.1", |
2271 | + "file_name": "MaxMind-DB-test-ipv4-24.mmdb", |
2272 | + "expected_prefix_len": 32, |
2273 | + "expected_record": {"ip": "1.1.1.1"}, |
2274 | + }, |
2275 | + { |
2276 | + "ip": "1.1.1.3", |
2277 | + "file_name": "MaxMind-DB-test-ipv4-24.mmdb", |
2278 | + "expected_prefix_len": 31, |
2279 | + "expected_record": {"ip": "1.1.1.2"}, |
2280 | + }, |
2281 | + { |
2282 | + "ip": "1.1.1.3", |
2283 | + "file_name": "MaxMind-DB-test-decoder.mmdb", |
2284 | + "expected_prefix_len": 24, |
2285 | + "expected_record": decoder_record, |
2286 | + }, |
2287 | + { |
2288 | + "ip": "::ffff:1.1.1.128", |
2289 | + "file_name": "MaxMind-DB-test-decoder.mmdb", |
2290 | + "expected_prefix_len": 120, |
2291 | + "expected_record": decoder_record, |
2292 | }, |
2293 | - }, { |
2294 | - 'ip': '::2:0:1', |
2295 | - 'file_name': 'MaxMind-DB-test-ipv6-24.mmdb', |
2296 | - 'expected_prefix_len': 122, |
2297 | - 'expected_record': { |
2298 | - "ip": "::2:0:0" |
2299 | + { |
2300 | + "ip": "::1.1.1.128", |
2301 | + "file_name": "MaxMind-DB-test-decoder.mmdb", |
2302 | + "expected_prefix_len": 120, |
2303 | + "expected_record": decoder_record, |
2304 | }, |
2305 | - }, { |
2306 | - 'ip': '1.1.1.1', |
2307 | - 'file_name': 'MaxMind-DB-test-ipv4-24.mmdb', |
2308 | - 'expected_prefix_len': 32, |
2309 | - 'expected_record': { |
2310 | - "ip": "1.1.1.1" |
2311 | + { |
2312 | + "ip": "200.0.2.1", |
2313 | + "file_name": "MaxMind-DB-no-ipv4-search-tree.mmdb", |
2314 | + "expected_prefix_len": 0, |
2315 | + "expected_record": "::0/64", |
2316 | }, |
2317 | - }, { |
2318 | - 'ip': '1.1.1.3', |
2319 | - 'file_name': 'MaxMind-DB-test-ipv4-24.mmdb', |
2320 | - 'expected_prefix_len': 31, |
2321 | - 'expected_record': { |
2322 | - "ip": "1.1.1.2" |
2323 | + { |
2324 | + "ip": "::200.0.2.1", |
2325 | + "file_name": "MaxMind-DB-no-ipv4-search-tree.mmdb", |
2326 | + "expected_prefix_len": 64, |
2327 | + "expected_record": "::0/64", |
2328 | }, |
2329 | - }, { |
2330 | - 'ip': '1.1.1.3', |
2331 | - 'file_name': 'MaxMind-DB-test-decoder.mmdb', |
2332 | - 'expected_prefix_len': 24, |
2333 | - 'expected_record': decoder_record, |
2334 | - }, { |
2335 | - 'ip': '::ffff:1.1.1.128', |
2336 | - 'file_name': 'MaxMind-DB-test-decoder.mmdb', |
2337 | - 'expected_prefix_len': 120, |
2338 | - 'expected_record': decoder_record, |
2339 | - }, { |
2340 | - 'ip': '::1.1.1.128', |
2341 | - 'file_name': 'MaxMind-DB-test-decoder.mmdb', |
2342 | - 'expected_prefix_len': 120, |
2343 | - 'expected_record': decoder_record, |
2344 | - }, { |
2345 | - 'ip': '200.0.2.1', |
2346 | - 'file_name': 'MaxMind-DB-no-ipv4-search-tree.mmdb', |
2347 | - 'expected_prefix_len': 0, |
2348 | - 'expected_record': "::0/64", |
2349 | - }, { |
2350 | - 'ip': '::200.0.2.1', |
2351 | - 'file_name': 'MaxMind-DB-no-ipv4-search-tree.mmdb', |
2352 | - 'expected_prefix_len': 64, |
2353 | - 'expected_record': "::0/64", |
2354 | - }, { |
2355 | - 'ip': '0:0:0:0:ffff:ffff:ffff:ffff', |
2356 | - 'file_name': 'MaxMind-DB-no-ipv4-search-tree.mmdb', |
2357 | - 'expected_prefix_len': 64, |
2358 | - 'expected_record': "::0/64", |
2359 | - }, { |
2360 | - 'ip': 'ef00::', |
2361 | - 'file_name': 'MaxMind-DB-no-ipv4-search-tree.mmdb', |
2362 | - 'expected_prefix_len': 1, |
2363 | - 'expected_record': None, |
2364 | - }] |
2365 | + { |
2366 | + "ip": "0:0:0:0:ffff:ffff:ffff:ffff", |
2367 | + "file_name": "MaxMind-DB-no-ipv4-search-tree.mmdb", |
2368 | + "expected_prefix_len": 64, |
2369 | + "expected_record": "::0/64", |
2370 | + }, |
2371 | + { |
2372 | + "ip": "ef00::", |
2373 | + "file_name": "MaxMind-DB-no-ipv4-search-tree.mmdb", |
2374 | + "expected_prefix_len": 1, |
2375 | + "expected_record": None, |
2376 | + }, |
2377 | + ] |
2378 | |
2379 | for test in tests: |
2380 | - with open_database('tests/data/test-data/' + test['file_name'], |
2381 | - self.mode) as reader: |
2382 | - (record, prefix_len) = reader.get_with_prefix_len(test['ip']) |
2383 | + with open_database( |
2384 | + "tests/data/test-data/" + test["file_name"], self.mode |
2385 | + ) as reader: |
2386 | + (record, prefix_len) = reader.get_with_prefix_len(test["ip"]) |
2387 | |
2388 | self.assertEqual( |
2389 | - prefix_len, test['expected_prefix_len'], |
2390 | - 'expected prefix_len of {} for {} in {} but got {}'.format( |
2391 | - test['expected_prefix_len'], test['ip'], |
2392 | - test['file_name'], prefix_len)) |
2393 | + prefix_len, |
2394 | + test["expected_prefix_len"], |
2395 | + "expected prefix_len of {} for {} in {} but got {}".format( |
2396 | + test["expected_prefix_len"], |
2397 | + test["ip"], |
2398 | + test["file_name"], |
2399 | + prefix_len, |
2400 | + ), |
2401 | + ) |
2402 | self.assertEqual( |
2403 | - record, test['expected_record'], 'expected_record for ' + |
2404 | - test['ip'] + ' in ' + test['file_name']) |
2405 | + record, |
2406 | + test["expected_record"], |
2407 | + "expected_record for " + test["ip"] + " in " + test["file_name"], |
2408 | + ) |
2409 | |
2410 | def test_decoder(self): |
2411 | reader = open_database( |
2412 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode) |
2413 | - record = reader.get(self.ipf('::1.1.1.0')) |
2414 | - |
2415 | - self.assertEqual(record['array'], [1, 2, 3]) |
2416 | - self.assertEqual(record['boolean'], True) |
2417 | - self.assertEqual(record['bytes'], bytearray(b'\x00\x00\x00*')) |
2418 | - self.assertEqual(record['double'], 42.123456) |
2419 | - self.assertAlmostEqual(record['float'], 1.1) |
2420 | - self.assertEqual(record['int32'], -268435456) |
2421 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", self.mode |
2422 | + ) |
2423 | + record = reader.get(self.ipf("::1.1.1.0")) |
2424 | + |
2425 | + self.assertEqual(record["array"], [1, 2, 3]) |
2426 | + self.assertEqual(record["boolean"], True) |
2427 | + self.assertEqual(record["bytes"], bytearray(b"\x00\x00\x00*")) |
2428 | + self.assertEqual(record["double"], 42.123456) |
2429 | + self.assertAlmostEqual(record["float"], 1.1) |
2430 | + self.assertEqual(record["int32"], -268435456) |
2431 | self.assertEqual( |
2432 | - { |
2433 | - 'mapX': { |
2434 | - 'arrayX': [7, 8, 9], |
2435 | - 'utf8_stringX': 'hello' |
2436 | - }, |
2437 | - }, record['map']) |
2438 | - |
2439 | - self.assertEqual(record['uint16'], 100) |
2440 | - self.assertEqual(record['uint32'], 268435456) |
2441 | - self.assertEqual(record['uint64'], 1152921504606846976) |
2442 | - self.assertEqual(record['utf8_string'], 'unicode! ☯ - ♫') |
2443 | - |
2444 | - self.assertEqual(1329227995784915872903807060280344576, |
2445 | - record['uint128']) |
2446 | + {"mapX": {"arrayX": [7, 8, 9], "utf8_stringX": "hello"},}, record["map"] |
2447 | + ) |
2448 | + |
2449 | + self.assertEqual(record["uint16"], 100) |
2450 | + self.assertEqual(record["uint32"], 268435456) |
2451 | + self.assertEqual(record["uint64"], 1152921504606846976) |
2452 | + self.assertEqual(record["utf8_string"], "unicode! ☯ - ♫") |
2453 | + |
2454 | + self.assertEqual(1329227995784915872903807060280344576, record["uint128"]) |
2455 | reader.close() |
2456 | |
2457 | def test_no_ipv4_search_tree(self): |
2458 | reader = open_database( |
2459 | - 'tests/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb', |
2460 | - self.mode) |
2461 | + "tests/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb", self.mode |
2462 | + ) |
2463 | |
2464 | - self.assertEqual(reader.get(self.ipf('1.1.1.1')), '::0/64') |
2465 | - self.assertEqual(reader.get(self.ipf('192.1.1.1')), '::0/64') |
2466 | + self.assertEqual(reader.get(self.ipf("1.1.1.1")), "::0/64") |
2467 | + self.assertEqual(reader.get(self.ipf("192.1.1.1")), "::0/64") |
2468 | reader.close() |
2469 | |
2470 | def test_ipv6_address_in_ipv4_database(self): |
2471 | reader = open_database( |
2472 | - 'tests/data/test-data/MaxMind-DB-test-ipv4-24.mmdb', self.mode) |
2473 | + "tests/data/test-data/MaxMind-DB-test-ipv4-24.mmdb", self.mode |
2474 | + ) |
2475 | with self.assertRaisesRegex( |
2476 | - ValueError, 'Error looking up 2001::. ' |
2477 | - 'You attempted to look up an IPv6 address ' |
2478 | - 'in an IPv4-only database'): |
2479 | - reader.get(self.ipf('2001::')) |
2480 | + ValueError, |
2481 | + "Error looking up 2001::. " |
2482 | + "You attempted to look up an IPv6 address " |
2483 | + "in an IPv4-only database", |
2484 | + ): |
2485 | + reader.get(self.ipf("2001::")) |
2486 | reader.close() |
2487 | |
2488 | def test_no_extension_exception(self): |
2489 | real_extension = maxminddb.extension |
2490 | maxminddb.extension = None |
2491 | with self.assertRaisesRegex( |
2492 | - ValueError, |
2493 | - 'MODE_MMAP_EXT requires the maxminddb.extension module to be available' |
2494 | + ValueError, |
2495 | + "MODE_MMAP_EXT requires the maxminddb.extension module to be available", |
2496 | ): |
2497 | - open_database('tests/data/test-data/MaxMind-DB-test-decoder.mmdb', |
2498 | - MODE_MMAP_EXT) |
2499 | + open_database( |
2500 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", MODE_MMAP_EXT |
2501 | + ) |
2502 | maxminddb.extension = real_extension |
2503 | |
2504 | def test_broken_database(self): |
2505 | reader = open_database( |
2506 | - 'tests/data/test-data/' |
2507 | - 'GeoIP2-City-Test-Broken-Double-Format.mmdb', self.mode) |
2508 | + "tests/data/test-data/" "GeoIP2-City-Test-Broken-Double-Format.mmdb", |
2509 | + self.mode, |
2510 | + ) |
2511 | with self.assertRaisesRegex( |
2512 | - InvalidDatabaseError, r"The MaxMind DB file's data " |
2513 | - r"section contains bad data \(unknown data " |
2514 | - r"type or corrupt data\)"): |
2515 | - reader.get(self.ipf('2001:220::')) |
2516 | + InvalidDatabaseError, |
2517 | + r"The MaxMind DB file's data " |
2518 | + r"section contains bad data \(unknown data " |
2519 | + r"type or corrupt data\)", |
2520 | + ): |
2521 | + reader.get(self.ipf("2001:220::")) |
2522 | reader.close() |
2523 | |
2524 | def test_ip_validation(self): |
2525 | reader = open_database( |
2526 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode) |
2527 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", self.mode |
2528 | + ) |
2529 | with self.assertRaisesRegex( |
2530 | - ValueError, "'not_ip' does not appear to be an IPv4 or " |
2531 | - "IPv6 address"): |
2532 | - reader.get('not_ip') |
2533 | + ValueError, "'not_ip' does not appear to be an IPv4 or " "IPv6 address" |
2534 | + ): |
2535 | + reader.get("not_ip") |
2536 | reader.close() |
2537 | |
2538 | def test_missing_database(self): |
2539 | - with self.assertRaisesRegex(FileNotFoundError, |
2540 | - "No such file or directory"): |
2541 | - open_database('file-does-not-exist.mmdb', self.mode) |
2542 | + with self.assertRaisesRegex(FileNotFoundError, "No such file or directory"): |
2543 | + open_database("file-does-not-exist.mmdb", self.mode) |
2544 | |
2545 | def test_nondatabase(self): |
2546 | with self.assertRaisesRegex( |
2547 | - InvalidDatabaseError, |
2548 | - r'Error opening database file \(README.rst\). ' |
2549 | - r'Is this a valid MaxMind DB file\?'): |
2550 | - open_database('README.rst', self.mode) |
2551 | + InvalidDatabaseError, |
2552 | + r"Error opening database file \(README.rst\). " |
2553 | + r"Is this a valid MaxMind DB file\?", |
2554 | + ): |
2555 | + open_database("README.rst", self.mode) |
2556 | + |
2557 | + # This is from https://github.com/maxmind/MaxMind-DB-Reader-python/issues/58 |
2558 | + def test_database_with_invalid_utf8_key(self): |
2559 | + reader = open_database( |
2560 | + "tests/data/bad-data/maxminddb-python/bad-unicode-in-map-key.mmdb", |
2561 | + self.mode, |
2562 | + ) |
2563 | + with self.assertRaises(UnicodeDecodeError): |
2564 | + reader.get_with_prefix_len("163.254.149.39") |
2565 | |
2566 | def test_too_many_constructor_args(self): |
2567 | with self.assertRaises(TypeError): |
2568 | - self.readerClass[0]('README.md', self.mode, 1) |
2569 | + self.readerClass[0]("README.md", self.mode, 1) |
2570 | |
2571 | def test_bad_constructor_mode(self): |
2572 | - with self.assertRaisesRegex(ValueError, |
2573 | - r'Unsupported open mode \(100\)'): |
2574 | - self.readerClass[0]('README.md', mode=100) |
2575 | + with self.assertRaisesRegex(ValueError, r"Unsupported open mode \(100\)"): |
2576 | + self.readerClass[0]("README.md", mode=100) |
2577 | |
2578 | def test_no_constructor_args(self): |
2579 | with self.assertRaisesRegex( |
2580 | - TypeError, r' 1 required positional argument|' |
2581 | - r'\(pos 1\) not found|' |
2582 | - r'takes at least 2 arguments|' |
2583 | - r'function missing required argument \'database\' \(pos 1\)'): |
2584 | + TypeError, |
2585 | + r" 1 required positional argument|" |
2586 | + r"\(pos 1\) not found|" |
2587 | + r"takes at least 2 arguments|" |
2588 | + r"function missing required argument \'database\' \(pos 1\)", |
2589 | + ): |
2590 | self.readerClass[0]() |
2591 | |
2592 | def test_too_many_get_args(self): |
2593 | reader = open_database( |
2594 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode) |
2595 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", self.mode |
2596 | + ) |
2597 | with self.assertRaises(TypeError): |
2598 | - reader.get(self.ipf('1.1.1.1'), 'blah') |
2599 | + reader.get(self.ipf("1.1.1.1"), "blah") |
2600 | reader.close() |
2601 | |
2602 | def test_no_get_args(self): |
2603 | reader = open_database( |
2604 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode) |
2605 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", self.mode |
2606 | + ) |
2607 | with self.assertRaises(TypeError): |
2608 | reader.get() |
2609 | reader.close() |
2610 | |
2611 | def test_incorrect_get_arg_type(self): |
2612 | - reader = open_database('tests/data/test-data/GeoIP2-City-Test.mmdb', |
2613 | - self.mode) |
2614 | + reader = open_database("tests/data/test-data/GeoIP2-City-Test.mmdb", self.mode) |
2615 | with self.assertRaisesRegex( |
2616 | - TypeError, "argument 1 must be a string or ipaddress object"): |
2617 | + TypeError, "argument 1 must be a string or ipaddress object" |
2618 | + ): |
2619 | reader.get(1) |
2620 | reader.close() |
2621 | |
2622 | def test_metadata_args(self): |
2623 | reader = open_database( |
2624 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode) |
2625 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", self.mode |
2626 | + ) |
2627 | with self.assertRaises(TypeError): |
2628 | - reader.metadata('blah') |
2629 | + reader.metadata("blah") |
2630 | reader.close() |
2631 | |
2632 | def test_metadata_unknown_attribute(self): |
2633 | reader = open_database( |
2634 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode) |
2635 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", self.mode |
2636 | + ) |
2637 | metadata = reader.metadata() |
2638 | with self.assertRaisesRegex( |
2639 | - AttributeError, "'Metadata' object has no " |
2640 | - "attribute 'blah'"): |
2641 | + AttributeError, "'Metadata' object has no " "attribute 'blah'" |
2642 | + ): |
2643 | metadata.blah |
2644 | reader.close() |
2645 | |
2646 | def test_close(self): |
2647 | reader = open_database( |
2648 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode) |
2649 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", self.mode |
2650 | + ) |
2651 | reader.close() |
2652 | |
2653 | def test_double_close(self): |
2654 | reader = open_database( |
2655 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode) |
2656 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", self.mode |
2657 | + ) |
2658 | reader.close() |
2659 | - self.assertIsNone(reader.close(), |
2660 | - 'Double close does not throw an exception') |
2661 | + self.assertIsNone(reader.close(), "Double close does not throw an exception") |
2662 | |
2663 | def test_closed_get(self): |
2664 | if self.mode in [MODE_MEMORY, MODE_FD]: |
2665 | return |
2666 | reader = open_database( |
2667 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode) |
2668 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", self.mode |
2669 | + ) |
2670 | reader.close() |
2671 | with self.assertRaisesRegex( |
2672 | - ValueError, |
2673 | - 'Attempt to read from a closed MaxMind DB.|closed'): |
2674 | - reader.get(self.ipf('1.1.1.1')) |
2675 | + ValueError, "Attempt to read from a closed MaxMind DB.|closed" |
2676 | + ): |
2677 | + reader.get(self.ipf("1.1.1.1")) |
2678 | |
2679 | def test_with_statement(self): |
2680 | - filename = 'tests/data/test-data/MaxMind-DB-test-ipv4-24.mmdb' |
2681 | + filename = "tests/data/test-data/MaxMind-DB-test-ipv4-24.mmdb" |
2682 | with open_database(filename, self.mode) as reader: |
2683 | self._check_ip_v4(reader, filename) |
2684 | self.assertEqual(reader.closed, True) |
2685 | |
2686 | def test_with_statement_close(self): |
2687 | - filename = 'tests/data/test-data/MaxMind-DB-test-ipv4-24.mmdb' |
2688 | + filename = "tests/data/test-data/MaxMind-DB-test-ipv4-24.mmdb" |
2689 | reader = open_database(filename, self.mode) |
2690 | reader.close() |
2691 | |
2692 | - with self.assertRaisesRegex(ValueError, |
2693 | - 'Attempt to reopen a closed MaxMind DB'): |
2694 | + with self.assertRaisesRegex( |
2695 | + ValueError, "Attempt to reopen a closed MaxMind DB" |
2696 | + ): |
2697 | with reader: |
2698 | pass |
2699 | |
2700 | def test_closed(self): |
2701 | reader = open_database( |
2702 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode) |
2703 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", self.mode |
2704 | + ) |
2705 | self.assertEqual(reader.closed, False) |
2706 | reader.close() |
2707 | self.assertEqual(reader.closed, True) |
2708 | @@ -372,7 +412,8 @@ class BaseTestReader(object): |
2709 | # to keep the metadata in memory. |
2710 | def test_closed_metadata(self): |
2711 | reader = open_database( |
2712 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode) |
2713 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", self.mode |
2714 | + ) |
2715 | reader.close() |
2716 | |
2717 | # The primary purpose of this is to ensure the extension doesn't |
2718 | @@ -380,11 +421,13 @@ class BaseTestReader(object): |
2719 | try: |
2720 | metadata = reader.metadata() |
2721 | except IOError as ex: |
2722 | - self.assertEqual('Attempt to read from a closed MaxMind DB.', |
2723 | - str(ex), 'extension throws exception') |
2724 | + self.assertEqual( |
2725 | + "Attempt to read from a closed MaxMind DB.", |
2726 | + str(ex), |
2727 | + "extension throws exception", |
2728 | + ) |
2729 | else: |
2730 | - self.assertIsNotNone(metadata, |
2731 | - 'pure Python implementation returns value') |
2732 | + self.assertIsNotNone(metadata, "pure Python implementation returns value") |
2733 | |
2734 | def test_multiprocessing(self): |
2735 | self._check_concurrency(Process) |
2736 | @@ -396,17 +439,19 @@ class BaseTestReader(object): |
2737 | |
2738 | def test_byte_ip_on_python2(self): |
2739 | reader = open_database( |
2740 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb', self.mode) |
2741 | - record = reader.get(b'::1.1.1.0') |
2742 | + "tests/data/test-data/MaxMind-DB-test-decoder.mmdb", self.mode |
2743 | + ) |
2744 | + record = reader.get(b"::1.1.1.0") |
2745 | |
2746 | def _check_concurrency(self, worker_class): |
2747 | - reader = open_database('tests/data/test-data/GeoIP2-Domain-Test.mmdb', |
2748 | - self.mode) |
2749 | + reader = open_database( |
2750 | + "tests/data/test-data/GeoIP2-Domain-Test.mmdb", self.mode |
2751 | + ) |
2752 | |
2753 | def lookup(pipe): |
2754 | try: |
2755 | for i in range(32): |
2756 | - reader.get(self.ipf('65.115.240.{i}'.format(i=i))) |
2757 | + reader.get(self.ipf("65.115.240.{i}".format(i=i))) |
2758 | pipe.send(1) |
2759 | except: |
2760 | pipe.send(0) |
2761 | @@ -416,7 +461,7 @@ class BaseTestReader(object): |
2762 | pipe.close() |
2763 | |
2764 | pipes = [Pipe() for _ in range(32)] |
2765 | - procs = [worker_class(target=lookup, args=(c, )) for (p, c) in pipes] |
2766 | + procs = [worker_class(target=lookup, args=(c,)) for (p, c) in pipes] |
2767 | for proc in procs: |
2768 | proc.start() |
2769 | for proc in procs: |
2770 | @@ -426,92 +471,95 @@ class BaseTestReader(object): |
2771 | |
2772 | count = sum([p.recv() for (p, c) in pipes]) |
2773 | |
2774 | - self.assertEqual(count, 32, 'expected number of successful lookups') |
2775 | + self.assertEqual(count, 32, "expected number of successful lookups") |
2776 | |
2777 | def _check_metadata(self, reader, ip_version, record_size): |
2778 | metadata = reader.metadata() |
2779 | |
2780 | - self.assertEqual(2, metadata.binary_format_major_version, |
2781 | - 'major version') |
2782 | + self.assertEqual(2, metadata.binary_format_major_version, "major version") |
2783 | self.assertEqual(metadata.binary_format_minor_version, 0) |
2784 | self.assertGreater(metadata.build_epoch, 1373571901) |
2785 | - self.assertEqual(metadata.database_type, 'Test') |
2786 | + self.assertEqual(metadata.database_type, "Test") |
2787 | |
2788 | - self.assertEqual({ |
2789 | - 'en': 'Test Database', |
2790 | - 'zh': 'Test Database Chinese' |
2791 | - }, metadata.description) |
2792 | + self.assertEqual( |
2793 | + {"en": "Test Database", "zh": "Test Database Chinese"}, metadata.description |
2794 | + ) |
2795 | self.assertEqual(metadata.ip_version, ip_version) |
2796 | - self.assertEqual(metadata.languages, ['en', 'zh']) |
2797 | + self.assertEqual(metadata.languages, ["en", "zh"]) |
2798 | self.assertGreater(metadata.node_count, 36) |
2799 | |
2800 | self.assertEqual(metadata.record_size, record_size) |
2801 | |
2802 | def _check_ip_v4(self, reader, file_name): |
2803 | for i in range(6): |
2804 | - address = '1.1.1.' + str(pow(2, i)) |
2805 | - self.assertEqual({'ip': address}, reader.get(self.ipf(address)), |
2806 | - 'found expected data record for ' + address + |
2807 | - ' in ' + file_name) |
2808 | + address = "1.1.1." + str(pow(2, i)) |
2809 | + self.assertEqual( |
2810 | + {"ip": address}, |
2811 | + reader.get(self.ipf(address)), |
2812 | + "found expected data record for " + address + " in " + file_name, |
2813 | + ) |
2814 | |
2815 | pairs = { |
2816 | - '1.1.1.3': '1.1.1.2', |
2817 | - '1.1.1.5': '1.1.1.4', |
2818 | - '1.1.1.7': '1.1.1.4', |
2819 | - '1.1.1.9': '1.1.1.8', |
2820 | - '1.1.1.15': '1.1.1.8', |
2821 | - '1.1.1.17': '1.1.1.16', |
2822 | - '1.1.1.31': '1.1.1.16' |
2823 | + "1.1.1.3": "1.1.1.2", |
2824 | + "1.1.1.5": "1.1.1.4", |
2825 | + "1.1.1.7": "1.1.1.4", |
2826 | + "1.1.1.9": "1.1.1.8", |
2827 | + "1.1.1.15": "1.1.1.8", |
2828 | + "1.1.1.17": "1.1.1.16", |
2829 | + "1.1.1.31": "1.1.1.16", |
2830 | } |
2831 | for key_address, value_address in pairs.items(): |
2832 | - data = {'ip': value_address} |
2833 | + data = {"ip": value_address} |
2834 | |
2835 | self.assertEqual( |
2836 | - data, reader.get(self.ipf(key_address)), |
2837 | - 'found expected data record for ' + key_address + ' in ' + |
2838 | - file_name) |
2839 | + data, |
2840 | + reader.get(self.ipf(key_address)), |
2841 | + "found expected data record for " + key_address + " in " + file_name, |
2842 | + ) |
2843 | |
2844 | - for ip in ['1.1.1.33', '255.254.253.123']: |
2845 | + for ip in ["1.1.1.33", "255.254.253.123"]: |
2846 | self.assertIsNone(reader.get(self.ipf(ip))) |
2847 | |
2848 | def _check_ip_v6(self, reader, file_name): |
2849 | - subnets = [ |
2850 | - '::1:ffff:ffff', '::2:0:0', '::2:0:40', '::2:0:50', '::2:0:58' |
2851 | - ] |
2852 | + subnets = ["::1:ffff:ffff", "::2:0:0", "::2:0:40", "::2:0:50", "::2:0:58"] |
2853 | |
2854 | for address in subnets: |
2855 | - self.assertEqual({'ip': address}, reader.get(self.ipf(address)), |
2856 | - 'found expected data record for ' + address + |
2857 | - ' in ' + file_name) |
2858 | + self.assertEqual( |
2859 | + {"ip": address}, |
2860 | + reader.get(self.ipf(address)), |
2861 | + "found expected data record for " + address + " in " + file_name, |
2862 | + ) |
2863 | |
2864 | pairs = { |
2865 | - '::2:0:1': '::2:0:0', |
2866 | - '::2:0:33': '::2:0:0', |
2867 | - '::2:0:39': '::2:0:0', |
2868 | - '::2:0:41': '::2:0:40', |
2869 | - '::2:0:49': '::2:0:40', |
2870 | - '::2:0:52': '::2:0:50', |
2871 | - '::2:0:57': '::2:0:50', |
2872 | - '::2:0:59': '::2:0:58' |
2873 | + "::2:0:1": "::2:0:0", |
2874 | + "::2:0:33": "::2:0:0", |
2875 | + "::2:0:39": "::2:0:0", |
2876 | + "::2:0:41": "::2:0:40", |
2877 | + "::2:0:49": "::2:0:40", |
2878 | + "::2:0:52": "::2:0:50", |
2879 | + "::2:0:57": "::2:0:50", |
2880 | + "::2:0:59": "::2:0:58", |
2881 | } |
2882 | |
2883 | for key_address, value_address in pairs.items(): |
2884 | - self.assertEqual({'ip': value_address}, |
2885 | - reader.get(self.ipf(key_address)), |
2886 | - 'found expected data record for ' + key_address + |
2887 | - ' in ' + file_name) |
2888 | + self.assertEqual( |
2889 | + {"ip": value_address}, |
2890 | + reader.get(self.ipf(key_address)), |
2891 | + "found expected data record for " + key_address + " in " + file_name, |
2892 | + ) |
2893 | |
2894 | - for ip in ['1.1.1.33', '255.254.253.123', '89fa::']: |
2895 | + for ip in ["1.1.1.33", "255.254.253.123", "89fa::"]: |
2896 | self.assertIsNone(reader.get(self.ipf(ip))) |
2897 | |
2898 | |
2899 | def has_maxminddb_extension(): |
2900 | - return maxminddb.extension and hasattr(maxminddb.extension, 'Reader') |
2901 | + return maxminddb.extension and hasattr(maxminddb.extension, "Reader") |
2902 | |
2903 | |
2904 | -@unittest.skipIf(not has_maxminddb_extension() |
2905 | - and not os.environ.get('MM_FORCE_EXT_TESTS'), |
2906 | - 'No C extension module found. Skipping tests') |
2907 | +@unittest.skipIf( |
2908 | + not has_maxminddb_extension() and not os.environ.get("MM_FORCE_EXT_TESTS"), |
2909 | + "No C extension module found. Skipping tests", |
2910 | +) |
2911 | class TestExtensionReader(BaseTestReader, unittest.TestCase): |
2912 | mode = MODE_MMAP_EXT |
2913 | |
2914 | @@ -519,9 +567,10 @@ class TestExtensionReader(BaseTestReader, unittest.TestCase): |
2915 | readerClass = [maxminddb.extension.Reader] |
2916 | |
2917 | |
2918 | -@unittest.skipIf(not has_maxminddb_extension() |
2919 | - and not os.environ.get('MM_FORCE_EXT_TESTS'), |
2920 | - 'No C extension module found. Skipping tests') |
2921 | +@unittest.skipIf( |
2922 | + not has_maxminddb_extension() and not os.environ.get("MM_FORCE_EXT_TESTS"), |
2923 | + "No C extension module found. Skipping tests", |
2924 | +) |
2925 | class TestExtensionReaderWithIPObjects(BaseTestReader, unittest.TestCase): |
2926 | mode = MODE_MMAP_EXT |
2927 | use_ip_objects = True |
2928 | @@ -564,7 +613,7 @@ class TestMemoryReader(BaseTestReader, unittest.TestCase): |
2929 | |
2930 | class TestFDReader(BaseTestReader, unittest.TestCase): |
2931 | def setUp(self): |
2932 | - self.open_database_patcher = mock.patch('reader_test.open_database') |
2933 | + self.open_database_patcher = mock.patch("reader_test.open_database") |
2934 | self.addCleanup(self.open_database_patcher.stop) |
2935 | self.open_database = self.open_database_patcher.start() |
2936 | self.open_database.side_effect = get_reader_from_file_descriptor |
2937 | @@ -575,9 +624,8 @@ class TestFDReader(BaseTestReader, unittest.TestCase): |
2938 | |
2939 | class TestOldReader(unittest.TestCase): |
2940 | def test_old_reader(self): |
2941 | - reader = maxminddb.Reader( |
2942 | - 'tests/data/test-data/MaxMind-DB-test-decoder.mmdb') |
2943 | - record = reader.get('::1.1.1.0') |
2944 | + reader = maxminddb.Reader("tests/data/test-data/MaxMind-DB-test-decoder.mmdb") |
2945 | + record = reader.get("::1.1.1.0") |
2946 | |
2947 | - self.assertEqual(record['array'], [1, 2, 3]) |
2948 | + self.assertEqual(record["array"], [1, 2, 3]) |
2949 | reader.close() |
Many cosmetic changes indeed - Hiding the actual changes :-)
But the upstream update as well as the merge of that LGTM.
Did you build it already anywhere together with bind maybe - just to ensure things work? /launchpad. net/~ci- train-ppa- service/ +archive/ ubuntu/ 4087/+packages
Ah yeah found it at https:/
+1