worth adding PyPy to continuous integration?

160 views
Skip to first unread message

Tim Graham

unread,
Dec 2, 2015, 11:46:38 AM12/2/15
to Django developers (Contributions to Django itself)
Once in a while, we get a ticket about failures when running the Django test suite on PyPy. Sometimes they are bugs in PyPy, other times we use something that's not available or behaves differently in PyPy. Is it worth adding PyPy to our continuous integration so we can proactively address these issues?

(We can't test with pypy3 since that's based on Python 3.2 which we've dropped support for in Django 1.9.)

Recent tickets:
https://code.djangoproject.com/ticket/24779
https://code.djangoproject.com/ticket/25844

Current failures with pypy 2.4.0 and Django 1.9:

======================================================================
ERROR: test_serialize_datetime (migrations.test_writer.WriterTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/tests/migrations/test_writer.py", line 248, in test_serialize_datetime
    self.assertSerializedEqual(datetime.datetime.utcnow)
  File "/home/tim/code/django/tests/migrations/test_writer.py", line 179, in assertSerializedEqual
    self.assertEqual(self.serialize_round_trip(value), value)
  File "/home/tim/code/django/tests/migrations/test_writer.py", line 175, in serialize_round_trip
    string, imports = MigrationWriter.serialize(value)
  File "/home/tim/code/django/django/db/migrations/writer.py", line 540, in serialize
    "topics/migrations/#migration-serializing" % (value, get_docs_version())
ValueError: Cannot serialize: <bound method type.utcnow of <class 'datetime.datetime'>>
There are some values Django cannot serialize into migration files.
For more, see https://docs.djangoproject.com/en/dev/topics/migrations/#migration-serializing

======================================================================
ERROR: test_simple_migration (migrations.test_writer.WriterTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/tests/migrations/test_writer.py", line 459, in test_simple_migration
    output = writer.as_string()
  File "/home/tim/code/django/django/db/migrations/writer.py", line 167, in as_string
    operation_string, operation_imports = OperationWriter(operation).serialize()
  File "/home/tim/code/django/django/db/migrations/writer.py", line 124, in serialize
    _write(arg_name, arg_value)
  File "/home/tim/code/django/django/db/migrations/writer.py", line 76, in _write
    arg_string, arg_imports = MigrationWriter.serialize(item)
  File "/home/tim/code/django/django/db/migrations/writer.py", line 357, in serialize
    item_string, item_imports = cls.serialize(item)
  File "/home/tim/code/django/django/db/migrations/writer.py", line 433, in serialize
    return cls.serialize_deconstructed(path, args, kwargs)
  File "/home/tim/code/django/django/db/migrations/writer.py", line 318, in serialize_deconstructed
    arg_string, arg_imports = cls.serialize(arg)
  File "/home/tim/code/django/django/db/migrations/writer.py", line 540, in serialize
    "topics/migrations/#migration-serializing" % (value, get_docs_version())
ValueError: Cannot serialize: <bound method type.utcnow of <class 'datetime.datetime'>>
There are some values Django cannot serialize into migration files.
For more, see https://docs.djangoproject.com/en/dev/topics/migrations/#migration-serializing

======================================================================
ERROR: test_band_data_setters (gis_tests.gdal_tests.test_raster.GDALBandTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/tests/gis_tests/gdal_tests/test_raster.py", line 357, in test_band_data_setters
    bandmem.data(packed_block, (1, 1), (2, 2))
  File "/home/tim/code/django/django/contrib/gis/gdal/raster/band.py", line 133, in data
    data_array = ctypes_array.from_buffer_copy(data)
AttributeError: type object 'c_ubyte_Array_4' has no attribute 'from_buffer_copy'

======================================================================
FAIL: test_prefetch_related_queryset (model_forms.tests.OtherModelFormTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/tests/model_forms/tests.py", line 2308, in test_prefetch_related_queryset
    (red_item.pk, 'red'),
  File "/home/tim/code/django/django/test/testcases.py", line 93, in __exit__
    query['sql'] for query in self.captured_queries
AssertionError: 2 queries executed, 4 expected
Captured queries were:
SELECT "model_forms_colourfulitem"."id", "model_forms_colourfulitem"."name" FROM "model_forms_colourfulitem"
SELECT ("model_forms_colourfulitem_colours"."colourfulitem_id") AS "_prefetch_related_val_colourfulitem_id", "model_forms_colour"."id", "model_forms_colour"."name" FROM "model_forms_colour" INNER JOIN "model_forms_colourfulitem_colours" ON ("model_forms_colour"."id" = "model_forms_colourfulitem_colours"."colour_id") WHERE "model_forms_colourfulitem_colours"."colourfulitem_id" IN (1, 2)

======================================================================
FAIL: test_load_backend_invalid_name (backends.test_utils.TestLoadBackend)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/tests/backends/test_utils.py", line 16, in test_load_backend_invalid_name
    load_backend('foo')
  File "/opt/pypy-2.4.0/lib-python/2.7/contextlib.py", line 35, in __exit__
    self.gen.throw(type, value, traceback)
  File "/home/tim/code/django/django/test/testcases.py", line 612, in _assert_raises_message_cm
    self.assertIn(expected_message, str(cm.exception))
AssertionError: "'foo' isn't an available database backend.\nTry using 'django.db.backends.XXX', where XXX is one of:\n    'mysql', 'oracle', 'postgresql', 'sqlite3'\nError was: No module named foo.base" not found in "'foo' isn't an available database backend.\nTry using 'django.db.backends.XXX', where XXX is one of:\n    'mysql', 'oracle', 'postgresql', 'sqlite3'\nError was: No module named foo"

======================================================================
FAIL: test_graph_iterative (migrations.test_graph.GraphTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/tests/migrations/test_graph.py", line 203, in test_graph_iterative
    self.assertEqual(len(w), 1)
AssertionError: 0 != 1

======================================================================
FAIL: test_serialize_datetime_safe (migrations.test_writer.WriterTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/tests/migrations/test_writer.py", line 271, in test_serialize_datetime_safe
    ("datetime.date(2014, 3, 31)", {'import datetime'})
  File "/home/tim/code/django/tests/migrations/test_writer.py", line 182, in assertSerializedResultEqual
    self.assertEqual(MigrationWriter.serialize(value), target)
AssertionError: Tuples differ: (u'datetime.datetime.date(2014... != (u'datetime.date(2014, 3, 31)'...

First differing element 0:
datetime.datetime.date(2014, 3, 31)
datetime.date(2014, 3, 31)

- (u'datetime.datetime.date(2014, 3, 31)', set([u'import datetime']))
?    ---------

+ (u'datetime.date(2014, 3, 31)', set([u'import datetime']))

======================================================================
FAIL: test_band_data (gis_tests.gdal_tests.test_raster.GDALBandTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tim/code/django/tests/gis_tests/gdal_tests/test_raster.py", line 309, in test_band_data
    self.assertEqual(self.band.max, 255)
AssertionError: 9.0 != 255

----------------------------------------------------------------------
Ran 10408 tests in 564.183s

FAILED (failures=5, errors=3, skipped=894, expected failures=7)

Marc Tamlyn

unread,
Dec 2, 2015, 11:52:24 AM12/2/15
to django-d...@googlegroups.com
If we can get it running on the CI reasonably easily I see no reason why not.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/8d525073-8011-49cc-9965-a0ef4ccf438f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Josh Smeaton

unread,
Dec 3, 2015, 12:56:50 AM12/3/15
to Django developers (Contributions to Django itself)
Shouldn't we decide if we want to support pypy first? By putting it on CI that's an implicit agreement to support pypy potentially at the cost of certain features.

There's also the consideration that python2 is going away in django 2.0, so if pypy3 isn't up to date wrt python3, we'd have to drop pypy.

Tim Graham

unread,
Dec 3, 2015, 10:09:38 AM12/3/15
to Django developers (Contributions to Django itself)
Yes, exactly Josh. I was hoping someone familiar with pypy could offer some insight. I think we can only add continuous integration support if at least a couple champion the effort and make themselves available to help with issues as they arise. As far as I know, we don't currently have this expertise on the Django team. It seems like at least a few people are using Django on pypy with at least some success (actually our docs say Django is compatible [1]).

[1] https://docs.djangoproject.com/en/dev/topics/performance/#id1

Those test failures I posted are with pypy 2.4.0 which I installed sometime ago. With the latest version pypy 4.0.1 the test aborts part way through with:

Python traceback:
  File "pypy_module_pypyjit_interp_jit.c", line 102, in jump_absolute__AccessDirect_None
  File "rpython_jit_metainterp_warmstate.c", line 17762, in maybe_compile_and_run__star_5_1
  File "rpython_jit_metainterp_warmstate.c", line 46755, in bound_reached__star_5_1
  File "rpython_jit_metainterp_pyjitpl.c", line 18015, in compile_and_run_once___rpython_jit_metainterp_ji_23
  File "rpython_jit_metainterp_pyjitpl.c", line 4721, in MetaInterp__compile_and_run_once
  File "rpython_jit_metainterp_pyjitpl.c", line 19485, in MetaInterp_interpret
  File "rpython_jit_metainterp_pyjitpl.c", line 32873, in MetaInterp__interpret
  File "rpython_jit_metainterp_pyjitpl.c", line 48286, in MIFrame_run_one_step
  File "rpython_jit_metainterp_pyjitpl_2.c", line 4858, in MIFrame_opimpl_jit_merge_point
  File "rpython_jit_metainterp_pyjitpl_2.c", line 59878, in MetaInterp_reached_loop_header
  File "rpython_jit_metainterp_pyjitpl_3.c", line 30731, in MetaInterp_compile_loop
  File "rpython_jit_metainterp_compile.c", line 11591, in compile_loop
  File "rpython_jit_metainterp_optimizeopt___init__.c", line 224, in optimize_trace
  File "rpython_jit_metainterp_optimizeopt_unroll.c", line 5499, in UnrollOptimizer_optimize_peeled_loop
  File "rpython_jit_metainterp_optimizeopt_unroll.c", line 17039, in UnrollOptimizer_jump_to_existing_trace
  File "rpython_jit_metainterp_optimizeopt_unroll.c", line 22464, in UnrollOptimizer_inline_short_preamble
  File "rpython_jit_metainterp_optimizeopt_unroll.c", line 24548, in UnrollOptimizer__map_args
~~~ Crash in JIT! <KeyError object at 0x7f6481610388>
Aborted (core dumped)

Markus Holtermann

unread,
Dec 3, 2015, 4:36:04 PM12/3/15
to django-d...@googlegroups.com
Hey Tim,

I think we should at least run the tests occasionally and see if they pass and if not see how much effort it takes to fix problems.

Regarding the migration date issues, I fixed them in newer PyPy versions: https://bitbucket.org/pypy/pypy/issues/2062/inconsistency-in-__repr__-for-date-time

/Markus
Reply all
Reply to author
Forward
0 new messages