Skip to content
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

URL.port becomes Optional[int] #1080

Merged
merged 3 commits into from
Jul 24, 2020
Merged

URL.port becomes Optional[int] #1080

merged 3 commits into from
Jul 24, 2020

Conversation

tomchristie
Copy link
Member

@tomchristie tomchristie commented Jul 23, 2020

This PR changes URL.port from int to Optional[int].

Previously any non http/https URL without an explicit port component would raise an error if url.port was accessed.
Now url.port is optional, and only returns any explicitly included port in the URL, without also trying to use a scheme-default if one is not present.

This is important because...

  1. URL is more generically useful. Eg. URL('ftp://www.example.com').port == None which makes more sense than KeyError("ftp").
  2. This is a precursor to Supporting alternate schemes. #954, since the only point we're now enforcing http/https schemes on URLs is strictly inside _transport_for_url, rather than at any point in the codebase that accesses url.port.

(Yes, it's a little bit fiddly)

@@ -543,10 +543,13 @@ def _transport_for_url(self, url: URL) -> httpcore.SyncHTTPTransport:
enforce_http_url(url)

if self._proxies and not should_not_be_proxied(url):
is_default_port = (url.scheme == "http" and url.port == 80) or (
url.scheme == "https" and url.port == 443
default_port = {"http": 80, "https": 443}[url.scheme]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a .get() to avoid KeyError: 'ftp'?

Suggested change
default_port = {"http": 80, "https": 443}[url.scheme]
default_port = {"http": 80, "https": 443}.get(url.scheme)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually no, because we've called enforce_http_url(url) before doing anything else, so url.scheme will always be http|https here, and default_port will be an int rather than an Optional[int].

(Agree that it's a bit futzy, and I think it'd potentially clean up a bit if we rethought the proxy_keys/mount API.)

httpx/_client.py Outdated
Comment on lines 548 to 552
hostname = (
f"{url.host}:{default_port}"
if url.port is None
else f"{url.host}:{url.port}"
)
Copy link
Contributor

@StephenBrown2 StephenBrown2 Jul 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be simplified:

Suggested change
hostname = (
f"{url.host}:{default_port}"
if url.port is None
else f"{url.host}:{url.port}"
)
port = url.port or default_port
hostname = f"{url.host}:{port}"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great call yup.

httpx/_client.py Outdated
Comment on lines 1082 to 1088
default_port = {"http": 80, "https": 443}[url.scheme]
is_default_port = url.port is None or url.port == default_port
hostname = (
f"{url.host}:{default_port}"
if url.port is None
else f"{url.host}:{url.port}"
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments as above

@@ -273,12 +273,20 @@ def enforce_http_url(url: "URL") -> None:
raise InvalidURL('URL scheme must be "http" or "https".')


def port_or_default(url: "URL") -> typing.Optional[int]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should be used above?

Copy link
Member

@florimondmanca florimondmanca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds sensible to me! And in line with the choice we've made in HTTPCore too.

@tomchristie tomchristie merged commit c089480 into master Jul 24, 2020
@tomchristie tomchristie deleted the port-becomes-optional branch July 24, 2020 10:42
@tomchristie tomchristie mentioned this pull request Jul 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants