yarl
yarl copied to clipboard
Rework of the URL subtraction feature
What do these changes do?
Rework of the URL subtraction feature (added in #1340; removed in #1391)
Are there changes in behavior for the user?
Being able to calculate the relative path between two URLs:
from yarl import URL
target_url = URL("http://example.com/path/index.html")
base_url = URL("http://example.com/path/")
relative_url = target_url.relative_to(base_url)
print(relative_url) # output: "index.html"
Related issue number
Resolves #1183
Checklist
- [ ] I think the code is well written
- [x] Unit tests for the changes exist
- [x] Documentation reflects the changes
Known issues
- [x] Time complexity is roughly O(base_path_segments * target_path_segments)
- [x] Empty segments are not handled correctly #1388
- [x] Potentially handling special cases with leading/trailing slashes #1388
CodSpeed Performance Report
Merging #1392 will not alter performance
Comparing oleksbabieiev:subtraction (ad61c24) with master (c1f6ef6)
Summary
โ
98 untouched
๐ 2 new
Benchmarks breakdown
| Benchmark | BASE |
HEAD |
Change | |
|---|---|---|---|---|
| ๐ | test_relative_to |
N/A | 778.9 ยตs | N/A |
| ๐ | test_relative_to_long_urls |
N/A | 4.4 ms | N/A |
Codecov Report
:white_check_mark: All modified and coverable lines are covered by tests.
:white_check_mark: Project coverage is 98.84%. Comparing base (937f030) to head (e15878f).
:warning: Report is 57 commits behind head on master.
Additional details and impacted files
@@ Coverage Diff @@
## master #1392 +/- ##
==========================================
- Coverage 98.93% 98.84% -0.10%
==========================================
Files 32 25 -7
Lines 6091 5007 -1084
Branches 365 347 -18
==========================================
- Hits 6026 4949 -1077
+ Misses 62 56 -6
+ Partials 3 2 -1
| Flag | Coverage ฮ | |
|---|---|---|
| CI-GHA | 98.80% <100.00%> (-0.14%) |
:arrow_down: |
| MyPy | ? |
|
| OS-Linux | 98.80% <100.00%> (+0.01%) |
:arrow_up: |
| OS-Windows | 98.83% <100.00%> (+0.01%) |
:arrow_up: |
| OS-macOS | 98.58% <100.00%> (+0.01%) |
:arrow_up: |
| Py-3.10.11 | 98.56% <100.00%> (+0.01%) |
:arrow_up: |
| Py-3.10.16 | 98.76% <100.00%> (+0.01%) |
:arrow_up: |
| Py-3.11.11 | 98.76% <100.00%> (+0.01%) |
:arrow_up: |
| Py-3.11.9 | 98.56% <100.00%> (+0.01%) |
:arrow_up: |
| Py-3.12.9 | 98.76% <100.00%> (+0.01%) |
:arrow_up: |
| Py-3.13.2 | 98.76% <100.00%> (+0.01%) |
:arrow_up: |
| Py-3.9.13 | 98.52% <100.00%> (+0.01%) |
:arrow_up: |
| Py-3.9.21 | 98.72% <100.00%> (+0.01%) |
:arrow_up: |
| Py-pypy7.3.16 | 98.71% <100.00%> (+0.01%) |
:arrow_up: |
| Py-pypy7.3.19 | 98.73% <100.00%> (+0.01%) |
:arrow_up: |
| VM-macos-latest | 98.58% <100.00%> (+0.01%) |
:arrow_up: |
| VM-ubuntu-latest | 98.80% <100.00%> (+0.01%) |
:arrow_up: |
| VM-windows-latest | 98.83% <100.00%> (+0.01%) |
:arrow_up: |
| pytest | 98.80% <100.00%> (+0.01%) |
:arrow_up: |
Flags with carried forward coverage won't be shown. Click here to find out more.
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
I'm going to do a 1.17.0 release so we can start preparing aiohttp 3.11.x and I want do to some more downstream cleanups. We can do a 1.18.0 for this once its ready
Some conflicts happened. I think I've resolved them correctly
I disagree with some of the unit tests, as I expect the returned relative path to add up to the complete path when concatenated as a relative path.
def test_relative_to(target: str, base: str, expected: str):
expected_url = URL(expected)
target_url = URL(target)
base_url = URL(base)
result_url = target_url.relative_to(base_url)
assert result_url == expected_url
combined = base_url / expected
assert target_url == combined
Please include this in the unit tests, it'll help to align those with the idea of a relative path and harden the semantics on this operation wrt. to trailing / in base and result.
Please, avoid touching anything in the
packaging/directory.
Ok, but this was an auto-fix from pre-commit hooks. The bot added it after I had already pushed the changes ๐คทโโ๏ธ
Oh, that's weird. I wonder if the pre-commit.ci cache got invalidated randomly and it pulled in some newer transitive deps...
combined = base_url / expected assert target_url == combinedPlease include this in the unit tests, it'll help to align those with the idea of a relative path and harden the semantics on this operation wrt. to trailing / in base and result.
@commonism this condition will only be true if we first normalize the URLs before comparing, so I've modified this code a bit:
combined_url = base_url / expected
combined_path = normalized_path(combined_url.path)
target_path = normalized_path(target_url.path)
assert combined_path == target_path
If we don't normalize them, the following can happen:
target_url = URL("/path/to")
base_url = URL("/spam")
relative_url = target_url.relative_to(base_url)
print(relative_url) # URL("../path/to")
combined_url = base_url / relative_url
print(combined_url) # URL("/spam/../path/to") => combined_url != target_url
But now everything seems to be working properly.
@babieiev could you fix linting and rebase?
Sorry, I messed up a few things, so I'll open a new pull request ๐