# Source code for sqlalchemy_utils.types.ip_address

    import six
    from sqlalchemy import types

    from ..exceptions import ImproperlyConfigured
    from .scalar_coercible import ScalarCoercible

    ip_address = None
    try:
        from ipaddress import ip_address
    except ImportError:
        try:
            from ipaddr import IPAddress as ip_address
        except ImportError:
            pass

    class IPAddressType(types.TypeDecorator, ScalarCoercible):
        """
        Changes IPAddress objects to a string representation on the way in and
        changes them back to IPAddress objects on the way out.

        IPAddressType uses ipaddress package on Python >= 3 and ipaddr_ package on
        Python 2. In order to use IPAddressType with python you need to install
        ipaddr_ first.

        .. _ipaddr: https://pypi.python.org/pypi/ipaddr

        ::

            from sqlalchemy_utils import IPAddressType

            class User(Base):
                __tablename__ = 'user'
                id = sa.Column(sa.Integer, autoincrement=True)
                name = sa.Column(sa.Unicode(255))
                ip_address = sa.Column(IPAddressType)

            user = User()
            user.ip_address = '123.123.123.123'
            session.add(user)
            session.commit()

            user.ip_address  # IPAddress object
        """

        impl = types.Unicode(50)

        def __init__(self, max_length=50, *args, **kwargs):
            if not ip_address:
                raise ImproperlyConfigured(
                    "'ipaddr' package is required to use 'IPAddressType' "
                    "in python 2"
                )

            super(IPAddressType, self).__init__(*args, **kwargs)
            self.impl = types.Unicode(max_length)

        def process_bind_param(self, value, dialect):
            return six.text_type(value) if value else None

        def process_result_value(self, value, dialect):
            return ip_address(value) if value else None

        def _coerce(self, value):
            return ip_address(value) if value else None

        @property
        def python_type(self):
            return self.impl.type.python_type