From 78c155cf2e5a27fd2db18c2d46953b1b0fdba829 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Thu, 27 Jul 2017 13:52:17 -0400 Subject: [PATCH] Fixed #28441 -- Fixed GEOS version parsing with a commit hash at the end. --- django/contrib/gis/geos/__init__.py | 2 +- django/contrib/gis/geos/libgeos.py | 26 +---------------------- docs/releases/1.11.5.txt | 3 ++- tests/gis_tests/geos_tests/test_geos.py | 28 +++++++++++-------------- 4 files changed, 16 insertions(+), 43 deletions(-) diff --git a/django/contrib/gis/geos/__init__.py b/django/contrib/gis/geos/__init__.py index 22a01a4cf2..65e7e54817 100644 --- a/django/contrib/gis/geos/__init__.py +++ b/django/contrib/gis/geos/__init__.py @@ -9,7 +9,7 @@ from .error import GEOSException # NOQA from .factory import fromfile, fromstr # NOQA from .geometry import GEOSGeometry, hex_regex, wkt_regex # NOQA from .io import WKBReader, WKBWriter, WKTReader, WKTWriter # NOQA -from .libgeos import geos_version, geos_version_info # NOQA +from .libgeos import geos_version # NOQA from .linestring import LinearRing, LineString # NOQA from .point import Point # NOQA from .polygon import Polygon # NOQA diff --git a/django/contrib/gis/geos/libgeos.py b/django/contrib/gis/geos/libgeos.py index 810161ffeb..29a15a249b 100644 --- a/django/contrib/gis/geos/libgeos.py +++ b/django/contrib/gis/geos/libgeos.py @@ -8,11 +8,9 @@ """ import logging import os -import re from ctypes import CDLL, CFUNCTYPE, POINTER, Structure, c_char_p from ctypes.util import find_library -from django.contrib.gis.geos.error import GEOSException from django.core.exceptions import ImproperlyConfigured from django.utils.functional import SimpleLazyObject from django.utils.version import get_version_tuple @@ -179,29 +177,7 @@ class GEOSFuncFactory: # explicitly to c_char_p to ensure compatibility across 32 and 64-bit platforms. geos_version = GEOSFuncFactory('GEOSversion', restype=c_char_p) -# Regular expression should be able to parse version strings such as -# '3.0.0rc4-CAPI-1.3.3', '3.0.0-CAPI-1.4.1', '3.4.0dev-CAPI-1.8.0' or '3.4.0dev-CAPI-1.8.0 r0' -version_regex = re.compile( - r'^(?P(?P\d+)\.(?P\d+)\.(?P\d+))' - r'((rc(?P\d+))|dev)?-CAPI-(?P\d+\.\d+\.\d+)( r\d+)?$' -) - - -def geos_version_info(): - """ - Return a dictionary containing the various version metadata parsed from - the GEOS version string, including the version number, whether the version - is a release candidate (and what number release candidate), and the C API - version. - """ - ver = geos_version().decode() - m = version_regex.match(ver) - if not m: - raise GEOSException('Could not parse version info string "%s"' % ver) - return {key: m.group(key) for key in ( - 'version', 'release_candidate', 'capi_version', 'major', 'minor', 'subminor')} - def geos_version_tuple(): """Return the GEOS version as a tuple (major, minor, subminor).""" - return get_version_tuple(geos_version_info()['version']) + return get_version_tuple(geos_version().decode()) diff --git a/docs/releases/1.11.5.txt b/docs/releases/1.11.5.txt index bbdd640e4b..55fa0eda7e 100644 --- a/docs/releases/1.11.5.txt +++ b/docs/releases/1.11.5.txt @@ -9,4 +9,5 @@ Django 1.11.5 fixes several bugs in 1.11.4. Bugfixes ======== -* ... +* Fixed GEOS version parsing if the version has a commit hash at the end (new + in GEOS 3.6.2) (:ticket:`28441`). diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index 35c06a5105..db373fd6c1 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -678,7 +678,7 @@ class GEOSTest(SimpleTestCase, TestDataMixin): self.assertFalse(MultiLineString(ls_closed, ls_not_closed).closed) self.assertTrue(MultiLineString(ls_closed, ls_closed).closed) - with mock.patch('django.contrib.gis.geos.libgeos.geos_version_info', lambda: {'version': '3.4.9'}): + with mock.patch('django.contrib.gis.geos.libgeos.geos_version', lambda: b'3.4.9'): with self.assertRaisesMessage(GEOSException, "MultiLineString.closed requires GEOS >= 3.5.0."): MultiLineString().closed @@ -1296,22 +1296,18 @@ class GEOSTest(SimpleTestCase, TestDataMixin): '{"coordinates": [[[0, 0], [0, 1], [1, 1], [0, 0]]], "type": "Polygon"}', ) - def test_geos_version(self): - """Testing the GEOS version regular expression.""" - from django.contrib.gis.geos.libgeos import version_regex - versions = [('3.0.0rc4-CAPI-1.3.3', '3.0.0', '1.3.3'), - ('3.0.0-CAPI-1.4.1', '3.0.0', '1.4.1'), - ('3.4.0dev-CAPI-1.8.0', '3.4.0', '1.8.0'), - ('3.4.0dev-CAPI-1.8.0 r0', '3.4.0', '1.8.0')] - for v_init, v_geos, v_capi in versions: - m = version_regex.match(v_init) - self.assertTrue(m, msg="Unable to parse the version string '%s'" % v_init) - self.assertEqual(m.group('version'), v_geos) - self.assertEqual(m.group('capi_version'), v_capi) - def test_geos_version_tuple(self): - with mock.patch('django.contrib.gis.geos.libgeos.geos_version_info', lambda: {'version': '3.4.9'}): - self.assertEqual(geos_version_tuple(), (3, 4, 9)) + versions = ( + (b'3.0.0rc4-CAPI-1.3.3', (3, 0, 0)), + (b'3.0.0-CAPI-1.4.1', (3, 0, 0)), + (b'3.4.0dev-CAPI-1.8.0', (3, 4, 0)), + (b'3.4.0dev-CAPI-1.8.0 r0', (3, 4, 0)), + (b'3.6.2-CAPI-1.10.2 4d2925d6', (3, 6, 2)), + ) + for version_string, version_tuple in versions: + with self.subTest(version_string=version_string): + with mock.patch('django.contrib.gis.geos.libgeos.geos_version', lambda: version_string): + self.assertEqual(geos_version_tuple(), version_tuple) def test_from_gml(self): self.assertEqual(