Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Here the hierarchy of possible installation targets available when running `pip
- `[xls]`
- `[xml]`
- `[yaml]`
- `[parse]`
- `[s3]`

## Usage
Expand Down
22 changes: 17 additions & 5 deletions benedict/dicts/parse/parse_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@
from datetime import datetime
from decimal import Decimal, DecimalException

import ftfy
import phonenumbers
from dateutil import parser as date_parser
from MailChecker import MailChecker
from phonenumbers import PhoneNumberFormat, phonenumberutil
try:
import ftfy
import phonenumbers
from dateutil import parser as date_parser
from MailChecker import MailChecker
from phonenumbers import PhoneNumberFormat, phonenumberutil

parse_installed = True
except ModuleNotFoundError:
parse_installed = False


from slugify import slugify

from benedict.extras import require_parse
from benedict.serializers import JSONSerializer
from benedict.utils import type_util

Expand Down Expand Up @@ -66,6 +74,7 @@ def _parse_datetime_from_timestamp(val):


def parse_datetime(val, format=None):
require_parse(installed=parse_installed)
if type_util.is_datetime(val):
return val
s = str(val)
Expand Down Expand Up @@ -124,6 +133,7 @@ def _parse_email(val, check_blacklist=True):


def parse_email(val, check_blacklist=True):
require_parse(installed=parse_installed)
return _parse_with(val, None, _parse_email, check_blacklist=check_blacklist)


Expand Down Expand Up @@ -183,6 +193,7 @@ def _parse_phonenumber(val, country_code=None):


def parse_phonenumber(val, country_code=None):
require_parse(installed=parse_installed)
s = parse_str(val)
if not s:
return None
Expand All @@ -205,6 +216,7 @@ def parse_slug(val):


def parse_str(val):
require_parse(installed=parse_installed)
if type_util.is_string(val):
val = ftfy.fix_text(val)
else:
Expand Down
17 changes: 11 additions & 6 deletions benedict/extras.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from benedict.exceptions import ExtrasRequireModuleNotFoundError

__all__ = [
"require_parse",
"require_s3",
"require_toml",
"require_xls",
Expand All @@ -9,26 +10,30 @@
]


def _require_optional_module(*, target, installed):
def _require_optional_dependencies(*, target, installed):
if not installed:
raise ExtrasRequireModuleNotFoundError(target=target)


def require_parse(*, installed):
_require_optional_dependencies(target="parse", installed=installed)


def require_s3(*, installed):
_require_optional_module(target="s3", installed=installed)
_require_optional_dependencies(target="s3", installed=installed)


def require_toml(*, installed):
_require_optional_module(target="toml", installed=installed)
_require_optional_dependencies(target="toml", installed=installed)


def require_xls(*, installed):
_require_optional_module(target="xls", installed=installed)
_require_optional_dependencies(target="xls", installed=installed)


def require_xml(*, installed):
_require_optional_module(target="xml", installed=installed)
_require_optional_dependencies(target="xml", installed=installed)


def require_yaml(*, installed):
_require_optional_module(target="yaml", installed=installed)
_require_optional_dependencies(target="yaml", installed=installed)
12 changes: 7 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,6 @@ classifiers = [
"Topic :: Utilities",
]
dependencies = [
"ftfy >= 6.0.0, < 7.0.0",
"mailchecker >= 4.1.0, < 6.0.0",
"phonenumbers >= 8.12.0, < 9.0.0",
"python-dateutil >= 2.8.0, < 3.0.0",
"python-fsutil >= 0.9.3, < 1.0.0",
"python-slugify >= 7.0.0, < 9.0.0",
"requests >= 2.26.0, < 3.0.0",
Expand Down Expand Up @@ -118,11 +114,17 @@ Twitter = "https://twitter.com/fabiocaccamo"

[project.optional-dependencies]
all = [
"python-benedict[io,s3]",
"python-benedict[io,parse,s3]",
]
io = [
"python-benedict[toml,xls,xml,yaml]",
]
parse = [
"ftfy >= 6.0.0, < 7.0.0",
"mailchecker >= 4.1.0, < 6.0.0",
"phonenumbers >= 8.12.0, < 9.0.0",
"python-dateutil >= 2.8.0, < 3.0.0",
]
s3 = [
"boto3 >= 1.24.89, < 2.0.0",
]
Expand Down
39 changes: 39 additions & 0 deletions tests/dicts/parse/test_parse_dict.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import unittest
from datetime import datetime
from decimal import Decimal
from unittest.mock import patch

from benedict.dicts.parse import ParseDict
from benedict.exceptions import ExtrasRequireModuleNotFoundError


class parse_dict_test_case(unittest.TestCase):
Expand Down Expand Up @@ -185,6 +187,16 @@ def test_get_datetime_without_format(self):
r = datetime(2019, 5, 1, 0, 0)
self.assertEqual(b.get_datetime("a"), r)

@patch("benedict.dicts.parse.parse_util.parse_installed", False)
def test_get_datetime_with_with_extra_not_installed(self):
with self.assertRaises(ExtrasRequireModuleNotFoundError):
d = {
"a": "2019-05-01",
}
b = ParseDict(d)
r = datetime(2019, 5, 1, 0, 0)
self.assertEqual(b.get_datetime("a", format="%Y-%m-%d"), r)

def test_get_datetime_list(self):
d = {
"a": ["2019-05-01", "2018-12-31", "Hello World"],
Expand Down Expand Up @@ -335,6 +347,15 @@ def test_get_email(self):
# invalid key
self.assertEqual(b.get_email("e"), "")

@patch("benedict.dicts.parse.parse_util.parse_installed", False)
def test_get_email_with_extra_not_installed(self):
with self.assertRaises(ExtrasRequireModuleNotFoundError):
d = {
"a": "[email protected]",
}
b = ParseDict(d)
b.get_email("a")

def test_get_int(self):
d = {
"a": 1,
Expand Down Expand Up @@ -504,6 +525,15 @@ def test_get_phonenumber(self):
p = b.get_phonenumber("z")
self.assertEqual(p, {})

@patch("benedict.dicts.parse.parse_util.parse_installed", False)
def test_get_phonenumber_with_extra_not_installed(self):
with self.assertRaises(ExtrasRequireModuleNotFoundError):
d = {
"a": "3334445566",
}
b = ParseDict(d)
b.get_phonenumber("a")

def test_get_slug(self):
d = {
"a": " Hello World ",
Expand Down Expand Up @@ -550,6 +580,15 @@ def test_get_str(self):
self.assertEqual(b.get_str("b"), "Hello World")
self.assertEqual(b.get_str("c"), "1")

@patch("benedict.dicts.parse.parse_util.parse_installed", False)
def test_get_str_with_extra_not_installed(self):
with self.assertRaises(ExtrasRequireModuleNotFoundError):
d = {
"a": "Hello World",
}
b = ParseDict(d)
b.get_str("a")

def test_get_str_fix_encoding(self):
d = {
"a": "Sexâ\x80\x99n Drug",
Expand Down
16 changes: 16 additions & 0 deletions tests/dicts/parse/test_parse_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ def test_parse_datetime(self):
# TODO
pass

def test_parse_datetime_with_extra_not_installed(self):
# TODO
pass

def test_parse_decimal(self):
# TODO
pass
Expand All @@ -50,6 +54,10 @@ def test_parse_email(self):
# TODO
pass

def test_parse_email_with_extra_not_installed(self):
# TODO
pass

def test_parse_int(self):
# TODO
pass
Expand Down Expand Up @@ -90,6 +98,10 @@ def test_parse_phonenumber(self):
# TODO
pass

def test_parse_phonenumber_with_extra_not_installed(self):
# TODO
pass

def test_parse_slug(self):
# TODO
pass
Expand All @@ -98,6 +110,10 @@ def test_parse_str(self):
# TODO
pass

def test_parse_str_with_extra_not_installed(self):
# TODO
pass

def test_parse_uuid(self):
# TODO
pass