from django.conf import settings
from django.db import models
from django.utils.encoding import force_bytes, force_str
from django.utils.six import with_metaclass

from cryptography.fernet import Fernet, InvalidToken


fernet = Fernet(settings.FERNET_KEY)


class EncryptedTextField(with_metaclass(models.SubfieldBase, models.TextField)):
    """A TextField encrypted with Fernet (AES).

    EncryptedTextField rely on `Fernet` from `cryptography` to ensure symetric
    encryption. This field is compatible with South migrations.
    """
    def db_type(self, connection):
        return 'bytea'

    def get_prep_value(self, value):
        return fernet.encrypt(force_bytes(value))

    def to_python(self, value):
        try:
            value = fernet.decrypt(force_bytes(value))
        except InvalidToken:
            return value
        else:
            return force_str(value)

    def south_field_triple(self):
        """Returns a suitable description of this field for South."""
        from south.modelsinspector import introspector
        field_class = '{}.{}'.format(self.__class__.__module__, self.__class__.__name__)
        args, kwargs = introspector(self)
        return (field_class, args, kwargs)

from django.conf import settings
from django.db import models
from django.utils.encoding import force_bytes, force_str
from django.utils.six import with_metaclass

from cryptography.fernet import Fernet, InvalidToken


fernet = Fernet(settings.FERNET_KEY)


class EncryptedTextField(with_metaclass(models.SubfieldBase, models.TextField)):
    """A TextField encrypted with Fernet (AES).

    EncryptedTextField rely on `Fernet` from `cryptography` to ensure symetric
    encryption. This field is compatible with South migrations.
    """
    def db_type(self, connection):
        return 'bytea'

    def get_prep_value(self, value):
        return fernet.encrypt(force_bytes(value))

    def to_python(self, value):
        """to_python is called every time an instance of the field is
        assigned a value and when retrieving the value from the database."""
        try:
            value = fernet.decrypt(force_bytes(value))
        except InvalidToken:
            return value
        else:
            return force_str(value)

    def south_field_triple(self):
        """Returns a suitable description of this field for South."""
        from south.modelsinspector import introspector
        field_class = '{}.{}'.format(self.__class__.__module__, self.__class__.__name__)
        args, kwargs = introspector(self)
        return (field_class, args, kwargs)

Add doctring for `to_python` [ci-skip].
Add doctring for `to_python` [ci-skip].

`to_python` is called when assigning and retrieving a value from the
database.

  from django.conf import settings
  from django.db import models
  from django.utils.encoding import force_bytes, force_str
  from django.utils.six import with_metaclass
  
  from cryptography.fernet import Fernet, InvalidToken
  
  
  fernet = Fernet(settings.FERNET_KEY)
  
  
  class EncryptedTextField(with_metaclass(models.SubfieldBase, models.TextField)):
      """A TextField encrypted with Fernet (AES).
  
      EncryptedTextField rely on `Fernet` from `cryptography` to ensure symetric
      encryption. This field is compatible with South migrations.
      """
      def db_type(self, connection):
          return 'bytea'
  
      def get_prep_value(self, value):
          return fernet.encrypt(force_bytes(value))
  
      def to_python(self, value):
+         """to_python is called every time an instance of the field is
+         assigned a value and when retrieving the value from the database."""
          try:
              value = fernet.decrypt(force_bytes(value))
          except InvalidToken:
              return value
          else:
              return force_str(value)
  
      def south_field_triple(self):
          """Returns a suitable description of this field for South."""
          from south.modelsinspector import introspector
          field_class = '{}.{}'.format(self.__class__.__module__, self.__class__.__name__)
          args, kwargs = introspector(self)
          return (field_class, args, kwargs)
  
Add doctring for `to_python` [ci-skip].
## Code Before:
from django.conf import settings
from django.db import models
from django.utils.encoding import force_bytes, force_str
from django.utils.six import with_metaclass

from cryptography.fernet import Fernet, InvalidToken


fernet = Fernet(settings.FERNET_KEY)


class EncryptedTextField(with_metaclass(models.SubfieldBase, models.TextField)):
    """A TextField encrypted with Fernet (AES).

    EncryptedTextField rely on `Fernet` from `cryptography` to ensure symetric
    encryption. This field is compatible with South migrations.
    """
    def db_type(self, connection):
        return 'bytea'

    def get_prep_value(self, value):
        return fernet.encrypt(force_bytes(value))

    def to_python(self, value):
        try:
            value = fernet.decrypt(force_bytes(value))
        except InvalidToken:
            return value
        else:
            return force_str(value)

    def south_field_triple(self):
        """Returns a suitable description of this field for South."""
        from south.modelsinspector import introspector
        field_class = '{}.{}'.format(self.__class__.__module__, self.__class__.__name__)
        args, kwargs = introspector(self)
        return (field_class, args, kwargs)

## Instruction:
Add doctring for `to_python` [ci-skip].
## Code After:
from django.conf import settings
from django.db import models
from django.utils.encoding import force_bytes, force_str
from django.utils.six import with_metaclass

from cryptography.fernet import Fernet, InvalidToken


fernet = Fernet(settings.FERNET_KEY)


class EncryptedTextField(with_metaclass(models.SubfieldBase, models.TextField)):
    """A TextField encrypted with Fernet (AES).

    EncryptedTextField rely on `Fernet` from `cryptography` to ensure symetric
    encryption. This field is compatible with South migrations.
    """
    def db_type(self, connection):
        return 'bytea'

    def get_prep_value(self, value):
        return fernet.encrypt(force_bytes(value))

    def to_python(self, value):
        """to_python is called every time an instance of the field is
        assigned a value and when retrieving the value from the database."""
        try:
            value = fernet.decrypt(force_bytes(value))
        except InvalidToken:
            return value
        else:
            return force_str(value)

    def south_field_triple(self):
        """Returns a suitable description of this field for South."""
        from south.modelsinspector import introspector
        field_class = '{}.{}'.format(self.__class__.__module__, self.__class__.__name__)
        args, kwargs = introspector(self)
        return (field_class, args, kwargs)
