PyPaf 0.7.0__tar.gz → 1.0.0__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.7.0/src/PyPaf.egg-info → PyPaf-1.0.0}/PKG-INFO +28 -28
- {pypaf-0.7.0 → PyPaf-1.0.0}/README.md +26 -26
- {pypaf-0.7.0 → PyPaf-1.0.0/src/PyPaf.egg-info}/PKG-INFO +28 -28
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/PyPaf.egg-info/SOURCES.txt +4 -2
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/address.py +5 -4
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/attribute.py +9 -8
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/immutable.py +1 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/initiator.py +6 -1
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/lineable.py +1 -0
- pypaf-0.7.0/src/paf/premises/premises.py → PyPaf-1.0.0/src/paf/premises/__init__.py +18 -9
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/attribute.py +7 -6
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/building_type.py +6 -2
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/dependent_premisable.py +1 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/exception.py +6 -5
- PyPaf-1.0.0/src/paf/premises/extender.py +26 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/lineable.py +5 -1
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/premisable.py +1 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/rule000.py +1 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/rule001.py +1 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/rule010.py +5 -1
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/rule011.py +1 -0
- PyPaf-1.0.0/src/paf/premises/rule100.py +47 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/rule101.py +1 -0
- PyPaf-1.0.0/src/paf/premises/rule110.py +29 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/rule111.py +3 -2
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/premises/split.py +2 -1
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/thoroughfare_locality.py +5 -5
- PyPaf-1.0.0/src/paf/version.py +3 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_empty.py +5 -2
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_exception_i.py +9 -3
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_exception_ii.py +10 -3
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_exception_iii.py +10 -3
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_exception_iv.py +60 -18
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_immutability.py +5 -2
- PyPaf-1.0.0/tests/test_kwargs.py +73 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_mainfile.py +5 -2
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_po_box.py +10 -3
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_premises.py +22 -9
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_rule_1.py +5 -2
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_rule_2.py +11 -4
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_rule_3.py +63 -18
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_rule_4.py +17 -4
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_rule_5.py +27 -8
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_rule_6.py +130 -14
- {pypaf-0.7.0 → PyPaf-1.0.0}/tests/test_rule_7.py +56 -12
- PyPaf-1.0.0/tests/test_rule_x.py +130 -0
- pypaf-0.7.0/src/paf/premises/__init__.py +0 -0
- pypaf-0.7.0/src/paf/premises/extender.py +0 -24
- pypaf-0.7.0/src/paf/premises/rule110.py +0 -20
- pypaf-0.7.0/src/paf/version.py +0 -3
- {pypaf-0.7.0 → PyPaf-1.0.0}/LICENSE.txt +0 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/pyproject.toml +0 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/setup.cfg +0 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/PyPaf.egg-info/dependency_links.txt +0 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/PyPaf.egg-info/top_level.txt +0 -0
- {pypaf-0.7.0 → PyPaf-1.0.0}/src/paf/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: PyPaf
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: Formats the elements of a Royal Mail Postcode Address File entry
|
|
5
5
|
Author-email: John Bard <johnbard@globalnet.co.uk>
|
|
6
6
|
License: MIT
|
|
@@ -27,7 +27,7 @@ Install it from PyPI:
|
|
|
27
27
|
|
|
28
28
|
### Formatting
|
|
29
29
|
|
|
30
|
-
May be used to format the PAF Address elements as a list of strings:
|
|
30
|
+
May be used to format the PAF Address elements - passed as either a single dictionary or as a series of keyword arguments - as a list of strings:
|
|
31
31
|
|
|
32
32
|
```python
|
|
33
33
|
import paf
|
|
@@ -48,14 +48,14 @@ Or as a tuple of strings:
|
|
|
48
48
|
|
|
49
49
|
```python
|
|
50
50
|
import paf
|
|
51
|
-
address = paf.Address(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
address = paf.Address(
|
|
52
|
+
building_name="1-2",
|
|
53
|
+
thoroughfare_name="NURSERY",
|
|
54
|
+
thoroughfare_descriptor="LANE",
|
|
55
|
+
dependent_locality="PENN",
|
|
56
|
+
post_town="HIGH WYCOMBE",
|
|
57
|
+
postcode="HP10 8LS"
|
|
58
|
+
)
|
|
59
59
|
address.as_tuple() # or tuple(address)
|
|
60
60
|
|
|
61
61
|
('1-2 NURSERY LANE', 'PENN', 'HIGH WYCOMBE', 'HP10 8LS')
|
|
@@ -82,14 +82,14 @@ Or as a dictionary:
|
|
|
82
82
|
|
|
83
83
|
```python
|
|
84
84
|
import paf
|
|
85
|
-
address = paf.Address(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
85
|
+
address = paf.Address(
|
|
86
|
+
building_name="1-2",
|
|
87
|
+
thoroughfare_name="NURSERY",
|
|
88
|
+
thoroughfare_descriptor="LANE",
|
|
89
|
+
dependent_locality="PENN",
|
|
90
|
+
post_town="HIGH WYCOMBE",
|
|
91
|
+
postcode="HP10 8LS"
|
|
92
|
+
)
|
|
93
93
|
address.as_dict()
|
|
94
94
|
|
|
95
95
|
{
|
|
@@ -147,15 +147,15 @@ If there is no `sub_building_name` element and the `dependent_thoroughfare` elem
|
|
|
147
147
|
|
|
148
148
|
```python
|
|
149
149
|
import paf
|
|
150
|
-
self.address = paf.Address(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
150
|
+
self.address = paf.Address(
|
|
151
|
+
building_name="1A",
|
|
152
|
+
dependent_thoroughfare_name="SEASTONE",
|
|
153
|
+
dependent_thoroughfare_descriptor="COURT",
|
|
154
|
+
thoroughfare_name="STATION",
|
|
155
|
+
thoroughfare_descriptor="ROAD",
|
|
156
|
+
post_town="HOLT",
|
|
157
|
+
postcode="NR25 7HG"
|
|
158
|
+
)
|
|
159
159
|
address.premises()
|
|
160
160
|
|
|
161
161
|
{
|
|
@@ -12,7 +12,7 @@ Install it from PyPI:
|
|
|
12
12
|
|
|
13
13
|
### Formatting
|
|
14
14
|
|
|
15
|
-
May be used to format the PAF Address elements as a list of strings:
|
|
15
|
+
May be used to format the PAF Address elements - passed as either a single dictionary or as a series of keyword arguments - as a list of strings:
|
|
16
16
|
|
|
17
17
|
```python
|
|
18
18
|
import paf
|
|
@@ -33,14 +33,14 @@ Or as a tuple of strings:
|
|
|
33
33
|
|
|
34
34
|
```python
|
|
35
35
|
import paf
|
|
36
|
-
address = paf.Address(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
address = paf.Address(
|
|
37
|
+
building_name="1-2",
|
|
38
|
+
thoroughfare_name="NURSERY",
|
|
39
|
+
thoroughfare_descriptor="LANE",
|
|
40
|
+
dependent_locality="PENN",
|
|
41
|
+
post_town="HIGH WYCOMBE",
|
|
42
|
+
postcode="HP10 8LS"
|
|
43
|
+
)
|
|
44
44
|
address.as_tuple() # or tuple(address)
|
|
45
45
|
|
|
46
46
|
('1-2 NURSERY LANE', 'PENN', 'HIGH WYCOMBE', 'HP10 8LS')
|
|
@@ -67,14 +67,14 @@ Or as a dictionary:
|
|
|
67
67
|
|
|
68
68
|
```python
|
|
69
69
|
import paf
|
|
70
|
-
address = paf.Address(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
address = paf.Address(
|
|
71
|
+
building_name="1-2",
|
|
72
|
+
thoroughfare_name="NURSERY",
|
|
73
|
+
thoroughfare_descriptor="LANE",
|
|
74
|
+
dependent_locality="PENN",
|
|
75
|
+
post_town="HIGH WYCOMBE",
|
|
76
|
+
postcode="HP10 8LS"
|
|
77
|
+
)
|
|
78
78
|
address.as_dict()
|
|
79
79
|
|
|
80
80
|
{
|
|
@@ -132,15 +132,15 @@ If there is no `sub_building_name` element and the `dependent_thoroughfare` elem
|
|
|
132
132
|
|
|
133
133
|
```python
|
|
134
134
|
import paf
|
|
135
|
-
self.address = paf.Address(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
135
|
+
self.address = paf.Address(
|
|
136
|
+
building_name="1A",
|
|
137
|
+
dependent_thoroughfare_name="SEASTONE",
|
|
138
|
+
dependent_thoroughfare_descriptor="COURT",
|
|
139
|
+
thoroughfare_name="STATION",
|
|
140
|
+
thoroughfare_descriptor="ROAD",
|
|
141
|
+
post_town="HOLT",
|
|
142
|
+
postcode="NR25 7HG"
|
|
143
|
+
)
|
|
144
144
|
address.premises()
|
|
145
145
|
|
|
146
146
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: PyPaf
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: Formats the elements of a Royal Mail Postcode Address File entry
|
|
5
5
|
Author-email: John Bard <johnbard@globalnet.co.uk>
|
|
6
6
|
License: MIT
|
|
@@ -27,7 +27,7 @@ Install it from PyPI:
|
|
|
27
27
|
|
|
28
28
|
### Formatting
|
|
29
29
|
|
|
30
|
-
May be used to format the PAF Address elements as a list of strings:
|
|
30
|
+
May be used to format the PAF Address elements - passed as either a single dictionary or as a series of keyword arguments - as a list of strings:
|
|
31
31
|
|
|
32
32
|
```python
|
|
33
33
|
import paf
|
|
@@ -48,14 +48,14 @@ Or as a tuple of strings:
|
|
|
48
48
|
|
|
49
49
|
```python
|
|
50
50
|
import paf
|
|
51
|
-
address = paf.Address(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
address = paf.Address(
|
|
52
|
+
building_name="1-2",
|
|
53
|
+
thoroughfare_name="NURSERY",
|
|
54
|
+
thoroughfare_descriptor="LANE",
|
|
55
|
+
dependent_locality="PENN",
|
|
56
|
+
post_town="HIGH WYCOMBE",
|
|
57
|
+
postcode="HP10 8LS"
|
|
58
|
+
)
|
|
59
59
|
address.as_tuple() # or tuple(address)
|
|
60
60
|
|
|
61
61
|
('1-2 NURSERY LANE', 'PENN', 'HIGH WYCOMBE', 'HP10 8LS')
|
|
@@ -82,14 +82,14 @@ Or as a dictionary:
|
|
|
82
82
|
|
|
83
83
|
```python
|
|
84
84
|
import paf
|
|
85
|
-
address = paf.Address(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
85
|
+
address = paf.Address(
|
|
86
|
+
building_name="1-2",
|
|
87
|
+
thoroughfare_name="NURSERY",
|
|
88
|
+
thoroughfare_descriptor="LANE",
|
|
89
|
+
dependent_locality="PENN",
|
|
90
|
+
post_town="HIGH WYCOMBE",
|
|
91
|
+
postcode="HP10 8LS"
|
|
92
|
+
)
|
|
93
93
|
address.as_dict()
|
|
94
94
|
|
|
95
95
|
{
|
|
@@ -147,15 +147,15 @@ If there is no `sub_building_name` element and the `dependent_thoroughfare` elem
|
|
|
147
147
|
|
|
148
148
|
```python
|
|
149
149
|
import paf
|
|
150
|
-
self.address = paf.Address(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
150
|
+
self.address = paf.Address(
|
|
151
|
+
building_name="1A",
|
|
152
|
+
dependent_thoroughfare_name="SEASTONE",
|
|
153
|
+
dependent_thoroughfare_descriptor="COURT",
|
|
154
|
+
thoroughfare_name="STATION",
|
|
155
|
+
thoroughfare_descriptor="ROAD",
|
|
156
|
+
post_town="HOLT",
|
|
157
|
+
postcode="NR25 7HG"
|
|
158
|
+
)
|
|
159
159
|
address.premises()
|
|
160
160
|
|
|
161
161
|
{
|
|
@@ -21,11 +21,11 @@ src/paf/premises/exception.py
|
|
|
21
21
|
src/paf/premises/extender.py
|
|
22
22
|
src/paf/premises/lineable.py
|
|
23
23
|
src/paf/premises/premisable.py
|
|
24
|
-
src/paf/premises/premises.py
|
|
25
24
|
src/paf/premises/rule000.py
|
|
26
25
|
src/paf/premises/rule001.py
|
|
27
26
|
src/paf/premises/rule010.py
|
|
28
27
|
src/paf/premises/rule011.py
|
|
28
|
+
src/paf/premises/rule100.py
|
|
29
29
|
src/paf/premises/rule101.py
|
|
30
30
|
src/paf/premises/rule110.py
|
|
31
31
|
src/paf/premises/rule111.py
|
|
@@ -36,6 +36,7 @@ tests/test_exception_ii.py
|
|
|
36
36
|
tests/test_exception_iii.py
|
|
37
37
|
tests/test_exception_iv.py
|
|
38
38
|
tests/test_immutability.py
|
|
39
|
+
tests/test_kwargs.py
|
|
39
40
|
tests/test_mainfile.py
|
|
40
41
|
tests/test_po_box.py
|
|
41
42
|
tests/test_premises.py
|
|
@@ -45,4 +46,5 @@ tests/test_rule_3.py
|
|
|
45
46
|
tests/test_rule_4.py
|
|
46
47
|
tests/test_rule_5.py
|
|
47
48
|
tests/test_rule_6.py
|
|
48
|
-
tests/test_rule_7.py
|
|
49
|
+
tests/test_rule_7.py
|
|
50
|
+
tests/test_rule_x.py
|
|
@@ -1,20 +1,21 @@
|
|
|
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"""
|
|
13
14
|
|
|
14
15
|
@attribute_init
|
|
15
|
-
def __init__(self, *args):
|
|
16
|
+
def __init__(self, *args, **kwargs):
|
|
16
17
|
"""Initialise Address elements"""
|
|
17
|
-
object.__setattr__(self, 'premises', Premises(*args))
|
|
18
|
+
object.__setattr__(self, 'premises', Premises(*args, **kwargs))
|
|
18
19
|
|
|
19
20
|
def __repr__(self):
|
|
20
21
|
"""Return full representation of an Address"""
|
|
@@ -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):
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import functools
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
def attribute_init(func):
|
|
6
7
|
"""Decorator to initiate an object based on a list of attributes"""
|
|
7
8
|
|
|
@@ -10,7 +11,11 @@ def attribute_init(func):
|
|
|
10
11
|
"""Initiate properties from specified dict"""
|
|
11
12
|
for key in list(getattr(self, 'attrs', [])):
|
|
12
13
|
object.__setattr__(self, key, '')
|
|
13
|
-
|
|
14
|
+
if kwargs:
|
|
15
|
+
elements = kwargs
|
|
16
|
+
else:
|
|
17
|
+
elements = args[0]
|
|
18
|
+
for key, val in elements.items():
|
|
14
19
|
if hasattr(self, key):
|
|
15
20
|
object.__setattr__(self, key, str(val))
|
|
16
21
|
return func(self, *args, **kwargs)
|
|
@@ -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):
|
|
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,9 +71,14 @@ 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
|
|
|
77
|
+
@property
|
|
78
|
+
def sub_name_and_thoroughfare_or_locality(self):
|
|
79
|
+
"""Returns sub-building number and first thoroughfare or locality"""
|
|
80
|
+
return self._concatenate(('sub_building_name', 'first_thoroughfare_or_locality'))
|
|
81
|
+
|
|
75
82
|
@property
|
|
76
83
|
def building_name_but_last_word(self):
|
|
77
84
|
"""Returns all but last word of the building name"""
|
|
@@ -93,5 +100,7 @@ class Premises(
|
|
|
93
100
|
return self.last_word('sub_building_name')
|
|
94
101
|
|
|
95
102
|
def _concatenate(self, keys, concatenator=' '):
|
|
96
|
-
"""Returns specified attributes concatenated with a
|
|
97
|
-
return concatenator.join(
|
|
103
|
+
"""Returns specified attributes concatenated with a separator"""
|
|
104
|
+
return concatenator.join(
|
|
105
|
+
filter(None, [getattr(self, k, None) for k in keys])
|
|
106
|
+
)
|
|
@@ -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"""
|
|
@@ -46,6 +47,6 @@ class ExceptionMixin(BuildingTypeMixin, SplitMixin):
|
|
|
46
47
|
"""Returns if attribute should be split"""
|
|
47
48
|
return (
|
|
48
49
|
self.__is_exception(self.last_word(attr))
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
and not self.last_word(attr).isdigit()
|
|
51
|
+
and not self.__is_exception_iv(attr)
|
|
51
52
|
)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Premises Extender Mixin"""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from .rule000 import Rule000 # pylint: disable=unused-import # noqa: F401
|
|
5
|
+
from .rule001 import Rule001 # pylint: disable=unused-import # noqa: F401
|
|
6
|
+
from .rule010 import Rule010 # pylint: disable=unused-import # noqa: F401
|
|
7
|
+
from .rule100 import Rule100 # pylint: disable=unused-import # noqa: F401
|
|
8
|
+
from .rule011 import Rule011 # pylint: disable=unused-import # noqa: F401
|
|
9
|
+
from .rule101 import Rule101 # pylint: disable=unused-import # noqa: F401
|
|
10
|
+
from .rule110 import Rule110 # pylint: disable=unused-import # noqa: F401
|
|
11
|
+
from .rule111 import Rule111 # pylint: disable=unused-import # noqa: F401
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ExtenderMixin():
|
|
15
|
+
"""Dynamic Premises processing"""
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def rule(self):
|
|
19
|
+
"""Returns premises rule class"""
|
|
20
|
+
rule = ''.join(['0' if self.is_empty(k) else '1' for k in self.building_attrs])
|
|
21
|
+
return getattr(sys.modules[__name__], 'Rule' + rule)
|
|
22
|
+
|
|
23
|
+
def extend(self):
|
|
24
|
+
"""Dynamically extends instance with appropriate rule"""
|
|
25
|
+
base_cls = self.__class__
|
|
26
|
+
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
|
+
)
|