Ticket #22943: validator_patch_2.diff

File validator_patch_2.diff, 11.8 KB (added by antialiasis@…, 10 years ago)

Allow MigrationWriter to serialize compiled regex objects.

  • django/db/migrations/writer.py

    diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py
    index 68f3eb5..4c89439 100644
    a b import decimal  
    66import collections
    77from importlib import import_module
    88import os
     9import re
    910import sys
    1011import types
    1112
    class MigrationWriter(object):  
    344345            # "()", not "(,)" because (,) is invalid Python syntax.
    345346            format = "(%s)" if len(strings) != 1 else "(%s,)"
    346347            return format % (", ".join(strings)), imports
     348        # Compiled regex (#22943)
     349        elif isinstance(value, type(re.compile(''))):
     350            imports = set(["import re"])
     351            regex_pattern, pattern_imports = cls.serialize(value.pattern)
     352            regex_flags, flag_imports = cls.serialize(value.flags)
     353            imports.update(pattern_imports)
     354            imports.update(flag_imports)
     355            args = [regex_pattern]
     356            if value.flags:
     357                args.append(regex_flags)
     358            return "re.compile(%s)" % ', '.join(args), imports
    347359        # Uh oh.
    348360        else:
    349361            raise ValueError("Cannot serialize: %r\nThere are some values Django cannot serialize into migration files.\nFor more, see https://docs.djangoproject.com/en/dev/topics/migrations/#migration-serializing" % value)
  • docs/releases/1.7.txt

    diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt
    index b738d16..6c75519 100644
    a b Miscellaneous  
    12721272  a relation from the related object back to the content type for filtering,
    12731273  ordering and other query operations.
    12741274
    1275 * When a model field's :attr:`~django.db.models.Field.validators` contains
    1276   a :class:`~django.core.validators.RegexValidator`, the regular expression
    1277   must now be passed as a regular expression string. You can no longer use a
    1278   pre-compiled regular expression in this case, as it is not serializable.
    1279   The :attr:`~django.core.validators.RegexValidator.flags` attribute was added
    1280   to :class:`~django.core.validators.RegexValidator` to simplify this change.
    1281 
    12821275* When running tests on PostgreSQL, the :setting:`USER` will need read access
    12831276  to the built-in ``postgres`` database. This is in lieu of the previous
    12841277  behavior of connecting to the actual non-test database.
  • tests/migrations/test_writer.py

    diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py
    index cce0775..67915e7 100644
    a b  
    22from __future__ import unicode_literals
    33
    44import datetime
     5import re
    56import os
    67import tokenize
    78import unittest
    89
    9 from django.core.validators import RegexValidator, EmailValidator
     10from django.core.validators import RegexValidator, EmailValidator, validate_slug
    1011from django.db import models, migrations
    1112from django.db.migrations.writer import MigrationWriter, SettingsReference
    1213from django.test import TestCase
    class WriterTests(TestCase):  
    104105        self.assertEqual(string, repr(datetime.datetime(2014, 3, 31, 16, 4, 31)))
    105106        self.assertEqual(imports, {'import datetime'})
    106107        # Classes
    107         validator = RegexValidator(message="hello")
    108         string, imports = MigrationWriter.serialize(validator)
    109         self.assertEqual(string, "django.core.validators.RegexValidator(message='hello')")
    110         self.serialize_round_trip(validator)
    111         validator = EmailValidator(message="hello")  # Test with a subclass.
    112         string, imports = MigrationWriter.serialize(validator)
    113         self.assertEqual(string, "django.core.validators.EmailValidator(message='hello')")
    114         self.serialize_round_trip(validator)
    115         validator = deconstructible(path="custom.EmailValidator")(EmailValidator)(message="hello")
    116         string, imports = MigrationWriter.serialize(validator)
    117         self.assertEqual(string, "custom.EmailValidator(message='hello')")
    118108        # Django fields
    119109        self.assertSerializedFieldEqual(models.CharField(max_length=255))
    120110        self.assertSerializedFieldEqual(models.TextField(null=True, blank=True))
    class WriterTests(TestCase):  
    135125            )
    136126        )
    137127
     128    def test_serialize_validators(self):
     129        """
     130        Test serialization of class-based validators, including
     131        regexes.
     132        """
     133        validator = RegexValidator(message="hello")
     134        string, imports = MigrationWriter.serialize(validator)
     135        self.assertEqual(string, "django.core.validators.RegexValidator(message='hello')")
     136        self.serialize_round_trip(validator)
     137
     138        validator = RegexValidator(regex=re.compile('^\\w+$', re.U))  # Test with a compiled regex.
     139        string, imports = MigrationWriter.serialize(validator)
     140        self.assertEqual(string, "django.core.validators.RegexValidator(regex=re.compile('^\\\\w+$', 32))")
     141        self.serialize_round_trip(validator)
     142
     143        validator = validate_slug
     144        string, imports = MigrationWriter.serialize(validator)
     145        self.assertEqual(string, "django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+$'), \"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.\", 'invalid')")
     146        self.serialize_round_trip(validator)
     147
     148        validator = EmailValidator(message="hello")  # Test with a subclass.
     149        string, imports = MigrationWriter.serialize(validator)
     150        self.assertEqual(string, "django.core.validators.EmailValidator(message='hello')")
     151        self.serialize_round_trip(validator)
     152
     153        validator = deconstructible(path="custom.EmailValidator")(EmailValidator)(message="hello")
     154        string, imports = MigrationWriter.serialize(validator)
     155        self.assertEqual(string, "custom.EmailValidator(message='hello')")
     156
    138157    def test_serialize_empty_nonempty_tuple(self):
    139158        """
    140159        Ticket #22679: makemigrations generates invalid code for (an empty
Back to Top