Opened 9 years ago
Closed 9 years ago
#25657 closed Bug (fixed)
gevent-monkeypatching with GIS PointField causes intermittent traceback on shutdown
Reported by: | James Addison | Owned by: | nobody |
---|---|---|---|
Component: | GIS | Version: | 1.9 |
Severity: | Normal | Keywords: | gevent |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
With the following model and a management command script that creates several instances of this model - some with point = None
- I get a traceback on shutdown of the management command script. Note that the instances are created/saved to the database perfectly fine. I also am unable to reproduce without gevent.
from django.contrib.gis.db import models class Provider(models.Model): point = models.PointField(blank=True, null=True)
Management script:
from django.contrib.gis.geos import Point from django.core.management import BaseCommand from businesses.models import Provider class Command(BaseCommand): def handle(self, *args, **options): for i in range(100): Provider.objects.create( point=Point(-123.329773, 48.407326) ) Provider.objects.create( point=None )
Finally, the traceback:
(geos_exception)vagrant@vagrant-ubuntu-trusty-64:/vagrant/geos_exception$ ./manage.py testcomm --settings=geos_exception.settings Exception ignored in: <bound method WKBWriter.__del__ of <django.contrib.gis.geos.prototypes.io.WKBWriter object at 0x7f7b62d85198>> Traceback (most recent call last): File "/home/vagrant/.virtualenvs/geos_exception/lib/python3.4/site-packages/django/contrib/gis/geos/prototypes/io.py", line 137, in __del__ File "/home/vagrant/.virtualenvs/geos_exception/lib/python3.4/site-packages/django/contrib/gis/geos/libgeos.py", line 157, in __call__ File "/home/vagrant/.virtualenvs/geos_exception/lib/python3.4/site-packages/django/contrib/gis/geos/prototypes/threadsafe.py", line 52, in __call__ File "/home/vagrant/.virtualenvs/geos_exception/lib/python3.4/site-packages/gevent/local.py", line 246, in __getattribute__ TypeError: 'NoneType' object is not callable
I am attached a tar.gz file containing the test project. Remember, this issue is intermittent - I can run the management command a time or two without traceback before seeing the problem.
Attachments (1)
Change History (8)
by , 9 years ago
Attachment: | geos_exception.tar.gz added |
---|
comment:1 by , 9 years ago
All of this is related to garbage collection, that's clear. WKBWriter
/ WKBReader
instances have a __del__
method, so they are not part of the normal Python garbage collection cycle (read https://docs.python.org/3/reference/datamodel.html?highlight=__del__#object.__del).
Looking at the traceback though, it seems that the error is happening in gevent
itself, that's why I doubt we'll able to fix this on Django's side. Also note that these errors are more annoying than harmful.
#20903 also reported this (but without reproducible code).
comment:2 by , 9 years ago
New information: I have also seen this traceback, and I haven't even used the model with the PointField
:
Exception ignored in: <bound method Point.__del__ of <Point object at 0x7fb1c9e55a28>> Traceback (most recent call last): File "/home/vagrant/.virtualenvs/myproject/src/django/django/contrib/gis/geos/geometry.py", line 125, in __del__ File "/home/vagrant/.virtualenvs/myproject/src/django/django/contrib/gis/geos/libgeos.py", line 156, in __call__ File "/home/vagrant/.virtualenvs/myproject/src/django/django/contrib/gis/geos/libgeos.py", line 160, in get_func File "<frozen importlib._bootstrap>", line 2237, in _find_and_load File "<frozen importlib._bootstrap>", line 2222, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 2155, in _find_spec TypeError: 'NoneType' object is not iterable
comment:3 by , 9 years ago
Triage Stage: | Unreviewed → Accepted |
---|
I also got one of those exception today with Django 1.8.5/Python 3.4.
I think we should simply catch TypeError
in the destructor methods and ignore in case of exceptions.
So instead of current:
if self._ptr and capi: capi.release_srs(self._ptr)
Let's write:
try: capi.release_srs(self._ptr) except TypeError: pass
comment:4 by , 9 years ago
Version: | 1.9b1 → 1.9 |
---|
comment:6 by , 9 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
Sample project exhibiting the problem.