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 · 6 comments
Closed

Support for IpAddress #333

samuelcolvin opened this issue Dec 27, 2018 · 6 comments

Comments

@samuelcolvin
Copy link
Owner

@samuelcolvin samuelcolvin commented Dec 27, 2018

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
Owner Author

@samuelcolvin samuelcolvin commented Jan 20, 2019

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 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
Owner Author

@samuelcolvin samuelcolvin commented Mar 15, 2019

yes please, reopened this.

@haizaar
Copy link
Contributor

@haizaar 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 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
Owner Author

@samuelcolvin samuelcolvin commented Apr 4, 2019

Yes should be supported.

@pilosus would be great if you could do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants