-
Notifications
You must be signed in to change notification settings - Fork 353
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
Fix TypeError in issue #158/#159 #160
base: master
Are you sure you want to change the base?
Fix TypeError in issue #158/#159 #160
Conversation
This makes only one more test pass (now only 3 failing) but at least prevents the `TypeError` when attempting to add a `list` and a `tuple`.
It's taken a while to arrive at the correct course of action, but this pickle of an issue has finally been fixed in 19.0.0, just released. Thanks for your work, and your patience :) |
Thought I was closing a different issue, reopening! |
@pytest.mark.parametrize( | ||
('expected', 'base', 'a', 'b'), [ | ||
('https://host/b', 'https://host', 'a', '/b'), | ||
('https://host/a/b', 'https://host', 'a', 'b'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using
boltons.urlutils.URL(boltons.urlutils.URL('https://host').navigate('a')).navigate('b')
the expected result should be https://host/b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't looked at this in a long time, so pardon me if I'm completely backwards and no longer clear on what I thought behavior should be.
When you say, "the expected result should be", where are you basing that "should be" on? The scant documentation says, "Useful for navigating those relative links with ease." I consider this analogous to using cd
on a Unix system; all references are relative unless the destination starts with /
.
Actually, the vexing nature of the way things work now is more apparent if you have multiple path segments:
>>> boltons.urlutils.URL('https://host/a/b/c').navigate('d')
URL('https://host/a/b/d')
>>> boltons.urlutils.URL('https://host/a/b/c').navigate('../d')
URL('https://host/a/d')
>>> boltons.urlutils.URL('https://host/a/b/c/').navigate('../d')
URL('https://host/a/b/d')
>>> boltons.urlutils.URL('https://host/a/b/c').navigate('#d')
URL('https://host/a/b/c#d')
What I find most surprising is that, without a trailing slash on the base, navigate
with a non-fragment argument assumes the last part of the path is (erm, not sure about the right terminology) a "leaf" instead of a "stem" (or "file" instead of a "directory"?).
To make a relative link from an URL without a trialing slash with the behavior you're describing, you have to: 1. to_text()
2. conditionally append a '/' (normalize()
will not make //
-> /
) 3. recreate URL. Because the URL
object is immutable, it's much easier to change the string argument to enable "upwards" navigation by pre-pending '../'. This is what I would find less surprising:
>>> boltons.urlutils.URL('https://host/a/b/c').navigate('d')
URL('https://host/a/b/c/d')
>>> boltons.urlutils.URL('https://host/a/b/c').navigate('../d')
URL('https://host/a/b/d')
>>> boltons.urlutils.URL('https://host/a/b/c/').navigate('../d')
URL('https://host/a/b/d')
Unfortunately, I think this ship has sailed; changing this behavior would be massively backwards-incompatible.
('https://host/b', 'https://host', 'a', '/b'), | ||
('https://host/a/b', 'https://host', 'a', 'b'), | ||
('https://host/a/b', 'https://host', 'a/', 'b'), | ||
('https://host/a/b', 'https://host', '/a', 'b'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using
boltons.urlutils.URL(boltons.urlutils.URL('https://host').navigate('/a')).navigate('b')
the expected result should be https://host/b
('https://host/a/b', 'https://host', 'a/', 'b'), | ||
('https://host/a/b', 'https://host', '/a', 'b'), | ||
('https://host/a/b', 'https://host/a/', None, 'b'), | ||
('https://host/a/b', 'https://host/a', None, 'b'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using
boltons.urlutils.URL(boltons.urlutils.URL('https://host').navigate('/a')).navigate('b')
the expected result should be https://host/b
This makes only one more test pass (now only 3 failing) but at least prevents the
TypeError
when attempting to add alist
and atuple
.pytest output attached
pytest-out-2.txt