Skip to content

Commit 8686e3b

Browse files
committed
Use overloading and type[] for typing instead of custom enum
1 parent 8d61c33 commit 8686e3b

File tree

4 files changed

+45
-56
lines changed

4 files changed

+45
-56
lines changed

khard/contacts.py

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@
3131

3232
from . import address_book # pylint: disable=unused-import # for type checking
3333
from . import helpers
34-
from .helpers.typing import (Date, ObjectType, PostAddress, StrList,
35-
convert_to_vcard, list_to_string, string_to_date,
36-
string_to_list)
34+
from .helpers.typing import (Date, PostAddress, StrList, convert_to_vcard,
35+
list_to_string, string_to_date, string_to_list)
3736
from .query import AnyQuery, Query
3837

3938

@@ -271,7 +270,7 @@ def version(self, value: str) -> None:
271270
# for version 4 but also makes sense for all other versions.
272271
self._delete_vcard_object("VERSION")
273272
version = self.vcard.add("version")
274-
version.value = convert_to_vcard("version", value, ObjectType.str)
273+
version.value = convert_to_vcard("version", value, str)
275274

276275
@property
277276
def uid(self) -> str:
@@ -283,7 +282,7 @@ def uid(self, value: str) -> None:
283282
# for version 4 but also makes sense for all other versions.
284283
self._delete_vcard_object("UID")
285284
uid = self.vcard.add('uid')
286-
uid.value = convert_to_vcard("uid", value, ObjectType.str)
285+
uid.value = convert_to_vcard("uid", value, str)
287286

288287
def _update_revision(self) -> None:
289288
"""Generate a new REV field for the vCard, replace any existing
@@ -413,7 +412,7 @@ def _get_new_group(self, group_type: str = "") -> str:
413412
def _add_labelled_property(
414413
self, property: str, value: StrList, label: Optional[str] = None,
415414
name_groups: bool = False,
416-
allowed_object_type: ObjectType = ObjectType.str) -> None:
415+
allowed_object_type: Union[None, type[str], type[list]] = str) -> None:
417416
"""Add an object to the VCARD. If a label is given it will be added to
418417
a group with an ABLABEL.
419418
@@ -501,7 +500,7 @@ def formatted_name(self, value: str) -> None:
501500
"""
502501
self._delete_vcard_object("FN")
503502
if value:
504-
final = convert_to_vcard("FN", value, ObjectType.str)
503+
final = convert_to_vcard("FN", value, str)
505504
elif self._get_first_names() or self._get_last_names():
506505
# autofill the FN field from the N field
507506
names = [self._get_name_prefixes(), self._get_first_names(),
@@ -593,12 +592,11 @@ def _add_name(self, prefix: StrList, first_name: StrList,
593592
"""
594593
name_obj = self.vcard.add('n')
595594
name_obj.value = vobject.vcard.Name(
596-
prefix=convert_to_vcard("name prefix", prefix, ObjectType.both),
597-
given=convert_to_vcard("first name", first_name, ObjectType.both),
598-
additional=convert_to_vcard("additional name", additional_name,
599-
ObjectType.both),
600-
family=convert_to_vcard("last name", last_name, ObjectType.both),
601-
suffix=convert_to_vcard("name suffix", suffix, ObjectType.both))
595+
prefix=convert_to_vcard("name prefix", prefix, None),
596+
given=convert_to_vcard("first name", first_name, None),
597+
additional=convert_to_vcard("additional name", additional_name, None),
598+
family=convert_to_vcard("last name", last_name, None),
599+
suffix=convert_to_vcard("name suffix", suffix, None))
602600

603601
@property
604602
def organisations(self) -> list[Union[list[str], dict[str, list[str]]]]:
@@ -613,8 +611,7 @@ def _add_organisation(self, organisation: StrList, label: Optional[str] = None)
613611
:param organisation: the value to add
614612
:param label: an optional label to add
615613
"""
616-
self._add_labelled_property("org", organisation, label, True,
617-
ObjectType.list)
614+
self._add_labelled_property("org", organisation, label, True, list)
618615
# check if fn attribute is already present
619616
if not self.vcard.getChildValue("fn") and self.organisations:
620617
# if not, set fn to organisation name
@@ -680,8 +677,7 @@ def _add_category(self, categories: list[str]) -> None:
680677
:param categories:
681678
"""
682679
categories_obj = self.vcard.add('categories')
683-
categories_obj.value = convert_to_vcard("category", categories,
684-
ObjectType.list)
680+
categories_obj.value = convert_to_vcard("category", categories, list)
685681

686682
@property
687683
def phone_numbers(self) -> dict[str, list[str]]:
@@ -725,13 +721,12 @@ def _add_phone_number(self, type: str, number: str) -> None:
725721
phone_obj = self.vcard.add('tel')
726722
if self.version == "4.0":
727723
phone_obj.value = "tel:{}".format(
728-
convert_to_vcard("phone number", number, ObjectType.str))
724+
convert_to_vcard("phone number", number, str))
729725
phone_obj.params['VALUE'] = ["uri"]
730726
if pref > 0:
731727
phone_obj.params['PREF'] = str(pref)
732728
else:
733-
phone_obj.value = convert_to_vcard("phone number", number,
734-
ObjectType.str)
729+
phone_obj.value = convert_to_vcard("phone number", number, str)
735730
if pref > 0:
736731
standard_types.append("pref")
737732
if standard_types:
@@ -777,8 +772,7 @@ def add_email(self, type: str, address: str) -> None:
777772
"than one custom label: " +
778773
list_to_string(custom_types, ", "))
779774
email_obj = self.vcard.add('email')
780-
email_obj.value = convert_to_vcard("email address", address,
781-
ObjectType.str)
775+
email_obj.value = convert_to_vcard("email address", address, str)
782776
if self.version == "4.0":
783777
if pref > 0:
784778
email_obj.params['PREF'] = str(pref)
@@ -877,14 +871,13 @@ def _add_post_address(self, type: str, box: StrList, extended: StrList,
877871
"label: " + list_to_string(custom_types, ", "))
878872
adr_obj = self.vcard.add('adr')
879873
adr_obj.value = vobject.vcard.Address(
880-
box=convert_to_vcard("box address field", box, ObjectType.both),
881-
extended=convert_to_vcard("extended address field", extended,
882-
ObjectType.both),
883-
street=convert_to_vcard("street", street, ObjectType.both),
884-
code=convert_to_vcard("post code", code, ObjectType.both),
885-
city=convert_to_vcard("city", city, ObjectType.both),
886-
region=convert_to_vcard("region", region, ObjectType.both),
887-
country=convert_to_vcard("country", country, ObjectType.both))
874+
box=convert_to_vcard("box address field", box, None),
875+
extended=convert_to_vcard("extended address field", extended, None),
876+
street=convert_to_vcard("street", street, None),
877+
code=convert_to_vcard("post code", code, None),
878+
city=convert_to_vcard("city", city, None),
879+
region=convert_to_vcard("region", region, None),
880+
country=convert_to_vcard("country", country, None))
888881
if self.version == "4.0":
889882
if pref > 0:
890883
adr_obj.params['PREF'] = str(pref)

khard/helpers/typing.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
"""Helper code for type annotations and runtime type conversion."""
22

33
from datetime import datetime
4-
from enum import Enum
5-
from typing import Union
6-
7-
8-
class ObjectType(Enum):
9-
str = 1
10-
list = 2
11-
both = 3
4+
from typing import Union, overload
125

136

147
# some type aliases
@@ -17,8 +10,13 @@ class ObjectType(Enum):
1710
PostAddress = dict[str, str]
1811

1912

20-
def convert_to_vcard(name: str, value: StrList, constraint: ObjectType
21-
) -> StrList:
13+
@overload
14+
def convert_to_vcard(name: str, value: StrList, constraint: type[str]) -> str: ...
15+
@overload
16+
def convert_to_vcard(name: str, value: StrList, constraint: type[list]) -> list[str]: ...
17+
@overload
18+
def convert_to_vcard(name: str, value: StrList, constraint: None) -> StrList: ...
19+
def convert_to_vcard(name: str, value: StrList, constraint: Union[None, type[str], type[list]]) -> StrList:
2220
"""converts user input into vCard compatible data structures
2321
2422
:param name: object name, only required for error messages
@@ -27,19 +25,19 @@ def convert_to_vcard(name: str, value: StrList, constraint: ObjectType
2725
:returns: cleaned user input, ready for vCard or a ValueError
2826
"""
2927
if isinstance(value, str):
30-
if constraint == ObjectType.list:
28+
if constraint is list:
3129
return [value.strip()]
3230
return value.strip()
3331
if isinstance(value, list):
34-
if constraint == ObjectType.str:
32+
if constraint is str:
3533
raise ValueError(f"{name} must contain a string.")
3634
if not all(isinstance(entry, str) for entry in value):
3735
raise ValueError(f"{name} must not contain a nested list")
3836
# filter out empty list items and strip leading and trailing space
3937
return [x.strip() for x in value if x.strip()]
40-
if constraint == ObjectType.str:
38+
if constraint is str:
4139
raise ValueError(f"{name} must be a string.")
42-
if constraint == ObjectType.list:
40+
if constraint is list:
4341
raise ValueError(f"{name} must be a list with strings.")
4442
raise ValueError(f"{name} must be a string or a list with strings.")
4543

test/test_helpers_typing.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import unittest
55

66
from khard.helpers.typing import (
7-
ObjectType,
87
convert_to_vcard,
98
list_to_string,
109
string_to_date,
@@ -14,42 +13,42 @@
1413
class ConvertToVcard(unittest.TestCase):
1514
def test_returns_strings(self):
1615
value = "some text"
17-
actual = convert_to_vcard("test", value, ObjectType.str)
16+
actual = convert_to_vcard("test", value, str)
1817
self.assertEqual(value, actual)
1918

2019
def test_returns_lists(self):
2120
value = ["some", "text"]
22-
actual = convert_to_vcard("test", value, ObjectType.list)
21+
actual = convert_to_vcard("test", value, list)
2322
self.assertListEqual(value, actual)
2423

2524
def test_fail_if_not_string(self):
2625
value = ["some", "text"]
2726
with self.assertRaises(ValueError):
28-
convert_to_vcard("test", value, ObjectType.str)
27+
convert_to_vcard("test", value, str)
2928

3029
def test_upgrades_string_to_list(self):
3130
value = "some text"
32-
actual = convert_to_vcard("test", value, ObjectType.list)
31+
actual = convert_to_vcard("test", value, list)
3332
self.assertListEqual([value], actual)
3433

3534
def test_fails_if_string_lists_are_not_homogeneous(self):
3635
value = ["some", ["nested", "list"]]
3736
with self.assertRaises(ValueError):
38-
convert_to_vcard("test", value, ObjectType.list)
37+
convert_to_vcard("test", value, list)
3938

4039
def test_empty_list_items_are_filtered(self):
4140
value = ["some", "", "text", "", "more text"]
42-
actual = convert_to_vcard("test", value, ObjectType.list)
41+
actual = convert_to_vcard("test", value, list)
4342
self.assertListEqual(["some", "text", "more text"], actual)
4443

4544
def test_strings_are_stripped(self):
4645
value = " some text "
47-
actual = convert_to_vcard("test", value, ObjectType.str)
46+
actual = convert_to_vcard("test", value, str)
4847
self.assertEqual("some text", actual)
4948

5049
def test_strings_in_lists_are_stripped(self):
5150
value = [" some ", " text "]
52-
actual = convert_to_vcard("test", value, ObjectType.list)
51+
actual = convert_to_vcard("test", value, list)
5352
self.assertListEqual(["some", "text"], actual)
5453

5554

test/test_vcard_wrapper.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import vobject
1010

1111
from khard.contacts import VCardWrapper
12-
from khard.helpers.typing import ObjectType
1312

1413
from .helpers import vCard, TestVCardWrapper
1514

@@ -524,7 +523,7 @@ def test_add_several_strings(self):
524523
def test_add_a_list_of_strings(self):
525524
with self.assertTitle([["foo","bar"]]) as wrapper:
526525
wrapper._add_labelled_property("title", ["foo", "bar"],
527-
allowed_object_type=ObjectType.list)
526+
allowed_object_type=list)
528527

529528
def test_add_string_with_label(self):
530529
with self.assertTitle([{"foo": "bar"}]) as wrapper:
@@ -543,7 +542,7 @@ def test_add_strings_with_different_label(self):
543542
def test_add_a_list_with_label(self):
544543
with self.assertTitle([{"foo": ["bar", "baz"]}]) as wrapper:
545544
wrapper._add_labelled_property("title", ["bar", "baz"], "foo",
546-
allowed_object_type=ObjectType.list)
545+
allowed_object_type=list)
547546

548547

549548
class GetFirst(unittest.TestCase):

0 commit comments

Comments
 (0)