diff --git a/CHANGES/1117.misc.rst b/CHANGES/1117.misc.rst new file mode 100644 index 00000000..4a2302a2 --- /dev/null +++ b/CHANGES/1117.misc.rst @@ -0,0 +1 @@ +Added internal types to the cache to prevent future refactoring errors -- by :user:`bdraco`. diff --git a/yarl/_url.py b/yarl/_url.py index ec92edb1..8289c2a2 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -9,7 +9,6 @@ TYPE_CHECKING, Any, Callable, - Dict, Iterable, Iterator, List, @@ -71,6 +70,42 @@ class _SplitResultDict(TypedDict, total=False): fragment: str +class _InternalURLCache(TypedDict, total=False): + + absolute: bool + scheme: str + raw_authority: str + _default_port: Union[int, None] + _port_not_default: Union[int, None] + authority: str + raw_user: Union[str, None] + user: Union[str, None] + raw_password: Union[str, None] + password: Union[str, None] + raw_host: Union[str, None] + host: Union[str, None] + port: Union[int, None] + explicit_port: Union[int, None] + raw_path: str + path: str + query: "MultiDictProxy[str]" + raw_query_string: str + query_string: str + path_qs: str + raw_path_qs: str + raw_fragment: str + fragment: str + raw_parts: Tuple[str, ...] + parts: Tuple[str, ...] + parent: "URL" + raw_name: str + name: str + raw_suffix: str + suffix: str + raw_suffixes: Tuple[str, ...] + suffixes: Tuple[str, ...] + + def rewrite_module(obj: _T) -> _T: obj.__module__ = "yarl" return obj @@ -210,7 +245,7 @@ def __new__( else: raise TypeError("Constructor parameter should be str") - cache: Dict[str, Union[str, int, None]] = {} + cache: _InternalURLCache = {} if not encoded: host: Union[str, None] scheme, netloc, path, query, fragment = val @@ -446,20 +481,6 @@ def is_absolute(self) -> bool: """ return self.absolute - @cached_property - def absolute(self) -> bool: - """A check for absolute URLs. - - Return True for absolute ones (having scheme or starting - with //), False otherwise. - - """ - # `netloc`` is an empty string for relative URLs - # Checking `netloc` is faster than checking `hostname` - # because `hostname` is a property that does some extra work - # to parse the host from the `netloc` - return self._val.netloc != "" - def is_default_port(self) -> bool: """A check for default port. @@ -505,6 +526,20 @@ def relative(self) -> "URL": val = self._val._replace(scheme="", netloc="") return URL(val, encoded=True) + @cached_property + def absolute(self) -> bool: + """A check for absolute URLs. + + Return True for absolute ones (having scheme or starting + with //), False otherwise. + + """ + # `netloc`` is an empty string for relative URLs + # Checking `netloc` is faster than checking `hostname` + # because `hostname` is a property that does some extra work + # to parse the host from the `netloc` + return self._val.netloc != "" + @cached_property def scheme(self) -> str: """Scheme for absolute URLs. @@ -514,7 +549,7 @@ def scheme(self) -> str: """ return self._val.scheme - @property + @cached_property def raw_authority(self) -> str: """Encoded authority part of URL. @@ -644,7 +679,7 @@ def explicit_port(self) -> Union[int, None]: self._cache_netloc() return self._cache["explicit_port"] - @property + @cached_property def raw_path(self) -> str: """Encoded path of URL.