PyPaf 0.8.0__tar.gz → 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pypaf-0.8.0/src/PyPaf.egg-info → pypaf-1.0.1}/PKG-INFO +1 -1
- {pypaf-0.8.0 → pypaf-1.0.1/src/PyPaf.egg-info}/PKG-INFO +1 -1
- {pypaf-0.8.0 → pypaf-1.0.1}/src/PyPaf.egg-info/SOURCES.txt +0 -1
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/address.py +3 -2
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/attribute.py +9 -8
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/immutable.py +1 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/initiator.py +1 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/lineable.py +1 -0
- pypaf-0.8.0/src/paf/premises/premises.py → pypaf-1.0.1/src/paf/premises/__init__.py +18 -9
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/attribute.py +7 -6
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/building_type.py +6 -2
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/dependent_premisable.py +1 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/exception.py +8 -6
- pypaf-1.0.1/src/paf/premises/extender.py +23 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/lineable.py +5 -1
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/premisable.py +1 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule000.py +1 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule001.py +1 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule010.py +5 -1
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule011.py +1 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule100.py +2 -1
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule101.py +1 -0
- pypaf-1.0.1/src/paf/premises/rule110.py +34 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule111.py +3 -2
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/split.py +2 -1
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/thoroughfare_locality.py +5 -5
- pypaf-1.0.1/src/paf/version.py +3 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_empty.py +5 -2
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_exception_i.py +9 -3
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_exception_ii.py +10 -3
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_exception_iii.py +10 -3
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_exception_iv.py +60 -18
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_immutability.py +5 -2
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_kwargs.py +13 -6
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_mainfile.py +5 -2
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_po_box.py +10 -3
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_premises.py +22 -9
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_1.py +5 -2
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_2.py +11 -4
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_3.py +138 -18
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_4.py +17 -4
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_5.py +27 -8
- pypaf-1.0.1/tests/test_rule_6.py +352 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_7.py +56 -12
- {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_x.py +15 -6
- pypaf-0.8.0/src/paf/premises/__init__.py +0 -0
- pypaf-0.8.0/src/paf/premises/extender.py +0 -25
- pypaf-0.8.0/src/paf/premises/rule110.py +0 -20
- pypaf-0.8.0/src/paf/version.py +0 -3
- pypaf-0.8.0/tests/test_rule_6.py +0 -166
- {pypaf-0.8.0 → pypaf-1.0.1}/LICENSE.txt +0 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/README.md +0 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/pyproject.toml +0 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/setup.cfg +0 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/src/PyPaf.egg-info/dependency_links.txt +0 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/src/PyPaf.egg-info/top_level.txt +0 -0
- {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/__init__.py +0 -0
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"""PAF Address"""
|
|
2
2
|
|
|
3
|
-
# Tried
|
|
3
|
+
# Tried dataclasses.dataclass(frozen=True) for immutablity but did not work"""
|
|
4
4
|
from .initiator import attribute_init
|
|
5
5
|
from .attribute import AttributeMixin
|
|
6
6
|
from .immutable import ImmutableMixin
|
|
7
7
|
from .lineable import LineableMixin
|
|
8
8
|
from .thoroughfare_locality import ThoroughfareLocalityMixin
|
|
9
|
-
from .premises
|
|
9
|
+
from .premises import Premises
|
|
10
|
+
|
|
10
11
|
|
|
11
12
|
class Address(ImmutableMixin, AttributeMixin, ThoroughfareLocalityMixin, LineableMixin):
|
|
12
13
|
"""Main PAF Address class"""
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Attribute Mixin"""
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
class AttributeMixin():
|
|
4
5
|
"""Address elements and derived properties"""
|
|
5
6
|
|
|
@@ -9,8 +10,8 @@ class AttributeMixin():
|
|
|
9
10
|
"""Returns Paf premises elements"""
|
|
10
11
|
return (
|
|
11
12
|
'organisation_name', 'department_name',
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
'sub_building_name', 'building_name', 'building_number',
|
|
14
|
+
'po_box_number'
|
|
14
15
|
)
|
|
15
16
|
|
|
16
17
|
@classmethod
|
|
@@ -29,13 +30,13 @@ class AttributeMixin():
|
|
|
29
30
|
@property
|
|
30
31
|
def attrs(cls):
|
|
31
32
|
"""Returns all Paf address elements"""
|
|
32
|
-
return(
|
|
33
|
+
return (
|
|
33
34
|
cls.premises_attrs
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
+ cls.dependent_thoroughfare_attrs
|
|
36
|
+
+ cls.thoroughfare_attrs
|
|
37
|
+
+ cls.locality_attrs
|
|
38
|
+
+ cls.post_attrs
|
|
39
|
+
+ cls.other_attrs
|
|
39
40
|
)
|
|
40
41
|
|
|
41
42
|
def is_empty(self, attr):
|
|
@@ -8,14 +8,15 @@ from .extender import ExtenderMixin
|
|
|
8
8
|
from .lineable import LineableMixin
|
|
9
9
|
from .split import SplitMixin
|
|
10
10
|
|
|
11
|
+
|
|
11
12
|
class Premises(
|
|
12
|
-
|
|
13
|
+
ImmutableMixin, ExtenderMixin, AttributeMixin,
|
|
13
14
|
ThoroughfareLocalityMixin, LineableMixin, SplitMixin
|
|
14
|
-
|
|
15
|
+
):
|
|
15
16
|
"""PAF Address Premises class"""
|
|
16
17
|
|
|
17
18
|
@attribute_init
|
|
18
|
-
def __init__(self, *args, **kwargs):
|
|
19
|
+
def __init__(self, *args, **kwargs): # pylint: disable=unused-argument
|
|
19
20
|
"""Initialise Premises elements"""
|
|
20
21
|
self.extend()
|
|
21
22
|
|
|
@@ -34,7 +35,7 @@ class Premises(
|
|
|
34
35
|
|
|
35
36
|
def __call__(self):
|
|
36
37
|
"""Return Premises as dictionary"""
|
|
37
|
-
return self.as_premisable()
|
|
38
|
+
return self.as_premisable() # pylint: disable=no-member
|
|
38
39
|
|
|
39
40
|
@property
|
|
40
41
|
def building_number_and_sub_building_name(self):
|
|
@@ -48,16 +49,17 @@ class Premises(
|
|
|
48
49
|
|
|
49
50
|
@property
|
|
50
51
|
def name_last_word_and_thoroughfare_or_locality(self):
|
|
51
|
-
"""Returns last word of building name and first thoroughfare
|
|
52
|
+
"""Returns last word of building name and first thoroughfare"""
|
|
52
53
|
return self._concatenate(('building_name_last_word', 'first_thoroughfare_or_locality'))
|
|
53
54
|
|
|
54
55
|
@property
|
|
55
56
|
def number_and_thoroughfare_or_locality(self):
|
|
56
57
|
"""Returns building number and first thoroughfare or locality"""
|
|
57
58
|
return self._concatenate(('building_number', 'first_thoroughfare_or_locality'))
|
|
59
|
+
|
|
58
60
|
@property
|
|
59
61
|
def number_sub_name_and_thoroughfare_or_locality(self):
|
|
60
|
-
"""Returns building number, sub-building name and first thoroughfare
|
|
62
|
+
"""Returns building number, sub-building name and first thoroughfare"""
|
|
61
63
|
return self._concatenate(
|
|
62
64
|
('building_number_and_sub_building_name', 'first_thoroughfare_or_locality')
|
|
63
65
|
)
|
|
@@ -69,7 +71,7 @@ class Premises(
|
|
|
69
71
|
|
|
70
72
|
@property
|
|
71
73
|
def sub_name_comma_name(self):
|
|
72
|
-
"""Returns sub-building name and building name
|
|
74
|
+
"""Returns sub-building name and building name joined with a comma"""
|
|
73
75
|
return self._concatenate(('sub_building_name', 'building_name'), ', ')
|
|
74
76
|
|
|
75
77
|
@property
|
|
@@ -77,6 +79,11 @@ class Premises(
|
|
|
77
79
|
"""Returns sub-building number and first thoroughfare or locality"""
|
|
78
80
|
return self._concatenate(('sub_building_name', 'first_thoroughfare_or_locality'))
|
|
79
81
|
|
|
82
|
+
@property
|
|
83
|
+
def sub_and_building_name_but_last_word(self):
|
|
84
|
+
"""Returns sub-building name and but last word of the building name"""
|
|
85
|
+
return self._concatenate(('sub_building_name', 'building_name_but_last_word'))
|
|
86
|
+
|
|
80
87
|
@property
|
|
81
88
|
def building_name_but_last_word(self):
|
|
82
89
|
"""Returns all but last word of the building name"""
|
|
@@ -98,5 +105,7 @@ class Premises(
|
|
|
98
105
|
return self.last_word('sub_building_name')
|
|
99
106
|
|
|
100
107
|
def _concatenate(self, keys, concatenator=' '):
|
|
101
|
-
"""Returns specified attributes concatenated with a
|
|
102
|
-
return concatenator.join(
|
|
108
|
+
"""Returns specified attributes concatenated with a separator"""
|
|
109
|
+
return concatenator.join(
|
|
110
|
+
filter(None, [getattr(self, k, None) for k in keys])
|
|
111
|
+
)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Attribute Mixin"""
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
class AttributeMixin():
|
|
4
5
|
"""Premises elements and derived properties"""
|
|
5
6
|
|
|
@@ -25,13 +26,13 @@ class AttributeMixin():
|
|
|
25
26
|
@property
|
|
26
27
|
def attrs(cls):
|
|
27
28
|
"""Returns all Paf premises elements"""
|
|
28
|
-
return(
|
|
29
|
+
return (
|
|
29
30
|
cls.organisation_attrs
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
+ cls.building_attrs
|
|
32
|
+
+ cls.dependent_thoroughfare_attrs
|
|
33
|
+
+ cls.thoroughfare_attrs
|
|
34
|
+
+ cls.locality_attrs
|
|
35
|
+
+ cls.other_attrs
|
|
35
36
|
)
|
|
36
37
|
|
|
37
38
|
def is_empty(self, attr):
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from .split import SplitMixin
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
class BuildingTypeMixin(SplitMixin):
|
|
6
7
|
"""Determines if a string represents a known building type"""
|
|
7
8
|
|
|
@@ -10,8 +11,11 @@ class BuildingTypeMixin(SplitMixin):
|
|
|
10
11
|
def known_building_types(cls):
|
|
11
12
|
"""Returns known building types"""
|
|
12
13
|
return (
|
|
13
|
-
"BACK OF", "BLOCK", "BLOCKS", "BUILDING",
|
|
14
|
-
"
|
|
14
|
+
"BACK OF", "BLOCK", "BLOCKS", "BUILDING",
|
|
15
|
+
"MAISONETTE", "MAISONETTES", "REAR OF",
|
|
16
|
+
"SHOP", "SHOPS", "STALL", "STALLS",
|
|
17
|
+
"SUITE", "SUITES", "UNIT", "UNITS",
|
|
18
|
+
"PO BOX"
|
|
15
19
|
)
|
|
16
20
|
|
|
17
21
|
@classmethod
|
|
@@ -4,6 +4,7 @@ import re
|
|
|
4
4
|
from .building_type import BuildingTypeMixin
|
|
5
5
|
from .split import SplitMixin
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
class ExceptionMixin(BuildingTypeMixin, SplitMixin):
|
|
8
9
|
"""Exceptions"""
|
|
9
10
|
|
|
@@ -27,8 +28,8 @@ class ExceptionMixin(BuildingTypeMixin, SplitMixin):
|
|
|
27
28
|
"""Returns if value is an exception"""
|
|
28
29
|
return (
|
|
29
30
|
cls.__is_exception_i(val)
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
or cls.__is_exception_ii(val)
|
|
32
|
+
or cls.__is_exception_iii(val)
|
|
32
33
|
)
|
|
33
34
|
|
|
34
35
|
def __is_exception_iv(self, attr): # pylint: disable=unused-argument
|
|
@@ -36,7 +37,7 @@ class ExceptionMixin(BuildingTypeMixin, SplitMixin):
|
|
|
36
37
|
and ends with numeric range or numeric alpha suffix"""
|
|
37
38
|
# Do not include suffix check as does not account for values such as BLOCK B
|
|
38
39
|
return self.is_known_building_type(attr)
|
|
39
|
-
# and re.match(r'^\d',
|
|
40
|
+
# and re.match(r'^\d', self.last_word(attr))
|
|
40
41
|
|
|
41
42
|
def is_exception(self, attr):
|
|
42
43
|
"""Returns if attribute is an exception"""
|
|
@@ -45,7 +46,8 @@ class ExceptionMixin(BuildingTypeMixin, SplitMixin):
|
|
|
45
46
|
def is_split_exception(self, attr):
|
|
46
47
|
"""Returns if attribute should be split"""
|
|
47
48
|
return (
|
|
48
|
-
self.
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
(self.__is_exception_i(self.last_word(attr))
|
|
50
|
+
or self.__is_exception_ii(self.last_word(attr)))
|
|
51
|
+
and not self.last_word(attr).isdigit()
|
|
52
|
+
and not self.__is_exception_iv(attr)
|
|
51
53
|
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Premises Extender Mixin"""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import importlib
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ExtenderMixin():
|
|
8
|
+
"""Dynamic Premises processing"""
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def rule(self):
|
|
12
|
+
"""Returns premises rule class"""
|
|
13
|
+
rule_num = ''.join(['0' if self.is_empty(k) else '1' for k in self.building_attrs])
|
|
14
|
+
package_name = getattr(sys.modules[__name__], '__package__', None)
|
|
15
|
+
module_name = f'rule{rule_num}'
|
|
16
|
+
module = importlib.import_module(f'{package_name}.{module_name}')
|
|
17
|
+
class_name = f'Rule{rule_num}'
|
|
18
|
+
return getattr(module, class_name)
|
|
19
|
+
|
|
20
|
+
def extend(self):
|
|
21
|
+
"""Dynamically extends instance with appropriate rule"""
|
|
22
|
+
base_cls = self.__class__
|
|
23
|
+
object.__setattr__(self, '__class__', type(base_cls.__name__, (base_cls, self.rule), {}))
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from itertools import chain
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
class LineableMixin():
|
|
6
7
|
"""Converts Paf address premises elements into list of lines"""
|
|
7
8
|
|
|
@@ -18,7 +19,10 @@ class LineableMixin():
|
|
|
18
19
|
@property
|
|
19
20
|
def po_box(self):
|
|
20
21
|
"""Returns PO Box"""
|
|
21
|
-
return
|
|
22
|
+
return (
|
|
23
|
+
'' if self.is_empty('po_box_number')
|
|
24
|
+
else f"PO BOX {getattr(self, 'po_box_number')}"
|
|
25
|
+
)
|
|
22
26
|
|
|
23
27
|
def _lines(self, attrs):
|
|
24
28
|
"""Returns list of premises lines from specified attributes"""
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from .dependent_premisable import DependentPremisableMixin
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
class Rule010(DependentPremisableMixin):
|
|
6
7
|
"""Rule 3 processing"""
|
|
7
8
|
|
|
@@ -17,4 +18,7 @@ class Rule010(DependentPremisableMixin):
|
|
|
17
18
|
@property
|
|
18
19
|
def includes_first_thoroughfare_or_locality(self):
|
|
19
20
|
"""Returns if premises includes first thoroughfare or locality"""
|
|
20
|
-
return
|
|
21
|
+
return (
|
|
22
|
+
self.is_exception('building_name')
|
|
23
|
+
or self.is_split_exception('building_name')
|
|
24
|
+
)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from .premisable import PremisableMixin
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
class Rule100(PremisableMixin):
|
|
6
7
|
"""Rule X processing"""
|
|
7
8
|
|
|
@@ -9,7 +10,7 @@ class Rule100(PremisableMixin):
|
|
|
9
10
|
def rule_attrs(self):
|
|
10
11
|
"""Returns premises list"""
|
|
11
12
|
if self.is_exception('sub_building_name'):
|
|
12
|
-
return('sub_name_and_thoroughfare_or_locality',)
|
|
13
|
+
return ('sub_name_and_thoroughfare_or_locality',)
|
|
13
14
|
return ('sub_building_name',)
|
|
14
15
|
|
|
15
16
|
@property
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Rule 6"""
|
|
2
|
+
|
|
3
|
+
from .premisable import PremisableMixin
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Rule110(PremisableMixin):
|
|
7
|
+
"""Rule 6 processing"""
|
|
8
|
+
|
|
9
|
+
@property
|
|
10
|
+
def rule_attrs(self):
|
|
11
|
+
"""Returns premises list"""
|
|
12
|
+
if self.is_exception('sub_building_name'):
|
|
13
|
+
if self.is_split_exception('building_name'):
|
|
14
|
+
return (
|
|
15
|
+
'sub_and_building_name_but_last_word',
|
|
16
|
+
'name_last_word_and_thoroughfare_or_locality'
|
|
17
|
+
)
|
|
18
|
+
return ('sub_name_and_name',)
|
|
19
|
+
if self.is_exception('building_name'):
|
|
20
|
+
return ('sub_building_name', 'name_and_thoroughfare_or_locality')
|
|
21
|
+
if self.is_split_exception('building_name'):
|
|
22
|
+
return (
|
|
23
|
+
'sub_building_name', 'building_name_but_last_word',
|
|
24
|
+
'name_last_word_and_thoroughfare_or_locality'
|
|
25
|
+
)
|
|
26
|
+
return ('sub_building_name', 'building_name')
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def includes_first_thoroughfare_or_locality(self):
|
|
30
|
+
"""Returns if premises includes first thoroughfare or locality"""
|
|
31
|
+
return (
|
|
32
|
+
self.is_split_exception('building_name')
|
|
33
|
+
or (not self.is_exception('sub_building_name') and self.is_exception('building_name'))
|
|
34
|
+
)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from .premisable import PremisableMixin
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
class Rule111(PremisableMixin):
|
|
6
7
|
"""Rule 7 processing"""
|
|
7
8
|
|
|
@@ -9,9 +10,9 @@ class Rule111(PremisableMixin):
|
|
|
9
10
|
def rule_attrs(self):
|
|
10
11
|
"""Returns premises list"""
|
|
11
12
|
if self.is_zero('building_number'):
|
|
12
|
-
return('sub_name_comma_name',)
|
|
13
|
+
return ('sub_name_comma_name',)
|
|
13
14
|
if self.is_exception('sub_building_name'):
|
|
14
|
-
return('sub_name_and_name', 'number_and_thoroughfare_or_locality')
|
|
15
|
+
return ('sub_name_and_name', 'number_and_thoroughfare_or_locality')
|
|
15
16
|
return ('sub_building_name', 'building_name', 'number_and_thoroughfare_or_locality')
|
|
16
17
|
|
|
17
18
|
@property
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import re
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
class SplitMixin():
|
|
6
7
|
"""Methods to extract various parts of a attribute value"""
|
|
7
8
|
|
|
@@ -53,5 +54,5 @@ class SplitMixin():
|
|
|
53
54
|
return self.__leading_digits(str(getattr(self, attr, '')))
|
|
54
55
|
|
|
55
56
|
def after_leading_digits(self, attr):
|
|
56
|
-
"""Returns
|
|
57
|
+
"""Returns characters after the leading digits from the attribute"""
|
|
57
58
|
return self.__after_leading_digits(str(getattr(self, attr, '')))
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Thoroughfare and Locality Mixin"""
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
class ThoroughfareLocalityMixin():
|
|
4
5
|
"""Thoroughfare and locality processing"""
|
|
5
6
|
|
|
@@ -37,8 +38,7 @@ class ThoroughfareLocalityMixin():
|
|
|
37
38
|
def dependent_thoroughfare(self):
|
|
38
39
|
"""Returns dependent thoroughfare"""
|
|
39
40
|
return ' '.join(
|
|
40
|
-
filter(None, [getattr(self, k, None) for k in self.dependent_thoroughfare_attrs])
|
|
41
|
-
)
|
|
41
|
+
filter(None, [getattr(self, k, None) for k in self.dependent_thoroughfare_attrs]))
|
|
42
42
|
|
|
43
43
|
@property
|
|
44
44
|
def thoroughfare(self):
|
|
@@ -47,7 +47,7 @@ class ThoroughfareLocalityMixin():
|
|
|
47
47
|
|
|
48
48
|
@property
|
|
49
49
|
def first_thoroughfare_or_locality_attr(self):
|
|
50
|
-
"""Returns name of first populated thoroughfare
|
|
50
|
+
"""Returns name of first populated thoroughfare / locality attribute"""
|
|
51
51
|
for k in self.thoroughfare_and_locality_attrs:
|
|
52
52
|
if not self.is_empty(k):
|
|
53
53
|
return k
|
|
@@ -63,7 +63,7 @@ class ThoroughfareLocalityMixin():
|
|
|
63
63
|
"""Returns if attribute value is empty or has already been used"""
|
|
64
64
|
if self.is_empty(attr):
|
|
65
65
|
return True
|
|
66
|
-
return(
|
|
66
|
+
return (
|
|
67
67
|
attr == self.first_thoroughfare_or_locality_attr
|
|
68
|
-
|
|
68
|
+
and self.premises.includes_first_thoroughfare_or_locality
|
|
69
69
|
)
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
import unittest
|
|
4
4
|
import paf
|
|
5
5
|
|
|
6
|
+
|
|
6
7
|
class TestEmpty(unittest.TestCase):
|
|
7
8
|
"""Test Address Exception I"""
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
@classmethod
|
|
11
|
+
def setUpClass(cls):
|
|
10
12
|
"""Set up Address instance"""
|
|
11
|
-
|
|
13
|
+
cls.address = paf.Address({})
|
|
12
14
|
|
|
13
15
|
def test_list(self):
|
|
14
16
|
"""Test conversion to an list"""
|
|
@@ -35,5 +37,6 @@ class TestEmpty(unittest.TestCase):
|
|
|
35
37
|
premises = {}
|
|
36
38
|
self.assertEqual(self.address.premises(), premises, "Incorrect empty premises")
|
|
37
39
|
|
|
40
|
+
|
|
38
41
|
if __name__ == '__main__':
|
|
39
42
|
unittest.main()
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
import unittest
|
|
4
4
|
import paf
|
|
5
5
|
|
|
6
|
+
|
|
6
7
|
class TestExceptionI(unittest.TestCase):
|
|
7
8
|
"""Test Address Exception I"""
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
@classmethod
|
|
11
|
+
def setUpClass(cls):
|
|
10
12
|
"""Set up Address instance"""
|
|
11
|
-
|
|
13
|
+
cls.address = paf.Address({
|
|
12
14
|
'building_name': "1-2",
|
|
13
15
|
'thoroughfare_name': "NURSERY",
|
|
14
16
|
'thoroughfare_descriptor': "LANE",
|
|
@@ -25,7 +27,10 @@ class TestExceptionI(unittest.TestCase):
|
|
|
25
27
|
def test_string(self):
|
|
26
28
|
"""Test conversion to a string"""
|
|
27
29
|
address = "1-2 NURSERY LANE, PENN, HIGH WYCOMBE. HP10 8LS"
|
|
28
|
-
self.assertEqual(
|
|
30
|
+
self.assertEqual(
|
|
31
|
+
self.address.as_str(), address,
|
|
32
|
+
"Incorrect Exception I string format"
|
|
33
|
+
)
|
|
29
34
|
|
|
30
35
|
def test_tuple(self):
|
|
31
36
|
"""Test conversion to a tuple"""
|
|
@@ -47,5 +52,6 @@ class TestExceptionI(unittest.TestCase):
|
|
|
47
52
|
premises = {'premises_number': 1, 'premises_suffix': '-2'}
|
|
48
53
|
self.assertEqual(self.address.premises(), premises, "Incorrect Exception I premises")
|
|
49
54
|
|
|
55
|
+
|
|
50
56
|
if __name__ == '__main__':
|
|
51
57
|
unittest.main()
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
import unittest
|
|
4
4
|
import paf
|
|
5
5
|
|
|
6
|
+
|
|
6
7
|
class TestExceptionII(unittest.TestCase):
|
|
7
8
|
"""Test Address Exception II"""
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
@classmethod
|
|
11
|
+
def setUpClass(cls):
|
|
10
12
|
"""Set up Address instance"""
|
|
11
|
-
|
|
13
|
+
cls.address = paf.Address({
|
|
12
14
|
'building_name': "12A",
|
|
13
15
|
'thoroughfare_name': "UPPERKIRKGATE",
|
|
14
16
|
'post_town': "ABERDEEN",
|
|
@@ -32,7 +34,11 @@ class TestExceptionII(unittest.TestCase):
|
|
|
32
34
|
|
|
33
35
|
def test_dict(self):
|
|
34
36
|
"""Test conversion to a dict"""
|
|
35
|
-
address = {
|
|
37
|
+
address = {
|
|
38
|
+
'line_1': "12A UPPERKIRKGATE",
|
|
39
|
+
'post_town': "ABERDEEN",
|
|
40
|
+
'postcode': "AB10 1BA"
|
|
41
|
+
}
|
|
36
42
|
self.assertEqual(self.address.as_dict(), address, "Incorrect Exception II dict format")
|
|
37
43
|
|
|
38
44
|
def test_premises(self):
|
|
@@ -40,5 +46,6 @@ class TestExceptionII(unittest.TestCase):
|
|
|
40
46
|
premises = {'premises_number': 12, 'premises_suffix': 'A'}
|
|
41
47
|
self.assertEqual(self.address.premises(), premises, "Incorrect Exception II premises")
|
|
42
48
|
|
|
49
|
+
|
|
43
50
|
if __name__ == '__main__':
|
|
44
51
|
unittest.main()
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
import unittest
|
|
4
4
|
import paf
|
|
5
5
|
|
|
6
|
+
|
|
6
7
|
class TestExceptionIII(unittest.TestCase):
|
|
7
8
|
"""Test Address Exception III"""
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
@classmethod
|
|
11
|
+
def setUpClass(cls):
|
|
10
12
|
"""Set up Address instance"""
|
|
11
|
-
|
|
13
|
+
cls.address = paf.Address({
|
|
12
14
|
'building_name': "K",
|
|
13
15
|
'thoroughfare_name': "PORTLAND",
|
|
14
16
|
'thoroughfare_descriptor': "ROAD",
|
|
@@ -33,7 +35,11 @@ class TestExceptionIII(unittest.TestCase):
|
|
|
33
35
|
|
|
34
36
|
def test_dict(self):
|
|
35
37
|
"""Test conversion to a dict"""
|
|
36
|
-
address = {
|
|
38
|
+
address = {
|
|
39
|
+
'line_1': "K PORTLAND ROAD",
|
|
40
|
+
'post_town': "DORKING",
|
|
41
|
+
'postcode': "RH4 1EW"
|
|
42
|
+
}
|
|
37
43
|
self.assertEqual(self.address.as_dict(), address, "Incorrect Exception III dict format")
|
|
38
44
|
|
|
39
45
|
def test_premises(self):
|
|
@@ -41,5 +47,6 @@ class TestExceptionIII(unittest.TestCase):
|
|
|
41
47
|
premises = {'premises_name': 'K'}
|
|
42
48
|
self.assertEqual(self.address.premises(), premises, "Incorrect Exception III premises")
|
|
43
49
|
|
|
50
|
+
|
|
44
51
|
if __name__ == '__main__':
|
|
45
52
|
unittest.main()
|