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.
Files changed (57) hide show
  1. {pypaf-0.8.0/src/PyPaf.egg-info → pypaf-1.0.1}/PKG-INFO +1 -1
  2. {pypaf-0.8.0 → pypaf-1.0.1/src/PyPaf.egg-info}/PKG-INFO +1 -1
  3. {pypaf-0.8.0 → pypaf-1.0.1}/src/PyPaf.egg-info/SOURCES.txt +0 -1
  4. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/address.py +3 -2
  5. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/attribute.py +9 -8
  6. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/immutable.py +1 -0
  7. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/initiator.py +1 -0
  8. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/lineable.py +1 -0
  9. pypaf-0.8.0/src/paf/premises/premises.py → pypaf-1.0.1/src/paf/premises/__init__.py +18 -9
  10. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/attribute.py +7 -6
  11. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/building_type.py +6 -2
  12. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/dependent_premisable.py +1 -0
  13. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/exception.py +8 -6
  14. pypaf-1.0.1/src/paf/premises/extender.py +23 -0
  15. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/lineable.py +5 -1
  16. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/premisable.py +1 -0
  17. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule000.py +1 -0
  18. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule001.py +1 -0
  19. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule010.py +5 -1
  20. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule011.py +1 -0
  21. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule100.py +2 -1
  22. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule101.py +1 -0
  23. pypaf-1.0.1/src/paf/premises/rule110.py +34 -0
  24. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/rule111.py +3 -2
  25. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/premises/split.py +2 -1
  26. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/thoroughfare_locality.py +5 -5
  27. pypaf-1.0.1/src/paf/version.py +3 -0
  28. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_empty.py +5 -2
  29. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_exception_i.py +9 -3
  30. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_exception_ii.py +10 -3
  31. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_exception_iii.py +10 -3
  32. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_exception_iv.py +60 -18
  33. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_immutability.py +5 -2
  34. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_kwargs.py +13 -6
  35. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_mainfile.py +5 -2
  36. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_po_box.py +10 -3
  37. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_premises.py +22 -9
  38. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_1.py +5 -2
  39. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_2.py +11 -4
  40. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_3.py +138 -18
  41. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_4.py +17 -4
  42. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_5.py +27 -8
  43. pypaf-1.0.1/tests/test_rule_6.py +352 -0
  44. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_7.py +56 -12
  45. {pypaf-0.8.0 → pypaf-1.0.1}/tests/test_rule_x.py +15 -6
  46. pypaf-0.8.0/src/paf/premises/__init__.py +0 -0
  47. pypaf-0.8.0/src/paf/premises/extender.py +0 -25
  48. pypaf-0.8.0/src/paf/premises/rule110.py +0 -20
  49. pypaf-0.8.0/src/paf/version.py +0 -3
  50. pypaf-0.8.0/tests/test_rule_6.py +0 -166
  51. {pypaf-0.8.0 → pypaf-1.0.1}/LICENSE.txt +0 -0
  52. {pypaf-0.8.0 → pypaf-1.0.1}/README.md +0 -0
  53. {pypaf-0.8.0 → pypaf-1.0.1}/pyproject.toml +0 -0
  54. {pypaf-0.8.0 → pypaf-1.0.1}/setup.cfg +0 -0
  55. {pypaf-0.8.0 → pypaf-1.0.1}/src/PyPaf.egg-info/dependency_links.txt +0 -0
  56. {pypaf-0.8.0 → pypaf-1.0.1}/src/PyPaf.egg-info/top_level.txt +0 -0
  57. {pypaf-0.8.0 → pypaf-1.0.1}/src/paf/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyPaf
3
- Version: 0.8.0
3
+ Version: 1.0.1
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PyPaf
3
- Version: 0.8.0
3
+ Version: 1.0.1
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
@@ -21,7 +21,6 @@ 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
@@ -1,12 +1,13 @@
1
1
  """PAF Address"""
2
2
 
3
- # Tried using dataclasses.dataclass(frozen=True) decorator for immutablity but did not work"""
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.premises import 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
- 'sub_building_name', 'building_name', 'building_number',
13
- 'po_box_number'
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
- + cls.dependent_thoroughfare_attrs
35
- + cls.thoroughfare_attrs
36
- + cls.locality_attrs
37
- + cls.post_attrs
38
- + cls.other_attrs
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
  from dataclasses import FrozenInstanceError
4
4
 
5
+
5
6
  class ImmutableMixin():
6
7
  """Prevent manipulation of object attributes"""
7
8
 
@@ -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
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  from itertools import chain
4
4
 
5
+
5
6
  class LineableMixin():
6
7
  """Converts Paf address elements into list of address lines"""
7
8
 
@@ -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
- ImmutableMixin, ExtenderMixin, AttributeMixin,
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): # pylint: disable=unused-argument
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() # pylint: disable=no-member
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 or locality"""
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 or locality"""
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 concatenated with a comma"""
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 specified separator"""
102
- return concatenator.join(filter(None, [getattr(self, k, None) for k in keys]))
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
- + cls.building_attrs
31
- + cls.dependent_thoroughfare_attrs
32
- + cls.thoroughfare_attrs
33
- + cls.locality_attrs
34
- + cls.other_attrs
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", "MAISONETTE", "MAISONETTES", "REAR OF",
14
- "SHOP", "SHOPS", "STALL", "STALLS", "SUITE", "SUITES", "UNIT", "UNITS", "PO BOX"
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
@@ -2,6 +2,7 @@
2
2
 
3
3
  from .premisable import PremisableMixin
4
4
 
5
+
5
6
  class DependentPremisableMixin(PremisableMixin):
6
7
  """Returns the values for the premises properties"""
7
8
 
@@ -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
- or cls.__is_exception_ii(val)
31
- or cls.__is_exception_iii(val)
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', splitstring.last_word(getattr(self, attr, None)))
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.__is_exception(self.last_word(attr))
49
- and not self.last_word(attr).isdigit()
50
- and not self.__is_exception_iv(attr)
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 '' if self.is_empty('po_box_number') else f"PO BOX {getattr(self, 'po_box_number')}"
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 .exception import ExceptionMixin
4
4
 
5
+
5
6
  class PremisableMixin(ExceptionMixin):
6
7
  """Returns the values for the premises properties"""
7
8
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  from .premisable import PremisableMixin
4
4
 
5
+
5
6
  class Rule000(PremisableMixin):
6
7
  """Rule 1 processing"""
7
8
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  from .dependent_premisable import DependentPremisableMixin
4
4
 
5
+
5
6
  class Rule001(DependentPremisableMixin):
6
7
  """Rule 2 processing"""
7
8
 
@@ -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 self.is_exception('building_name') or self.is_split_exception('building_name')
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 .dependent_premisable import DependentPremisableMixin
4
4
 
5
+
5
6
  class Rule011(DependentPremisableMixin):
6
7
  """Rule 4 processing"""
7
8
 
@@ -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
@@ -2,6 +2,7 @@
2
2
 
3
3
  from .premisable import PremisableMixin
4
4
 
5
+
5
6
  class Rule101(PremisableMixin):
6
7
  """Rule 5 processing"""
7
8
 
@@ -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 the characters after the leading digits from the attribute"""
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 or locality attribute"""
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
- and self.premises.includes_first_thoroughfare_or_locality
68
+ and self.premises.includes_first_thoroughfare_or_locality
69
69
  )
@@ -0,0 +1,3 @@
1
+ """Version"""
2
+
3
+ __version__ = '1.0.1'
@@ -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
- def setUp(self):
10
+ @classmethod
11
+ def setUpClass(cls):
10
12
  """Set up Address instance"""
11
- self.address = paf.Address({})
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
- def setUp(self):
10
+ @classmethod
11
+ def setUpClass(cls):
10
12
  """Set up Address instance"""
11
- self.address = paf.Address({
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(self.address.as_str(), address, "Incorrect Exception I string format")
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
- def setUp(self):
10
+ @classmethod
11
+ def setUpClass(cls):
10
12
  """Set up Address instance"""
11
- self.address = paf.Address({
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 = {'line_1': "12A UPPERKIRKGATE", 'post_town': "ABERDEEN", 'postcode': "AB10 1BA"}
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
- def setUp(self):
10
+ @classmethod
11
+ def setUpClass(cls):
10
12
  """Set up Address instance"""
11
- self.address = paf.Address({
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 = {'line_1': "K PORTLAND ROAD", 'post_town': "DORKING", 'postcode': "RH4 1EW"}
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()