Changes between Initial Version and Version 1 of Ticket #28981
- Timestamp:
- Jan 2, 2018, 12:14:45 PM (7 years ago)
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.1 When 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`. 2 2 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 5 If 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 9 If you create object and then call either `__repr__` (which can be done implicitly by calling `print(obj)`) or `info` methods, an `AttributeError` is raised. 4 10 5 11 {{{#!python 6 >>> import os7 12 >>> 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 15 14 >>> print(g) 16 15 # traceback truncated … … 23 22 }}} 24 23 25 Error occurs in `https://github.com/django/django/blob/1.11.9/django/contrib/gis/geoip2/base.py` 24 The 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: 26 25 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 }}}