From 2bbfa96d2aaa442fddb667df9e759fb449f89ff2 Mon Sep 17 00:00:00 2001 From: Artur Barseghyan Date: Wed, 6 May 2026 14:37:23 +0200 Subject: [PATCH] Cleanup/cleanup (#146) * Ty * Fixes in type --- .secrets.baseline | 8 +- Makefile | 9 +- docs/requirements.txt | 11 +- pyproject.toml | 14 +- requirements/bench.txt | 11 +- requirements/build.txt | 11 +- runtests.py | 4 + src/tld/base.py | 19 ++- src/tld/res/effective_tld_names.dat.txt | 127 ++++++++++++++---- .../effective_tld_names_public_only.dat.txt | 127 ++++++++++++++---- src/tld/result.py | 2 +- src/tld/tests/test_core.py | 40 ++++-- src/tld/utils.py | 38 +++--- 13 files changed, 290 insertions(+), 131 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index cb6ab20..dbbe6b9 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -118,14 +118,14 @@ "filename": "Makefile", "hashed_secret": "2fe086eab8479dc298cbfe887222b405de9e1d83", "is_verified": true, - "line_number": 168 + "line_number": 171 }, { "type": "Secret Keyword", "filename": "Makefile", "hashed_secret": "e441659cd1b30148c99024a81228d16b63f772af", "is_verified": true, - "line_number": 171 + "line_number": 174 } ], "src/tld/tests/test_core.py": [ @@ -134,9 +134,9 @@ "filename": "src/tld/tests/test_core.py", "hashed_secret": "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33", "is_verified": true, - "line_number": 157 + "line_number": 174 } ] }, - "generated_at": "2026-05-05T22:56:41Z" + "generated_at": "2026-05-06T07:41:53Z" } diff --git a/Makefile b/Makefile index 6147336..f075de4 100644 --- a/Makefile +++ b/Makefile @@ -57,8 +57,8 @@ doc8: ruff: uv run ruff check . -mypy: - uv run mypy src/tld/ +ty: + uv run ty check src/tld/ # ---------------------------------------------------------------------------- # Installation @@ -110,6 +110,9 @@ profile-test: uv run python -m cProfile -o runtests.cprof runtests.py uv run pyprof2calltree -k -i runtests.cprof +update-tld-names: + uv run update-tld-names + # ---------------------------------------------------------------------------- # Development # ---------------------------------------------------------------------------- @@ -141,7 +144,7 @@ clean: rm -rf testdocs/ rm -rf .coverage rm -rf .pytest_cache/ - rm -rf .mypy_cache/ + rm -rf .ty_cache/ rm -rf .ruff_cache/ rm -rf dist/ rm -rf dist_py27/ diff --git a/docs/requirements.txt b/docs/requirements.txt index ae5598c..7c9f675 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -86,8 +86,6 @@ jinja2==3.1.6 # via sphinx keyring==25.7.0 # via twine -librt==0.8.1 - # via mypy markdown-it-py==4.0.0 # via rich markupsafe==3.0.3 @@ -100,10 +98,6 @@ more-itertools==10.8.0 # via # jaraco-classes # jaraco-functools -mypy==1.19.1 - # via tld (pyproject.toml) -mypy-extensions==1.1.0 - # via mypy nh3==0.3.3 # via readme-renderer packaging==26.0 @@ -117,8 +111,6 @@ packaging==26.0 # wheel parso==0.8.6 # via jedi -pathspec==1.0.4 - # via mypy pexpect==4.9.0 # via ipython pkginfo==1.12.1.2 @@ -240,10 +232,11 @@ traitlets==5.14.3 # matplotlib-inline twine==6.2.0 # via tld (pyproject.toml) +ty==0.0.34 + # via tld (pyproject.toml) typing-extensions==4.15.0 # via # anyio - # mypy # starlette urllib3==2.6.3 # via diff --git a/pyproject.toml b/pyproject.toml index 988259c..ab59b67 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,9 +52,9 @@ build = [ ] lint = [ "doc8", - "mypy", "pydoclint", "ruff", + "ty", ] dev = [ "detect-secrets", @@ -139,7 +139,6 @@ lint.exclude = [ ".eggs", ".git", ".hg", - ".mypy_cache", ".nox", ".pants.d", ".ruff_cache", @@ -224,16 +223,6 @@ markers = [ "documentation: mark test as a documentation test", ] -# ---------------------------------------------------------------------------- -# mypy configuration -# ---------------------------------------------------------------------------- -[tool.mypy] -check_untyped_defs = true -warn_unused_ignores = true -warn_redundant_casts = true -warn_unused_configs = true -ignore_missing_imports = true - # ---------------------------------------------------------------------------- # coverage configuration # ---------------------------------------------------------------------------- @@ -270,7 +259,6 @@ ignore = [ ".hg", ".hypothesis", ".idea", - ".mypy_cache", ".nox", ".pre-commit-config.yaml", ".pre-commit-hooks.yaml", diff --git a/requirements/bench.txt b/requirements/bench.txt index e6698e3..fb15f14 100644 --- a/requirements/bench.txt +++ b/requirements/bench.txt @@ -96,8 +96,6 @@ keyring==25.7.0 # via twine kiwisolver==1.4.9 # via matplotlib -librt==0.8.1 - # via mypy line-profiler==5.0.2 # via -r requirements/bench.in markdown-it-py==4.0.0 @@ -116,10 +114,6 @@ more-itertools==10.8.0 # via # jaraco-classes # jaraco-functools -mypy==1.19.1 - # via tld (pyproject.toml) -mypy-extensions==1.1.0 - # via mypy nh3==0.3.3 # via readme-renderer numpy==2.4.2 @@ -138,8 +132,6 @@ packaging==26.0 # wheel parso==0.8.6 # via jedi -pathspec==1.0.4 - # via mypy pexpect==4.9.0 # via ipython pillow==12.1.1 @@ -282,11 +274,12 @@ traitlets==5.14.3 # matplotlib-inline twine==6.2.0 # via tld (pyproject.toml) +ty==0.0.34 + # via tld (pyproject.toml) typing-extensions==4.15.0 # via # anyio # line-profiler - # mypy # starlette urllib3==2.6.3 # via diff --git a/requirements/build.txt b/requirements/build.txt index d8819ec..dd44403 100644 --- a/requirements/build.txt +++ b/requirements/build.txt @@ -86,8 +86,6 @@ jinja2==3.1.6 # via sphinx keyring==25.7.0 # via twine -librt==0.8.1 - # via mypy markdown-it-py==4.0.0 # via rich markupsafe==3.0.3 @@ -100,10 +98,6 @@ more-itertools==10.8.0 # via # jaraco-classes # jaraco-functools -mypy==1.19.1 - # via tld (pyproject.toml) -mypy-extensions==1.1.0 - # via mypy nh3==0.3.3 # via readme-renderer packaging==26.0 @@ -117,8 +111,6 @@ packaging==26.0 # wheel parso==0.8.6 # via jedi -pathspec==1.0.4 - # via mypy pexpect==4.9.0 # via ipython pkginfo==1.12.1.2 @@ -242,10 +234,11 @@ traitlets==5.14.3 # matplotlib-inline twine==6.2.0 # via tld (pyproject.toml) +ty==0.0.34 + # via tld (pyproject.toml) typing-extensions==4.15.0 # via # anyio - # mypy # starlette urllib3==2.6.3 # via diff --git a/runtests.py b/runtests.py index 62f5b59..63b5adc 100755 --- a/runtests.py +++ b/runtests.py @@ -1,4 +1,8 @@ #!/usr/bin/env python +""" +Used in `make profile-test`. Do NOT use this directly. +""" + import os import sys diff --git a/src/tld/base.py b/src/tld/base.py index 0afb3ec..0291ada 100644 --- a/src/tld/base.py +++ b/src/tld/base.py @@ -1,6 +1,5 @@ import logging -from codecs import open as codecs_open -from typing import Dict, ItemsView, Optional, Union, ValuesView +from typing import Dict, ItemsView, Optional, Type, ValuesView from urllib.request import urlopen from .exceptions import TldImproperlyConfigured, TldIOError @@ -18,14 +17,14 @@ class Registry(type): - REGISTRY: Dict[str, "BaseTLDSourceParser"] = {} + REGISTRY: Dict[str, Type["BaseTLDSourceParser"]] = {} def __new__(mcs, name, bases, attrs): # noqa: N804 new_cls = type.__new__(mcs, name, bases, attrs) # Here the name of the class is used as key but it could be any class # parameter. if getattr(new_cls, "_uid", None): - mcs.REGISTRY[new_cls._uid] = new_cls + mcs.REGISTRY[new_cls._uid] = new_cls # type: ignore return new_cls @property @@ -38,16 +37,16 @@ def reset(cls) -> None: @classmethod def get( - cls, key: str, default: "BaseTLDSourceParser" = None - ) -> Union["BaseTLDSourceParser", None]: + cls, key: str, default: Optional[Type["BaseTLDSourceParser"]] = None + ) -> Optional[Type["BaseTLDSourceParser"]]: return cls.REGISTRY.get(key, default) @classmethod - def items(cls) -> ItemsView[str, "BaseTLDSourceParser"]: + def items(cls) -> ItemsView[str, Type["BaseTLDSourceParser"]]: return cls.REGISTRY.items() @classmethod - def values(cls) -> ValuesView["BaseTLDSourceParser"]: + def values(cls) -> ValuesView[Type["BaseTLDSourceParser"]]: return cls.REGISTRY.values() # @classmethod @@ -98,9 +97,7 @@ def update_tld_names(cls, fail_silently: bool = False) -> bool: try: remote_file = urlopen(cls.source_url) local_file_abs_path = project_dir(cls.local_path) - with codecs_open( - local_file_abs_path, "wb", encoding="utf8" - ) as local_file: + with open(local_file_abs_path, "w", encoding="utf8") as local_file: local_file.write(remote_file.read().decode("utf8")) remote_file.close() LOGGER.info( diff --git a/src/tld/res/effective_tld_names.dat.txt b/src/tld/res/effective_tld_names.dat.txt index eedd6a4..cd7c2c7 100644 --- a/src/tld/res/effective_tld_names.dat.txt +++ b/src/tld/res/effective_tld_names.dat.txt @@ -5,8 +5,8 @@ // Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat, // rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported. -// VERSION: 2026-03-06_02-20-37_UTC -// COMMIT: a7621207f34b3a739a5cfb2c47a518b0b9054fe6 +// VERSION: 2026-05-01_02-51-25_UTC +// COMMIT: 8b4345f9a2513011b21e6fc7b8a7197a849be52c // Instructions on pulling and using this list can be found at https://publicsuffix.org/list/. @@ -6824,7 +6824,7 @@ org.zw // newGTLDs -// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2026-02-18T15:51:43Z +// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2026-04-30T16:18:08Z // This list is auto-generated, don't edit it manually. // aaa : American Automobile Association, Inc. // https://www.iana.org/domains/root/db/aaa.html @@ -7010,7 +7010,7 @@ anquan // https://www.iana.org/domains/root/db/anz.html anz -// aol : Yahoo Inc. +// aol : AOL Media LLC // https://www.iana.org/domains/root/db/aol.html aol @@ -7566,7 +7566,7 @@ church // https://www.iana.org/domains/root/db/cipriani.html cipriani -// circle : Amazon Registry Services, Inc. +// circle : Jolly Host, LLC // https://www.iana.org/domains/root/db/circle.html circle @@ -8418,7 +8418,7 @@ google // https://www.iana.org/domains/root/db/gop.html gop -// got : Amazon Registry Services, Inc. +// got : Jolly Host, LLC // https://www.iana.org/domains/root/db/got.html got @@ -8790,7 +8790,7 @@ jnj // https://www.iana.org/domains/root/db/joburg.html joburg -// jot : Amazon Registry Services, Inc. +// jot : Jolly Host, LLC // https://www.iana.org/domains/root/db/jot.html jot @@ -9926,7 +9926,7 @@ saarland // https://www.iana.org/domains/root/db/safe.html safe -// safety : Safety Registry Services, LLC. +// safety : Jolly Host, LLC // https://www.iana.org/domains/root/db/safety.html safety @@ -12336,10 +12336,18 @@ eero-stage.online // concludes Amazon +// Anomaly : https://opencode.ai +// Submitted by Dax Raad +opentunnel.xyz + // Antagonist B.V. : https://www.antagonist.nl/ // Submitted by Sander Hoentjen antagonist.cloud +// Anthropic : https://www.anthropic.com/ +// Submitted by Sid Bidasaria +claude.app + // Apigee : https://apigee.com/ // Submitted by Apigee Security Team apigee.io @@ -12419,7 +12427,10 @@ sweetpepper.org myasustor.com // Atlassian : https://atlassian.com -// Submitted by Sam Smyth +// Submitted by Benjamin McAlary +*.atlassian-3p.com +*.atlassian-3p-us-gov-mod.com +*.atlassian-isolated-3p.com cdn.prod.atlassian-dev.net // AVM : https://avm.de @@ -12889,6 +12900,12 @@ deno-staging.dev deno.net sandbox.deno.net +// DeployAgent : https://deployagent.com +// Submitted by Danny +deployagent.com +piebox.site +deployagent.space + // deSEC : https://desec.io/ // Submitted by Peter Thomassen dedyn.io @@ -13453,15 +13470,25 @@ us-4.evennode.com relay.evervault.app relay.evervault.dev +// Exe : https://exe.dev +// Submitted by Josh Bleecher Snyder +exe.xyz + // Expo : https://expo.dev/ -// Submitted by James Ide +// Submitted by Phil Pluckthun expo.app +on.expo.app staging.expo.app +on.staging.expo.app // Fabrica Technologies, Inc. : https://www.fabrica.dev/ // Submitted by Eric Jiang onfabrica.com +// fachschaften.org: https://fachschaften.org/ +// Submitted by Felix Schäfer +fspages.org + // FAITID : https://faitid.org/ // Submitted by Maxim Alzoba // https://www.flexireg.net/stat_info @@ -13594,6 +13621,7 @@ fh-muenster.io // Figma : https://www.figma.com // Submitted by Nick Frost +payload.dev figma.site figma-gov.site preview.site @@ -13908,11 +13936,6 @@ goupile.fr // Submitted by Richard Baker pymnt.uk -// GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ -// Submitted by Tom Whitwell -cloudapps.digital -london.cloudapps.digital - // Government of the Netherlands : https://www.government.nl // Submitted by gov.nl @@ -14018,6 +14041,10 @@ homesklep.pl *.id.pub *.kin.pub +// HOOC AG : https://www.hooc.ch +// Submitted by Fabrizio Steiner +seprox.hooc.me + // Hoplix : https://www.hoplix.com // Submitted by Danilo De Franco hoplix.shop @@ -14302,14 +14329,22 @@ us1-plenit.com webadorsite.com jouwweb.site -// Joyent : https://www.joyent.com/ -// Submitted by Brian Bennett -*.triton.zone - // JS.ORG : http://dns.js.org // Submitted by Stefan Keim js.org +// K2 Cloud : https://k2.cloud/ +// Submitted by K2 Cloud +elastic.k2.cloud +lb.ru-msk.k2.cloud +s3.ru-msk.k2.cloud +website.ru-msk.k2.cloud +lb.ru-spb.k2.cloud +s3.ru-spb.k2.cloud +website.ru-spb.k2.cloud +s3.k2.cloud +website.k2.cloud + // KaasHosting : http://www.kaashosting.nl/ // Submitted by Wouter Bakker kaas.gg @@ -14597,6 +14632,7 @@ messerli.app // Submitted by Jacob Cordero atmeta.com apps.fbsbx.com +*.metaaiusercontent.com // MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ // Submitted by Zdeněk Šustr and Radim Janča @@ -14892,6 +14928,35 @@ noop.app *.database.run *.migration.run +// Northwest Nexus dba NuOz : https://nuoz.net/ +// An RFC 1480 locality domain delegate host +// Submitted by Peter Briggs on behalf of NuOz +aberdeen.wa.us +bainbridge-isl.wa.us +bellevue.wa.us +bremerton.wa.us +centralia.wa.us +chehalis.wa.us +forks.wa.us +gig-harbor.wa.us +hoquiam.wa.us +keyport.wa.us +kingston.wa.us +olympia.wa.us +port-angeles.wa.us +port-ludlow.wa.us +port-orchard.wa.us +port-townsend.wa.us +poulsbo.wa.us +redmond.wa.us +renton.wa.us +sea.wa.us +seattle.wa.us +sequim.wa.us +shelton.wa.us +silverdale.wa.us +yarrow-point.wa.us + // Noticeable : https://noticeable.io // Submitted by Laurent Pellegrino noticeable.news @@ -15061,10 +15126,6 @@ oy.lc // Submitted by Derek Myers pgfog.com -// PageXL : https://pagexl.com -// Submitted by Yann Guichard -pagexl.com - // Pantheon Systems, Inc. : https://pantheon.io/ // Submitted by Gary Dylina gotpantheon.com @@ -15087,6 +15148,10 @@ gl.srv.us // Submitted by Steve Leung mypep.link +// Perplexity AI : https://www.perplexity.ai/ +// Submitted by Alec Xiang +pplx.app + // Perspecta : https://perspecta.com/ // Submitted by Kenneth Van Alstyne perspecta.cloud @@ -15597,6 +15662,12 @@ pp.ua // Submitted by Information Administration as.sh.cn +// Shanghai Oray Information Technology Co., Ltd.: https://www.oray.com/ +// Submitted by: Shanghai Oray Information Technology Co., Ltd. +vicp.fun +yicp.fun +zicp.fun + // Sheezy.Art : https://sheezy.art // Submitted by Nyoom sheezy.games @@ -15747,6 +15818,7 @@ stackit.zone // Stackryze : https://stackryze.com // Submitted by Sudheer Bhuvana +sryze.cc indevs.in // Staclar : https://staclar.com @@ -15981,6 +16053,10 @@ lima.zone site.transip.me *.transurl.nl +// Triton Data Center project : https://tritondatacenter.com +// Submitted by Triton Data Center staff +*.triton.zone + // Tunnelmole: https://tunnelmole.com // Submitted by Robbie Cahill tunnelmole.net @@ -16090,6 +16166,11 @@ vistablog.ir // Submitted by Deus Team deus-canvas.com +// vivenu GmbH : https://vivenu.com/ +// Submitted by Marvin Frick +vivenushop.com +vivenushop.dev + // Voorloper.com : https://voorloper.com // Submitted by Nathan van Bakel voorloper.cloud diff --git a/src/tld/res/effective_tld_names_public_only.dat.txt b/src/tld/res/effective_tld_names_public_only.dat.txt index eedd6a4..cd7c2c7 100644 --- a/src/tld/res/effective_tld_names_public_only.dat.txt +++ b/src/tld/res/effective_tld_names_public_only.dat.txt @@ -5,8 +5,8 @@ // Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat, // rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported. -// VERSION: 2026-03-06_02-20-37_UTC -// COMMIT: a7621207f34b3a739a5cfb2c47a518b0b9054fe6 +// VERSION: 2026-05-01_02-51-25_UTC +// COMMIT: 8b4345f9a2513011b21e6fc7b8a7197a849be52c // Instructions on pulling and using this list can be found at https://publicsuffix.org/list/. @@ -6824,7 +6824,7 @@ org.zw // newGTLDs -// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2026-02-18T15:51:43Z +// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2026-04-30T16:18:08Z // This list is auto-generated, don't edit it manually. // aaa : American Automobile Association, Inc. // https://www.iana.org/domains/root/db/aaa.html @@ -7010,7 +7010,7 @@ anquan // https://www.iana.org/domains/root/db/anz.html anz -// aol : Yahoo Inc. +// aol : AOL Media LLC // https://www.iana.org/domains/root/db/aol.html aol @@ -7566,7 +7566,7 @@ church // https://www.iana.org/domains/root/db/cipriani.html cipriani -// circle : Amazon Registry Services, Inc. +// circle : Jolly Host, LLC // https://www.iana.org/domains/root/db/circle.html circle @@ -8418,7 +8418,7 @@ google // https://www.iana.org/domains/root/db/gop.html gop -// got : Amazon Registry Services, Inc. +// got : Jolly Host, LLC // https://www.iana.org/domains/root/db/got.html got @@ -8790,7 +8790,7 @@ jnj // https://www.iana.org/domains/root/db/joburg.html joburg -// jot : Amazon Registry Services, Inc. +// jot : Jolly Host, LLC // https://www.iana.org/domains/root/db/jot.html jot @@ -9926,7 +9926,7 @@ saarland // https://www.iana.org/domains/root/db/safe.html safe -// safety : Safety Registry Services, LLC. +// safety : Jolly Host, LLC // https://www.iana.org/domains/root/db/safety.html safety @@ -12336,10 +12336,18 @@ eero-stage.online // concludes Amazon +// Anomaly : https://opencode.ai +// Submitted by Dax Raad +opentunnel.xyz + // Antagonist B.V. : https://www.antagonist.nl/ // Submitted by Sander Hoentjen antagonist.cloud +// Anthropic : https://www.anthropic.com/ +// Submitted by Sid Bidasaria +claude.app + // Apigee : https://apigee.com/ // Submitted by Apigee Security Team apigee.io @@ -12419,7 +12427,10 @@ sweetpepper.org myasustor.com // Atlassian : https://atlassian.com -// Submitted by Sam Smyth +// Submitted by Benjamin McAlary +*.atlassian-3p.com +*.atlassian-3p-us-gov-mod.com +*.atlassian-isolated-3p.com cdn.prod.atlassian-dev.net // AVM : https://avm.de @@ -12889,6 +12900,12 @@ deno-staging.dev deno.net sandbox.deno.net +// DeployAgent : https://deployagent.com +// Submitted by Danny +deployagent.com +piebox.site +deployagent.space + // deSEC : https://desec.io/ // Submitted by Peter Thomassen dedyn.io @@ -13453,15 +13470,25 @@ us-4.evennode.com relay.evervault.app relay.evervault.dev +// Exe : https://exe.dev +// Submitted by Josh Bleecher Snyder +exe.xyz + // Expo : https://expo.dev/ -// Submitted by James Ide +// Submitted by Phil Pluckthun expo.app +on.expo.app staging.expo.app +on.staging.expo.app // Fabrica Technologies, Inc. : https://www.fabrica.dev/ // Submitted by Eric Jiang onfabrica.com +// fachschaften.org: https://fachschaften.org/ +// Submitted by Felix Schäfer +fspages.org + // FAITID : https://faitid.org/ // Submitted by Maxim Alzoba // https://www.flexireg.net/stat_info @@ -13594,6 +13621,7 @@ fh-muenster.io // Figma : https://www.figma.com // Submitted by Nick Frost +payload.dev figma.site figma-gov.site preview.site @@ -13908,11 +13936,6 @@ goupile.fr // Submitted by Richard Baker pymnt.uk -// GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ -// Submitted by Tom Whitwell -cloudapps.digital -london.cloudapps.digital - // Government of the Netherlands : https://www.government.nl // Submitted by gov.nl @@ -14018,6 +14041,10 @@ homesklep.pl *.id.pub *.kin.pub +// HOOC AG : https://www.hooc.ch +// Submitted by Fabrizio Steiner +seprox.hooc.me + // Hoplix : https://www.hoplix.com // Submitted by Danilo De Franco hoplix.shop @@ -14302,14 +14329,22 @@ us1-plenit.com webadorsite.com jouwweb.site -// Joyent : https://www.joyent.com/ -// Submitted by Brian Bennett -*.triton.zone - // JS.ORG : http://dns.js.org // Submitted by Stefan Keim js.org +// K2 Cloud : https://k2.cloud/ +// Submitted by K2 Cloud +elastic.k2.cloud +lb.ru-msk.k2.cloud +s3.ru-msk.k2.cloud +website.ru-msk.k2.cloud +lb.ru-spb.k2.cloud +s3.ru-spb.k2.cloud +website.ru-spb.k2.cloud +s3.k2.cloud +website.k2.cloud + // KaasHosting : http://www.kaashosting.nl/ // Submitted by Wouter Bakker kaas.gg @@ -14597,6 +14632,7 @@ messerli.app // Submitted by Jacob Cordero atmeta.com apps.fbsbx.com +*.metaaiusercontent.com // MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ // Submitted by Zdeněk Šustr and Radim Janča @@ -14892,6 +14928,35 @@ noop.app *.database.run *.migration.run +// Northwest Nexus dba NuOz : https://nuoz.net/ +// An RFC 1480 locality domain delegate host +// Submitted by Peter Briggs on behalf of NuOz +aberdeen.wa.us +bainbridge-isl.wa.us +bellevue.wa.us +bremerton.wa.us +centralia.wa.us +chehalis.wa.us +forks.wa.us +gig-harbor.wa.us +hoquiam.wa.us +keyport.wa.us +kingston.wa.us +olympia.wa.us +port-angeles.wa.us +port-ludlow.wa.us +port-orchard.wa.us +port-townsend.wa.us +poulsbo.wa.us +redmond.wa.us +renton.wa.us +sea.wa.us +seattle.wa.us +sequim.wa.us +shelton.wa.us +silverdale.wa.us +yarrow-point.wa.us + // Noticeable : https://noticeable.io // Submitted by Laurent Pellegrino noticeable.news @@ -15061,10 +15126,6 @@ oy.lc // Submitted by Derek Myers pgfog.com -// PageXL : https://pagexl.com -// Submitted by Yann Guichard -pagexl.com - // Pantheon Systems, Inc. : https://pantheon.io/ // Submitted by Gary Dylina gotpantheon.com @@ -15087,6 +15148,10 @@ gl.srv.us // Submitted by Steve Leung mypep.link +// Perplexity AI : https://www.perplexity.ai/ +// Submitted by Alec Xiang +pplx.app + // Perspecta : https://perspecta.com/ // Submitted by Kenneth Van Alstyne perspecta.cloud @@ -15597,6 +15662,12 @@ pp.ua // Submitted by Information Administration as.sh.cn +// Shanghai Oray Information Technology Co., Ltd.: https://www.oray.com/ +// Submitted by: Shanghai Oray Information Technology Co., Ltd. +vicp.fun +yicp.fun +zicp.fun + // Sheezy.Art : https://sheezy.art // Submitted by Nyoom sheezy.games @@ -15747,6 +15818,7 @@ stackit.zone // Stackryze : https://stackryze.com // Submitted by Sudheer Bhuvana +sryze.cc indevs.in // Staclar : https://staclar.com @@ -15981,6 +16053,10 @@ lima.zone site.transip.me *.transurl.nl +// Triton Data Center project : https://tritondatacenter.com +// Submitted by Triton Data Center staff +*.triton.zone + // Tunnelmole: https://tunnelmole.com // Submitted by Robbie Cahill tunnelmole.net @@ -16090,6 +16166,11 @@ vistablog.ir // Submitted by Deus Team deus-canvas.com +// vivenu GmbH : https://vivenu.com/ +// Submitted by Marvin Frick +vivenushop.com +vivenushop.dev + // Voorloper.com : https://voorloper.com // Submitted by Nathan van Bakel voorloper.cloud diff --git a/src/tld/result.py b/src/tld/result.py index ae56e63..f994b21 100644 --- a/src/tld/result.py +++ b/src/tld/result.py @@ -50,7 +50,7 @@ def __str__(self) -> str: __repr__ = __str__ @property - def __dict__(self) -> Dict[str, Any]: # type: ignore + def __dict__(self) -> Dict[str, Any]: """Mimic __dict__ functionality. :return: diff --git a/src/tld/tests/test_core.py b/src/tld/tests/test_core.py index d046727..1927863 100644 --- a/src/tld/tests/test_core.py +++ b/src/tld/tests/test_core.py @@ -5,7 +5,7 @@ import unittest from os.path import abspath, join from tempfile import gettempdir -from typing import Type +from typing import Any, Dict, List, Optional, Type, TypedDict, Union from urllib.parse import SplitResult, urlsplit from fake import FAKER @@ -20,6 +20,7 @@ TldIOError, ) from ..helpers import project_dir +from ..result import Result from ..utils import ( BaseMozillaTLDSourceParser, MozillaTLDSourceParser, @@ -36,6 +37,22 @@ ) from .base import internet_available_only + +class GoodPattern(TypedDict): + url: Union[str, SplitResult] + fld: str + subdomain: str + domain: str + suffix: str + tld: str + kwargs: Dict[str, Any] + + +class BadPatternParams(TypedDict, total=False): + exception: Type[BaseException] + kwargs: Dict[str, Any] + + __author__ = "Artur Barseghyan" __copyright__ = "2013-2026 Artur Barseghyan" __license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later" @@ -53,7 +70,7 @@ def setUpClass(cls): def setUp(self): """Set up.""" - self.good_patterns = [ + self.good_patterns: List[GoodPattern] = [ { "url": "http://www.google.co.uk", "fld": "google.co.uk", @@ -326,7 +343,7 @@ def setUp(self): }, ] - self.bad_patterns = { + self.bad_patterns: Dict[str, BadPatternParams] = { "v2.www.google.com": { "exception": TldBadUrl, }, @@ -366,7 +383,7 @@ def setUp(self): self.tld_names_local_path_custom = project_dir( join("tests", "res", "effective_tld_names_custom.dat.txt") ) - self.good_patterns_custom_parser = [ + self.good_patterns_custom_parser: List[GoodPattern] = [ { "url": "http://www.foreverchild", "fld": "www.foreverchild", @@ -410,7 +427,7 @@ def bad_url(self): def get_custom_parser_class( self, uid: str = "custom_mozilla", - source_url: str = None, + source_url: Optional[str] = None, local_path: str = "tests/res/effective_tld_names_custom.dat.txt", ) -> Type[BaseTLDSourceParser]: # Define a custom TLD source parser class @@ -471,9 +488,10 @@ def override_settings(): def test_tld_good_patterns_pass_parsed_object(self): """Test good URL patterns.""" for data in self.good_patterns: - kwargs = copy.copy(data["kwargs"]) + kwargs: Dict[str, Any] = copy.copy(data["kwargs"]) kwargs["as_object"] = True _res = get_tld(data["url"], **kwargs) + assert isinstance(_res, Result) self.assertEqual(_res.tld, data["tld"]) self.assertEqual(_res.subdomain, data["subdomain"]) self.assertEqual(_res.domain, data["domain"]) @@ -606,7 +624,7 @@ def test_fail_get_tld_names(self): reset_tld_names() # Assert raise TldIOError on wrong NAMES_SOURCE_URL for params in self.good_patterns: - kwargs = {"url": params["url"]} + kwargs: Dict[str, Any] = {"url": params["url"]} kwargs.update(params["kwargs"]) kwargs["fail_silently"] = False kwargs["parser_class"] = parser_class @@ -677,7 +695,7 @@ def test_parse_tld_custom_tld_names_good_patterns(self): def test_tld_custom_tld_names_good_patterns_pass_parsed_object(self): """Test `get_tld` good URL patterns for custom tld names.""" for data in self.good_patterns_custom_parser: - kwargs = copy.copy(data["kwargs"]) + kwargs: Dict[str, Any] = copy.copy(data["kwargs"]) kwargs.update( { "as_object": True, @@ -685,6 +703,7 @@ def test_tld_custom_tld_names_good_patterns_pass_parsed_object(self): } ) _res = get_tld(data["url"], **kwargs) + assert isinstance(_res, Result) self.assertEqual(_res.tld, data["tld"]) self.assertEqual(_res.subdomain, data["subdomain"]) self.assertEqual(_res.domain, data["domain"]) @@ -710,7 +729,7 @@ def test_reset_tld_names_for_custom_parser(self): """Test `reset_tld_names` for `tld_names_local_path`.""" parser_class = self.get_custom_parser_class() for data in self.good_patterns_custom_parser: - kwargs = copy.copy(data["kwargs"]) + kwargs: Dict[str, Any] = copy.copy(data["kwargs"]) kwargs.update( { "as_object": True, @@ -718,6 +737,7 @@ def test_reset_tld_names_for_custom_parser(self): } ) _res = get_tld(data["url"], **kwargs) + assert isinstance(_res, Result) self.assertEqual(_res.tld, data["tld"]) self.assertEqual(_res.subdomain, data["subdomain"]) self.assertEqual(_res.domain, data["domain"]) @@ -770,6 +790,7 @@ def test_len_trie_nodes(self): def test_get_tld_names_no_arguments(self): """Test len of the trie nodes.""" tld_names = get_tld_names() + assert tld_names is not None self.assertGreater(len(tld_names), 0) def test_case(self): @@ -779,6 +800,7 @@ def test_case(self): search_private=False, as_object=True, ) + assert isinstance(res, Result) self.assertEqual(res.tld, "com") self.assertEqual(res.domain, "mydomain") self.assertEqual(res.subdomain, "") diff --git a/src/tld/utils.py b/src/tld/utils.py index e24dd60..ae39b4c 100644 --- a/src/tld/utils.py +++ b/src/tld/utils.py @@ -3,7 +3,6 @@ import argparse import re import sys -from codecs import open as codecs_open from functools import lru_cache from os.path import isabs from typing import Dict, List, Optional, Tuple, Type, Union @@ -20,9 +19,6 @@ from .result import Result from .trie import Trie -# codecs_open = open - - __author__ = "Artur Barseghyan" __copyright__ = "2013-2026 Artur Barseghyan" __license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later" @@ -87,7 +83,7 @@ def pop_tld_names_container(tld_names_local_path: str) -> None: @lru_cache(maxsize=128, typed=True) def update_tld_names( - fail_silently: bool = False, parser_uid: str = None + fail_silently: bool = False, parser_uid: Optional[str] = None ) -> bool: """Update TLD names. @@ -144,8 +140,8 @@ def update_tld_names_cli(argv=None) -> int: def get_tld_names( fail_silently: bool = False, retry_count: int = 0, - parser_class: Type[BaseTLDSourceParser] = None, -) -> Dict[str, Trie]: + parser_class: Optional[Type[BaseTLDSourceParser]] = None, +) -> Optional[Dict[str, Trie]]: """Build the ``tlds`` list if empty. Recursive. :param fail_silently: If set to True, no exceptions are raised and None @@ -206,7 +202,7 @@ def get_tld_names( local_path = cls.local_path else: local_path = project_dir(cls.local_path) - with codecs_open(local_path, "r", encoding="utf8") as local_file: + with open(local_path, "r", encoding="utf8") as local_file: trie = Trie() trie_add = trie.add # Performance opt # Make a list of it all, strip all garbage @@ -278,7 +274,7 @@ def process_url( fix_protocol: bool = False, search_public: bool = True, search_private: bool = True, - parser_class: Type[BaseTLDSourceParser] = MozillaTLDSourceParser, + parser_class: Optional[Type[BaseTLDSourceParser]] = MozillaTLDSourceParser, ) -> Union[Tuple[List[str], int, SplitResult], Tuple[None, None, SplitResult]]: """Process URL. @@ -296,11 +292,19 @@ def process_url( "set to True." ) + if parser_class is None: + parser_class = MozillaTLDSourceParser + # Init _tld_names = get_tld_names( fail_silently=fail_silently, parser_class=parser_class ) + if _tld_names is None: + if fail_silently: + return None, None, SplitResult("", "", "", "", "") + raise TldIOError() + if not isinstance(url, SplitResult): if fix_protocol and not protocol_re.match(url.lower()): url = f"https://{url}" @@ -310,7 +314,7 @@ def process_url( parsed_url = urlsplit(url) except ValueError as e: if fail_silently: - return None, None, url + return None, None, SplitResult("", "", "", "", "") else: raise e else: @@ -396,7 +400,7 @@ def get_fld( fix_protocol: bool = False, search_public: bool = True, search_private: bool = True, - parser_class: Type[BaseTLDSourceParser] = None, + parser_class: Optional[Type[BaseTLDSourceParser]] = None, **kwargs, ) -> Optional[str]: """Extract the first level domain. @@ -466,7 +470,7 @@ def get_tld( fix_protocol: bool = False, search_public: bool = True, search_private: bool = True, - parser_class: Type[BaseTLDSourceParser] = None, + parser_class: Optional[Type[BaseTLDSourceParser]] = None, ) -> Optional[Union[str, Result]]: """Extract the top level domain. @@ -549,7 +553,7 @@ def parse_tld( fix_protocol: bool = False, search_public: bool = True, search_private: bool = True, - parser_class: Type[BaseTLDSourceParser] = None, + parser_class: Optional[Type[BaseTLDSourceParser]] = None, ) -> Union[Tuple[None, None, None], Tuple[str, str, str]]: """Parse TLD into parts. @@ -579,10 +583,10 @@ def parse_tld( search_private=search_private, parser_class=parser_class, ) - if obj is None: + if obj is None or not isinstance(obj, Result): return None, None, None - return obj.tld, obj.domain, obj.subdomain # type: ignore + return obj.tld, obj.domain, obj.subdomain except (TldBadUrl, TldDomainNotFound, TldImproperlyConfigured, TldIOError): pass @@ -594,7 +598,7 @@ def is_tld( value: Union[str, SplitResult], search_public: bool = True, search_private: bool = True, - parser_class: Type[BaseTLDSourceParser] = None, + parser_class: Optional[Type[BaseTLDSourceParser]] = None, ) -> bool: """Check if given URL is tld. @@ -626,7 +630,7 @@ def is_tld( return value == _tld -def reset_tld_names(tld_names_local_path: str = None) -> None: +def reset_tld_names(tld_names_local_path: Optional[str] = None) -> None: """Reset the ``tld_names`` to empty value. If ``tld_names_local_path`` is given, removes specified