# Changelog

## To be included in v1.22.0- (if present)

## Released versions

## 1.22.0

(2025-10-05)

### Features

- Added arm64 Windows wheel builds – by @finnagin.

  Related issues and pull requests on GitHub: #1516.

## 1.21.0

(2025-10-05)

### Contributor-facing changes

- The `reusable-cibuildwheel.yml` workflow has been refactored to be more generic and `ci-cd.yml` now holds all the configuration toggles – by @webknjaz.

  Related issues and pull requests on GitHub: #1535.

- When building wheels, the source distribution is now passed directly to the `cibuildwheel` invocation – by @webknjaz.

  Related issues and pull requests on GitHub: #1536.

- Added CI for Python 3.14 – by @kumaraditya303.

  Related issues and pull requests on GitHub: #1560.

## 1.20.1

(2025-06-09)

### Bug fixes

- Started raising a `ValueError` exception raised for corrupted IPv6 URL values.

  These fixes the issue where exception `IndexError` was leaking from the internal code because of not being handled and transformed into a user-facing error. The problem was happening under the following conditions: empty IPv6 URL, brackets in reverse order.

  – by @MaelPic.

  Related issues and pull requests on GitHub: #1512.

### Packaging updates and notes for downstreams

- Updated to use Cython 3.1 universally across the build path – by @lysnikolaou.

  Related issues and pull requests on GitHub: #1514.

- Made Cython line tracing opt-in via the `with-cython-tracing` build config setting – by @bdraco.

  Previously, line tracing was enabled by default in `pyproject.toml`, which caused build issues for some users and made wheels nearly twice as slow. Now line tracing is only enabled when explicitly requested via `pip install . --config-setting=with-cython-tracing=true` or by setting the `YARL_CYTHON_TRACING` environment variable.

  Related issues and pull requests on GitHub: #1521.

## 1.20.0

(2025-04-16)

### Features

- Implemented support for the free-threaded build of CPython 3.13 – by @lysnikolaou.

  Related issues and pull requests on GitHub: #1456.

### Packaging updates and notes for downstreams

- Started building wheels for the free-threaded build of CPython 3.13 – by @lysnikolaou.

  Related issues and pull requests on GitHub: #1456.

## 1.19.0

(2025-04-05)

### Bug fixes

- Fixed entire name being re-encoded when using `yarl.URL.with_suffix()` – by @NTFSvolume.

  Related issues and pull requests on GitHub: #1468.

### Features

- Started building armv7l wheels for manylinux – by @bdraco.

  Related issues and pull requests on GitHub: #1495.

### Contributor-facing changes

- GitHub Actions CI/CD is now configured to manage caching pip-ecosystem dependencies using re-actors/cache-python-deps – an action by @webknjaz that takes into account ABI stability and the exact version of Python runtime.

  Related issues and pull requests on GitHub: #1471.

- Increased minimum propcache version to 0.2.1 to fix failing tests – by @bdraco.

  Related issues and pull requests on GitHub: #1479.

- Added all hidden folders to pytest’s `norecursedirs` to prevent it from trying to collect tests there – by @lysnikolaou.

  Related issues and pull requests on GitHub: #1480.

### Miscellaneous internal changes

- Improved accuracy of type annotations – by @Dreamsorcerer.

  Related issues and pull requests on GitHub: #1484.

- Improved performance of parsing query strings – by @bdraco.

  Related issues and pull requests on GitHub: #1493, #1497.

- Improved performance of the C unquoter – by @bdraco.

  Related issues and pull requests on GitHub: #1496, #1498.

## 1.18.3

(2024-12-01)

### Bug fixes

- Fixed uppercase ASCII hosts being rejected by `URL.build()` and `with_host()` – by @bdraco.

  Related issues and pull requests on GitHub: #954, #1442.

### Miscellaneous internal changes

- Improved performances of multiple path properties on cache miss – by @bdraco.

  Related issues and pull requests on GitHub: #1443.

## 1.18.2

(2024-11-29)

No significant changes.

## 1.18.1

(2024-11-29)

### Miscellaneous internal changes

- Improved cache performance when `URL` objects are constructed from `build()` with `encoded=True` – by @bdraco.

  Related issues and pull requests on GitHub: #1432.

- Improved cache performance for operations that produce a new `URL` object – by @bdraco.

  Related issues and pull requests on GitHub: #1434, #1436.

## 1.18.0

(2024-11-21)

### Features

- Added `keep_query` and `keep_fragment` flags in the `yarl.URL.with_path()`, `yarl.URL.with_name()` and `yarl.URL.with_suffix()` methods, allowing users to optionally retain the query string and fragment in the resulting URL when replacing the path – by @paul-nameless.

  Related issues and pull requests on GitHub: #111, #1421.

### Contributor-facing changes

- Started running downstream `aiohttp` tests in CI – by @Cycloctane.

  Related issues and pull requests on GitHub: #1415.

### Miscellaneous internal changes

- Improved performance of converting `URL` to a string – by @bdraco.

  Related issues and pull requests on GitHub: #1422.

## 1.17.2

(2024-11-17)

### Bug fixes

- Stopped implicitly allowing the use of Cython pre-release versions when building the distribution package – by @ajsanchezsanz and @markgreene74.

  Related issues and pull requests on GitHub: #1411, #1412.

- Fixed a bug causing `port` to return the default port when the given port was zero – by @gmacon.

  Related issues and pull requests on GitHub: #1413.

### Features

- Make error messages include details of incorrect type when `port` is not int in `build()`. – by @Cycloctane.

  Related issues and pull requests on GitHub: #1414.

### Packaging updates and notes for downstreams

- Stopped implicitly allowing the use of Cython pre-release versions when building the distribution package – by @ajsanchezsanz and @markgreene74.

  Related issues and pull requests on GitHub: #1411, #1412.

### Miscellaneous internal changes

- Improved performance of the `joinpath()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1418.

## 1.17.1

(2024-10-30)

### Miscellaneous internal changes

- Improved performance of many `URL` methods – by @bdraco.

  Related issues and pull requests on GitHub: #1396, #1397, #1398.

- Improved performance of passing a `dict` or `str` to `extend_query()` – by @bdraco.

  Related issues and pull requests on GitHub: #1401.

## 1.17.0

(2024-10-28)

### Features

- Added `host_port_subcomponent` which returns the RFC 3986 Section 3.2.2 host and RFC 3986 Section 3.2.3 port subcomponent – by @bdraco.

  Related issues and pull requests on GitHub: #1375.

## 1.16.0

(2024-10-21)

### Bug fixes

- Fixed blocking I/O to load Python code when creating a new `URL` with non-ascii characters in the network location part – by @bdraco.

  Related issues and pull requests on GitHub: #1342.

### Removals and backward incompatible breaking changes

- Migrated to using a single cache for encoding hosts – by @bdraco.

  Passing `ip_address_size` and `host_validate_size` to `cache_configure()` is deprecated in favor of the new `encode_host_size` parameter and will be removed in a future release. For backwards compatibility, the old parameters affect the `encode_host` cache size.

  Related issues and pull requests on GitHub: #1348, #1357, #1363.

### Miscellaneous internal changes

- Improved performance of constructing `URL` – by @bdraco.

  Related issues and pull requests on GitHub: #1336.

- Improved performance of calling `build()` and constructing unencoded `URL` – by @bdraco.

  Related issues and pull requests on GitHub: #1345.

- Reworked the internal encoding cache to improve performance on cache hit – by @bdraco.

  Related issues and pull requests on GitHub: #1369.

## 1.15.5

(2024-10-18)

### Miscellaneous internal changes

- Improved performance of the `joinpath()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1304.

- Improved performance of the `extend_query()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1305.

- Improved performance of the `origin()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1306.

- Improved performance of the `with_path()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1307.

- Improved performance of the `with_query()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1308, #1328.

- Improved performance of the `update_query()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1309, #1327.

- Improved performance of the `join()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1313.

- Improved performance of `URL` equality checks – by @bdraco.

  Related issues and pull requests on GitHub: #1315.

- Improved performance of `URL` methods that modify the network location – by @bdraco.

  Related issues and pull requests on GitHub: #1316.

- Improved performance of the `with_fragment()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1317.

- Improved performance of calculating the hash of `URL` objects – by @bdraco.

  Related issues and pull requests on GitHub: #1318.

- Improved performance of the `relative()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1319.

- Improved performance of the `with_name()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1320.

- Improved performance of `parent` – by @bdraco.

  Related issues and pull requests on GitHub: #1321.

- Improved performance of the `with_scheme()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1322.

## 1.15.4

(2024-10-16)

### Miscellaneous internal changes

- Improved performance of the quoter when all characters are safe – by @bdraco.

  Related issues and pull requests on GitHub: #1288.

- Improved performance of unquoting strings – by @bdraco.

  Related issues and pull requests on GitHub: #1292, #1293.

- Improved performance of calling `build()` – by @bdraco.

  Related issues and pull requests on GitHub: #1297.

## 1.15.3

(2024-10-15)

### Bug fixes

- Fixed `build()` failing to validate paths must start with a `/` when passing `authority` – by @bdraco.

  The validation only worked correctly when passing `host`.

  Related issues and pull requests on GitHub: #1265.

### Removals and backward incompatible breaking changes

- Removed support for Python 3.8 as it has reached end of life – by @bdraco.

  Related issues and pull requests on GitHub: #1203.

### Miscellaneous internal changes

- Improved performance of constructing `URL` when the net location is only the host – by @bdraco.

  Related issues and pull requests on GitHub: #1271.

## 1.15.2

(2024-10-13)

### Miscellaneous internal changes

- Improved performance of converting `URL` to a string – by @bdraco.

  Related issues and pull requests on GitHub: #1234.

- Improved performance of `joinpath()` – by @bdraco.

  Related issues and pull requests on GitHub: #1248, #1250.

- Improved performance of constructing query strings from `MultiDict` – by @bdraco.

  Related issues and pull requests on GitHub: #1256.

- Improved performance of constructing query strings with `int` values – by @bdraco.

  Related issues and pull requests on GitHub: #1259.

## 1.15.1

(2024-10-12)

### Miscellaneous internal changes

- Improved performance of calling `build()` – by @bdraco.

  Related issues and pull requests on GitHub: #1222.

- Improved performance of all `URL` methods that create new `URL` objects – by @bdraco.

  Related issues and pull requests on GitHub: #1226.

- Improved performance of `URL` methods that modify the network location – by @bdraco.

  Related issues and pull requests on GitHub: #1229.

## 1.15.0

(2024-10-11)

### Bug fixes

- Fixed validation with `with_scheme()` when passed scheme is not lowercase – by @bdraco.

  Related issues and pull requests on GitHub: #1189.

### Features

- Started building `armv7l` wheels – by @bdraco.

  Related issues and pull requests on GitHub: #1204.

### Miscellaneous internal changes

- Improved performance of constructing unencoded `URL` objects – by @bdraco.

  Related issues and pull requests on GitHub: #1188.

- Added a cache for parsing hosts to reduce overhead of encoding `URL` – by @bdraco.

  Related issues and pull requests on GitHub: #1190.

- Improved performance of constructing query strings from `Mapping` – by @bdraco.

  Related issues and pull requests on GitHub: #1193.

- Improved performance of converting `URL` objects to strings – by @bdraco.

  Related issues and pull requests on GitHub: #1198.

## 1.14.0

(2024-10-08)

### Packaging updates and notes for downstreams

- Switched to using the `propcache` package for property caching – by @bdraco.

  The `propcache` package is derived from the property caching code in `yarl` and has been broken out to avoid maintaining it for multiple projects.

  Related issues and pull requests on GitHub: #1169.

### Contributor-facing changes

- Started testing with Hypothesis – by @webknjaz and @bdraco.

  Special thanks to @Zac-HD for helping us get started with this framework.

  Related issues and pull requests on GitHub: #860.

### Miscellaneous internal changes

- Improved performance of `is_default_port()` when no explicit port is set – by @bdraco.

  Related issues and pull requests on GitHub: #1168.

- Improved performance of converting `URL` to a string when no explicit port is set – by @bdraco.

  Related issues and pull requests on GitHub: #1170.

- Improved performance of the `origin()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1175.

- Improved performance of encoding hosts – by @bdraco.

  Related issues and pull requests on GitHub: #1176.

## 1.13.1

(2024-09-27)

### Miscellaneous internal changes

- Improved performance of calling `build()` with `authority` – by @bdraco.

  Related issues and pull requests on GitHub: #1163.

## 1.13.0

(2024-09-26)

### Bug fixes

- Started rejecting ASCII hostnames with invalid characters. For host strings that look like authority strings, the exception message includes advice on what to do instead – by @mjpieters.

  Related issues and pull requests on GitHub: #880, #954.

- Fixed IPv6 addresses missing brackets when the `URL` was converted to a string – by @bdraco.

  Related issues and pull requests on GitHub: #1157, #1158.

### Features

- Added `host_subcomponent` which returns the RFC 3986 Section 3.2.2 host subcomponent – by @bdraco.

  The only current practical difference between `raw_host` and `host_subcomponent` is that IPv6 addresses are returned bracketed.

  Related issues and pull requests on GitHub: #1159.

## 1.12.1

(2024-09-23)

No significant changes.

## 1.12.0

(2024-09-23)

### Features

- Added `path_safe` to be able to fetch the path without `%2F` and `%25` decoded – by @bdraco.

  Related issues and pull requests on GitHub: #1150.

### Removals and backward incompatible breaking changes

- Restore decoding `%2F` (`/`) in `URL.path` – by @bdraco.

  This change restored the behavior before #1057.

  Related issues and pull requests on GitHub: #1151.

### Miscellaneous internal changes

- Improved performance of processing paths – by @bdraco.

  Related issues and pull requests on GitHub: #1143.

## 1.11.1

(2024-09-09)

### Bug fixes

- Allowed scheme replacement for relative URLs if the scheme does not require a host – by @bdraco.

  Related issues and pull requests on GitHub: #280, #1138.

- Allowed empty host for URL schemes other than the special schemes listed in the WHATWG URL spec – by @bdraco.

  Related issues and pull requests on GitHub: #1136.

### Features

- Loosened restriction on integers as query string values to allow classes that implement `__int__` – by @bdraco.

  Related issues and pull requests on GitHub: #1139.

### Miscellaneous internal changes

- Improved performance of normalizing paths – by @bdraco.

  Related issues and pull requests on GitHub: #1137.

## 1.11.0

(2024-09-08)

### Features

- Added `URL.extend_query()` method, which can be used to extend parameters without replacing same named keys – by @bdraco.

  This method was primarily added to replace the inefficient hand rolled method currently used in `aiohttp`.

  Related issues and pull requests on GitHub: #1128.

### Miscellaneous internal changes

- Improved performance of the Cython `cached_property` implementation – by @bdraco.

  Related issues and pull requests on GitHub: #1122.

- Simplified computing ports by removing unnecessary code – by @bdraco.

  Related issues and pull requests on GitHub: #1123.

- Improved performance of encoding non IPv6 hosts – by @bdraco.

  Related issues and pull requests on GitHub: #1125.

- Improved performance of `URL.build()` when the path, query string, or fragment is an empty string – by @bdraco.

  Related issues and pull requests on GitHub: #1126.

- Improved performance of the `URL.update_query()` method – by @bdraco.

  Related issues and pull requests on GitHub: #1130.

- Improved performance of processing query string changes when arguments are `str` – by @bdraco.

  Related issues and pull requests on GitHub: #1131.

## 1.10.0

(2024-09-06)

### Bug fixes

- Fixed joining a path when the existing path was empty – by @bdraco.

  A regression in `URL.join()` was introduced in #1082.

  Related issues and pull requests on GitHub: #1118.

### Features

- Added `URL.without_query_params()` method, to drop some parameters from query string – by @hongquan.

  Related issues and pull requests on GitHub: #774, #898, #1010.

- The previously protected types `_SimpleQuery`, `_QueryVariable`, and `_Query` are now available for use externally as `SimpleQuery`, `QueryVariable`, and `Query` – by @bdraco.

  Related issues and pull requests on GitHub: #1050, #1113.

### Contributor-facing changes

- Replaced all `Optional` with `Union` – by @bdraco.

  Related issues and pull requests on GitHub: #1095.

### Miscellaneous internal changes

- Significantly improved performance of parsing the network location – by @bdraco.

  Related issues and pull requests on GitHub: #1112.

- Added internal types to the cache to prevent future refactoring errors – by @bdraco.

  Related issues and pull requests on GitHub: #1117.

## 1.9.11

(2024-09-04)

### Bug fixes

- Fixed a `TypeError` with `MultiDictProxy` and Python 3.8 – by @bdraco.

  Related issues and pull requests on GitHub: #1084, #1105, #1107.

### Miscellaneous internal changes

- Improved performance of encoding hosts – by @bdraco.

  Previously, the library would unconditionally try to parse a host as an IP Address. The library now avoids trying to parse a host as an IP Address if the string is not in one of the formats described in RFC 3986 Section 3.2.2.

  Related issues and pull requests on GitHub: #1104.

## 1.9.10

(2024-09-04)

### Bug fixes

- `URL.join()` has been changed to match RFC 3986 and align with `/ operation` and `URL.joinpath()` when joining URLs with empty segments. Previously `urllib.parse.urljoin()` was used, which has known issues with empty segments (python/cpython#84774).

  Due to the semantics of `URL.join()`, joining an URL with scheme requires making it relative, prefixing with `./`.

      >>> URL("https://web.archive.org/web/").join(URL("./https://github.com/aio-libs/yarl"))
      URL('https://web.archive.org/web/https://github.com/aio-libs/yarl')

  Empty segments are honored in the base as well as the joined part.

      >>> URL("https://web.archive.org/web/https://").join(URL("github.com/aio-libs/yarl"))
      URL('https://web.archive.org/web/https://github.com/aio-libs/yarl')

  – by @commonism

  This change initially appeared in 1.9.5 but was reverted in 1.9.6 to resolve a problem with query string handling.

  Related issues and pull requests on GitHub: #1039, #1082.

### Features

- Added `absolute` which is now preferred over `URL.is_absolute()` – by @bdraco.

  Related issues and pull requests on GitHub: #1100.

## 1.9.9

(2024-09-04)

### Bug fixes

- Added missing type on `port` – by @bdraco.

  Related issues and pull requests on GitHub: #1097.

## 1.9.8

(2024-09-03)

### Features

- Covered the `URL` object with types – by @bdraco.

  Related issues and pull requests on GitHub: #1084.

- Cache parsing of IP Addresses when encoding hosts – by @bdraco.

  Related issues and pull requests on GitHub: #1086.

### Contributor-facing changes

- Covered the `URL` object with types – by @bdraco.

  Related issues and pull requests on GitHub: #1084.

### Miscellaneous internal changes

- Improved performance of handling ports – by @bdraco.

  Related issues and pull requests on GitHub: #1081.

## 1.9.7

(2024-09-01)

### Removals and backward incompatible breaking changes

- Removed support RFC 3986 Section 3.2.3 port normalization when the scheme is not one of `http`, `https`, `wss`, or `ws` – by @bdraco.

  Support for port normalization was recently added in #1033 and contained code that would do blocking I/O if the scheme was not one of the four listed above. The code has been removed because this library is intended to be safe for usage with `asyncio`.

  Related issues and pull requests on GitHub: #1076.

### Miscellaneous internal changes

- Improved performance of property caching – by @bdraco.

  The `reify` implementation from `aiohttp` was adapted to replace the internal `cached_property` implementation.

  Related issues and pull requests on GitHub: #1070.

## 1.9.6

(2024-08-30)

### Bug fixes

- Reverted RFC 3986 compatible `URL.join()` honoring empty segments which was introduced in #1039.

  This change introduced a regression handling query string parameters with joined URLs. The change was reverted to maintain compatibility with the previous behavior.

  Related issues and pull requests on GitHub: #1067.

## 1.9.5

(2024-08-30)

### Bug fixes

- Joining URLs with empty segments has been changed to match RFC 3986.

  Previously empty segments would be removed from path, breaking use-cases such as

      URL("https://web.archive.org/web/") / "https://github.com/"

  Now `/ operation` and `URL.joinpath()` keep empty segments, but do not introduce new empty segments. e.g.

      URL("https://example.org/") / ""

  does not introduce an empty segment.

  – by @commonism and @youtux

  Related issues and pull requests on GitHub: #1026.

- The default protocol ports of well-known URI schemes are now taken into account during the normalization of the URL string representation in accordance with RFC 3986 Section 3.2.3.

  Specified ports are removed from the `str` representation of a `URL` if the port matches the scheme’s default port – by @commonism.

  Related issues and pull requests on GitHub: #1033.

- `URL.join()` has been changed to match RFC 3986 and align with `/ operation` and `URL.joinpath()` when joining URLs with empty segments. Previously `urllib.parse.urljoin()` was used, which has known issues with empty segments (python/cpython#84774).

  Due to the semantics of `URL.join()`, joining an URL with scheme requires making it relative, prefixing with `./`.

      >>> URL("https://web.archive.org/web/").join(URL("./https://github.com/aio-libs/yarl"))
      URL('https://web.archive.org/web/https://github.com/aio-libs/yarl')

  Empty segments are honored in the base as well as the joined part.

      >>> URL("https://web.archive.org/web/https://").join(URL("github.com/aio-libs/yarl"))
      URL('https://web.archive.org/web/https://github.com/aio-libs/yarl')

  – by @commonism

  Related issues and pull requests on GitHub: #1039.

### Removals and backward incompatible breaking changes

- Stopped decoding `%2F` (`/`) in `URL.path`, as this could lead to code incorrectly treating it as a path separator – by @Dreamsorcerer.

  Related issues and pull requests on GitHub: #1057.

- Dropped support for Python 3.7 – by @Dreamsorcerer.

  Related issues and pull requests on GitHub: #1016.

### Improved documentation

- On the Contributing docs page, a link to the `Towncrier philosophy` has been fixed.

  Related issues and pull requests on GitHub: #981.

- The pre-existing `/ magic method` has been documented in the API reference – by @commonism.

  Related issues and pull requests on GitHub: #1026.

### Packaging updates and notes for downstreams

- A flaw in the logic for copying the project directory into a temporary folder that led to infinite recursion when `TMPDIR` was set to a project subdirectory path. This was happening in Fedora and its downstream due to the use of pyproject-rpm-macros. It was only reproducible with `pip wheel` and was not affecting the `pyproject-build` users.

  – by @hroncok and @webknjaz

  Related issues and pull requests on GitHub: #992, #1014.

- Support Python 3.13 and publish non-free-threaded wheels

  Related issues and pull requests on GitHub: #1054.

### Contributor-facing changes

- The CI/CD setup has been updated to test `arm64` wheels under macOS 14, except for Python 3.7 that is unsupported in that environment – by @webknjaz.

  Related issues and pull requests on GitHub: #1015.

- Removed unused type ignores and casts – by @hauntsaninja.

  Related issues and pull requests on GitHub: #1031.

### Miscellaneous internal changes

- `port`, `scheme`, and `raw_host` are now `cached_property` – by @bdraco.

  `aiohttp` accesses these properties quite often, which cause `urllib` to build the `_hostinfo` property every time. `port`, `scheme`, and `raw_host` are now cached properties, which will improve performance.

  Related issues and pull requests on GitHub: #1044, #1058.

## 1.9.4 (2023-12-06)

### Bug fixes

- Started raising `TypeError` when a string value is passed into `build()` as the `port` argument – by @commonism.

  Previously the empty string as port would create malformed URLs when rendered as string representations. (#883)

### Packaging updates and notes for downstreams

- The leading `--` has been dropped from the PEP 517 in-tree build backend config setting names. `--pure-python` is now just `pure-python` – by @webknjaz.

  The usage now looks as follows:

      $ python -m build \
          --config-setting=pure-python=true \
          --config-setting=with-cython-tracing=true

  (#963)

### Contributor-facing changes

- A step-by-step Release Guide guide has been added, describing how to release yarl – by @webknjaz.

  This is primarily targeting maintainers. (#960)

- Coverage collection has been implemented for the Cython modules – by @webknjaz.

  It will also be reported to Codecov from any non-release CI jobs.

  To measure coverage in a development environment, yarl can be installed in editable mode:

      $ python -Im pip install -e .

  Editable install produces C-files required for the Cython coverage plugin to map the measurements back to the PYX-files.

  #961

- It is now possible to request line tracing in Cython builds using the `with-cython-tracing` PEP 517 config setting – @webknjaz.

  This can be used in CI and development environment to measure coverage on Cython modules, but is not normally useful to the end-users or downstream packagers.

  Here’s a usage example:

      $ python -Im pip install . --config-settings=with-cython-tracing=true

  For editable installs, this setting is on by default. Otherwise, it’s off unless requested explicitly.

  The following produces C-files required for the Cython coverage plugin to map the measurements back to the PYX-files:

      $ python -Im pip install -e .

  Alternatively, the `YARL_CYTHON_TRACING=1` environment variable can be set to do the same as the PEP 517 config setting.

  #962

## 1.9.3 (2023-11-20)

### Bug fixes

- Stopped dropping trailing slashes in `joinpath()` – by @gmacon. (#862, #866)

- Started accepting string subclasses in `__truediv__()` operations (`URL / segment`) – by @mjpieters. (#871, #884)

- Fixed the human representation of URLs with square brackets in usernames and passwords – by @mjpieters. (#876, #882)

- Updated type hints to include `URL.missing_port()`, `URL.__bytes__()` and the `encoding` argument to `joinpath()` – by @mjpieters. (#891)

### Packaging updates and notes for downstreams

- Integrated Cython 3 to enable building yarl under Python 3.12 – by @mjpieters. (#829, #881)

- Declared modern `setuptools.build_meta` as the PEP 517 build backend in `pyproject.toml` explicitly – by @webknjaz. (#886)

- Converted most of the packaging setup into a declarative `setup.cfg` config – by @webknjaz. (#890)

- The packaging is replaced from an old-fashioned `setup.py` to an in-tree PEP 517 build backend – by @webknjaz.

  Whenever the end-users or downstream packagers need to build `yarl` from source (a Git checkout or an sdist), they may pass a `config_settings` flag `--pure-python`. If this flag is not set, a C-extension will be built and included into the distribution.

  Here is how this can be done with `pip`:

      $ python -m pip install . --config-settings=--pure-python=false

  This will also work with `-e | --editable`.

  The same can be achieved via `pypa/build`:

      $ python -m build --config-setting=--pure-python=false

  Adding `-w | --wheel` can force `pypa/build` produce a wheel from source directly, as opposed to building an `sdist` and then building from it. (#893)

  Attention

  v1.9.3 was the only version using the `--pure-python` setting name. Later versions dropped the `--` prefix, making it just `pure-python`.

- Declared Python 3.12 supported officially in the distribution package metadata – by @edgarrmondragon. (#942)

### Contributor-facing changes

- A regression test for no-host URLs was added per #821 and RFC 3986 – by @kenballus. (#821, #822)

- Started testing yarl against Python 3.12 in CI – by @mjpieters. (#881)

- All Python 3.12 jobs are now marked as required to pass in CI – by @edgarrmondragon. (#942)

- MyST is now integrated in Sphinx – by @webknjaz.

  This allows the contributors to author new documents in Markdown when they have difficulties with going straight RST. (#953)

## 1.9.2 (2023-04-25)

### Bugfixes

- Fix regression with `__truediv__()` and absolute URLs with empty paths causing the raw path to lack the leading `/`. (#854)

## 1.9.1 (2023-04-21)

### Bugfixes

- Marked tests that fail on older Python patch releases (< 3.7.10, < 3.8.8 and < 3.9.2) as expected to fail due to missing a security fix for CVE-2021-23336. (#850)

## 1.9.0 (2023-04-19)

This release was never published to PyPI, due to issues with the build process.

### Features

- Added `URL.joinpath(*elements)`, to create a new URL appending multiple path elements. (#704)

- Made `URL.__truediv__()` return `NotImplemented` if called with an unsupported type — by @michaeljpeters. (#832)

### Bugfixes

- Path normalization for absolute URLs no longer raises a ValueError exception when `..` segments would otherwise go beyond the URL path root. (#536)

- Fixed an issue with update_query() not getting rid of the query when argument is None. (#792)

- Added some input restrictions on with_port() function to prevent invalid boolean inputs or out of valid port inputs; handled incorrect 0 port representation. (#793)

- Made `build()` raise a `TypeError` if the `host` argument is `None` — by @paulpapacz. (#808)

- Fixed an issue with `update_query()` getting rid of the query when the argument is empty but not `None`. (#845)

### Misc

- #220

## 1.8.2 (2022-12-03)

This is the first release that started shipping wheels for Python 3.11.

## 1.8.1 (2022-08-01)

### Misc

- #694, #699, #700, #701, #702, #703, #739

## 1.8.0 (2022-08-01)

### Features

- Added `URL.raw_suffix`, `URL.suffix`, `URL.raw_suffixes`, `URL.suffixes`, `URL.with_suffix`. (#613)

### Improved Documentation

- Fixed broken internal references to `human_repr()`. (#665)

- Fixed broken external references to multidict:index docs. (#665)

### Deprecations and Removals

- Dropped Python 3.6 support. (#672)

### Misc

- #646, #699, #701

## 1.7.2 (2021-11-01)

### Bugfixes

- Changed call in `with_port()` to stop reencoding parts of the URL that were already encoded. (#623)

## 1.7.1 (2021-10-07)

### Bugfixes

- Fix 1.7.0 build error

## 1.7.0 (2021-10-06)

### Features

- Add `__bytes__()` magic method so that `bytes(url)` will work and use optimal ASCII encoding. (#582)

- Started shipping platform-specific arm64 wheels for Apple Silicon. (#622)

- Started shipping platform-specific wheels with the `musl` tag targeting typical Alpine Linux runtimes. (#622)

- Added support for Python 3.10. (#622)

## 1.6.3 (2020-11-14)

### Bugfixes

- No longer loose characters when decoding incorrect percent-sequences (like `%e2%82%f8`). All non-decodable percent-sequences are now preserved. #517

- Provide x86 Windows wheels. #535

## 1.6.2 (2020-10-12)

### Bugfixes

- Provide generated `.c` files in TarBall distribution. #530

## 1.6.1 (2020-10-12)

### Features

- Provide wheels for `aarch64`, `i686`, `ppc64le`, `s390x` architectures on Linux as well as `x86_64`. #507

- Provide wheels for Python 3.9. #526

### Bugfixes

- `human_repr()` now always produces valid representation equivalent to the original URL (if the original URL is valid). #511

- Fixed requoting a single percent followed by a percent-encoded character in the Cython implementation. #514

- Fix ValueError when decoding `%` which is not followed by two hexadecimal digits. #516

- Fix decoding `%` followed by a space and hexadecimal digit. #520

- Fix annotation of `with_query()`/`update_query()` methods for `key=[val1, val2]` case. #528

### Removal

- Drop Python 3.5 support; Python 3.6 is the minimal supported Python version.

## 1.6.0 (2020-09-23)

### Features

- Allow for int and float subclasses in query, while still denying bool. #492

### Bugfixes

- Do not requote arguments in `URL.build()`, `with_xxx()` and in `/` operator. #502

- Keep IPv6 brackets in `origin()`. #504

## 1.5.1 (2020-08-01)

### Bugfixes

- Fix including relocated internal `yarl._quoting_c` C-extension into published PyPI dists. #485

### Misc

- #484

## 1.5.0 (2020-07-26)

### Features

- Convert host to lowercase on URL building. #386

- Allow using `mod` operator (`%`) for updating query string (an alias for `update_query()` method). #435

- Allow use of sequences such as `list` and `tuple` in the values of a mapping such as `dict` to represent that a key has many values:

      url = URL("http://example.com")
      assert url.with_query({"a": [1, 2]}) == URL("http://example.com/?a=1&a=2")

  #443

- Support `URL.build()` with scheme and path (creates a relative URL). #464

- Cache slow IDNA encode/decode calls. #476

- Add `@final` / `Final` type hints #477

- Support URL authority/raw_authority properties and authority argument of `URL.build()` method. #478

- Hide the library implementation details, make the exposed public list very clean. #483

### Bugfixes

- Fix tests with newer Python (3.7.6, 3.8.1 and 3.9.0+). #409

- Fix a bug where query component, passed in a form of mapping or sequence, is unquoted in unexpected way. #426

- Hide `Query` and `QueryVariable` type aliases in `__init__.pyi`, now they are prefixed with underscore. #431

- Keep IPv6 brackets after updating port/user/password. #451

## 1.4.2 (2019-12-05)

### Features

- Workaround for missing `str.isascii()` in Python 3.6 #389

## 1.4.1 (2019-11-29)

- Fix regression, make the library work on Python 3.5 and 3.6 again.

## 1.4.0 (2019-11-29)

- Distinguish an empty password in URL from a password not provided at all (#262)

- Fixed annotations for optional parameters of `URL.build` (#309)

- Use None as default value of `user` parameter of `URL.build` (#309)

- Enforce building C Accelerated modules when installing from source tarball, use `YARL_NO_EXTENSIONS` environment variable for falling back to (slower) Pure Python implementation (#329)

- Drop Python 3.5 support

- Fix quoting of plus in path by pure python version (#339)

- Don’t create a new URL if fragment is unchanged (#292)

- Included in error message the path that produces starting slash forbidden error (#376)

- Skip slow IDNA encoding for ASCII-only strings (#387)

## 1.3.0 (2018-12-11)

- Fix annotations for `query` parameter (#207)

- An incoming query sequence can have int variables (the same as for Mapping type) (#208)

- Add `URL.explicit_port` property (#218)

- Give a friendlier error when port can’t be converted to int (#168)

- `bool(URL())` now returns `False` (#272)

## 1.2.6 (2018-06-14)

- Drop Python 3.4 trove classifier (#205)

## 1.2.5 (2018-05-23)

- Fix annotations for `build` (#199)

## 1.2.4 (2018-05-08)

- Fix annotations for `cached_property` (#195)

## 1.2.3 (2018-05-03)

- Accept `str` subclasses in `URL` constructor (#190)

## 1.2.2 (2018-05-01)

- Fix build

## 1.2.1 (2018-04-30)

- Pin minimal required Python to 3.5.3 (#189)

## 1.2.0 (2018-04-30)

- Forbid inheritance, replace `__init__` with `__new__` (#171)

- Support PEP-561 (provide type hinting marker) (#182)

## 1.1.1 (2018-02-17)

- Fix performance regression: don’t encode empty `netloc` (#170)

## 1.1.0 (2018-01-21)

- Make pure Python quoter consistent with Cython version (#162)

## 1.0.0 (2018-01-15)

- Use fast path if quoted string does not need requoting (#154)

- Speed up quoting/unquoting by `_Quoter` and `_Unquoter` classes (#155)

- Drop `yarl.quote` and `yarl.unquote` public functions (#155)

- Add custom string writer, reuse static buffer if available (#157) Code is 50-80 times faster than Pure Python version (was 4-5 times faster)

- Don’t recode IP zone (#144)

- Support `encoded=True` in `yarl.URL.build()` (#158)

- Fix updating query with multiple keys (#160)

## 0.18.0 (2018-01-10)

- Fallback to IDNA 2003 if domain name is not IDNA 2008 compatible (#152)

## 0.17.0 (2017-12-30)

- Use IDNA 2008 for domain name processing (#149)

## 0.16.0 (2017-12-07)

- Fix raising `TypeError` by `url.query_string()` after `url.with_query({})` (empty mapping) (#141)

## 0.15.0 (2017-11-23)

- Add `raw_path_qs` attribute (#137)

## 0.14.2 (2017-11-14)

- Restore `strict` parameter as no-op in `quote` / `unquote`

## 0.14.1 (2017-11-13)

- Restore `strict` parameter as no-op for sake of compatibility with aiohttp 2.2

## 0.14.0 (2017-11-11)

- Drop strict mode (#123)

- Fix `"ValueError: Unallowed PCT %"` when there’s a `"%"` in the URL (#124)

## 0.13.0 (2017-10-01)

- Document `encoded` parameter (#102)

- Support relative URLs like `'?key=value'` (#100)

- Unsafe encoding for QS fixed. Encode `;` character in value parameter (#104)

- Process passwords without user names (#95)

## 0.12.0 (2017-06-26)

- Properly support paths without leading slash in `URL.with_path()` (#90)

- Enable type annotation checks

## 0.11.0 (2017-06-26)

- Normalize path (#86)

- Clear query and fragment parts in `.with_path()` (#85)

## 0.10.3 (2017-06-13)

- Prevent double URL arguments unquoting (#83)

## 0.10.2 (2017-05-05)

- Unexpected hash behavior (#75)

## 0.10.1 (2017-05-03)

- Unexpected compare behavior (#73)

- Do not quote or unquote + if not a query string. (#74)

## 0.10.0 (2017-03-14)

- Added `URL.build` class method (#58)

- Added `path_qs` attribute (#42)

## 0.9.8 (2017-02-16)

- Do not quote `:` in path

## 0.9.7 (2017-02-16)

- Load from pickle without _cache (#56)

- Percent-encoded pluses in path variables become spaces (#59)

## 0.9.6 (2017-02-15)

- Revert backward incompatible change (BaseURL)

## 0.9.5 (2017-02-14)

- Fix BaseURL rich comparison support

## 0.9.4 (2017-02-14)

- Use BaseURL

## 0.9.3 (2017-02-14)

- Added BaseURL

## 0.9.2 (2017-02-08)

- Remove debug print

## 0.9.1 (2017-02-07)

- Do not lose tail chars (#45)

## 0.9.0 (2017-02-07)

- Allow to quote `%` in non strict mode (#21)

- Incorrect parsing of query parameters with %3B (;) inside (#34)

- Fix core dumps (#41)

- `tmpbuf` - compiling error (#43)

- Added `URL.update_path()` method

- Added `URL.update_query()` method (#47)

## 0.8.1 (2016-12-03)

- Fix broken aiohttp: revert back `quote` / `unquote`.

## 0.8.0 (2016-12-03)

- Support more verbose error messages in `.with_query()` (#24)

- Don’t percent-encode `@` and `:` in path (#32)

- Don’t expose `yarl.quote` and `yarl.unquote`, these functions are part of private API

## 0.7.1 (2016-11-18)

- Accept not only `str` but all classes inherited from `str` also (#25)

## 0.7.0 (2016-11-07)

- Accept `int` as value for `.with_query()`

## 0.6.0 (2016-11-07)

- Explicitly use UTF8 encoding in `setup.py` (#20)

- Properly unquote non-UTF8 strings (#19)

## 0.5.3 (2016-11-02)

- Don’t use `typing.NamedTuple` fields but indexes on URL construction

## 0.5.2 (2016-11-02)

- Inline `_encode` class method

## 0.5.1 (2016-11-02)

- Make URL construction faster by removing extra classmethod calls

## 0.5.0 (2016-11-02)

- Add Cython optimization for quoting/unquoting

- Provide binary wheels

## 0.4.3 (2016-09-29)

- Fix typing stubs

## 0.4.2 (2016-09-29)

- Expose `quote()` and `unquote()` as public API

## 0.4.1 (2016-09-28)

- Support empty values in query (`'/path?arg'`)

## 0.4.0 (2016-09-27)

- Introduce `relative()` (#16)

## 0.3.2 (2016-09-27)

- Typo fixes #15

## 0.3.1 (2016-09-26)

- Support sequence of pairs as `with_query()` parameter

## 0.3.0 (2016-09-26)

- Introduce `is_default_port()`

## 0.2.1 (2016-09-26)

- Raise ValueError for URLs like ‘http://:8080/’

## 0.2.0 (2016-09-18)

- Avoid doubling slashes when joining paths (#13)

- Appending path starting from slash is forbidden (#12)

## 0.1.4 (2016-09-09)

- Add `kwargs` support for `with_query()` (#10)

## 0.1.3 (2016-09-07)

- Document `with_query()`, `with_fragment()` and `origin()`

- Allow `None` for `with_query()` and `with_fragment()`

## 0.1.2 (2016-09-07)

- Fix links, tune docs theme.

## 0.1.1 (2016-09-06)

- Update README, old version used obsolete API

## 0.1.0 (2016-09-06)

- The library was deeply refactored, bytes are gone away but all accepted strings are encoded if needed.

## 0.0.1 (2016-08-30)

- The first release.