Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[py3] Added buffer/memoryview compatibility

Even if buffer and memoryview are not strictly identical, it should
be safe to consider them equivalent for GIS support.
Thanks Aymeric Augustin for the review.
  • Loading branch information...
commit 8cdc84726e13da4c796db614765658835d4786a1 1 parent 3174b5f
@claudep claudep authored
View
6 django/contrib/gis/__init__.py
@@ -0,0 +1,6 @@
+from django.utils import six
+
+if six.PY3:
+ memoryview = memoryview
+else:
+ memoryview = buffer
View
3  django/contrib/gis/db/models/proxy.py
@@ -5,6 +5,7 @@
Thanks to Robert Coup for providing this functionality (see #4322).
"""
+from django.contrib.gis import memoryview
from django.utils import six
class GeometryProxy(object):
@@ -54,7 +55,7 @@ def __set__(self, obj, value):
if isinstance(value, self._klass) and (str(value.geom_type).upper() == gtype or gtype == 'GEOMETRY'):
# Assigning the SRID to the geometry.
if value.srid is None: value.srid = self._field.srid
- elif value is None or isinstance(value, six.string_types + (buffer,)):
+ elif value is None or isinstance(value, six.string_types + (memoryview,)):
# Set with None, WKT, HEX, or WKB
pass
else:
View
3  django/contrib/gis/db/models/query.py
@@ -1,6 +1,7 @@
from django.db import connections
from django.db.models.query import QuerySet, ValuesQuerySet, ValuesListQuerySet
+from django.contrib.gis import memoryview
from django.contrib.gis.db.models import aggregates
from django.contrib.gis.db.models.fields import get_srid_info, PointField, LineStringField
from django.contrib.gis.db.models.sql import AreaField, DistanceField, GeomField, GeoQuery
@@ -676,7 +677,7 @@ def _distance_attribute(self, func, geom=None, tolerance=0.05, spheroid=False, *
if not backend.geography:
if not isinstance(geo_field, PointField):
raise ValueError('Spherical distance calculation only supported on PointFields.')
- if not str(Geometry(buffer(params[0].ewkb)).geom_type) == 'Point':
+ if not str(Geometry(memoryview(params[0].ewkb)).geom_type) == 'Point':
raise ValueError('Spherical distance calculation only supported with Point Geometry parameters')
# The `function` procedure argument needs to be set differently for
# geodetic distance calculations.
View
8 django/contrib/gis/gdal/geometries.py
@@ -43,6 +43,8 @@
from binascii import a2b_hex, b2a_hex
from ctypes import byref, string_at, c_char_p, c_double, c_ubyte, c_void_p
+from django.contrib.gis import memoryview
+
# Getting GDAL prerequisites
from django.contrib.gis.gdal.base import GDALBase
from django.contrib.gis.gdal.envelope import Envelope, OGREnvelope
@@ -76,7 +78,7 @@ def __init__(self, geom_input, srs=None):
# If HEX, unpack input to to a binary buffer.
if str_instance and hex_regex.match(geom_input):
- geom_input = buffer(a2b_hex(geom_input.upper()))
+ geom_input = memoryview(a2b_hex(geom_input.upper()))
str_instance = False
# Constructing the geometry,
@@ -106,7 +108,7 @@ def __init__(self, geom_input, srs=None):
# (e.g., 'Point', 'POLYGON').
ogr_t = OGRGeomType(geom_input)
g = capi.create_geom(OGRGeomType(geom_input).num)
- elif isinstance(geom_input, buffer):
+ elif isinstance(geom_input, memoryview):
# WKB was passed in
g = capi.from_wkb(str(geom_input), None, byref(c_void_p()), len(geom_input))
elif isinstance(geom_input, OGRGeomType):
@@ -354,7 +356,7 @@ def wkb(self):
buf = (c_ubyte * sz)()
wkb = capi.to_wkb(self.ptr, byteorder, byref(buf))
# Returning a buffer of the string at the pointer.
- return buffer(string_at(buf, sz))
+ return memoryview(string_at(buf, sz))
@property
def wkt(self):
View
3  django/contrib/gis/geos/factory.py
@@ -1,3 +1,4 @@
+from django.contrib.gis import memoryview
from django.contrib.gis.geos.geometry import GEOSGeometry, wkt_regex, hex_regex
from django.utils import six
@@ -18,7 +19,7 @@ def fromfile(file_h):
if wkt_regex.match(buf) or hex_regex.match(buf):
return GEOSGeometry(buf)
else:
- return GEOSGeometry(buffer(buf))
+ return GEOSGeometry(memoryview(buf))
def fromstr(string, **kwargs):
"Given a string value, returns a GEOSGeometry object."
View
7 django/contrib/gis/geos/geometry.py
@@ -5,6 +5,7 @@
# Python, ctypes and types dependencies.
from ctypes import addressof, byref, c_double
+from django.contrib.gis import memoryview
# super-class for mutable list behavior
from django.contrib.gis.geos.mutable_list import ListMixin
@@ -75,7 +76,7 @@ def __init__(self, geo_input, srid=None):
elif isinstance(geo_input, GEOM_PTR):
# When the input is a pointer to a geomtry (GEOM_PTR).
g = geo_input
- elif isinstance(geo_input, buffer):
+ elif isinstance(geo_input, memoryview):
# When the input is a buffer (WKB).
g = wkb_r().read(geo_input)
elif isinstance(geo_input, GEOSGeometry):
@@ -139,12 +140,12 @@ def __repr__(self):
def __getstate__(self):
# The pickled state is simply a tuple of the WKB (in string form)
# and the SRID.
- return str(self.wkb), self.srid
+ return bytes(self.wkb), self.srid
def __setstate__(self, state):
# Instantiating from the tuple state that was pickled.
wkb, srid = state
- ptr = wkb_r().read(buffer(wkb))
+ ptr = wkb_r().read(memoryview(wkb))
if not ptr: raise GEOSException('Invalid Geometry loaded from pickled state.')
self.ptr = ptr
self._post_init(srid)
View
7 django/contrib/gis/geos/prototypes/io.py
@@ -1,5 +1,6 @@
import threading
from ctypes import byref, c_char_p, c_int, c_char, c_size_t, Structure, POINTER
+from django.contrib.gis import memoryview
from django.contrib.gis.geos.base import GEOSBase
from django.contrib.gis.geos.libgeos import GEOM_PTR
from django.contrib.gis.geos.prototypes.errcheck import check_geom, check_string, check_sized_string
@@ -130,8 +131,8 @@ class _WKBReader(IOBase):
def read(self, wkb):
"Returns a _pointer_ to C GEOS Geometry object from the given WKB."
- if isinstance(wkb, buffer):
- wkb_s = str(wkb)
+ if isinstance(wkb, memoryview):
+ wkb_s = bytes(wkb)
return wkb_reader_read(self.ptr, wkb_s, len(wkb_s))
elif isinstance(wkb, six.string_types):
return wkb_reader_read_hex(self.ptr, wkb, len(wkb))
@@ -155,7 +156,7 @@ class WKBWriter(IOBase):
def write(self, geom):
"Returns the WKB representation of the given geometry."
- return buffer(wkb_writer_write(self.ptr, geom.ptr, byref(c_size_t())))
+ return memoryview(wkb_writer_write(self.ptr, geom.ptr, byref(c_size_t())))
def write_hex(self, geom):
"Returns the HEXEWKB representation of the given geometry."
View
9 django/contrib/gis/geos/tests/test_geos.py
@@ -2,6 +2,7 @@
import json
import random
+from django.contrib.gis import memoryview
from django.contrib.gis.geos import (GEOSException, GEOSIndexError, GEOSGeometry,
GeometryCollection, Point, MultiPoint, Polygon, MultiPolygon, LinearRing,
LineString, MultiLineString, fromfile, fromstr, geos_version_info)
@@ -118,9 +119,9 @@ def test_hexewkb(self):
self.fail('Should have raised GEOSException.')
# Same for EWKB.
- self.assertEqual(buffer(a2b_hex(hexewkb_2d)), pnt_2d.ewkb)
+ self.assertEqual(memoryview(a2b_hex(hexewkb_2d)), pnt_2d.ewkb)
if GEOS_PREPARE:
- self.assertEqual(buffer(a2b_hex(hexewkb_3d)), pnt_3d.ewkb)
+ self.assertEqual(memoryview(a2b_hex(hexewkb_3d)), pnt_3d.ewkb)
else:
try:
ewkb = pnt_3d.ewkb
@@ -150,7 +151,7 @@ def test_errors(self):
pass
# Bad WKB
- self.assertRaises(GEOSException, GEOSGeometry, buffer('0'))
+ self.assertRaises(GEOSException, GEOSGeometry, memoryview(b'0'))
print("\nEND - expecting GEOS_ERROR; safe to ignore.\n")
@@ -182,7 +183,7 @@ def test_create_wkb(self):
"Testing creation from WKB."
from binascii import a2b_hex
for g in self.geometries.hex_wkt:
- wkb = buffer(a2b_hex(g.hex))
+ wkb = memoryview(a2b_hex(g.hex))
geom_h = GEOSGeometry(wkb)
# we need to do this so decimal places get normalised
geom_t = fromstr(g.wkt)
View
26 django/contrib/gis/geos/tests/test_io.py
@@ -1,5 +1,7 @@
import binascii
import unittest
+
+from django.contrib.gis import memoryview
from django.contrib.gis.geos import GEOSGeometry, WKTReader, WKTWriter, WKBReader, WKBWriter, geos_version_info
from django.utils import six
@@ -20,7 +22,7 @@ def test01_wktreader(self):
# Should only accept six.string_types objects.
self.assertRaises(TypeError, wkt_r.read, 1)
- self.assertRaises(TypeError, wkt_r.read, buffer('foo'))
+ self.assertRaises(TypeError, wkt_r.read, memoryview(b'foo'))
def test02_wktwriter(self):
# Creating a WKTWriter instance, testing its ptr property.
@@ -29,14 +31,14 @@ def test02_wktwriter(self):
ref = GEOSGeometry('POINT (5 23)')
ref_wkt = 'POINT (5.0000000000000000 23.0000000000000000)'
- self.assertEqual(ref_wkt, wkt_w.write(ref))
+ self.assertEqual(ref_wkt, wkt_w.write(ref).decode())
def test03_wkbreader(self):
# Creating a WKBReader instance
wkb_r = WKBReader()
- hex = '000000000140140000000000004037000000000000'
- wkb = buffer(binascii.a2b_hex(hex))
+ hex = b'000000000140140000000000004037000000000000'
+ wkb = memoryview(binascii.a2b_hex(hex))
ref = GEOSGeometry(hex)
# read() should return a GEOSGeometry on either a hex string or
@@ -56,10 +58,10 @@ def test04_wkbwriter(self):
# Representations of 'POINT (5 23)' in hex -- one normal and
# the other with the byte order changed.
g = GEOSGeometry('POINT (5 23)')
- hex1 = '010100000000000000000014400000000000003740'
- wkb1 = buffer(binascii.a2b_hex(hex1))
- hex2 = '000000000140140000000000004037000000000000'
- wkb2 = buffer(binascii.a2b_hex(hex2))
+ hex1 = b'010100000000000000000014400000000000003740'
+ wkb1 = memoryview(binascii.a2b_hex(hex1))
+ hex2 = b'000000000140140000000000004037000000000000'
+ wkb2 = memoryview(binascii.a2b_hex(hex2))
self.assertEqual(hex1, wkb_w.write_hex(g))
self.assertEqual(wkb1, wkb_w.write(g))
@@ -81,10 +83,10 @@ def test04_wkbwriter(self):
g = GEOSGeometry('POINT (5 23 17)')
g.srid = 4326
- hex3d = '0101000080000000000000144000000000000037400000000000003140'
- wkb3d = buffer(binascii.a2b_hex(hex3d))
- hex3d_srid = '01010000A0E6100000000000000000144000000000000037400000000000003140'
- wkb3d_srid = buffer(binascii.a2b_hex(hex3d_srid))
+ hex3d = b'0101000080000000000000144000000000000037400000000000003140'
+ wkb3d = memoryview(binascii.a2b_hex(hex3d))
+ hex3d_srid = b'01010000A0E6100000000000000000144000000000000037400000000000003140'
+ wkb3d_srid = memoryview(binascii.a2b_hex(hex3d_srid))
# Ensuring bad output dimensions are not accepted
for bad_outdim in (-1, 0, 1, 4, 423, 'foo', None):
Please sign in to comment.
Something went wrong with that request. Please try again.