Convert an IRI to a URI. All non-ASCII and unsafe characters are quoted. If the URL has a domain, it is encoded to Punycode. >>> iri_to_uri('http://\\u2603.net/p\\xe5th?q=\\xe8ry%DF') 'http://xn--n3h.net/p%C3%A5th?q=%C3%A8ry%DF' :param iri: The IRI to convert. .. versionchange
(iri: str)
| 111 | |
| 112 | |
| 113 | def iri_to_uri(iri: str) -> str: |
| 114 | """Convert an IRI to a URI. All non-ASCII and unsafe characters are |
| 115 | quoted. If the URL has a domain, it is encoded to Punycode. |
| 116 | |
| 117 | >>> iri_to_uri('http://\\u2603.net/p\\xe5th?q=\\xe8ry%DF') |
| 118 | 'http://xn--n3h.net/p%C3%A5th?q=%C3%A8ry%DF' |
| 119 | |
| 120 | :param iri: The IRI to convert. |
| 121 | |
| 122 | .. versionchanged:: 3.0 |
| 123 | Passing a tuple or bytes, the ``charset`` and ``errors`` parameters, |
| 124 | and the ``safe_conversion`` parameter, are removed. |
| 125 | |
| 126 | .. versionchanged:: 2.3 |
| 127 | Which characters remain unquoted is specific to each part of the URL. |
| 128 | |
| 129 | .. versionchanged:: 0.15 |
| 130 | All reserved characters remain unquoted. Previously, only some reserved |
| 131 | characters were left unquoted. |
| 132 | |
| 133 | .. versionchanged:: 0.9.6 |
| 134 | The ``safe_conversion`` parameter was added. |
| 135 | |
| 136 | .. versionadded:: 0.6 |
| 137 | """ |
| 138 | parts = urlsplit(iri) |
| 139 | # safe = https://url.spec.whatwg.org/#url-path-segment-string |
| 140 | # as well as percent for things that are already quoted |
| 141 | path = quote(parts.path, safe="%!$&'()*+,/:;=@") |
| 142 | query = quote(parts.query, safe="%!$&'()*+,/:;=?@") |
| 143 | fragment = quote(parts.fragment, safe="%!#$&'()*+,/:;=?@") |
| 144 | |
| 145 | if parts.hostname: |
| 146 | netloc = parts.hostname.encode("idna").decode("ascii") |
| 147 | else: |
| 148 | netloc = "" |
| 149 | |
| 150 | if ":" in netloc: |
| 151 | netloc = f"[{netloc}]" |
| 152 | |
| 153 | if parts.port: |
| 154 | netloc = f"{netloc}:{parts.port}" |
| 155 | |
| 156 | if parts.username: |
| 157 | auth = quote(parts.username, safe="%!$&'()*+,;=") |
| 158 | |
| 159 | if parts.password: |
| 160 | password = quote(parts.password, safe="%!$&'()*+,;=") |
| 161 | auth = f"{auth}:{password}" |
| 162 | |
| 163 | netloc = f"{auth}@{netloc}" |
| 164 | |
| 165 | return urlunsplit((parts.scheme, netloc, path, query, fragment)) |
| 166 | |
| 167 | |
| 168 | # Python < 3.12 |
no outgoing calls