mirror of
https://github.com/morpheus65535/bazarr
synced 2024-12-21 23:32:31 +00:00
no log: updating some dependencies that were having pending PR.
This commit is contained in:
parent
3a10df7724
commit
ec65f05399
23 changed files with 2796 additions and 28135 deletions
|
@ -0,0 +1 @@
|
|||
__version__ = "0.5.0"
|
|
@ -1,4 +1,5 @@
|
|||
import codecs
|
||||
from collections.abc import MutableMapping
|
||||
import logging
|
||||
import os
|
||||
import pickle
|
||||
|
@ -7,14 +8,6 @@ import tempfile
|
|||
|
||||
import appdirs
|
||||
|
||||
try:
|
||||
from collections.abc import MutableMapping
|
||||
unicode = str
|
||||
except ImportError:
|
||||
# Python 2 imports
|
||||
from collections import MutableMapping
|
||||
FileNotFoundError = IOError
|
||||
|
||||
from .posixemulation import rename
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -33,14 +26,14 @@ class FileCache(MutableMapping):
|
|||
|
||||
.. NOTE::
|
||||
Keys and values are always stored as :class:`bytes` objects. If data
|
||||
serialization is enabled, keys are returned as :class:`str` or
|
||||
:class:`unicode` objects.
|
||||
serialization is enabled, keys are returned as :class:`str` objects.
|
||||
If data serialization is disabled, keys are returned as a
|
||||
:class:`bytes` object.
|
||||
|
||||
:param str appname: The app/script the cache should be associated with.
|
||||
:param str flag: How the cache should be opened. See below for details.
|
||||
:param mode: The Unix mode for the cache files or False to prevent changing permissions.
|
||||
:param mode: The Unix mode for the cache files or False to prevent changing
|
||||
permissions.
|
||||
:param str keyencoding: The encoding the keys use, defaults to 'utf-8'.
|
||||
This is used if *serialize* is ``False``; the keys are treated as
|
||||
:class:`bytes` objects.
|
||||
|
@ -85,57 +78,66 @@ class FileCache(MutableMapping):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, appname, flag='c', mode=0o666, keyencoding='utf-8',
|
||||
serialize=True, app_cache_dir=None):
|
||||
def __init__(
|
||||
self,
|
||||
appname,
|
||||
flag="c",
|
||||
mode=0o666,
|
||||
keyencoding="utf-8",
|
||||
serialize=True,
|
||||
app_cache_dir=None,
|
||||
):
|
||||
"""Initialize a :class:`FileCache` object."""
|
||||
if not isinstance(flag, str):
|
||||
raise TypeError("flag must be str not '{}'".format(type(flag)))
|
||||
elif flag[0] not in 'rwcn':
|
||||
raise ValueError("invalid flag: '{}', first flag must be one of "
|
||||
"'r', 'w', 'c' or 'n'".format(flag))
|
||||
elif len(flag) > 1 and flag[1] != 's':
|
||||
raise ValueError("invalid flag: '{}', second flag must be "
|
||||
"'s'".format(flag))
|
||||
elif flag[0] not in "rwcn":
|
||||
raise ValueError(
|
||||
"invalid flag: '{}', first flag must be one of "
|
||||
"'r', 'w', 'c' or 'n'".format(flag)
|
||||
)
|
||||
elif len(flag) > 1 and flag[1] != "s":
|
||||
raise ValueError(
|
||||
"invalid flag: '{}', second flag must be " "'s'".format(flag)
|
||||
)
|
||||
|
||||
appname, subcache = self._parse_appname(appname)
|
||||
if 'cache' in subcache:
|
||||
if "cache" in subcache:
|
||||
raise ValueError("invalid subcache name: 'cache'.")
|
||||
self._is_subcache = bool(subcache)
|
||||
|
||||
if not app_cache_dir:
|
||||
app_cache_dir = appdirs.user_cache_dir(appname, appname)
|
||||
subcache_dir = os.path.join(app_cache_dir, *subcache)
|
||||
self.cache_dir = os.path.join(subcache_dir, 'cache')
|
||||
self.cache_dir = os.path.join(subcache_dir, "cache")
|
||||
exists = os.path.exists(self.cache_dir)
|
||||
|
||||
if len(flag) > 1 and flag[1] == 's':
|
||||
if len(flag) > 1 and flag[1] == "s":
|
||||
self._sync = True
|
||||
else:
|
||||
self._sync = False
|
||||
self._buffer = {}
|
||||
|
||||
if exists and 'n' in flag:
|
||||
if exists and "n" in flag:
|
||||
self.clear()
|
||||
self.create()
|
||||
elif not exists and ('c' in flag or 'n' in flag):
|
||||
elif not exists and ("c" in flag or "n" in flag):
|
||||
self.create()
|
||||
elif not exists:
|
||||
raise FileNotFoundError("no such directory: '{}'".format(
|
||||
self.cache_dir))
|
||||
raise FileNotFoundError("no such directory: '{}'".format(self.cache_dir))
|
||||
|
||||
self._flag = 'rb' if 'r' in flag else 'wb'
|
||||
self._flag = "rb" if "r" in flag else "wb"
|
||||
self._mode = mode
|
||||
self._keyencoding = keyencoding
|
||||
self._serialize = serialize
|
||||
|
||||
def _parse_appname(self, appname):
|
||||
"""Splits an appname into the appname and subcache components."""
|
||||
components = appname.split('.')
|
||||
components = appname.split(".")
|
||||
return components[0], components[1:]
|
||||
|
||||
def create(self):
|
||||
"""Create the write buffer and cache directory."""
|
||||
if not self._sync and not hasattr(self, '_buffer'):
|
||||
if not self._sync and not hasattr(self, "_buffer"):
|
||||
self._buffer = {}
|
||||
if not os.path.exists(self.cache_dir):
|
||||
os.makedirs(self.cache_dir)
|
||||
|
@ -195,11 +197,11 @@ class FileCache(MutableMapping):
|
|||
:class:`str`.
|
||||
|
||||
"""
|
||||
if isinstance(key, str) or isinstance(key, unicode):
|
||||
if isinstance(key, str):
|
||||
key = key.encode(self._keyencoding)
|
||||
elif not isinstance(key, bytes):
|
||||
raise TypeError("key must be bytes or str")
|
||||
return codecs.encode(key, 'hex_codec').decode(self._keyencoding)
|
||||
return codecs.encode(key, "hex_codec").decode(self._keyencoding)
|
||||
|
||||
def _decode_key(self, key):
|
||||
"""Decode key using hex_codec to retrieve the original key.
|
||||
|
@ -208,7 +210,7 @@ class FileCache(MutableMapping):
|
|||
Keys are returned as :class:`bytes` if serialization is disabled.
|
||||
|
||||
"""
|
||||
bkey = codecs.decode(key.encode(self._keyencoding), 'hex_codec')
|
||||
bkey = codecs.decode(key.encode(self._keyencoding), "hex_codec")
|
||||
return bkey.decode(self._keyencoding) if self._serialize else bkey
|
||||
|
||||
def _dumps(self, value):
|
||||
|
@ -228,8 +230,10 @@ class FileCache(MutableMapping):
|
|||
def _all_filenames(self):
|
||||
"""Return a list of absolute cache filenames"""
|
||||
try:
|
||||
return [os.path.join(self.cache_dir, filename) for filename in
|
||||
os.listdir(self.cache_dir)]
|
||||
return [
|
||||
os.path.join(self.cache_dir, filename)
|
||||
for filename in os.listdir(self.cache_dir)
|
||||
]
|
||||
except (FileNotFoundError, OSError):
|
||||
return []
|
||||
|
||||
|
@ -252,12 +256,8 @@ class FileCache(MutableMapping):
|
|||
|
||||
def _read_from_file(self, filename):
|
||||
"""Read data from filename."""
|
||||
try:
|
||||
with open(filename, 'rb') as f:
|
||||
return self._loads(f.read())
|
||||
except (IOError, OSError):
|
||||
logger.warning('Error opening file: {}'.format(filename))
|
||||
return None
|
||||
with open(filename, "rb") as f:
|
||||
return self._loads(f.read())
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
ekey = self._encode_key(key)
|
||||
|
@ -281,17 +281,17 @@ class FileCache(MutableMapping):
|
|||
|
||||
def __delitem__(self, key):
|
||||
ekey = self._encode_key(key)
|
||||
filename = self._key_to_filename(ekey)
|
||||
found_in_buffer = hasattr(self, "_buffer") and ekey in self._buffer
|
||||
if not self._sync:
|
||||
try:
|
||||
del self._buffer[ekey]
|
||||
except KeyError:
|
||||
if filename not in self._all_filenames():
|
||||
raise KeyError(key)
|
||||
try:
|
||||
pass
|
||||
filename = self._key_to_filename(ekey)
|
||||
if filename in self._all_filenames():
|
||||
os.remove(filename)
|
||||
except (IOError, OSError):
|
||||
pass
|
||||
elif not found_in_buffer:
|
||||
raise KeyError(key)
|
||||
|
||||
def __iter__(self):
|
||||
for key in self._all_keys():
|
||||
|
@ -303,3 +303,9 @@ class FileCache(MutableMapping):
|
|||
def __contains__(self, key):
|
||||
ekey = self._encode_key(key)
|
||||
return ekey in self._all_keys()
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, type_, value, traceback):
|
||||
self.close()
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
from .utils import (
|
||||
Result,
|
||||
get_fld,
|
||||
get_tld,
|
||||
get_tld_names,
|
||||
is_tld,
|
||||
parse_tld,
|
||||
Result,
|
||||
update_tld_names,
|
||||
)
|
||||
|
||||
__title__ = "tld"
|
||||
__version__ = "0.12.6"
|
||||
__version__ = "0.13"
|
||||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2021 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = (
|
||||
"get_fld",
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
from codecs import open as codecs_open
|
||||
import logging
|
||||
from codecs import open as codecs_open
|
||||
from typing import Dict, ItemsView, Optional, Union
|
||||
from urllib.request import urlopen
|
||||
from typing import Optional, Dict, Union, ItemsView
|
||||
|
||||
from .exceptions import (
|
||||
TldIOError,
|
||||
TldImproperlyConfigured,
|
||||
)
|
||||
from .exceptions import TldImproperlyConfigured, TldIOError
|
||||
from .helpers import project_dir
|
||||
|
||||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2021 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = (
|
||||
"BaseTLDSourceParser",
|
||||
|
@ -98,17 +95,15 @@ class BaseTLDSourceParser(metaclass=Registry):
|
|||
try:
|
||||
remote_file = urlopen(cls.source_url)
|
||||
local_file_abs_path = project_dir(cls.local_path)
|
||||
local_file = codecs_open(
|
||||
local_file_abs_path, "wb", encoding="utf8"
|
||||
)
|
||||
local_file = codecs_open(local_file_abs_path, "wb", encoding="utf8")
|
||||
local_file.write(remote_file.read().decode("utf8"))
|
||||
local_file.close()
|
||||
remote_file.close()
|
||||
LOGGER.debug(
|
||||
LOGGER.info(
|
||||
f"Fetched '{cls.source_url}' as '{local_file_abs_path}'"
|
||||
)
|
||||
except Exception as err:
|
||||
LOGGER.debug(
|
||||
LOGGER.error(
|
||||
f"Failed fetching '{cls.source_url}'. Reason: {str(err)}"
|
||||
)
|
||||
if fail_silently:
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
from typing import Any
|
||||
|
||||
from . import defaults
|
||||
|
||||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2020 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = (
|
||||
"get_setting",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from os.path import dirname
|
||||
|
||||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2020 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = (
|
||||
"DEBUG",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2021 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = (
|
||||
"TldBadUrl",
|
||||
|
|
|
@ -3,7 +3,7 @@ from os.path import abspath, join
|
|||
from .conf import get_setting
|
||||
|
||||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2021 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = (
|
||||
"project_dir",
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import warnings
|
||||
from .base import Registry
|
||||
|
||||
from .base import Registry # noqa
|
||||
|
||||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2021 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = ("Registry",)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,7 @@ from typing import Any, Dict
|
|||
from urllib.parse import SplitResult
|
||||
|
||||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2021 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = ("Result",)
|
||||
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
import unittest
|
||||
|
||||
from .test_core import *
|
||||
from .test_commands import *
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,11 +1,11 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from functools import lru_cache
|
||||
import logging
|
||||
import socket
|
||||
from functools import lru_cache
|
||||
|
||||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2021 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = (
|
||||
"internet_available_only",
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
import subprocess
|
||||
import unittest
|
||||
|
||||
import subprocess
|
||||
|
||||
from .base import log_info, internet_available_only
|
||||
from .base import internet_available_only, log_info
|
||||
|
||||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2021 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "GPL 2.0/LGPL 2.1"
|
||||
__all__ = ("TestCommands",)
|
||||
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
import copy
|
||||
import logging
|
||||
from os.path import abspath, join
|
||||
import unittest
|
||||
from os.path import abspath, join
|
||||
from tempfile import gettempdir
|
||||
from typing import Type
|
||||
|
||||
from urllib.parse import urlsplit, SplitResult
|
||||
from urllib.parse import SplitResult, urlsplit
|
||||
|
||||
from faker import Faker # type: ignore
|
||||
|
||||
|
@ -22,23 +21,22 @@ from ..exceptions import (
|
|||
)
|
||||
from ..helpers import project_dir
|
||||
from ..utils import (
|
||||
BaseMozillaTLDSourceParser,
|
||||
MozillaTLDSourceParser,
|
||||
get_fld,
|
||||
get_tld,
|
||||
get_tld_names,
|
||||
get_tld_names_container,
|
||||
is_tld,
|
||||
MozillaTLDSourceParser,
|
||||
BaseMozillaTLDSourceParser,
|
||||
parse_tld,
|
||||
reset_tld_names,
|
||||
update_tld_names,
|
||||
update_tld_names_cli,
|
||||
)
|
||||
|
||||
from .base import internet_available_only, log_info
|
||||
|
||||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2021 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = ("TestCore",)
|
||||
|
||||
|
@ -647,9 +645,7 @@ class TestCore(unittest.TestCase):
|
|||
|
||||
Assert raise TldIOError on wrong `NAMES_SOURCE_URL` for `parse_tld`.
|
||||
"""
|
||||
parser_class = self.get_custom_parser_class(
|
||||
source_url="i-do-not-exist"
|
||||
)
|
||||
parser_class = self.get_custom_parser_class(source_url="i-do-not-exist")
|
||||
parsed_tld = parse_tld(
|
||||
self.bad_url, fail_silently=False, parser_class=parser_class
|
||||
)
|
||||
|
@ -810,9 +806,7 @@ class TestCore(unittest.TestCase):
|
|||
"""Test len of the trie nodes."""
|
||||
get_tld("http://delusionalinsanity.com")
|
||||
tld_names = get_tld_names_container()
|
||||
self.assertGreater(
|
||||
len(tld_names[MozillaTLDSourceParser.local_path]), 0
|
||||
)
|
||||
self.assertGreater(len(tld_names[MozillaTLDSourceParser.local_path]), 0)
|
||||
|
||||
@log_info
|
||||
def test_25_get_tld_names_no_arguments(self):
|
||||
|
@ -842,3 +836,16 @@ class TestCore(unittest.TestCase):
|
|||
fragment="",
|
||||
),
|
||||
)
|
||||
|
||||
@log_info
|
||||
def test_27_tld_fail_silently_pass(self):
|
||||
"""Test `get_tld` bad URL patterns that would raise exception
|
||||
if `fail_silently` isn't `True`.
|
||||
"""
|
||||
res = []
|
||||
bad_url = ["https://user:password[@host.com", "https://user[@host.com"]
|
||||
for url in bad_url:
|
||||
_res = get_tld(url, fail_silently=True)
|
||||
self.assertEqual(_res, None)
|
||||
res.append(_res)
|
||||
return res
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import unittest
|
||||
|
||||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2021 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = ("TestRegistry",)
|
||||
|
||||
|
@ -11,4 +11,4 @@ class TestRegistry(unittest.TestCase):
|
|||
|
||||
def test_import_from_registry(self):
|
||||
"""Test import from deprecated `valuta.registry` module."""
|
||||
from ..registry import Registry
|
||||
from ..registry import Registry # noqa
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2021 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = (
|
||||
"Trie",
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from codecs import open as codecs_open
|
||||
from functools import lru_cache
|
||||
|
||||
# codecs_open = open
|
||||
from os.path import isabs
|
||||
import sys
|
||||
from typing import Dict, Type, Union, Tuple, List, Optional
|
||||
from urllib.parse import urlsplit, SplitResult
|
||||
from typing import Dict, List, Optional, Tuple, Type, Union
|
||||
from urllib.parse import SplitResult, urlsplit
|
||||
|
||||
from .base import BaseTLDSourceParser, Registry
|
||||
from .exceptions import (
|
||||
|
@ -17,11 +16,14 @@ from .exceptions import (
|
|||
TldIOError,
|
||||
)
|
||||
from .helpers import project_dir
|
||||
from .trie import Trie
|
||||
from .result import Result
|
||||
from .trie import Trie
|
||||
|
||||
# codecs_open = open
|
||||
|
||||
|
||||
__author__ = "Artur Barseghyan"
|
||||
__copyright__ = "2013-2021 Artur Barseghyan"
|
||||
__copyright__ = "2013-2023 Artur Barseghyan"
|
||||
__license__ = "MPL-1.1 OR GPL-2.0-only OR LGPL-2.1-or-later"
|
||||
__all__ = (
|
||||
"BaseMozillaTLDSourceParser",
|
||||
|
@ -132,9 +134,7 @@ def update_tld_names_cli() -> int:
|
|||
parser_uid = args.parser_uid
|
||||
fail_silently = args.fail_silently
|
||||
return int(
|
||||
not update_tld_names(
|
||||
parser_uid=parser_uid, fail_silently=fail_silently
|
||||
)
|
||||
not update_tld_names(parser_uid=parser_uid, fail_silently=fail_silently)
|
||||
)
|
||||
|
||||
|
||||
|
@ -229,7 +229,7 @@ class BaseMozillaTLDSourceParser(BaseTLDSourceParser):
|
|||
update_tld_names_container(cls.local_path, trie)
|
||||
|
||||
local_file.close()
|
||||
except IOError as err:
|
||||
except IOError:
|
||||
# Grab the file
|
||||
cls.update_tld_names(fail_silently=fail_silently)
|
||||
# Increment ``retry_count`` in order to avoid infinite loops
|
||||
|
@ -314,20 +314,14 @@ def process_url(
|
|||
parsed_url = urlsplit(url)
|
||||
except ValueError as e:
|
||||
if fail_silently:
|
||||
parsed_url = url
|
||||
return None, None, url
|
||||
else:
|
||||
raise e
|
||||
else:
|
||||
parsed_url = url
|
||||
|
||||
# Get (sub) domain name
|
||||
try:
|
||||
domain_name = parsed_url.hostname
|
||||
except AttributeError as e:
|
||||
if fail_silently:
|
||||
domain_name = None
|
||||
else:
|
||||
raise e
|
||||
domain_name = parsed_url.hostname
|
||||
|
||||
if not domain_name:
|
||||
if fail_silently:
|
||||
|
|
|
@ -129,9 +129,9 @@ webencodings==0.5.1
|
|||
|
||||
# Required-by: subzero
|
||||
backports.functools-lru-cache==1.6.4
|
||||
fcache==0.4.7 # https://github.com/tsroten/fcache/pull/34 and 35
|
||||
fcache==0.5.0
|
||||
json_tricks==3.16.1
|
||||
tld==0.12.6 # https://github.com/barseghyanartur/tld/pull/119
|
||||
tld==0.13
|
||||
|
||||
# Required-by: requests
|
||||
certifi==2022.9.24
|
||||
|
|
Loading…
Reference in a new issue