Fixed #28665 -- Change some database exceptions to NotImplementedError per PEP 249.

This commit is contained in:
Simon Charette 2017-10-06 12:47:08 -04:00 committed by Tim Graham
parent 7d8d630e37
commit 9d93dff333
15 changed files with 37 additions and 32 deletions

View File

@ -3,6 +3,7 @@ from django.contrib.gis.db.models.functions import Distance
from django.contrib.gis.measure import (
Area as AreaMeasure, Distance as DistanceMeasure,
)
from django.db.utils import NotSupportedError
from django.utils.functional import cached_property
@ -105,7 +106,7 @@ class BaseSpatialOperations:
def check_expression_support(self, expression):
if isinstance(expression, self.disallowed_aggregates):
raise NotImplementedError(
raise NotSupportedError(
"%s spatial aggregation is not supported by this database backend." % expression.name
)
super().check_expression_support(expression)
@ -115,7 +116,7 @@ class BaseSpatialOperations:
def spatial_function_name(self, func_name):
if func_name in self.unsupported_functions:
raise NotImplementedError("This backend doesn't support the %s function." % func_name)
raise NotSupportedError("This backend doesn't support the %s function." % func_name)
return self.function_names.get(func_name, self.geom_func_prefix + func_name)
# Routines for getting the OGC-compliant models.

View File

@ -13,7 +13,7 @@ from django.contrib.gis.measure import Distance
from django.core.exceptions import ImproperlyConfigured
from django.db.backends.postgresql.operations import DatabaseOperations
from django.db.models import Func, Value
from django.db.utils import ProgrammingError
from django.db.utils import NotSupportedError, ProgrammingError
from django.utils.functional import cached_property
from django.utils.version import get_version_tuple
@ -231,7 +231,7 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
geom_type = f.geom_type
if f.geography:
if f.srid != 4326:
raise NotImplementedError('PostGIS only supports geography columns with an SRID of 4326.')
raise NotSupportedError('PostGIS only supports geography columns with an SRID of 4326.')
return 'geography(%s,%d)' % (geom_type, f.srid)
else:

View File

@ -9,6 +9,7 @@ from django.db.models import (
)
from django.db.models.expressions import Func, Value
from django.db.models.functions import Cast
from django.db.utils import NotSupportedError
from django.utils.functional import cached_property
NUMERIC_TYPES = (int, float, Decimal)
@ -123,7 +124,7 @@ class Area(OracleToleranceMixin, GeoFunc):
def as_sql(self, compiler, connection, **extra_context):
if not connection.features.supports_area_geodetic and self.geo_field.geodetic(connection):
raise NotImplementedError('Area on geodetic coordinate systems not supported.')
raise NotSupportedError('Area on geodetic coordinate systems not supported.')
return super().as_sql(compiler, connection, **extra_context)
def as_sqlite(self, compiler, connection, **extra_context):
@ -316,7 +317,7 @@ class Length(DistanceResultMixin, OracleToleranceMixin, GeoFunc):
def as_sql(self, compiler, connection, **extra_context):
if self.geo_field.geodetic(connection) and not connection.features.supports_length_geodetic:
raise NotImplementedError("This backend doesn't support Length on geodetic fields")
raise NotSupportedError("This backend doesn't support Length on geodetic fields")
return super().as_sql(compiler, connection, **extra_context)
def as_postgresql(self, compiler, connection):
@ -372,7 +373,7 @@ class Perimeter(DistanceResultMixin, OracleToleranceMixin, GeoFunc):
def as_postgresql(self, compiler, connection):
function = None
if self.geo_field.geodetic(connection) and not self.source_is_geography():
raise NotImplementedError("ST_Perimeter cannot use a non-projected non-geography field.")
raise NotSupportedError("ST_Perimeter cannot use a non-projected non-geography field.")
dim = min(f.dim for f in self.get_source_fields())
if dim > 2:
function = connection.ops.perimeter3d
@ -380,7 +381,7 @@ class Perimeter(DistanceResultMixin, OracleToleranceMixin, GeoFunc):
def as_sqlite(self, compiler, connection):
if self.geo_field.geodetic(connection):
raise NotImplementedError("Perimeter cannot use a non-projected field.")
raise NotSupportedError("Perimeter cannot use a non-projected field.")
return super().as_sql(compiler, connection)

View File

@ -1,5 +1,5 @@
from django.db.models.aggregates import StdDev
from django.db.utils import ProgrammingError
from django.db.utils import NotSupportedError, ProgrammingError
from django.utils.functional import cached_property
@ -269,9 +269,9 @@ class BaseDatabaseFeatures:
"""Confirm support for STDDEV and related stats functions."""
try:
self.connection.ops.check_expression_support(StdDev(1))
return True
except NotImplementedError:
except NotSupportedError:
return False
return True
def introspected_boolean_field_type(self, field=None):
"""

View File

@ -579,7 +579,7 @@ class BaseDatabaseOperations:
This is used on specific backends to rule out known expressions
that have problematic or nonexistent implementations. If the
expression has a known problem, the backend should raise
NotImplementedError.
NotSupportedError.
"""
pass

View File

@ -43,7 +43,7 @@ class DatabaseOperations(BaseDatabaseOperations):
pass
else:
if isinstance(output_field, bad_fields):
raise NotImplementedError(
raise utils.NotSupportedError(
'You cannot use Sum, Avg, StdDev, and Variance '
'aggregations on date/time fields in sqlite3 '
'since date/time is saved as text.'

View File

@ -25,7 +25,7 @@ class Lookup:
# a bilateral transformation on a nested QuerySet: that won't work.
from django.db.models.sql.query import Query # avoid circular import
if isinstance(rhs, Query):
raise NotImplementedError("Bilateral transformations on nested querysets are not supported.")
raise NotImplementedError("Bilateral transformations on nested querysets are not implemented.")
self.bilateral_transforms = bilateral_transforms
def apply_bilateral_transforms(self, value):

View File

@ -198,7 +198,9 @@ Backwards incompatible changes in 2.1
Database backend API
--------------------
* ...
* To adhere to :pep:`249`, exceptions where a database doesn't support a
feature are changed from :exc:`NotImplementedError` to
:exc:`django.db.NotSupportedError`.
:mod:`django.contrib.gis`
-------------------------

View File

@ -4,6 +4,7 @@ import unittest
from django.db import connection
from django.db.models import Avg, StdDev, Sum, Variance
from django.db.utils import NotSupportedError
from django.test import TestCase, TransactionTestCase, override_settings
from ..models import Item, Object, Square
@ -34,13 +35,13 @@ class Tests(TestCase):
Raise NotImplementedError when aggregating on date/time fields (#19360).
"""
for aggregate in (Sum, Avg, Variance, StdDev):
with self.assertRaises(NotImplementedError):
with self.assertRaises(NotSupportedError):
Item.objects.all().aggregate(aggregate('time'))
with self.assertRaises(NotImplementedError):
with self.assertRaises(NotSupportedError):
Item.objects.all().aggregate(aggregate('date'))
with self.assertRaises(NotImplementedError):
with self.assertRaises(NotSupportedError):
Item.objects.all().aggregate(aggregate('last_modified'))
with self.assertRaises(NotImplementedError):
with self.assertRaises(NotSupportedError):
Item.objects.all().aggregate(
**{'complex': aggregate('last_modified') + aggregate('last_modified')}
)

View File

@ -319,7 +319,7 @@ class BilateralTransformTests(TestCase):
def test_bilateral_inner_qs(self):
with register_lookup(models.CharField, UpperBilateralTransform):
msg = 'Bilateral transformations on nested querysets are not supported.'
msg = 'Bilateral transformations on nested querysets are not implemented.'
with self.assertRaisesMessage(NotImplementedError, msg):
Author.objects.filter(name__upper__in=Author.objects.values_list('name'))

View File

@ -5,7 +5,7 @@ from django.contrib.gis.db.models.functions import (
)
from django.contrib.gis.geos import GEOSGeometry, LineString, Point
from django.contrib.gis.measure import D # alias for Distance
from django.db import connection
from django.db import NotSupportedError, connection
from django.db.models import F, Q
from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
@ -474,7 +474,7 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
# TODO: test with spheroid argument (True and False)
else:
# Does not support geodetic coordinate systems.
with self.assertRaises(NotImplementedError):
with self.assertRaises(NotSupportedError):
list(Interstate.objects.annotate(length=Length('path')))
# Now doing length on a projected coordinate system.
@ -513,7 +513,7 @@ class DistanceFunctionsTests(FuncTestMixin, TestCase):
if connection.features.supports_perimeter_geodetic:
self.assertAlmostEqual(qs1[0].perim.m, 18406.3818954314, 3)
else:
with self.assertRaises(NotImplementedError):
with self.assertRaises(NotSupportedError):
list(qs1)
# But should work fine when transformed to projected coordinates
qs2 = CensusZipcode.objects.annotate(perim=Perimeter(Transform('poly', 32140))).filter(name='77002')

View File

@ -8,7 +8,7 @@ from django.contrib.gis.geos import (
GEOSGeometry, LineString, Point, Polygon, fromstr,
)
from django.contrib.gis.measure import Area
from django.db import connection
from django.db import NotSupportedError, connection
from django.db.models import Sum
from django.test import TestCase, skipUnlessDBFeature
@ -28,7 +28,7 @@ class GISFunctionsTests(FuncTestMixin, TestCase):
def test_asgeojson(self):
# Only PostGIS and SpatiaLite support GeoJSON.
if not connection.features.has_AsGeoJSON_function:
with self.assertRaises(NotImplementedError):
with self.assertRaises(NotSupportedError):
list(Country.objects.annotate(json=functions.AsGeoJSON('mpoly')))
return

View File

@ -8,7 +8,7 @@ from django.contrib.gis.geos import (
MultiPoint, MultiPolygon, Point, Polygon, fromstr,
)
from django.core.management import call_command
from django.db import connection
from django.db import NotSupportedError, connection
from django.test import TestCase, skipUnlessDBFeature
from ..utils import (
@ -516,7 +516,7 @@ class GeoQuerySetTest(TestCase):
Testing the `MakeLine` aggregate.
"""
if not connection.features.supports_make_line_aggr:
with self.assertRaises(NotImplementedError):
with self.assertRaises(NotSupportedError):
City.objects.all().aggregate(MakeLine('point'))
return

View File

@ -7,7 +7,7 @@ from unittest import skipIf, skipUnless
from django.contrib.gis.db import models
from django.contrib.gis.db.models.functions import Area, Distance
from django.contrib.gis.measure import D
from django.db import connection
from django.db import NotSupportedError, connection
from django.db.models.functions import Cast
from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
@ -152,5 +152,5 @@ class GeographyFunctionTests(FuncTestMixin, TestCase):
@skipUnlessDBFeature("has_Area_function")
@skipIfDBFeature("supports_area_geodetic")
def test_geodetic_area_raises_if_not_supported(self):
with self.assertRaisesMessage(NotImplementedError, 'Area on geodetic coordinate systems not supported.'):
with self.assertRaisesMessage(NotSupportedError, 'Area on geodetic coordinate systems not supported.'):
Zipcode.objects.annotate(area=Area('poly')).get(code='77002')

View File

@ -1,6 +1,6 @@
from django.contrib.gis.db.models import Collect, Count, Extent, F, Union
from django.contrib.gis.geos import GEOSGeometry, MultiPoint, Point
from django.db import connection
from django.db import NotSupportedError, connection
from django.test import TestCase, skipUnlessDBFeature
from django.test.utils import override_settings
from django.utils import timezone
@ -147,7 +147,7 @@ class RelatedGeoModelTest(TestCase):
self.assertEqual('P2', qs.get().name)
else:
msg = "This backend doesn't support the Transform function."
with self.assertRaisesMessage(NotImplementedError, msg):
with self.assertRaisesMessage(NotSupportedError, msg):
list(qs)
# Should return the first Parcel, which has the center point equal
@ -162,7 +162,7 @@ class RelatedGeoModelTest(TestCase):
self.assertEqual('P1', qs.get().name)
else:
msg = "This backend doesn't support the Transform function."
with self.assertRaisesMessage(NotImplementedError, msg):
with self.assertRaisesMessage(NotSupportedError, msg):
list(qs)
def test07_values(self):