aio-libs / yarl

Yet another URL library

Home Page:https://yarl.aio-libs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Test failures with Python 3.12.0b2

hrnciar opened this issue · comments

Describe the bug

Hello, I am experiencing test failures with Python 3.12.0b2. yarl was working with 3.12 up until the 7th alpha. I've consulted this with @encukou and it is happening because of changes in CPython. He will provide more context.

To Reproduce

Build yarl with Python 3.12.0b2.

Expected behavior

All tests pass successfully.

Logs/tracebacks

=================================== FAILURES ===================================
________________________________ test_ipv6_zone ________________________________
    def test_ipv6_zone():
>       url = URL("http://[fe80::822a:a8ff:fe49:470c%тест%42]:123")
tests/test_url.py:239: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../BUILDROOT/python-yarl-1.9.2-2.fc39.aarch64/usr/lib64/python3.12/site-packages/yarl/_url.py:172: in __new__
    val = urlsplit(val)
/usr/lib64/python3.12/urllib/parse.py:500: in urlsplit
    _check_bracketed_host(bracketed_host)
/usr/lib64/python3.12/urllib/parse.py:446: in _check_bracketed_host
    ip = ipaddress.ip_address(hostname) # Throws Value Error if not IPv6 or IPv4
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
address = 'fe80::822a:a8ff:fe49:470c%тест%42'
    def ip_address(address):
        """Take an IP string/int and return an object of the correct type.
    
        Args:
            address: A string or integer, the IP address.  Either IPv4 or
              IPv6 addresses may be supplied; integers less than 2**32 will
              be considered to be IPv4 by default.
    
        Returns:
            An IPv4Address or IPv6Address object.
    
        Raises:
            ValueError: if the *address* passed isn't either a v4 or a v6
              address
    
        """
        try:
            return IPv4Address(address)
        except (AddressValueError, NetmaskValueError):
            pass
    
        try:
            return IPv6Address(address)
        except (AddressValueError, NetmaskValueError):
            pass
    
>       raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address')
E       ValueError: 'fe80::822a:a8ff:fe49:470c%тест%42' does not appear to be an IPv4 or IPv6 address
/usr/lib64/python3.12/ipaddress.py:54: ValueError
__________________________ test_human_repr_delimiters __________________________
    def test_human_repr_delimiters():
        url = URL.build(
            scheme="http",
            user=" !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
            password=" !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
            host="хост.домен",
            port=8080,
            path="/ !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
            query={
                " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~": " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
            },
            fragment=" !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
        )
        s = url.human_repr()
>       assert URL(s) == url
tests/test_url.py:1630: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../BUILDROOT/python-yarl-1.9.2-2.fc39.aarch64/usr/lib64/python3.12/site-packages/yarl/_url.py:172: in __new__
    val = urlsplit(val)
/usr/lib64/python3.12/urllib/parse.py:500: in urlsplit
    _check_bracketed_host(bracketed_host)
/usr/lib64/python3.12/urllib/parse.py:446: in _check_bracketed_host
    ip = ipaddress.ip_address(hostname) # Throws Value Error if not IPv6 or IPv4
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
address = '\\'
    def ip_address(address):
        """Take an IP string/int and return an object of the correct type.
    
        Args:
            address: A string or integer, the IP address.  Either IPv4 or
              IPv6 addresses may be supplied; integers less than 2**32 will
              be considered to be IPv4 by default.
    
        Returns:
            An IPv4Address or IPv6Address object.
    
        Raises:
            ValueError: if the *address* passed isn't either a v4 or a v6
              address
    
        """
        try:
            return IPv4Address(address)
        except (AddressValueError, NetmaskValueError):
            pass
    
        try:
            return IPv6Address(address)
        except (AddressValueError, NetmaskValueError):
            pass
    
>       raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address')
E       ValueError: '\\' does not appear to be an IPv4 or IPv6 address
/usr/lib64/python3.12/ipaddress.py:54: ValueError
__________________________ TestHost.test_masked_ipv4 ___________________________
self = <test_url_parsing.TestHost object at 0xffffad29d250>
    def test_masked_ipv4(self):
>       u = URL("//[127.0.0.1]/")
tests/test_url_parsing.py:182: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../BUILDROOT/python-yarl-1.9.2-2.fc39.aarch64/usr/lib64/python3.12/site-packages/yarl/_url.py:172: in __new__
    val = urlsplit(val)
/usr/lib64/python3.12/urllib/parse.py:500: in urlsplit
    _check_bracketed_host(bracketed_host)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
hostname = '127.0.0.1'
    def _check_bracketed_host(hostname):
        if hostname.startswith('v'):
            if not re.match(r"\Av[a-fA-F0-9]+\..+\Z", hostname):
                raise ValueError(f"IPvFuture address is invalid")
        else:
            ip = ipaddress.ip_address(hostname) # Throws Value Error if not IPv6 or IPv4
            if isinstance(ip, ipaddress.IPv4Address):
>               raise ValueError(f"An IPv4 address cannot be in brackets")
E               ValueError: An IPv4 address cannot be in brackets
/usr/lib64/python3.12/urllib/parse.py:448: ValueError
___________________________ TestHost.test_strange_ip ___________________________
self = <test_url_parsing.TestHost object at 0xffffad29c560>
    def test_strange_ip(self):
>       u = URL("//[-1]/")
tests/test_url_parsing.py:198: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../BUILDROOT/python-yarl-1.9.2-2.fc39.aarch64/usr/lib64/python3.12/site-packages/yarl/_url.py:172: in __new__
    val = urlsplit(val)
/usr/lib64/python3.12/urllib/parse.py:500: in urlsplit
    _check_bracketed_host(bracketed_host)
/usr/lib64/python3.12/urllib/parse.py:446: in _check_bracketed_host
    ip = ipaddress.ip_address(hostname) # Throws Value Error if not IPv6 or IPv4
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
address = '-1'
    def ip_address(address):
        """Take an IP string/int and return an object of the correct type.
    
        Args:
            address: A string or integer, the IP address.  Either IPv4 or
              IPv6 addresses may be supplied; integers less than 2**32 will
              be considered to be IPv4 by default.
    
        Returns:
            An IPv4Address or IPv6Address object.
    
        Raises:
            ValueError: if the *address* passed isn't either a v4 or a v6
              address
    
        """
        try:
            return IPv4Address(address)
        except (AddressValueError, NetmaskValueError):
            pass
    
        try:
            return IPv6Address(address)
        except (AddressValueError, NetmaskValueError):
            pass
    
>       raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address')
E       ValueError: '-1' does not appear to be an IPv4 or IPv6 address
/usr/lib64/python3.12/ipaddress.py:54: ValueError
________________________ TestUserInfo.test_weird_user3 _________________________
self = <test_url_parsing.TestUserInfo object at 0xffffad29d8e0>
    def test_weird_user3(self):
>       u = URL("//[some]@host")
tests/test_url_parsing.py:323: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../BUILDROOT/python-yarl-1.9.2-2.fc39.aarch64/usr/lib64/python3.12/site-packages/yarl/_url.py:172: in __new__
    val = urlsplit(val)
/usr/lib64/python3.12/urllib/parse.py:500: in urlsplit
    _check_bracketed_host(bracketed_host)
/usr/lib64/python3.12/urllib/parse.py:446: in _check_bracketed_host
    ip = ipaddress.ip_address(hostname) # Throws Value Error if not IPv6 or IPv4
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
address = 'some'
    def ip_address(address):
        """Take an IP string/int and return an object of the correct type.
    
        Args:
            address: A string or integer, the IP address.  Either IPv4 or
              IPv6 addresses may be supplied; integers less than 2**32 will
              be considered to be IPv4 by default.
    
        Returns:
            An IPv4Address or IPv6Address object.
    
        Raises:
            ValueError: if the *address* passed isn't either a v4 or a v6
              address
    
        """
        try:
            return IPv4Address(address)
        except (AddressValueError, NetmaskValueError):
            pass
    
        try:
            return IPv6Address(address)
        except (AddressValueError, NetmaskValueError):
            pass
    
>       raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address')
E       ValueError: 'some' does not appear to be an IPv4 or IPv6 address
/usr/lib64/python3.12/ipaddress.py:54: ValueError
=========================== short test summary info ============================
FAILED tests/test_url.py::test_ipv6_zone - ValueError: 'fe80::822a:a8ff:fe49:...
FAILED tests/test_url.py::test_human_repr_delimiters - ValueError: '\\' does ...
FAILED tests/test_url_parsing.py::TestHost::test_masked_ipv4 - ValueError: An...
FAILED tests/test_url_parsing.py::TestHost::test_strange_ip - ValueError: '-1...
FAILED tests/test_url_parsing.py::TestUserInfo::test_weird_user3 - ValueError...
================== 5 failed, 1095 passed, 2 xfailed in 2.37s ===================

Python Version

$ python --version
Python 3.12.0b2

multidict Version

$ python -m pip show multidict
6.0.4

yarl Version

$ python -m pip show yarl
1.9.2

OS

Fedora rawhide x86_64

Additional context

No response

Code of Conduct

  • I agree to follow the aio-libs Code of Conduct

@mjpieters could you cut a new release? I'm on vacation and won't be completing the packaging remake this week.

commented

Hi,
any progress on this?
There is a RC bug from Debian:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1042342

And I can confirm the issue is in 1.9.2 also.

Affects python3.11 and at least yarl 1.8.2-1.9.2.
HEAD is fine