Fixed #30461 -- Made GeoIP2 and GEOIP_PATH setting accept pathlib.Path as library path.

Thanks Nikita Krokosh for the initial patch.
This commit is contained in:
Claude Paroz 2019-08-10 11:55:22 +02:00 committed by Mariusz Felisiak
parent 88c0b907e7
commit eed2e740f7
4 changed files with 24 additions and 7 deletions

View File

@ -1,11 +1,11 @@
import socket import socket
from pathlib import Path
import geoip2.database import geoip2.database
from django.conf import settings from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import validate_ipv46_address from django.core.validators import validate_ipv46_address
from django.utils._os import to_path
from .resources import City, Country from .resources import City, Country
@ -76,10 +76,8 @@ class GeoIP2:
path = path or GEOIP_SETTINGS['GEOIP_PATH'] path = path or GEOIP_SETTINGS['GEOIP_PATH']
if not path: if not path:
raise GeoIP2Exception('GeoIP path must be provided via parameter or the GEOIP_PATH setting.') raise GeoIP2Exception('GeoIP path must be provided via parameter or the GEOIP_PATH setting.')
if not isinstance(path, str):
raise TypeError('Invalid path type: %s' % type(path).__name__)
path = Path(path) path = to_path(path)
if path.is_dir(): if path.is_dir():
# Constructing the GeoIP database filenames using the settings # Constructing the GeoIP database filenames using the settings
# dictionary. If the database files for the GeoLite country # dictionary. If the database files for the GeoLite country

View File

@ -86,6 +86,10 @@ Keyword Arguments Description
the :setting:`GEOIP_CITY` setting. the :setting:`GEOIP_CITY` setting.
=================== ======================================================= =================== =======================================================
.. versionchanged:: 3.0
Support for :class:`pathlib.Path` ``path`` was added.
Methods Methods
======= =======
@ -151,10 +155,14 @@ Settings
``GEOIP_PATH`` ``GEOIP_PATH``
-------------- --------------
A string specifying the directory where the GeoIP data files are A string or :class:`pathlib.Path` specifying the directory where the GeoIP data
located. This setting is *required* unless manually specified files are located. This setting is *required* unless manually specified
with ``path`` keyword when initializing the :class:`GeoIP2` object. with ``path`` keyword when initializing the :class:`GeoIP2` object.
.. versionchanged:: 3.0
Support for :class:`pathlib.Path` was added.
.. setting:: GEOIP_COUNTRY .. setting:: GEOIP_COUNTRY
``GEOIP_COUNTRY`` ``GEOIP_COUNTRY``

View File

@ -133,6 +133,11 @@ Minor features
* Added support for the ``furlong`` unit in * Added support for the ``furlong`` unit in
:class:`~django.contrib.gis.measure.Distance`. :class:`~django.contrib.gis.measure.Distance`.
* The :setting:`GEOIP_PATH` setting now supports :class:`pathlib.Path`.
* The :class:`~django.contrib.gis.geoip2.GeoIP2` class now accepts
:class:`pathlib.Path` ``path``.
:mod:`django.contrib.messages` :mod:`django.contrib.messages`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -1,4 +1,5 @@
import os import os
import pathlib
from unittest import mock, skipUnless from unittest import mock, skipUnless
from django.conf import settings from django.conf import settings
@ -28,8 +29,13 @@ class GeoIPTest(SimpleTestCase):
path = settings.GEOIP_PATH path = settings.GEOIP_PATH
g2 = GeoIP2(path, 0) # Passing in data path explicitly. g2 = GeoIP2(path, 0) # Passing in data path explicitly.
g3 = GeoIP2.open(path, 0) # MaxMind Python API syntax. g3 = GeoIP2.open(path, 0) # MaxMind Python API syntax.
# path accepts str and pathlib.Path.
if isinstance(path, str):
g4 = GeoIP2(pathlib.Path(path))
else:
g4 = GeoIP2(str(path))
for g in (g1, g2, g3): for g in (g1, g2, g3, g4):
self.assertTrue(g._country) self.assertTrue(g._country)
self.assertTrue(g._city) self.assertTrue(g._city)