Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for IpAddress #333

Closed
samuelcolvin opened this issue Dec 27, 2018 · 7 comments
Closed

Support for IpAddress #333

samuelcolvin opened this issue Dec 27, 2018 · 7 comments
Labels
feature request help wanted Pull Request welcome

Comments

@samuelcolvin
Copy link
Member

Feature Request

https://docs.python.org/3/library/ipaddress.html

Both the stdlib IPv4Address and IPv6Address should work out of the box, also I guess IPAddress or IPvXAddress class will have to be included in pydantic which allows both v4 and v6 addresses. I guess this should inherit from _BaseAddress in Lib/ipaddress.py

@samuelcolvin
Copy link
Member Author

I guess IPv4Network and IPv4Interface and their v6 equivalents should also be supported.

This would be a great issue for anyone new keen to contribute to pydantic.

@pilosus
Copy link
Contributor

pilosus commented Mar 15, 2019

@samuelcolvin
#417 implements IPv4Address and IPv6Address but doesn't support networks and interfaces from ipaddress. I've been working on the networks and interfaces. Please, let me know if I should submit a PR once networks and interfaces are completed or their support's no longer needed.

@samuelcolvin samuelcolvin reopened this Mar 15, 2019
@samuelcolvin
Copy link
Member Author

yes please, reopened this.

@haizaar
Copy link
Contributor

haizaar commented Apr 4, 2019

Is json serialization supposed to work for this field? Is it just a matter of adding it to ENCODERS_BY_TYPE?

$ pip freeze |grep pydantic
pydantic==0.22
$ cat /tmp/my.py
from pydantic import BaseModel
from ipaddress import IPv4Address

class Model(BaseModel):
    ip: IPv4Address

Model(ip="127.0.0.1").json()
$ python /tmp/my.py
Traceback (most recent call last):
  File "/home/.../python3.7/site-packages/pydantic/json.py", line 38, in pydantic_encoder
    encoder = ENCODERS_BY_TYPE[type(obj)]
KeyError: <class 'ipaddress.IPv4Address'>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/tmp/my.py", line 9, in <module>
    Model(ip="127.0.0.1").json()
  File "/home/.../python3.7/site-packages/pydantic/main.py", line 308, in json
    **dumps_kwargs,
  File "/usr/lib/python3.7/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/usr/lib/python3.7/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.7/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/home/.../python3.7/site-packages/pydantic/json.py", line 40, in pydantic_encoder
    raise TypeError(f"Object of type '{obj.__class__.__name__}' is not JSON serializable")
TypeError: Object of type 'IPv4Address' is not JSON serializable

@pilosus
Copy link
Contributor

pilosus commented Apr 4, 2019

ipaddress address, interface and network object are indeed not serializable by default, they should be converted to str. I personally think we should support this conversion just like we do for UUID objects.
Yes, extending ENCODERS_BY_TYPE with these keys will solve the problem:

ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = {
    IPv4Address: str,
    IPv6Address: str,
    IPv4Interface: str,
    IPv6Interface: str,
    IPv4Network: str,
    IPv6Network: str,
    ...

Unittests to tests/test_json.py should also be added.
@samuelcolvin I'm not sure if a new issue should be open or it's okay to use this one. Anyway, If my help needed, please tag me, I'll fix serialization in a matter a few hours.

@samuelcolvin
Copy link
Member Author

Yes should be supported.

@pilosus would be great if you could do this.

@alex-eri
Copy link

>>> pydantic.__version__
'2.5.2'
>>> from pydantic import IPvAnyAddress
>>> import json
>>> ip=IPvAnyAddress("127.0.0.1")
>>> json.dumps(ip)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.12/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/json/encoder.py", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/json/encoder.py", line 258, in iterencode
    return _iterencode(o, 0)
           ^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/json/encoder.py", line 180, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type IPv4Address is not JSON serializable
>>>

I have error...

alexdrydew pushed a commit to alexdrydew/pydantic that referenced this issue Dec 23, 2023
* add s390x & ppc64le linux binaries

* bump

* setting interpreter and container
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request help wanted Pull Request welcome
Projects
None yet
Development

No branches or pull requests

4 participants