Changes between Initial Version and Version 1 of Ticket #28981


Ignore:
Timestamp:
Jan 2, 2018, 12:14:45 PM (7 years ago)
Author:
Hugo Rodger-Brown
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #28981 – Description

    initial v1  
    1 If a GEOIP_PATH setting is specified, but there is no database file at that location, the initialisation of GeoIP2 runs without raising an error, which is the expected behaviour. However, during this process, neither the `_country` nor `_city` attributes are set (as there is no database), which means in turn that the `_reader` property will always return `None`. The problem occurs because both the `__repr__` and `info` methods expect the `_reader` to exist, and will fail with an `AttributeError` if it is None.
     1When initialising a GeoIP2 object, if the GEOIP_PATH setting points to a directory that exists, but there is no MaxMind database in that location, the object is created in a state such that any call to `obj.__repr__` or `obj.info()` will raise an `AttributeError`.
    22
    3 The expected behaviour is that neither method will fail. The actual behaviour can be replicated below, where GEOIP_PATH is a valid directory that does not contain a MaxMind database file.
     3**Expected behaviour:**
     4
     5If it is possible to create a new GeoIP2 object in the absence of a source database, then the object methods should either handle that situation gracefully, or raise an appropriate error (e.g. `GeoIP2Exception`).
     6
     7**Actual behaviour:**
     8
     9If you create object and then call either `__repr__` (which can be done implicitly by calling `print(obj)`) or `info` methods, an `AttributeError` is raised.
    410
    511{{{#!python
    6 >>> import os
    712>>> from django.contrib.gis.geoip2 import GeoIP2
    8 >>> from django.contrib.gis.geoip2.base import GEOIP_SETTINGS
    9 >>> assert GEOIP_SETTINGS['GEOIP_PATH']
    10 >>> assert os.path.isdir(GEOIP_SETTINGS['GEOIP_PATH'])
    11 >>> g = GeoIP2()
    12 >>> assert g._city is None
    13 >>> assert g._country is None
    14 >>> assert g._reader is None
     13>>> g = GeoIP2()  # the GEOIP_PATH exists, but there is no database
    1514>>> print(g)
    1615# traceback truncated
     
    2322}}}
    2423
    25 Error occurs in `https://github.com/django/django/blob/1.11.9/django/contrib/gis/geoip2/base.py`
     24The problem is caused by both methods assuming that the `_reader` attribute will always be a valid `geoip2.database.Reader` object, which is **not** true in this case:
    2625
    27 Sugggested remedy: update `GeoIP2.__repr__` and `GeoIP2.info` to handle `_reader is None`.
     26{{{#!python
     27>>> from django.contrib.gis.geoip2 import GeoIP2
     28>>> g = GeoIP2()  # the GEOIP_PATH exists, but there is no database
     29>>> assert g._city is None
     30>>> assert g._country is None
     31>>> assert g._reader is None
     32}}}
Back to Top