-
Notifications
You must be signed in to change notification settings - Fork 15
Update URI join semantics #630
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
c5e8d01
9417db3
d037676
3f231f9
92baf46
14cf93b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,13 +29,25 @@ def _token_to_string(token: _URI_LIKE) -> str: | |
| return str(token) | ||
| return "" | ||
|
|
||
| # TODO(kmonte): You should not be able to join a Uri with a Uri of a different type. | ||
| # *or* join HTTP on HTTP or GCS on GCS. | ||
| # This is not backwards compatible, so come around to this later. | ||
| @classmethod | ||
| def _is_absolute_path(cls, token: _URI_LIKE) -> bool: | ||
| token_str = cls._token_to_string(token) | ||
|
|
||
| # Note: "://" is used to detect GcsUri and HttpUri prefixes, but will incorrectly | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not thrilled about this but it seems like the simplest way to detect
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason to not check the subclasses here? e.g.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My thought was that it's not great to have to hardcode this, in case new subclasses appear. Also, we probably want to raise when the rhs token is a string like
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed, the check against |
||
| # classify relative LocalUri path's containing "://" as absolute | ||
| return Path(token_str).is_absolute() or "://" in token_str | ||
|
|
||
| @classmethod | ||
| def join(cls, token: _URI_LIKE, *tokens: _URI_LIKE) -> Self: | ||
|
jchmura-sc marked this conversation as resolved.
|
||
| """ | ||
| Join multiple tokens to create a new Uri instance. | ||
| The first token may be an absolute or relative path. Every additional token must be relative. | ||
|
|
||
| Note: | ||
| - Rejecting suffix strings containing "://" may break callers that | ||
| intentionally store URI-looking strings inside paths. | ||
| - Rejecting absolute LocalUri suffix tokens is stricter than os.path.join, | ||
| which implicitly discards earlier tokens on the join path. | ||
|
|
||
| Args: | ||
| token: The first token to join. | ||
|
|
@@ -45,6 +57,12 @@ def join(cls, token: _URI_LIKE, *tokens: _URI_LIKE) -> Self: | |
| A new Uri instance representing the joined URI. | ||
|
|
||
| """ | ||
| for suffix in tokens: | ||
| if cls._is_absolute_path(suffix): | ||
| raise TypeError( | ||
| f"URI join suffixes must be relative; got absolute path: {suffix}" | ||
| ) | ||
|
|
||
| token = cls._token_to_string(token) | ||
| token_strs: list[str] = [cls._token_to_string(token) for token in tokens] | ||
| joined_tmp_path = os.path.join(token, *token_strs) | ||
|
|
@@ -88,10 +106,6 @@ def __eq__(self, other: Any) -> bool: | |
| return False | ||
|
|
||
| def __truediv__(self, other: _URI_LIKE) -> Self: | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously,
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As per my comment above, Its probably safe to disallow this. |
||
| if isinstance(other, Uri) and not isinstance(other, type(self)): | ||
| raise TypeError( | ||
| f"Cannot use '/' operator to join {type(self).__name__} with {type(other).__name__}" | ||
| ) | ||
| return self.join(self, other) | ||
|
|
||
|
|
||
|
|
||
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.
is_abs()could be an abstract method or property that subclasses could implement.