PyPaf 0.4.0__tar.gz → 0.5.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.4.0/src/PyPaf.egg-info → pypaf-0.5.0}/PKG-INFO +1 -1
- {pypaf-0.4.0 → pypaf-0.5.0/src/PyPaf.egg-info}/PKG-INFO +1 -1
- {pypaf-0.4.0 → pypaf-0.5.0}/src/PyPaf.egg-info/SOURCES.txt +2 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/address.py +7 -5
- pypaf-0.5.0/src/paf/immutable.py +12 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/premises/rule010.py +3 -3
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/premises_extender.py +3 -1
- pypaf-0.5.0/src/paf/version.py +3 -0
- pypaf-0.5.0/tests/test_immutability.py +38 -0
- pypaf-0.4.0/src/paf/version.py +0 -3
- {pypaf-0.4.0 → pypaf-0.5.0}/LICENSE.txt +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/README.md +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/pyproject.toml +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/setup.cfg +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/PyPaf.egg-info/dependency_links.txt +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/PyPaf.egg-info/top_level.txt +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/__init__.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/attribute.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/lineable.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/premises/__init__.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/premises/common.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/premises/rule000.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/premises/rule001.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/premises/rule011.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/premises/rule101.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/premises/rule110.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/premises/rule111.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/src/paf/thoroughfare_locality.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_exception_i.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_exception_ii.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_exception_iii.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_exception_iv.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_mainfile.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_po_box.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_rule_1.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_rule_2.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_rule_3.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_rule_4.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_rule_5.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_rule_6.py +0 -0
- {pypaf-0.4.0 → pypaf-0.5.0}/tests/test_rule_7.py +0 -0
|
@@ -8,6 +8,7 @@ src/PyPaf.egg-info/top_level.txt
|
|
|
8
8
|
src/paf/__init__.py
|
|
9
9
|
src/paf/address.py
|
|
10
10
|
src/paf/attribute.py
|
|
11
|
+
src/paf/immutable.py
|
|
11
12
|
src/paf/lineable.py
|
|
12
13
|
src/paf/premises_extender.py
|
|
13
14
|
src/paf/thoroughfare_locality.py
|
|
@@ -25,6 +26,7 @@ tests/test_exception_i.py
|
|
|
25
26
|
tests/test_exception_ii.py
|
|
26
27
|
tests/test_exception_iii.py
|
|
27
28
|
tests/test_exception_iv.py
|
|
29
|
+
tests/test_immutability.py
|
|
28
30
|
tests/test_mainfile.py
|
|
29
31
|
tests/test_po_box.py
|
|
30
32
|
tests/test_rule_1.py
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
"""PAF Address"""
|
|
2
2
|
|
|
3
|
+
# Tried using dataclasses.dataclass(frozen=True) decorator for immutablity but did not work"""
|
|
4
|
+
from .immutable import ImmutableMixin
|
|
3
5
|
from .lineable import LineableMixin
|
|
4
6
|
|
|
5
|
-
class Address(LineableMixin):
|
|
7
|
+
class Address(ImmutableMixin, LineableMixin):
|
|
6
8
|
"""Main PAF Address class"""
|
|
7
9
|
|
|
8
10
|
def __init__(self, args):
|
|
9
11
|
"""Initialise Address elements"""
|
|
10
|
-
for key in self.__class__.attrs:
|
|
11
|
-
|
|
12
|
+
for key in self.__class__.attrs: # pylint: disable=not-an-iterable
|
|
13
|
+
object.__setattr__(self, key, '')
|
|
12
14
|
for key, val in args.items():
|
|
13
15
|
if hasattr(self, key):
|
|
14
|
-
|
|
16
|
+
object.__setattr__(self, key, val)
|
|
15
17
|
self.extend_premises()
|
|
16
18
|
|
|
17
19
|
def __repr__(self):
|
|
18
20
|
"""Return full representation of an Address"""
|
|
19
|
-
args = {k: getattr(self, k) for k in self.__class__.attrs if getattr(self, k, None)}
|
|
21
|
+
args = {k: getattr(self, k) for k in self.__class__.attrs if getattr(self, k, None)} # pylint: disable=not-an-iterable
|
|
20
22
|
return self.__class__.__name__ + '(' + str(args) + ')'
|
|
21
23
|
|
|
22
24
|
def __str__(self):
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Immutable Mixin"""
|
|
2
|
+
|
|
3
|
+
from dataclasses import FrozenInstanceError
|
|
4
|
+
|
|
5
|
+
class ImmutableMixin():
|
|
6
|
+
"""Prevent manipulation of object attributes"""
|
|
7
|
+
|
|
8
|
+
def __setattr__(self, *_):
|
|
9
|
+
raise FrozenInstanceError
|
|
10
|
+
|
|
11
|
+
def __delattr__(self, *_):
|
|
12
|
+
raise FrozenInstanceError
|
|
@@ -26,12 +26,12 @@ class Rule010(Common):
|
|
|
26
26
|
return(
|
|
27
27
|
self.is_exception('building_name_last_word') and
|
|
28
28
|
not re.match(r'^\d+$', self.building_name_last_word) and
|
|
29
|
-
not self.
|
|
29
|
+
not self.is_known_building_type
|
|
30
30
|
)
|
|
31
31
|
|
|
32
32
|
@property
|
|
33
|
-
def
|
|
34
|
-
"""Returns if building name
|
|
33
|
+
def is_known_building_type(self):
|
|
34
|
+
"""Returns if building name starts with a known building type"""
|
|
35
35
|
return self.building_name_but_last_word in [
|
|
36
36
|
"BACK OF", "BLOCK", "BLOCKS", "BUILDING", "MAISONETTE", "MAISONETTES", "REAR OF",
|
|
37
37
|
"SHOP", "SHOPS", "STALL", "STALLS", "SUITE", "SUITES", "UNIT", "UNITS"
|
|
@@ -22,4 +22,6 @@ class PremisesExtenderMixin(AttributeMixin):
|
|
|
22
22
|
def extend_premises(self):
|
|
23
23
|
"""Dynamically extends instance with appropriate premises rule"""
|
|
24
24
|
base_cls = self.__class__
|
|
25
|
-
|
|
25
|
+
object.__setattr__(
|
|
26
|
+
self, '__class__', type(base_cls.__name__, (base_cls, self.premises_rule), {})
|
|
27
|
+
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Test Immutability"""
|
|
2
|
+
|
|
3
|
+
import unittest
|
|
4
|
+
from dataclasses import FrozenInstanceError
|
|
5
|
+
import paf
|
|
6
|
+
|
|
7
|
+
class TestImmutability(unittest.TestCase):
|
|
8
|
+
"""Test Immutable"""
|
|
9
|
+
|
|
10
|
+
def setUp(self):
|
|
11
|
+
"""Set up Address instance"""
|
|
12
|
+
self.address = paf.Address({
|
|
13
|
+
'building_number': "16",
|
|
14
|
+
'thoroughfare_name': "VIXEN",
|
|
15
|
+
'thoroughfare_descriptor': "ROAD",
|
|
16
|
+
'post_town': "BRADOCK",
|
|
17
|
+
'postcode': "KT6 5BT"
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
def test_assignment(self):
|
|
21
|
+
"""Test setting attribute by direct assignment"""
|
|
22
|
+
with self.assertRaises(FrozenInstanceError):
|
|
23
|
+
self.address.building_name = "THE HOUSE"
|
|
24
|
+
|
|
25
|
+
def test_setattr(self):
|
|
26
|
+
"""Test setting new attribute"""
|
|
27
|
+
self.assertRaises(FrozenInstanceError, setattr, self.address, 'building_name', "THE HOUSE")
|
|
28
|
+
|
|
29
|
+
def test_resetattr(self):
|
|
30
|
+
"""Test re-setting existing attribute"""
|
|
31
|
+
self.assertRaises(FrozenInstanceError, setattr, self.address, 'building_number', "20")
|
|
32
|
+
|
|
33
|
+
def test_delattr(self):
|
|
34
|
+
"""Test deleting attribute"""
|
|
35
|
+
self.assertRaises(FrozenInstanceError, delattr, self.address, 'post_town')
|
|
36
|
+
|
|
37
|
+
if __name__ == '__main__':
|
|
38
|
+
unittest.main()
|
pypaf-0.4.0/src/paf/version.py
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|