Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
dan-mm committed Jan 23, 2024
2 parents 30ca918 + d9b91e3 commit 6521eea
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 19 deletions.
13 changes: 9 additions & 4 deletions django/contrib/gis/gdal/geometries.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
True True
"""
import sys
import warnings
from binascii import b2a_hex
from ctypes import byref, c_char_p, c_double, c_ubyte, c_void_p, string_at

Expand All @@ -50,6 +51,7 @@
from django.contrib.gis.gdal.prototypes import srs as srs_api
from django.contrib.gis.gdal.srs import CoordTransform, SpatialReference
from django.contrib.gis.geometry import hex_regex, json_regex, wkt_regex
from django.utils.deprecation import RemovedInDjango60Warning
from django.utils.encoding import force_bytes


Expand Down Expand Up @@ -206,18 +208,21 @@ def dimension(self):
"Return 0 for points, 1 for lines, and 2 for surfaces."
return capi.get_dims(self.ptr)

def _get_coord_dim(self):
@property
def coord_dim(self):
"Return the coordinate dimension of the Geometry."
return capi.get_coord_dim(self.ptr)

def _set_coord_dim(self, dim):
# RemovedInDjango60Warning
@coord_dim.setter
def coord_dim(self, dim):
"Set the coordinate dimension of this Geometry."
msg = "coord_dim setter is deprecated. Use set_3d() instead."
warnings.warn(msg, RemovedInDjango60Warning, stacklevel=2)
if dim not in (2, 3):
raise ValueError("Geometry dimension must be either 2 or 3")
capi.set_coord_dim(self.ptr, dim)

coord_dim = property(_get_coord_dim, _set_coord_dim)

@property
def geom_count(self):
"Return the number of elements in this Geometry."
Expand Down
6 changes: 0 additions & 6 deletions django/db/backends/oracle/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
"db_functions.datetime.test_extract_trunc.DateFunctionWithTimeZoneTests."
"test_trunc_week_before_1000",
},
"Oracle extracts seconds including fractional seconds (#33517).": {
"db_functions.datetime.test_extract_trunc.DateFunctionTests."
"test_extract_second_func_no_fractional",
"db_functions.datetime.test_extract_trunc.DateFunctionWithTimeZoneTests."
"test_extract_second_func_no_fractional",
},
"Oracle doesn't support bitwise XOR.": {
"expressions.tests.ExpressionOperatorTests.test_lefthand_bitwise_xor",
"expressions.tests.ExpressionOperatorTests.test_lefthand_bitwise_xor_null",
Expand Down
9 changes: 9 additions & 0 deletions django/db/backends/oracle/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ def datetime_cast_time_sql(self, sql, params, tzname):

def datetime_extract_sql(self, lookup_type, sql, params, tzname):
sql, params = self._convert_sql_to_tz(sql, params, tzname)
if lookup_type == "second":
# Truncate fractional seconds.
return f"FLOOR(EXTRACT(SECOND FROM {sql}))", params
return self.date_extract_sql(lookup_type, sql, params)

def datetime_trunc_sql(self, lookup_type, sql, params, tzname):
Expand All @@ -188,6 +191,12 @@ def datetime_trunc_sql(self, lookup_type, sql, params, tzname):
return f"CAST({sql} AS DATE)", params
return f"TRUNC({sql}, %s)", (*params, trunc_param)

def time_extract_sql(self, lookup_type, sql, params):
if lookup_type == "second":
# Truncate fractional seconds.
return f"FLOOR(EXTRACT(SECOND FROM {sql}))", params
return self.date_extract_sql(lookup_type, sql, params)

def time_trunc_sql(self, lookup_type, sql, params, tzname=None):
# The implementation is similar to `datetime_trunc_sql` as both
# `DateTimeField` and `TimeField` are stored as TIMESTAMP where
Expand Down
8 changes: 8 additions & 0 deletions django/forms/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ def __deepcopy__(self, memo):
result.validators = self.validators[:]
return result

def _clean_bound_field(self, bf):
value = bf.initial if self.disabled else bf.data
return self.clean(value)


class CharField(Field):
def __init__(
Expand Down Expand Up @@ -694,6 +698,10 @@ def bound_data(self, _, initial):
def has_changed(self, initial, data):
return not self.disabled and data is not None

def _clean_bound_field(self, bf):
value = bf.initial if self.disabled else bf.data
return self.clean(value, bf.initial)


class ImageField(FileField):
default_validators = [validators.validate_image_file_extension]
Expand Down
9 changes: 2 additions & 7 deletions django/forms/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import datetime

from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
from django.forms.fields import Field, FileField
from django.forms.fields import Field
from django.forms.utils import ErrorDict, ErrorList, RenderableFormMixin
from django.forms.widgets import Media, MediaDefiningClass
from django.utils.datastructures import MultiValueDict
Expand Down Expand Up @@ -329,13 +329,8 @@ def full_clean(self):
def _clean_fields(self):
for name, bf in self._bound_items():
field = bf.field
value = bf.initial if field.disabled else bf.data
try:
if isinstance(field, FileField):
value = field.clean(value, bf.initial)
else:
value = field.clean(value)
self.cleaned_data[name] = value
self.cleaned_data[name] = field._clean_bound_field(bf)
if hasattr(self, "clean_%s" % name):
value = getattr(self, "clean_%s" % name)()
self.cleaned_data[name] = value
Expand Down
3 changes: 3 additions & 0 deletions docs/internals/deprecation.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ details on these changes.
* Support for passing positional arguments to ``Model.save()`` and
``Model.asave()`` will be removed.

* The setter for ``django.contrib.gis.gdal.OGRGeometry.coord_dim`` will be
removed.

.. _deprecation-removed-in-5.1:

5.1
Expand Down
8 changes: 6 additions & 2 deletions docs/ref/contrib/gis/gdal.txt
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,12 @@ coordinate transformation:

.. attribute:: coord_dim

Returns or sets the coordinate dimension of this geometry. For example, the
value would be 2 for two-dimensional geometries.
Returns the coordinate dimension of this geometry. For example, the value
would be 2 for two-dimensional geometries.

.. deprecated:: 5.1

The ``coord_dim`` setter is deprecated. Use :meth:`.set_3d` instead.

.. attribute:: is_3d

Expand Down
3 changes: 3 additions & 0 deletions docs/releases/5.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,9 @@ Miscellaneous
* Passing positional arguments to :meth:`.Model.save` and :meth:`.Model.asave`
is deprecated in favor of keyword-only arguments.

* Setting ``django.contrib.gis.gdal.OGRGeometry.coord_dim`` is deprecated. Use
:meth:`~django.contrib.gis.gdal.OGRGeometry.set_3d` instead.

Features removed in 5.1
=======================

Expand Down
10 changes: 10 additions & 0 deletions tests/gis_tests/gdal_tests/test_geom.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from django.template import Context
from django.template.engine import Engine
from django.test import SimpleTestCase
from django.utils.deprecation import RemovedInDjango60Warning

from ..test_data import TestDataMixin

Expand Down Expand Up @@ -810,3 +811,12 @@ def test_wkt_and_wkb_output(self):
g = OGRGeometry(geom)
self.assertEqual(g.wkt, geom)
self.assertEqual(g.wkb.hex(), wkb)


class DeprecationTests(SimpleTestCase):
def test_coord_setter_deprecation(self):
geom = OGRGeometry("POINT (1 2)")
msg = "coord_dim setter is deprecated. Use set_3d() instead."
with self.assertWarnsMessage(RemovedInDjango60Warning, msg):
geom.coord_dim = 3
self.assertEqual(geom.coord_dim, 3)

0 comments on commit 6521eea

Please sign in to comment.