Skip to content

Commit 4073f83

Browse files
authored
Reduce dependencies making the core installation super lightweight. #567 (#568)
1 parent 253e40d commit 4073f83

13 files changed

Lines changed: 96 additions & 27 deletions

File tree

benedict/core/items_sorted.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
from __future__ import annotations
22

33
from collections.abc import Mapping
4-
5-
from useful_types import SupportsRichComparisonT
4+
from typing import Any
65

76

87
def _items_sorted_by_item_at_index(
9-
d: Mapping[SupportsRichComparisonT, SupportsRichComparisonT],
8+
d: Mapping[Any, Any],
109
index: int,
1110
reverse: bool,
12-
) -> list[tuple[SupportsRichComparisonT, SupportsRichComparisonT]]:
11+
) -> list[tuple[Any, Any]]:
1312
return sorted(d.items(), key=lambda item: item[index], reverse=reverse)
1413

1514

1615
def items_sorted_by_keys(
17-
d: Mapping[SupportsRichComparisonT, SupportsRichComparisonT], reverse: bool = False
18-
) -> list[tuple[SupportsRichComparisonT, SupportsRichComparisonT]]:
16+
d: Mapping[Any, Any], reverse: bool = False
17+
) -> list[tuple[Any, Any]]:
1918
return _items_sorted_by_item_at_index(d, 0, reverse)
2019

2120

2221
def items_sorted_by_values(
23-
d: Mapping[SupportsRichComparisonT, SupportsRichComparisonT], reverse: bool = False
24-
) -> list[tuple[SupportsRichComparisonT, SupportsRichComparisonT]]:
22+
d: Mapping[Any, Any], reverse: bool = False
23+
) -> list[tuple[Any, Any]]:
2524
return _items_sorted_by_item_at_index(d, 1, reverse)

benedict/dicts/io/io_util.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@
1212
import boto3
1313

1414
s3_installed = True
15-
except ModuleNotFoundError:
15+
except ModuleNotFoundError: # pragma: no cover
1616
s3_installed = False
1717

18-
import fsutil
18+
try:
19+
import fsutil
20+
21+
fsutil_installed = True
22+
except ModuleNotFoundError: # pragma: no cover
23+
fsutil_installed = False
1924

20-
from benedict.extras import require_s3
25+
from benedict.extras import require_fsutil, require_s3
2126
from benedict.serializers import (
2227
get_format_by_path,
2328
get_serializer_by_format,
@@ -88,7 +93,7 @@ def is_data(s: str | bytes) -> bool:
8893

8994

9095
def is_filepath(s: Path | str) -> bool:
91-
if fsutil.is_file(s):
96+
if fsutil_installed and fsutil.is_file(s):
9297
return True
9398
return bool(
9499
get_format_by_path(s)
@@ -147,15 +152,18 @@ def read_content(
147152

148153

149154
def read_content_from_file(filepath: str, format: str | None = None) -> str:
155+
require_fsutil(installed=fsutil_installed)
150156
binary_format = is_binary_format(format)
151157
if binary_format:
152158
return filepath
153-
return fsutil.read_file(filepath) # type: ignore[no-any-return]
159+
content = fsutil.read_file(filepath)
160+
return str(content)
154161

155162

156163
def read_content_from_s3(
157164
url: str, s3_options: Mapping[str, Any], format: str | None = None
158165
) -> str:
166+
require_fsutil(installed=fsutil_installed)
159167
require_s3(installed=s3_installed)
160168
s3_url = parse_s3_url(url)
161169
dirpath = tempfile.gettempdir()
@@ -171,12 +179,14 @@ def read_content_from_s3(
171179
def read_content_from_url(
172180
url: str, requests_options: Mapping[str, Any], format: str | None = None
173181
) -> str:
182+
require_fsutil(installed=fsutil_installed)
174183
binary_format = is_binary_format(format)
175184
if binary_format:
176185
dirpath = tempfile.gettempdir()
177186
filepath = fsutil.download_file(url, dirpath=dirpath, **requests_options)
178-
return filepath # type: ignore[no-any-return]
179-
return fsutil.read_file_from_url(url, **requests_options) # type: ignore[no-any-return]
187+
return str(filepath)
188+
content = fsutil.read_file_from_url(url, **requests_options)
189+
return str(content)
180190

181191

182192
def write_content(filepath: str, content: str, **options: Any) -> None:
@@ -187,12 +197,14 @@ def write_content(filepath: str, content: str, **options: Any) -> None:
187197

188198

189199
def write_content_to_file(filepath: str, content: str, **options: Any) -> None:
200+
require_fsutil(installed=fsutil_installed)
190201
fsutil.write_file(filepath, content)
191202

192203

193204
def write_content_to_s3(
194205
url: str, content: str, s3_options: Mapping[str, Any], **options: Any
195206
) -> None:
207+
require_fsutil(installed=fsutil_installed)
196208
require_s3(installed=s3_installed)
197209
s3_url = parse_s3_url(url)
198210
dirpath = tempfile.gettempdir()

benedict/dicts/parse/parse_util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from phonenumbers import PhoneNumberFormat, phonenumberutil
1313

1414
parse_installed = True
15-
except ModuleNotFoundError:
15+
except ModuleNotFoundError: # pragma: no cover
1616
parse_installed = False
1717

1818

benedict/extras.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from benedict.exceptions import ExtrasRequireModuleNotFoundError
22

33
__all__ = [
4+
"require_fsutil",
45
"require_html",
56
"require_parse",
67
"require_s3",
@@ -20,6 +21,10 @@ def require_html(*, installed: bool) -> None:
2021
_require_optional_dependencies(target="html", installed=installed)
2122

2223

24+
def require_fsutil(*, installed: bool) -> None:
25+
_require_optional_dependencies(target="io", installed=installed)
26+
27+
2328
def require_parse(*, installed: bool) -> None:
2429
_require_optional_dependencies(target="parse", installed=installed)
2530

benedict/serializers/html.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from bs4 import BeautifulSoup
55

66
html_installed = True
7-
except ModuleNotFoundError:
7+
except ModuleNotFoundError: # pragma: no cover
88
html_installed = False
99

1010
from typing import Any, NoReturn

benedict/serializers/toml.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import toml
33

44
toml_installed = True
5-
except ModuleNotFoundError:
5+
except ModuleNotFoundError: # pragma: no cover
66
toml_installed = False
77

88
try:

benedict/serializers/xls.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
from __future__ import annotations
22

3-
import fsutil
3+
try:
4+
import fsutil
5+
6+
fsutil_installed = True
7+
except ModuleNotFoundError: # pragma: no cover
8+
fsutil_installed = False
49

510
try:
611
from openpyxl import load_workbook
712
from xlrd import open_workbook
813

914
xls_installed = True
10-
except ModuleNotFoundError:
15+
except ModuleNotFoundError: # pragma: no cover
1116
xls_installed = False
1217

1318
from collections.abc import Sequence
1419
from typing import Any, NoReturn
1520

1621
from slugify import slugify
1722

18-
from benedict.extras import require_xls
23+
from benedict.extras import require_fsutil, require_xls
1924
from benedict.serializers.abstract import AbstractSerializer
2025

2126

@@ -175,6 +180,7 @@ def _decode(self, s: str, **kwargs: Any) -> list[dict[str, Any]]:
175180

176181
def decode(self, s: str, **kwargs: Any) -> list[dict[str, Any]]:
177182
require_xls(installed=xls_installed)
183+
require_fsutil(installed=fsutil_installed)
178184
extension = fsutil.get_file_extension(s)
179185
if extension in ["xlsx", "xlsm"]:
180186
return self._decode(s, **kwargs)

benedict/serializers/xml.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import xmltodict
55

66
xml_installed = True
7-
except ModuleNotFoundError:
7+
except ModuleNotFoundError: # pragma: no cover
88
xml_installed = False
99

1010

benedict/serializers/yaml.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from yaml.representer import SafeRepresenter
77

88
yaml_installed = True
9-
except ModuleNotFoundError:
9+
except ModuleNotFoundError: # pragma: no cover
1010
yaml_installed = False
1111

1212

pyproject.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,8 @@ classifiers = [
9090
"Typing :: Typed",
9191
]
9292
dependencies = [
93-
"python-fsutil >= 0.16.0, < 1.0.0",
9493
"python-slugify >= 7.0.0, < 9.0.0",
95-
"requests >= 2.33.0, < 3.0.0",
9694
"typing_extensions >= 4.13.2, < 4.16.0",
97-
"useful-types >= 0.2.1, < 0.3.0"
9895
]
9996
dynamic = ["version"]
10097
maintainers = [
@@ -126,6 +123,8 @@ html = [
126123
"python-benedict[xml]",
127124
]
128125
io = [
126+
"python-fsutil >= 0.16.1, < 1.0.0",
127+
"requests >= 2.33.0, < 3.0.0",
129128
"python-benedict[html,toml,xls,xml,yaml]",
130129
]
131130
parse = [
@@ -136,12 +135,14 @@ parse = [
136135
]
137136
s3 = [
138137
"boto3 >= 1.24.89, < 2.0.0",
138+
"python-fsutil >= 0.16.1, < 1.0.0",
139139
]
140140
toml = [
141141
"toml >= 0.10.2, < 1.0.0",
142142
]
143143
xls = [
144144
"openpyxl >= 3.0.0, < 4.0.0",
145+
"python-fsutil >= 0.16.1, < 1.0.0",
145146
"xlrd >= 2.0.0, < 3.0.0",
146147
]
147148
xml = [

0 commit comments

Comments
 (0)