Skip to content

Commit 40205f6

Browse files
authored
Add types to the public API (#244)
Resolves #189
1 parent bdaa6f3 commit 40205f6

File tree

8 files changed

+47
-31
lines changed

8 files changed

+47
-31
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ matrix:
1414
env: TOXENV=pypy3
1515
- env: TOXENV=codestyle
1616
- env: TOXENV=lint
17+
- env: TOXENV=typecheck
1718
python: 3.9
1819
install: pip install tox
1920
script: tox

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
include tldextract/.tld_set_snapshot
2+
include tldextract/py.typed
23
include LICENSE
34
recursive-include tests *.py *.dat

tldextract/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33
from .tldextract import extract, TLDExtract
44

5-
from ._version import version as __version__
5+
from . import _version
6+
__version__: str = _version.version

tldextract/cache.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
_DID_LOG_UNABLE_TO_CACHE = False
1616

1717

18-
def get_pkg_unique_identifier():
18+
def get_pkg_unique_identifier() -> str:
1919
"""
2020
Generate an identifier unique to the python version, tldextract version, and python instance
2121
@@ -46,7 +46,7 @@ def get_pkg_unique_identifier():
4646
return pkg_identifier
4747

4848

49-
def get_cache_dir():
49+
def get_cache_dir() -> str:
5050
"""
5151
Get a cache dir that we have permission to write to
5252

tldextract/py.typed

Whitespace-only changes.

tldextract/suffix_list.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import re
66

77
import requests
8-
from requests_file import FileAdapter
8+
from requests_file import FileAdapter # type: ignore[import]
99

1010
LOG = logging.getLogger("tldextract")
1111

tldextract/tldextract.py

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@
4949
'127.0.0.1'
5050
"""
5151

52-
import collections
5352
import logging
5453
import os
5554
from functools import wraps
55+
from typing import List, NamedTuple, Optional, Sequence, Union
5656

5757
import idna
5858

@@ -71,14 +71,15 @@
7171
)
7272

7373

74-
class ExtractResult(collections.namedtuple("ExtractResult", "subdomain domain suffix")):
74+
class ExtractResult(NamedTuple):
7575
"""namedtuple of a URL's subdomain, domain, and suffix."""
7676

77-
# Necessary for __dict__ member to get populated in Python 3+
78-
__slots__ = ()
77+
subdomain: str
78+
domain: str
79+
suffix: str
7980

8081
@property
81-
def registered_domain(self):
82+
def registered_domain(self) -> str:
8283
"""
8384
Joins the domain and suffix fields with a dot, if they're both set.
8485
@@ -92,7 +93,7 @@ def registered_domain(self):
9293
return ""
9394

9495
@property
95-
def fqdn(self):
96+
def fqdn(self) -> str:
9697
"""
9798
Returns a Fully Qualified Domain Name, if there is a proper domain/suffix.
9899
@@ -102,12 +103,13 @@ def fqdn(self):
102103
''
103104
"""
104105
if self.domain and self.suffix:
105-
# self is the namedtuple (subdomain domain suffix)
106+
# Disable bogus lint error (https://github.com/PyCQA/pylint/issues/2568)
107+
# pylint: disable-next=not-an-iterable
106108
return ".".join(i for i in self if i)
107109
return ""
108110

109111
@property
110-
def ipv4(self):
112+
def ipv4(self) -> str:
111113
"""
112114
Returns the ipv4 if that is what the presented domain/url is
113115
@@ -130,13 +132,13 @@ class TLDExtract:
130132
# TODO: Agreed with Pylint: too-many-arguments
131133
def __init__( # pylint: disable=too-many-arguments
132134
self,
133-
cache_dir=get_cache_dir(),
134-
suffix_list_urls=PUBLIC_SUFFIX_LIST_URLS,
135-
fallback_to_snapshot=True,
136-
include_psl_private_domains=False,
137-
extra_suffixes=(),
138-
cache_fetch_timeout=CACHE_TIMEOUT,
139-
):
135+
cache_dir: str = get_cache_dir(),
136+
suffix_list_urls: Sequence[str] = PUBLIC_SUFFIX_LIST_URLS,
137+
fallback_to_snapshot: bool = True,
138+
include_psl_private_domains: bool = False,
139+
extra_suffixes: Sequence[str] = (),
140+
cache_fetch_timeout: Union[str, float, None] = CACHE_TIMEOUT,
141+
) -> None:
140142
"""
141143
Constructs a callable for extracting subdomain, domain, and suffix
142144
components from a URL.
@@ -193,14 +195,18 @@ def __init__( # pylint: disable=too-many-arguments
193195

194196
self.include_psl_private_domains = include_psl_private_domains
195197
self.extra_suffixes = extra_suffixes
196-
self._extractor = None
198+
self._extractor: Optional[_PublicSuffixListTLDExtractor] = None
197199

198-
self.cache_fetch_timeout = cache_fetch_timeout
200+
self.cache_fetch_timeout = (
201+
float(cache_fetch_timeout)
202+
if isinstance(cache_fetch_timeout, str)
203+
else cache_fetch_timeout
204+
)
199205
self._cache = DiskCache(cache_dir)
200-
if isinstance(self.cache_fetch_timeout, str):
201-
self.cache_fetch_timeout = float(self.cache_fetch_timeout)
202206

203-
def __call__(self, url, include_psl_private_domains=None):
207+
def __call__(
208+
self, url: str, include_psl_private_domains: Optional[bool] = None
209+
) -> ExtractResult:
204210
"""
205211
Takes a string URL and splits it into its subdomain, domain, and
206212
suffix (effective TLD, gTLD, ccTLD, etc.) component.
@@ -238,23 +244,23 @@ def __call__(self, url, include_psl_private_domains=None):
238244
domain = labels[suffix_index - 1] if suffix_index else ""
239245
return ExtractResult(subdomain, domain, suffix)
240246

241-
def update(self, fetch_now=False):
247+
def update(self, fetch_now: bool = False) -> None:
242248
"""Force fetch the latest suffix list definitions."""
243249
self._extractor = None
244250
self._cache.clear()
245251
if fetch_now:
246252
self._get_tld_extractor()
247253

248254
@property
249-
def tlds(self):
255+
def tlds(self) -> List[str]:
250256
"""
251257
Returns the list of tld's used by default
252258
253259
This will vary based on `include_psl_private_domains` and `extra_suffixes`
254260
"""
255261
return list(self._get_tld_extractor().tlds())
256262

257-
def _get_tld_extractor(self):
263+
def _get_tld_extractor(self) -> "_PublicSuffixListTLDExtractor":
258264
"""Get or compute this object's TLDExtractor. Looks up the TLDExtractor
259265
in roughly the following order, based on the settings passed to
260266
__init__:
@@ -290,9 +296,9 @@ def _get_tld_extractor(self):
290296

291297

292298
@wraps(TLD_EXTRACTOR.__call__)
293-
def extract(
294-
url, include_psl_private_domains=False
295-
): # pylint: disable=missing-function-docstring
299+
def extract( # pylint: disable=missing-function-docstring
300+
url: str, include_psl_private_domains: Optional[bool] = False
301+
) -> ExtractResult:
296302
return TLD_EXTRACTOR(url, include_psl_private_domains=include_psl_private_domains)
297303

298304

tox.ini

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tox]
2-
envlist = py{36,37,38,39,py3},codestyle,lint
2+
envlist = py{36,37,38,39,py3},codestyle,lint,typecheck
33

44
[testenv]
55
deps =
@@ -24,6 +24,13 @@ deps =
2424
responses
2525
commands = pytest --pylint -m pylint {posargs}
2626

27+
[testenv:typecheck]
28+
deps =
29+
mypy
30+
types-requests
31+
types-filelock
32+
commands = mypy tldextract --show-error-codes
33+
2734
[pycodestyle]
2835
# E203 - whitespace before; disagrees with PEP8 https://github.com/psf/black/issues/354#issuecomment-397684838
2936
# E501 - line too long

0 commit comments

Comments
 (0)