From edcf8532ffda006bc125d9c93fca59f9037f490f Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Fri, 5 Jan 2024 06:03:19 +0100 Subject: [PATCH 1/5] Removed obsolete rpm-related install code. --- scripts/rpm-install.sh | 28 ---------------------------- setup.cfg | 4 ---- 2 files changed, 32 deletions(-) delete mode 100644 scripts/rpm-install.sh diff --git a/scripts/rpm-install.sh b/scripts/rpm-install.sh deleted file mode 100644 index 89cf4dd04954..000000000000 --- a/scripts/rpm-install.sh +++ /dev/null @@ -1,28 +0,0 @@ -#! /bin/sh -# -# This file becomes the install section of the generated spec file. -# - -# This is what dist.py normally does. -%{__python} setup.py install --root=${RPM_BUILD_ROOT} --record="INSTALLED_FILES" - -# Sort the filelist so that directories appear before files. This avoids -# duplicate filename problems on some systems. -touch DIRS -for i in `cat INSTALLED_FILES`; do - if [ -f ${RPM_BUILD_ROOT}/$i ]; then - echo $i >>FILES - fi - if [ -d ${RPM_BUILD_ROOT}/$i ]; then - echo %dir $i >>DIRS - fi -done - -# Make sure we match foo.pyo and foo.pyc along with foo.py (but only once each) -sed -e "/\.py[co]$/d" -e "s/\.py$/.py*/" DIRS FILES >INSTALLED_FILES - -mkdir -p ${RPM_BUILD_ROOT}/%{_mandir}/man1/ -cp docs/man/* ${RPM_BUILD_ROOT}/%{_mandir}/man1/ -cat << EOF >> INSTALLED_FILES -%doc %{_mandir}/man1/*" -EOF diff --git a/setup.cfg b/setup.cfg index c6f48bab1388..2f92092aa907 100644 --- a/setup.cfg +++ b/setup.cfg @@ -50,10 +50,6 @@ console_scripts = argon2 = argon2-cffi >= 19.1.0 bcrypt = bcrypt -[bdist_rpm] -doc_files = docs extras AUTHORS INSTALL LICENSE README.rst -install_script = scripts/rpm-install.sh - [flake8] exclude = build,.git,.tox,./tests/.env extend-ignore = E203 From 7dd19a367e58752bc0b138f5b1a9a3aa35581965 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Fri, 5 Jan 2024 08:15:45 +0100 Subject: [PATCH 2/5] Moved isort config from setup.cfg to pyproject.toml. --- pyproject.toml | 5 +++++ setup.cfg | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2c776030cea2..f8632ac3cea4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,3 +5,8 @@ build-backend = 'setuptools.build_meta' [tool.black] target-version = ['py310'] force-exclude = 'tests/test_runner_apps/tagged/tests_syntax_error.py' + +[tool.isort] +profile = 'black' +default_section = 'THIRDPARTY' +known_first_party = 'django' diff --git a/setup.cfg b/setup.cfg index 2f92092aa907..29814e54e6b6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -59,8 +59,3 @@ per-file-ignores = django/core/cache/backends/base.py:W601 django/core/cache/backends/redis.py:W601 tests/cache/tests.py:W601 - -[isort] -profile = black -default_section = THIRDPARTY -known_first_party = django From 9b056aa5afbd1f037189f5b9250ef68e87a93e19 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Fri, 5 Jan 2024 08:23:31 +0100 Subject: [PATCH 3/5] Bumped versions in pre-commit and npm configurations. --- .pre-commit-config.yaml | 10 +++++----- package.json | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d42a0dd21266..1c3571406fda 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.10.0 + rev: 23.12.1 hooks: - id: black exclude: \.py-tpl$ @@ -9,17 +9,17 @@ repos: hooks: - id: blacken-docs additional_dependencies: - - black==23.10.0 + - black==23.12.1 files: 'docs/.*\.txt$' - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 + rev: 7.0.0 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.52.0 + rev: v8.56.0 hooks: - id: eslint diff --git a/package.json b/package.json index e9b3982dc68d..02589973403b 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "npm": ">=1.3.0" }, "devDependencies": { - "eslint": "^8.52.0", - "puppeteer": "^21.4.0", + "eslint": "^8.56.0", + "puppeteer": "^21.7.0", "grunt": "^1.6.1", "grunt-cli": "^1.4.3", "grunt-contrib-qunit": "^8.0.1", From 45f59d0eab56629f88826117e911af05bd55d2c3 Mon Sep 17 00:00:00 2001 From: David Smith <39445562+smithdc1@users.noreply.github.com> Date: Thu, 4 Jan 2024 20:50:14 +0000 Subject: [PATCH 4/5] Fixed #35086 -- Added support for BoundedCircle on Spatialite 5.1+. Spatialite 5.1 added support for BoundingCircle (GEOSMinimumBoundingCircle). GEOS 3.7 is required which is lower than Django's currently supported minmum of 3.8. https://groups.google.com/g/spatialite-users/c/hAJ2SgitN4M https://www.gaia-gis.it/gaia-sins/spatialite-sql-5.1.0.html --- django/contrib/gis/db/backends/spatialite/operations.py | 5 ++++- django/contrib/gis/db/models/functions.py | 7 +++++++ docs/ref/contrib/gis/db-api.txt | 2 +- docs/ref/contrib/gis/functions.txt | 7 ++++++- docs/releases/5.1.txt | 3 ++- tests/gis_tests/geoapp/test_functions.py | 7 ++++++- 6 files changed, 26 insertions(+), 5 deletions(-) diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py index 0b8b26ab6f8b..8a3d84b5de62 100644 --- a/django/contrib/gis/db/backends/spatialite/operations.py +++ b/django/contrib/gis/db/backends/spatialite/operations.py @@ -66,6 +66,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations): function_names = { "AsWKB": "St_AsBinary", + "BoundingCircle": "GEOSMinimumBoundingCircle", "ForcePolygonCW": "ST_ForceLHR", "FromWKB": "ST_GeomFromWKB", "FromWKT": "ST_GeomFromText", @@ -80,9 +81,11 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations): @cached_property def unsupported_functions(self): - unsupported = {"BoundingCircle", "GeometryDistance", "IsEmpty", "MemSize"} + unsupported = {"GeometryDistance", "IsEmpty", "MemSize"} if not self.geom_lib_version(): unsupported |= {"Azimuth", "GeoHash", "MakeValid"} + if self.spatial_version < (5, 1): + unsupported |= {"BoundingCircle"} return unsupported @cached_property diff --git a/django/contrib/gis/db/models/functions.py b/django/contrib/gis/db/models/functions.py index bd02e3717d85..419b64c5e8e6 100644 --- a/django/contrib/gis/db/models/functions.py +++ b/django/contrib/gis/db/models/functions.py @@ -274,6 +274,13 @@ def as_oracle(self, compiler, connection, **extra_context): compiler, connection, **extra_context ) + def as_sqlite(self, compiler, connection, **extra_context): + clone = self.copy() + clone.set_source_expressions([self.get_source_expressions()[0]]) + return super(BoundingCircle, clone).as_sqlite( + compiler, connection, **extra_context + ) + class Centroid(OracleToleranceMixin, GeomOutputGeoFunc): arity = 1 diff --git a/docs/ref/contrib/gis/db-api.txt b/docs/ref/contrib/gis/db-api.txt index df1d3847e60c..f2dd1c7bf433 100644 --- a/docs/ref/contrib/gis/db-api.txt +++ b/docs/ref/contrib/gis/db-api.txt @@ -397,7 +397,7 @@ Function PostGIS Oracle MariaDB MySQL :class:`AsWKB` X X X X X :class:`AsWKT` X X X X X :class:`Azimuth` X X (LWGEOM/RTTOPO) -:class:`BoundingCircle` X X +:class:`BoundingCircle` X X X (≥ 5.1) :class:`Centroid` X X X X X :class:`ClosestPoint` X X :class:`Difference` X X X X X diff --git a/docs/ref/contrib/gis/functions.txt b/docs/ref/contrib/gis/functions.txt index 36ef651cfe72..f55d314b3f85 100644 --- a/docs/ref/contrib/gis/functions.txt +++ b/docs/ref/contrib/gis/functions.txt @@ -230,13 +230,18 @@ south = ``π``; west = ``3π/2``. *Availability*: `PostGIS `__, `Oracle `_ +SDO_GEOM-reference.html#GUID-82A61626-BB64-4793-B53D-A0DBEC91831A>`_, +SpatiaLite 5.1+ Accepts a single geographic field or expression and returns the smallest circle polygon that can fully contain the geometry. The ``num_seg`` parameter is used only on PostGIS. +.. versionchanged:: 5.1 + + SpatiaLite 5.1+ support was added. + ``Centroid`` ============ diff --git a/docs/releases/5.1.txt b/docs/releases/5.1.txt index 544b1f5d0855..03ca07f298d2 100644 --- a/docs/releases/5.1.txt +++ b/docs/releases/5.1.txt @@ -53,7 +53,8 @@ Minor features :mod:`django.contrib.gis` ~~~~~~~~~~~~~~~~~~~~~~~~~ -* ... +* :class:`~django.contrib.gis.db.models.functions.BoundingCircle` is now + supported on SpatiaLite 5.1+. :mod:`django.contrib.messages` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/gis_tests/geoapp/test_functions.py b/tests/gis_tests/geoapp/test_functions.py index 047c7f903602..9edadc48c21e 100644 --- a/tests/gis_tests/geoapp/test_functions.py +++ b/tests/gis_tests/geoapp/test_functions.py @@ -258,7 +258,12 @@ def circle_num_points(num_seg): # num_seg is the number of segments per quarter circle. return (4 * num_seg) + 1 - expected_areas = (169, 136) if connection.ops.postgis else (171, 126) + if connection.ops.postgis: + expected_areas = (169, 136) + elif connection.ops.spatialite: + expected_areas = (168, 135) + else: # Oracle. + expected_areas = (171, 126) qs = Country.objects.annotate( circle=functions.BoundingCircle("mpoly") ).order_by("name") From 5c043286e2fde48a6230cbd2d91d5bdd3c49a418 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Fri, 5 Jan 2024 16:50:48 +0100 Subject: [PATCH 5/5] Simplified dropping spatial indexes on MySQL and Oracle. --- django/contrib/gis/db/backends/mysql/schema.py | 8 ++------ django/contrib/gis/db/backends/oracle/schema.py | 11 ++--------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/django/contrib/gis/db/backends/mysql/schema.py b/django/contrib/gis/db/backends/mysql/schema.py index 1c9fe0e56585..27f6df174a8d 100644 --- a/django/contrib/gis/db/backends/mysql/schema.py +++ b/django/contrib/gis/db/backends/mysql/schema.py @@ -9,7 +9,6 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor): sql_add_spatial_index = "CREATE SPATIAL INDEX %(index)s ON %(table)s(%(column)s)" - sql_drop_spatial_index = "DROP INDEX %(index)s ON %(table)s" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -56,11 +55,8 @@ def add_field(self, model, field): def remove_field(self, model, field): if isinstance(field, GeometryField) and field.spatial_index: - qn = self.connection.ops.quote_name - sql = self.sql_drop_spatial_index % { - "index": qn(self._create_spatial_index_name(model, field)), - "table": qn(model._meta.db_table), - } + index_name = self._create_spatial_index_name(model, field) + sql = self._delete_index_sql(model, index_name) try: self.execute(sql) except OperationalError: diff --git a/django/contrib/gis/db/backends/oracle/schema.py b/django/contrib/gis/db/backends/oracle/schema.py index c9192d03fa02..fd542531ebae 100644 --- a/django/contrib/gis/db/backends/oracle/schema.py +++ b/django/contrib/gis/db/backends/oracle/schema.py @@ -20,7 +20,6 @@ class OracleGISSchemaEditor(DatabaseSchemaEditor): "CREATE INDEX %(index)s ON %(table)s(%(column)s) " "INDEXTYPE IS MDSYS.SPATIAL_INDEX" ) - sql_drop_spatial_index = "DROP INDEX %(index)s" sql_clear_geometry_table_metadata = ( "DELETE FROM USER_SDO_GEOM_METADATA WHERE TABLE_NAME = %(table)s" ) @@ -98,14 +97,8 @@ def remove_field(self, model, field): } ) if field.spatial_index: - self.execute( - self.sql_drop_spatial_index - % { - "index": self.quote_name( - self._create_spatial_index_name(model, field) - ), - } - ) + index_name = self._create_spatial_index_name(model, field) + self.execute(self._delete_index_sql(model, index_name)) super().remove_field(model, field) def run_geometry_sql(self):