followthemoney 3.5.8__py2.py3-none-any.whl → 3.6.0__py2.py3-none-any.whl
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.
- followthemoney/__init__.py +1 -1
- followthemoney/cli/cli.py +18 -14
- followthemoney/export/excel.py +6 -6
- followthemoney/mapping/entity.py +14 -2
- followthemoney/mapping/property.py +15 -3
- followthemoney/mapping/sql.py +1 -1
- followthemoney/property.py +11 -0
- followthemoney/proxy.py +29 -19
- followthemoney/schema/Analyzable.yaml +2 -0
- followthemoney/schema/BankAccount.yaml +3 -0
- followthemoney/schema/LegalEntity.yaml +4 -0
- followthemoney/schema/Person.yaml +4 -0
- followthemoney/schema/Security.yaml +2 -0
- followthemoney/schema/Thing.yaml +1 -0
- followthemoney/translations/ru/LC_MESSAGES/followthemoney.po +24 -22
- followthemoney/types/__init__.py +2 -2
- followthemoney/types/common.py +13 -5
- followthemoney/types/date.py +7 -2
- followthemoney/types/email.py +3 -1
- followthemoney/types/entity.py +3 -1
- followthemoney/types/iban.py +7 -9
- followthemoney/types/identifier.py +17 -0
- followthemoney/types/ip.py +3 -1
- followthemoney/types/language.py +1 -1
- followthemoney/types/mimetype.py +2 -2
- followthemoney/types/name.py +6 -35
- followthemoney/types/phone.py +3 -1
- followthemoney/types/topic.py +6 -1
- followthemoney/types/url.py +5 -21
- {followthemoney-3.5.8.dist-info → followthemoney-3.6.0.dist-info}/METADATA +6 -10
- {followthemoney-3.5.8.dist-info → followthemoney-3.6.0.dist-info}/RECORD +40 -40
- {followthemoney-3.5.8.dist-info → followthemoney-3.6.0.dist-info}/WHEEL +1 -1
- {followthemoney-3.5.8.dist-info → followthemoney-3.6.0.dist-info}/entry_points.txt +0 -1
- tests/types/test_dates.py +5 -5
- tests/types/test_iban.py +2 -1
- tests/types/test_identifiers.py +99 -0
- tests/types/test_names.py +1 -7
- {followthemoney-3.5.8.dist-info → followthemoney-3.6.0.dist-info}/LICENSE +0 -0
- {followthemoney-3.5.8.dist-info → followthemoney-3.6.0.dist-info}/namespace_packages.txt +0 -0
- {followthemoney-3.5.8.dist-info → followthemoney-3.6.0.dist-info}/top_level.txt +0 -0
followthemoney/types/email.py
CHANGED
|
@@ -36,7 +36,9 @@ class EmailType(PropertyType):
|
|
|
36
36
|
# except:
|
|
37
37
|
# return False
|
|
38
38
|
|
|
39
|
-
def validate(
|
|
39
|
+
def validate(
|
|
40
|
+
self, value: str, fuzzy: bool = False, format: Optional[str] = None
|
|
41
|
+
) -> bool:
|
|
40
42
|
"""Check to see if this is a valid email address."""
|
|
41
43
|
# TODO: adopt email.utils.parseaddr
|
|
42
44
|
email = sanitize_text(value)
|
followthemoney/types/entity.py
CHANGED
|
@@ -29,7 +29,9 @@ class EntityType(PropertyType):
|
|
|
29
29
|
matchable = True
|
|
30
30
|
pivot = True
|
|
31
31
|
|
|
32
|
-
def validate(
|
|
32
|
+
def validate(
|
|
33
|
+
self, value: str, fuzzy: bool = False, format: Optional[str] = None
|
|
34
|
+
) -> bool:
|
|
33
35
|
text = sanitize_text(value)
|
|
34
36
|
if text is None:
|
|
35
37
|
return False
|
followthemoney/types/iban.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
from typing import Optional, TYPE_CHECKING
|
|
2
|
-
from
|
|
3
|
-
from stdnum.exceptions import ValidationError # type: ignore
|
|
1
|
+
from typing import Optional, TYPE_CHECKING
|
|
2
|
+
from rigour.ids import IBAN
|
|
4
3
|
|
|
5
4
|
from followthemoney.types.common import PropertyType
|
|
6
5
|
from followthemoney.rdf import URIRef, Identifier
|
|
@@ -26,12 +25,11 @@ class IbanType(PropertyType):
|
|
|
26
25
|
matchable = True
|
|
27
26
|
pivot = True
|
|
28
27
|
|
|
29
|
-
def validate(self, value: str) -> bool:
|
|
28
|
+
def validate(self, value: str, fuzzy: bool = False, format: Optional[str] = None) -> bool:
|
|
30
29
|
text = sanitize_text(value)
|
|
31
|
-
|
|
32
|
-
return cast(bool, iban.validate(text))
|
|
33
|
-
except ValidationError:
|
|
30
|
+
if text is None:
|
|
34
31
|
return False
|
|
32
|
+
return IBAN.is_valid(text)
|
|
35
33
|
|
|
36
34
|
def clean_text(
|
|
37
35
|
self,
|
|
@@ -42,7 +40,7 @@ class IbanType(PropertyType):
|
|
|
42
40
|
) -> Optional[str]:
|
|
43
41
|
"""Create a more clean, but still user-facing version of an
|
|
44
42
|
instance of the type."""
|
|
45
|
-
return
|
|
43
|
+
return IBAN.normalize(text)
|
|
46
44
|
|
|
47
45
|
def country_hint(self, value: str) -> str:
|
|
48
46
|
return value[:2].lower()
|
|
@@ -54,4 +52,4 @@ class IbanType(PropertyType):
|
|
|
54
52
|
return f"iban:{value.upper()}"
|
|
55
53
|
|
|
56
54
|
def caption(self, value: str) -> str:
|
|
57
|
-
return
|
|
55
|
+
return IBAN.format(value)
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import re
|
|
2
|
+
from typing import Optional, TYPE_CHECKING
|
|
3
|
+
from rigour.ids import get_identifier_format_names, get_identifier_format
|
|
2
4
|
|
|
3
5
|
from followthemoney.types.common import PropertyType
|
|
4
6
|
from followthemoney.util import dampen, shortest, longest
|
|
5
7
|
from followthemoney.util import defer as _
|
|
6
8
|
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from followthemoney.proxy import EntityProxy
|
|
11
|
+
|
|
7
12
|
|
|
8
13
|
class IdentifierType(PropertyType):
|
|
9
14
|
"""Used for registration numbers and other codes assigned by an authority
|
|
@@ -22,6 +27,18 @@ class IdentifierType(PropertyType):
|
|
|
22
27
|
matchable = True
|
|
23
28
|
pivot = True
|
|
24
29
|
|
|
30
|
+
def clean_text(
|
|
31
|
+
self,
|
|
32
|
+
text: str,
|
|
33
|
+
fuzzy: bool = False,
|
|
34
|
+
format: Optional[str] = None,
|
|
35
|
+
proxy: Optional["EntityProxy"] = None,
|
|
36
|
+
) -> Optional[str]:
|
|
37
|
+
if format in get_identifier_format_names():
|
|
38
|
+
format_ = get_identifier_format(format)
|
|
39
|
+
return format_.normalize(text)
|
|
40
|
+
return text
|
|
41
|
+
|
|
25
42
|
def clean_compare(self, value: str) -> str:
|
|
26
43
|
# TODO: should this be used for normalization?
|
|
27
44
|
value = self.COMPARE_CLEAN.sub("", value)
|
followthemoney/types/ip.py
CHANGED
|
@@ -21,7 +21,9 @@ class IpType(PropertyType):
|
|
|
21
21
|
matchable = True
|
|
22
22
|
pivot = True
|
|
23
23
|
|
|
24
|
-
def validate(
|
|
24
|
+
def validate(
|
|
25
|
+
self, value: str, fuzzy: bool = False, format: Optional[str] = None
|
|
26
|
+
) -> bool:
|
|
25
27
|
"""Check to see if this is a valid ip address."""
|
|
26
28
|
try:
|
|
27
29
|
ip_address(value)
|
followthemoney/types/language.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Optional, TYPE_CHECKING
|
|
2
2
|
from babel.core import Locale
|
|
3
|
-
from
|
|
3
|
+
from rigour.langs import iso_639_alpha3
|
|
4
4
|
|
|
5
5
|
from followthemoney.types.common import EnumType, EnumValues
|
|
6
6
|
from followthemoney.rdf import URIRef, Identifier
|
followthemoney/types/mimetype.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Optional, TYPE_CHECKING
|
|
2
|
-
from
|
|
3
|
-
from
|
|
2
|
+
from rigour.mime import normalize_mimetype, parse_mimetype
|
|
3
|
+
from rigour.mime import DEFAULT
|
|
4
4
|
|
|
5
5
|
from followthemoney.types.common import PropertyType
|
|
6
6
|
from followthemoney.rdf import URIRef, Identifier
|
followthemoney/types/name.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING,
|
|
2
|
-
|
|
3
|
-
from
|
|
1
|
+
from typing import TYPE_CHECKING, Optional, Sequence
|
|
2
|
+
from rigour.text.distance import levenshtein_similarity
|
|
3
|
+
from rigour.names import pick_name
|
|
4
4
|
from normality import slugify
|
|
5
5
|
from normality.cleaning import collapse_spaces, strip_quotes
|
|
6
6
|
|
|
@@ -40,44 +40,15 @@ class NameType(PropertyType):
|
|
|
40
40
|
|
|
41
41
|
def pick(self, values: Sequence[str]) -> Optional[str]:
|
|
42
42
|
"""From a set of names, pick the most plausible user-facing one."""
|
|
43
|
-
|
|
44
|
-
values = sorted(values)
|
|
45
|
-
if not len(values):
|
|
46
|
-
return None
|
|
47
|
-
normalised: List[Union[str, bytes]] = []
|
|
48
|
-
lookup: Dict[str, List[Union[str, bytes]]] = {}
|
|
49
|
-
# We're doing this in two stages, to avoid name forms with varied casing
|
|
50
|
-
# (e.g. Smith vs. SMITH) are counted as widly different, leading to
|
|
51
|
-
# implausible median outcomes.
|
|
52
|
-
for value in values:
|
|
53
|
-
norm = slugify(value, sep=" ")
|
|
54
|
-
if norm is None:
|
|
55
|
-
continue
|
|
56
|
-
normalised.append(norm)
|
|
57
|
-
lookup.setdefault(norm, [])
|
|
58
|
-
lookup[norm].append(value)
|
|
59
|
-
|
|
60
|
-
if not normalised:
|
|
61
|
-
return None
|
|
62
|
-
|
|
63
|
-
norm = setmedian(normalised)
|
|
64
|
-
if norm is None:
|
|
65
|
-
return None
|
|
66
|
-
forms = lookup.get(norm, [])
|
|
67
|
-
if len(forms) > 1:
|
|
68
|
-
return setmedian(forms)
|
|
69
|
-
for form in forms:
|
|
70
|
-
return str(form)
|
|
71
|
-
return None
|
|
43
|
+
return pick_name(list(values))
|
|
72
44
|
|
|
73
45
|
def _specificity(self, value: str) -> float:
|
|
74
46
|
# TODO: insert artificial intelligence here.
|
|
75
47
|
return dampen(3, 50, value)
|
|
76
48
|
|
|
77
49
|
def compare(self, left: str, right: str) -> float:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return (longest - edits) / longest
|
|
50
|
+
"""Compare two names for similarity."""
|
|
51
|
+
return levenshtein_similarity(left, right)
|
|
81
52
|
|
|
82
53
|
def node_id(self, value: str) -> Optional[str]:
|
|
83
54
|
slug = slugify(value)
|
followthemoney/types/phone.py
CHANGED
|
@@ -62,7 +62,9 @@ class PhoneType(PropertyType):
|
|
|
62
62
|
except NumberParseException:
|
|
63
63
|
pass
|
|
64
64
|
|
|
65
|
-
def validate(
|
|
65
|
+
def validate(
|
|
66
|
+
self, value: str, fuzzy: bool = False, format: Optional[str] = None
|
|
67
|
+
) -> bool:
|
|
66
68
|
for num in self._parse_number(value):
|
|
67
69
|
if is_valid_number(num):
|
|
68
70
|
return True
|
followthemoney/types/topic.py
CHANGED
|
@@ -38,6 +38,7 @@ class TopicType(EnumType):
|
|
|
38
38
|
"corp.offshore": _("Offshore"),
|
|
39
39
|
"corp.shell": _("Shell company"),
|
|
40
40
|
"corp.public": _("Public listed company"),
|
|
41
|
+
"corp.disqual": _("Disqualified"),
|
|
41
42
|
"gov": _("Government"),
|
|
42
43
|
"gov.national": _("National government"),
|
|
43
44
|
"gov.state": _("State government"),
|
|
@@ -55,7 +56,10 @@ class TopicType(EnumType):
|
|
|
55
56
|
"fin.bank": _("Bank"),
|
|
56
57
|
"fin.fund": _("Fund"),
|
|
57
58
|
"fin.adivsor": _("Financial advisor"),
|
|
58
|
-
"
|
|
59
|
+
"reg.action": _("Regulator action"),
|
|
60
|
+
"reg.warn": _("Regulator warning"),
|
|
61
|
+
"role.pep": _("Politican"),
|
|
62
|
+
"role.pol": _("Non-PEP"),
|
|
59
63
|
"role.rca": _("Close Associate"),
|
|
60
64
|
"role.judge": _("Judge"),
|
|
61
65
|
"role.civil": _("Civil servant"),
|
|
@@ -73,6 +77,7 @@ class TopicType(EnumType):
|
|
|
73
77
|
"asset.frozen": _("Frozen asset"),
|
|
74
78
|
"sanction": _("Sanctioned entity"),
|
|
75
79
|
"sanction.linked": _("Sanction-linked entity"),
|
|
80
|
+
"sanction.counter": _("Counter-sanctioned entity"),
|
|
76
81
|
"export.control": _("Export controlled"),
|
|
77
82
|
"debarment": _("Debarred entity"),
|
|
78
83
|
"poi": _("Person of interest"),
|
followthemoney/types/url.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from typing import Optional, TYPE_CHECKING
|
|
2
|
-
from
|
|
2
|
+
from rigour.urls import clean_url, compare_urls
|
|
3
3
|
|
|
4
4
|
from followthemoney.types.common import PropertyType
|
|
5
5
|
from followthemoney.rdf import URIRef, Identifier
|
|
@@ -33,26 +33,10 @@ class UrlType(PropertyType):
|
|
|
33
33
|
) -> Optional[str]:
|
|
34
34
|
"""Perform intensive care on URLs to make sure they have a scheme
|
|
35
35
|
and a host name. If no scheme is given HTTP is assumed."""
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if not len(parsed.netloc):
|
|
41
|
-
if "." in parsed.path and not text.startswith("//"):
|
|
42
|
-
# This is a pretty weird rule meant to catch things like
|
|
43
|
-
# 'www.google.com', but it'll likely backfire in some
|
|
44
|
-
# really creative ways.
|
|
45
|
-
return self.clean_text(f"//{text}")
|
|
46
|
-
return None
|
|
47
|
-
if not len(parsed.scheme):
|
|
48
|
-
parsed = parsed._replace(scheme=self.DEFAULT_SCHEME)
|
|
49
|
-
else:
|
|
50
|
-
parsed = parsed._replace(scheme=parsed.scheme.lower())
|
|
51
|
-
if parsed.scheme not in self.SCHEMES:
|
|
52
|
-
return None
|
|
53
|
-
if not len(parsed.path):
|
|
54
|
-
parsed = parsed._replace(path="/")
|
|
55
|
-
return parsed.geturl()
|
|
36
|
+
return clean_url(text)
|
|
37
|
+
|
|
38
|
+
def compare(self, left: str, right: str) -> float:
|
|
39
|
+
return compare_urls(left, right)
|
|
56
40
|
|
|
57
41
|
def _specificity(self, value: str) -> float:
|
|
58
42
|
return dampen(10, 120, value)
|
|
@@ -1,38 +1,35 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: followthemoney
|
|
3
|
-
Version: 3.
|
|
4
|
-
Summary: UNKNOWN
|
|
3
|
+
Version: 3.6.0
|
|
5
4
|
Home-page: https://followthemoney.tech/
|
|
6
5
|
Author: Organized Crime and Corruption Reporting Project
|
|
7
6
|
Author-email: data@occrp.org
|
|
8
7
|
License: MIT
|
|
9
|
-
Platform: UNKNOWN
|
|
10
8
|
Classifier: Intended Audience :: Developers
|
|
11
9
|
Classifier: Operating System :: OS Independent
|
|
12
10
|
Classifier: Programming Language :: Python
|
|
13
11
|
Classifier: Programming Language :: Python :: 3.9
|
|
14
12
|
Description-Content-Type: text/markdown
|
|
15
|
-
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: babel <3.0.0,>=2.14.0
|
|
16
15
|
Requires-Dist: pyyaml <7.0.0,>=5.0.0
|
|
17
16
|
Requires-Dist: types-PyYAML
|
|
18
17
|
Requires-Dist: sqlalchemy2-stubs
|
|
19
18
|
Requires-Dist: banal <1.1.0,>=1.0.6
|
|
19
|
+
Requires-Dist: rigour <1.0.0,>=0.5.1
|
|
20
20
|
Requires-Dist: click <9.0.0,>=8.0
|
|
21
21
|
Requires-Dist: stringcase <2.0.0,>=1.2.0
|
|
22
22
|
Requires-Dist: requests <3.0.0,>=2.21.0
|
|
23
|
-
Requires-Dist: python-levenshtein <1.0.0,>=0.12.0
|
|
24
23
|
Requires-Dist: normality <3.0.0,>=2.4.0
|
|
25
24
|
Requires-Dist: sqlalchemy <3.0.0,>=1.4.49
|
|
26
25
|
Requires-Dist: countrynames <2.0.0,>=1.13.0
|
|
27
|
-
Requires-Dist: languagecodes <2.0.0,>=1.1.0
|
|
28
26
|
Requires-Dist: prefixdate <1.0.0,>=0.4.0
|
|
29
27
|
Requires-Dist: fingerprints <2.0.0,>=1.0.1
|
|
30
28
|
Requires-Dist: phonenumbers <9.0.0,>=8.12.22
|
|
31
29
|
Requires-Dist: python-stdnum <2.0.0,>=1.16
|
|
32
|
-
Requires-Dist: pantomime <1.0.0,>=0.5.1
|
|
33
30
|
Requires-Dist: pytz >=2021.1
|
|
34
31
|
Requires-Dist: rdflib <7.1.0,>=6.2.0
|
|
35
|
-
Requires-Dist: networkx <3.
|
|
32
|
+
Requires-Dist: networkx <3.4,>=2.5
|
|
36
33
|
Requires-Dist: openpyxl <4.0.0,>=3.0.5
|
|
37
34
|
Requires-Dist: orjson <4.0,>=3.7
|
|
38
35
|
Provides-Extra: dev
|
|
@@ -46,6 +43,7 @@ Requires-Dist: pytest-cov ; extra == 'dev'
|
|
|
46
43
|
Requires-Dist: types-PyYAML ; extra == 'dev'
|
|
47
44
|
Requires-Dist: types-requests ; extra == 'dev'
|
|
48
45
|
Requires-Dist: types-setuptools ; extra == 'dev'
|
|
46
|
+
Requires-Dist: types-openpyxl ; extra == 'dev'
|
|
49
47
|
Requires-Dist: flake8 >=2.6.0 ; extra == 'dev'
|
|
50
48
|
Requires-Dist: transifex-client ; extra == 'dev'
|
|
51
49
|
Requires-Dist: responses >=0.9.0 ; extra == 'dev'
|
|
@@ -127,5 +125,3 @@ or `major` arguments.
|
|
|
127
125
|
When the schema is updated, please update the docs, ideally including the
|
|
128
126
|
diagrams. For the RDF namespace and JavaScript version of the model,
|
|
129
127
|
run `make generate`.
|
|
130
|
-
|
|
131
|
-
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
followthemoney/__init__.py,sha256=
|
|
1
|
+
followthemoney/__init__.py,sha256=r3yXZluiZbP17mu2VZIJ5Q9_ItUb_kX81WIMtyWzaK0,360
|
|
2
2
|
followthemoney/compare.py,sha256=1GFkCfTzA8QR0CH90kvySR8hvl9hQRUerW5Xw2Ivmpg,5134
|
|
3
3
|
followthemoney/exc.py,sha256=ynZs_UnTVxHR-iBfat_CpVLraYzVX5yLtVf5Ti14hl4,734
|
|
4
4
|
followthemoney/graph.py,sha256=VNDKrUBkz_-DmKsr5v-Xm8VfxzabnTwkU_MFk92_TjA,10848
|
|
@@ -8,15 +8,15 @@ followthemoney/model.py,sha256=p4Bk0XPi9z7SKZVgG1FqeM2i45xwAlDIkHwyyUcDKk0,6426
|
|
|
8
8
|
followthemoney/namespace.py,sha256=qYplxKn5OO3zDMf3NItKwTwDsJOnski5JbeyhssqhR8,4434
|
|
9
9
|
followthemoney/offshore.py,sha256=Pf0tx-7GyhIZRueshDRqPNlxkHfGstmW5yNDID5Mnws,1060
|
|
10
10
|
followthemoney/ontology.py,sha256=7PEoUKISNpkRvVhuLeE3IE9ZiNtdR8mn9_kzZ9yF9l0,2986
|
|
11
|
-
followthemoney/property.py,sha256=
|
|
12
|
-
followthemoney/proxy.py,sha256=
|
|
11
|
+
followthemoney/property.py,sha256=EXU4kH6rOD9ubmuDXE-3LGc6gwQspW9_NjSacDb4xYA,7494
|
|
12
|
+
followthemoney/proxy.py,sha256=YvnAUWtu_BCsK36N6xTcoI0Ffjn-gIyj-eDVhtsjoLA,20033
|
|
13
13
|
followthemoney/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
followthemoney/rdf.py,sha256=_BzWiBc61UYjiyadvGKya4P4JlJfvZtNrn8SP2hC2JM,328
|
|
15
15
|
followthemoney/schema.py,sha256=Tk61vRmWaawW-1HOmu-hbYZtkD8it0fIvNtSRxBEQxA,16774
|
|
16
16
|
followthemoney/util.py,sha256=ec_n8Q_CVAfN4HkUnOZB6IRbMz-p4XXxxwTm1RzLYV4,4508
|
|
17
17
|
followthemoney/cli/__init__.py,sha256=Fl05wMr5-FlOSMRpmu1HJSNfPRpy8u9as5IRbGXdo4U,421
|
|
18
18
|
followthemoney/cli/aggregate.py,sha256=Gwfi5Bt1LCwqbpsCu4P1Cr-QJtCWhbaqgGEzfwJUUL4,2142
|
|
19
|
-
followthemoney/cli/cli.py,sha256=
|
|
19
|
+
followthemoney/cli/cli.py,sha256=yrPw2iyKY-E-uRWe6KN9W3ayvz-22vfpe_ZeD0RiI0c,3591
|
|
20
20
|
followthemoney/cli/exports.py,sha256=HsTyIOz1KQSeObp9-9SKzSUBW158XOhpU5_Stv_2HWM,4016
|
|
21
21
|
followthemoney/cli/mapping.py,sha256=aEl57en0zu57yMA2AU5y01U5Yyqo_42hkMlAdfIQP08,3284
|
|
22
22
|
followthemoney/cli/sieve.py,sha256=Wh1UQxzyM9Gh60ooS4s4ydlW1b69bMzFM08tg8ttSIY,1940
|
|
@@ -24,26 +24,26 @@ followthemoney/cli/util.py,sha256=CFcS-PEwpMasMWX_Yg283O_PaAhcPwkvahFNWc13C8c,47
|
|
|
24
24
|
followthemoney/export/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
25
|
followthemoney/export/common.py,sha256=_YrXrwsqmyboDZDhtJ_PazUUJYe1Y-Trqc9lz4YlVR8,991
|
|
26
26
|
followthemoney/export/csv.py,sha256=WPAeHMEKnQE1ZL1_I5qgxki-qKJ5gytur-sTOHAubW0,2635
|
|
27
|
-
followthemoney/export/excel.py,sha256
|
|
27
|
+
followthemoney/export/excel.py,sha256=pj6zNpIbye_Zm3vhCamcqHEe9Fw-RyjtWQDCFY6608s,2645
|
|
28
28
|
followthemoney/export/graph.py,sha256=v0z1FgadyFk5aQ0A5q8E9R4fSO-Tpi5JU9YTDwnRKD8,2765
|
|
29
29
|
followthemoney/export/neo4j.py,sha256=JCLb1eW5FFIJXqmnpNMRzRs1KYuYkCtHZp7KJcu-JNY,7104
|
|
30
30
|
followthemoney/export/rdf.py,sha256=E6RiW7oIsJdaBaLAVm6o-MTokARZtqONPuayILqTqo0,786
|
|
31
31
|
followthemoney/mapping/__init__.py,sha256=iwNqzzvrzJNbNDlOCaDLlBTUrNTlnYHIB5cvo_-9oN4,82
|
|
32
32
|
followthemoney/mapping/csv.py,sha256=Tvc6VSh7-ca63LEE4G0yqOCeGMETkuKzUjIkVn4_d7Q,3185
|
|
33
|
-
followthemoney/mapping/entity.py,sha256=
|
|
34
|
-
followthemoney/mapping/property.py,sha256=
|
|
33
|
+
followthemoney/mapping/entity.py,sha256=1Mj6qKkFN10IdElRmULZoqTWIAJ9OSk9wpPpmWBlvA0,5697
|
|
34
|
+
followthemoney/mapping/property.py,sha256=41V16HJh6da7oKdSJWyRcyMkx2XFd6iDm9-4PH7Wihw,5036
|
|
35
35
|
followthemoney/mapping/query.py,sha256=8M6bOlEX2p_bbVwEwTu_1slEtU0cfRJB7ajZp-F07CE,2622
|
|
36
36
|
followthemoney/mapping/source.py,sha256=sri-XpSjeHZbQtqNcz1eJYvwVSBNqGO5JwhWswiEx3c,649
|
|
37
|
-
followthemoney/mapping/sql.py,sha256=
|
|
37
|
+
followthemoney/mapping/sql.py,sha256=m3Ho8B2pFsg6q2zj-y55h0O3x9eb6wzjlPBQyZ6DVcI,4752
|
|
38
38
|
followthemoney/schema/Address.yaml,sha256=xCKyak0qdJC0W5jfROUq6pEMCcSupNSB6GAxx5QfN5E,1689
|
|
39
39
|
followthemoney/schema/Airplane.yaml,sha256=uijTw6-1exomw1clZoDcRvj34mUBmDxNtd6K7nX3XQ4,573
|
|
40
|
-
followthemoney/schema/Analyzable.yaml,sha256=
|
|
40
|
+
followthemoney/schema/Analyzable.yaml,sha256=WvyhjYqI7QzBt3qPDgO7MDasJH1qQtgQMToHkV_xtlU,1237
|
|
41
41
|
followthemoney/schema/Article.yaml,sha256=WI8517oZINSLDmgwJiArWXTjZiK6hY8X3bMlMdwaOn8,260
|
|
42
42
|
followthemoney/schema/Assessment.yaml,sha256=UGxJIIe8xf2ddGWaj0l-ui7KwWwbgRPCEWC3ZFAPrhU,624
|
|
43
43
|
followthemoney/schema/Asset.yaml,sha256=xQhHJJtnGLfiOaUncqGv4JR3Yn7l46yAg7p0hKFAFVE,260
|
|
44
44
|
followthemoney/schema/Associate.yaml,sha256=3u3t5bpDBSQ7p5jyrHTEM0GbhBaG1ar9UKN4uquvq9g,887
|
|
45
45
|
followthemoney/schema/Audio.yaml,sha256=qEoWTw_WrY7EjkztMdRQ-DRA1DZRCreib2HkOlCqKn8,446
|
|
46
|
-
followthemoney/schema/BankAccount.yaml,sha256=
|
|
46
|
+
followthemoney/schema/BankAccount.yaml,sha256=PwQWqEox-MrhBNBRiXLr-P_tJ1qyG3cHtUsUH0QbBZo,1387
|
|
47
47
|
followthemoney/schema/Call.yaml,sha256=kbVCnVxucBrEplxehXHThLSJAJjy_GhWan-IeZZjr0M,980
|
|
48
48
|
followthemoney/schema/CallForTenders.yaml,sha256=2IWonTzfSbrkynMoEWqv5fekUeFM_xDKpKIbRe1XDbo,3227
|
|
49
49
|
followthemoney/schema/Company.yaml,sha256=7dWBPetd7xOJtu8AlhKsjxBYzYBK5E3LssYguSf0glA,3321
|
|
@@ -67,7 +67,7 @@ followthemoney/schema/Identification.yaml,sha256=XVvZXTZZUg8qDzTga8dgF3mJqK9eSDg
|
|
|
67
67
|
followthemoney/schema/Image.yaml,sha256=MMrK4wQJBuN07STwTmsPjXXpYZB7fPt_hQtweSBM4m0,388
|
|
68
68
|
followthemoney/schema/Interest.yaml,sha256=xPYobeuxFMFXUWlQuPvDjAsr3QQDPteRz68_rq7Dvf0,276
|
|
69
69
|
followthemoney/schema/Interval.yaml,sha256=WtmSoBngajhpNLtDZ8Ocpdd0I0tLG-7A4afuHXxssow,1919
|
|
70
|
-
followthemoney/schema/LegalEntity.yaml,sha256=
|
|
70
|
+
followthemoney/schema/LegalEntity.yaml,sha256=p_ty9cXsv8f7TTuz644R5SEmVePW-Gbp0ZrHgCgDIyk,3645
|
|
71
71
|
followthemoney/schema/License.yaml,sha256=9Ye5vGEBhi7ttGqf0DdAGCJCN3zz5HtGu52dCcmCsQk,452
|
|
72
72
|
followthemoney/schema/Membership.yaml,sha256=TzU1A-hPVXRJcNkC78N-EPhZ_qUgO14IZ8lB9WQ63AM,696
|
|
73
73
|
followthemoney/schema/Mention.yaml,sha256=nBeulR_Jm4x75aJ7yNF0TAVhHJqXQaEzOutLIn_YU-4,1086
|
|
@@ -81,7 +81,7 @@ followthemoney/schema/Page.yaml,sha256=sQt_CnVyjDVGVECLQoGYZH4hxpjdPhxVRz4XJW-_1
|
|
|
81
81
|
followthemoney/schema/Pages.yaml,sha256=deUgHFxgC_lmfRon9K6JlCyfJ-5WdoTmLiU_lr393u0,444
|
|
82
82
|
followthemoney/schema/Passport.yaml,sha256=VkGMSJ2rG3_trME4wci45qmk1f_NUHYOn2YoLzrdre0,730
|
|
83
83
|
followthemoney/schema/Payment.yaml,sha256=WRBJuj9ljsxLBs-0g9Z9UD87uR1RTtuUiYnWOnKr1qA,1757
|
|
84
|
-
followthemoney/schema/Person.yaml,sha256=
|
|
84
|
+
followthemoney/schema/Person.yaml,sha256=N4qaVSwDs1V3fzTYTMwg57wOlgbkjaeZuPn0QbYICG8,1886
|
|
85
85
|
followthemoney/schema/PlainText.yaml,sha256=AYShjP5T_YUQypeAGJT7qdXbhBT_KahBKnwoypAqcjQ,272
|
|
86
86
|
followthemoney/schema/Position.yaml,sha256=k5xdmowJfxR-A93aWMqZ1Z3EuEHsTwvXefKyy0K9DtU,1303
|
|
87
87
|
followthemoney/schema/Post.yaml,sha256=NRn3NZpcDUmFW-uUQP8YAYOMYpWirD7-wrljETNh-lA,1029
|
|
@@ -91,12 +91,12 @@ followthemoney/schema/PublicBody.yaml,sha256=QqL_awWLLabrgLo4gUqY99BCmeqz_h16Unr
|
|
|
91
91
|
followthemoney/schema/RealEstate.yaml,sha256=R_KiyvfKRYgmkZUfmo8ANQUJNi-zIfdc34gQhTgn_3A,1357
|
|
92
92
|
followthemoney/schema/Representation.yaml,sha256=gSLx9nc63PgJ8UjR8MpIwzwBm-dvRTgW5vnLPcm4H_0,778
|
|
93
93
|
followthemoney/schema/Sanction.yaml,sha256=3q4Xo8xHU03hjWTDypJe_fVIboSa6D8KOurjxzNGSao,931
|
|
94
|
-
followthemoney/schema/Security.yaml,sha256=
|
|
94
|
+
followthemoney/schema/Security.yaml,sha256=Ix8yCF5sm6JQzitZR7bKb5_P48RNaW1PAF6FDot-ks8,1120
|
|
95
95
|
followthemoney/schema/Similar.yaml,sha256=gD8rZEaPQWzU-rEfsKdn62uEucF3KxYBcPMoSdnxvME,817
|
|
96
96
|
followthemoney/schema/Succession.yaml,sha256=cwz1CwPl8btfUEpmr1YxF6T2WQQuLUboaW9EVEuW2Ng,735
|
|
97
97
|
followthemoney/schema/Table.yaml,sha256=VcgOA2wcczHhRCwObIO39yStoMuoPZYE0VlXrAH9xCQ,635
|
|
98
98
|
followthemoney/schema/TaxRoll.yaml,sha256=5DXK_rkJimpy2ZLjxx2RntYiGPXiK8Iiphr6cJjUiag,740
|
|
99
|
-
followthemoney/schema/Thing.yaml,sha256=
|
|
99
|
+
followthemoney/schema/Thing.yaml,sha256=72gInrI4VEWxUcld7w4by1QPI46F-NR8QZJ09JyUcnc,2438
|
|
100
100
|
followthemoney/schema/Trip.yaml,sha256=nLQD_ApmVJ8D56Czl7K700hhNZjzFV9FOQ3NBSQDLiM,771
|
|
101
101
|
followthemoney/schema/UnknownLink.yaml,sha256=a7BUbNbrsGylewJGg2fcSody_Kmt4eEw_IKIvgHIt8c,668
|
|
102
102
|
followthemoney/schema/UserAccount.yaml,sha256=V1JWwwcggCO4G9ByJY9zlQ0uOVp8HQK2mRXwqaGJnBM,763
|
|
@@ -125,31 +125,31 @@ followthemoney/translations/pt_BR/LC_MESSAGES/followthemoney.mo,sha256=wes82jLA_
|
|
|
125
125
|
followthemoney/translations/pt_BR/LC_MESSAGES/followthemoney.po,sha256=sSj8Mfu8Oq0m-RF_quETKl4f5zMYtJOYGof4-qff8bE,89847
|
|
126
126
|
followthemoney/translations/ru/followthemoney.po,sha256=SgrP3BfjgAp8e4Y9htH7Il2tqGuzy8YXoAqzyQl12Ko,130621
|
|
127
127
|
followthemoney/translations/ru/LC_MESSAGES/followthemoney.mo,sha256=K30zowxjvE3UzoO1eXG8qTTL5XeSPkdwCMTmVDXDG68,64182
|
|
128
|
-
followthemoney/translations/ru/LC_MESSAGES/followthemoney.po,sha256=
|
|
128
|
+
followthemoney/translations/ru/LC_MESSAGES/followthemoney.po,sha256=Gva5A2VXKfFboAtQc313CJ1SGNmjhsLZiQCwf-1ZVt8,139453
|
|
129
129
|
followthemoney/translations/tr/LC_MESSAGES/followthemoney.mo,sha256=3h8kg6ryzuV2xmcG6_I0HtS1atddTmIvkeuU3bJcH14,487
|
|
130
130
|
followthemoney/translations/tr/LC_MESSAGES/followthemoney.po,sha256=2yqoZ4vXTpxcSEPwSlF29cXpo3ou4CgaOhIcaalswvA,89829
|
|
131
|
-
followthemoney/types/__init__.py,sha256=
|
|
131
|
+
followthemoney/types/__init__.py,sha256=X9XeM6JktzirAw5gGkyDKGM70NuiJ9Tbjoq0IwVclxU,1745
|
|
132
132
|
followthemoney/types/address.py,sha256=P6ctzojJks70RZIwk5Bhc9djxejZo4Te0m5pQ9M7bAM,1651
|
|
133
133
|
followthemoney/types/checksum.py,sha256=2KLOoZiYUnkButMl_Q8_I4Ju7qfQX8PcdoyzwOf-Aj4,917
|
|
134
|
-
followthemoney/types/common.py,sha256=
|
|
134
|
+
followthemoney/types/common.py,sha256=qPVj-jrDMEASWFYjl02NXoDO6lfPRQxE6dERLt_dmu8,9809
|
|
135
135
|
followthemoney/types/country.py,sha256=1fAwIc8gqmP004Y22uILLJxBD3m552MoDwaEMGOD58o,3053
|
|
136
|
-
followthemoney/types/date.py,sha256=
|
|
137
|
-
followthemoney/types/email.py,sha256=
|
|
138
|
-
followthemoney/types/entity.py,sha256=
|
|
136
|
+
followthemoney/types/date.py,sha256=XWFSKPJLpo8JSfcleyaEXih0q65ydf_d42Y_rcWZ-3s,2663
|
|
137
|
+
followthemoney/types/email.py,sha256=zAnMHwC_FZh7IagpDRhGZf-GfQR6uW8d-lZP4UCdGcM,2745
|
|
138
|
+
followthemoney/types/entity.py,sha256=RCDD9j7MWA_dd0Ib33dl1E6PubsiS1yfVeIOsDxWYpY,2431
|
|
139
139
|
followthemoney/types/gender.py,sha256=N1xghyYtb4WZh8s3ogF9kDTRtx367o3gRZWbG30QGI8,1800
|
|
140
|
-
followthemoney/types/iban.py,sha256=
|
|
141
|
-
followthemoney/types/identifier.py,sha256=
|
|
142
|
-
followthemoney/types/ip.py,sha256=
|
|
140
|
+
followthemoney/types/iban.py,sha256=C8GdfIdDl8Ip89VsZ_hk6v3tJUrRgab_wFLo9ff2lYo,1763
|
|
141
|
+
followthemoney/types/identifier.py,sha256=tX-XepAPreP6u4dzMKyy5mp507NH71DdByYA7pXyKrw,2016
|
|
142
|
+
followthemoney/types/ip.py,sha256=Z4s8mIlY5-IK9Oo13_YbL9lMQpY8SE_NAz0eqaonaYo,1392
|
|
143
143
|
followthemoney/types/json.py,sha256=Hefwns1-ziJf310MWvdfX5ICkOgj9cnnMJuqq1e6qKY,1676
|
|
144
|
-
followthemoney/types/language.py,sha256=
|
|
145
|
-
followthemoney/types/mimetype.py,sha256=
|
|
146
|
-
followthemoney/types/name.py,sha256=
|
|
144
|
+
followthemoney/types/language.py,sha256=4GT8_kqCwq4tOs7s9TffM7SSr9AaszAQsNJHK27fqVY,2612
|
|
145
|
+
followthemoney/types/mimetype.py,sha256=EZ5hIdn-wosfLc-GjXDaOzevxaSXPbSPHDUJmPT1h0I,1355
|
|
146
|
+
followthemoney/types/name.py,sha256=EbdHQz08qXYJk2DRqtQ4cbYasDuPHWAVziJ-MyrsBLI,1864
|
|
147
147
|
followthemoney/types/number.py,sha256=9l5v3hcAoJ4V6jaBS_-Kc1gtdJlQrY9L98ElC5e_PLQ,943
|
|
148
|
-
followthemoney/types/phone.py,sha256=
|
|
148
|
+
followthemoney/types/phone.py,sha256=cppWyfZfOFZoGNjjqpMuTgxSgC1j5JFMpPHMHZYvoDQ,4020
|
|
149
149
|
followthemoney/types/registry.py,sha256=hvQ1oIWz_4PpyUnKA5azbaZCulNb5LCIPyC-AQYVVyw,1936
|
|
150
150
|
followthemoney/types/string.py,sha256=paSCnFt9TJrCmelmw5-OiwCBu0rkqNh6iauteJIj26k,1130
|
|
151
|
-
followthemoney/types/topic.py,sha256=
|
|
152
|
-
followthemoney/types/url.py,sha256=
|
|
151
|
+
followthemoney/types/topic.py,sha256=6kIXdlZNeE28MPbRXaDhSI1whNA7tpkTgFwU_o_gxds,3625
|
|
152
|
+
followthemoney/types/url.py,sha256=6p3ctjh0S_VciPLYuyMPwvK9147rpkhWDd4f2kahe10,1470
|
|
153
153
|
tests/export/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
154
154
|
tests/export/test_csv.py,sha256=r0ACsWnGdLHIZgXvbshGBQ9An0v1dJGAWulRT-Xittc,1261
|
|
155
155
|
tests/export/test_excel.py,sha256=ShLtaJ1-zgq-1rzbNoGJp1bVbRKZ-HcGtU8oJpKwjjY,1696
|
|
@@ -162,25 +162,25 @@ tests/types/test_addresses.py,sha256=49L67aGIJS8CjwZI1I3DwD_MEtV_ALG-syAIuQHYAbE
|
|
|
162
162
|
tests/types/test_checksum.py,sha256=eKJ5enVvS8TdhL8GnhtqhwTwpvih8ndOtnv4zLfNCws,216
|
|
163
163
|
tests/types/test_common.py,sha256=PCaewAF2x08M4Jv7YEPxaSoSLpci6LzKShOqYIB1xH0,673
|
|
164
164
|
tests/types/test_countries.py,sha256=LiIiDQsrYIFQnD7Z_fwIlLkjyX1p23yVxqdpi3-7tDU,1132
|
|
165
|
-
tests/types/test_dates.py,sha256
|
|
165
|
+
tests/types/test_dates.py,sha256=-S0WOSVPdz93iMgaZ5QCEfe7FOmvFvrL44hcdg9VBDM,3774
|
|
166
166
|
tests/types/test_emails.py,sha256=8CyyedWe--wlbEZ7lQVVLw75pjIcI6ZpeTFUFPqxPg8,1606
|
|
167
167
|
tests/types/test_entity.py,sha256=Jf7LarSILlgdWUV7bmXIQM8yh1YgCkSkrp0rFenduto,819
|
|
168
|
-
tests/types/test_iban.py,sha256=
|
|
169
|
-
tests/types/test_identifiers.py,sha256=
|
|
168
|
+
tests/types/test_iban.py,sha256=4gj9NUPMgKAfB4V3NZpua-c7Q5MSOokQVg4gZGl_SmM,6510
|
|
169
|
+
tests/types/test_identifiers.py,sha256=yP7iv5KdVbNA_iSfVb6MpbpcUAoE2ZJDxmf49lMOFFY,6472
|
|
170
170
|
tests/types/test_ip.py,sha256=lHRqT-MyPWTgtfnWisFm7N5n6TncebDp2ZEiEBIsYBM,1043
|
|
171
171
|
tests/types/test_json.py,sha256=wOTW8wDwfSd2uOok40b7Y2pZKeZnayMVI6wX3hvYjgs,772
|
|
172
172
|
tests/types/test_languages.py,sha256=gWxkmpf48R7Yfk2o41KGkrYrAjA-ew8Rwa4TDHunqmc,947
|
|
173
173
|
tests/types/test_mimetypes.py,sha256=YYIFKJU4DhP6JMyP_sNmtLpsQnOOiZ_rJkIeJ5cgtAk,445
|
|
174
|
-
tests/types/test_names.py,sha256=
|
|
174
|
+
tests/types/test_names.py,sha256=zFgEojnNWbXgkFiB2YdjL1o8-UiMrJxAMaP9XwFVLvY,1060
|
|
175
175
|
tests/types/test_number.py,sha256=uIoKq1aEYuxzRxI0oB30yJnd9oxPJ0r03AWba9AIgFg,474
|
|
176
176
|
tests/types/test_phones.py,sha256=_GTl-0r5hok8ovUJPRqP7k9kJYMVbanjYUMLrbzFb5U,1196
|
|
177
177
|
tests/types/test_registry.py,sha256=IkrHjrEiIIPd4PdMFUg_jVh_gsE6CzGXIF8s3LIbnl0,296
|
|
178
178
|
tests/types/test_topic.py,sha256=m35GSwTy-r77YACGDDac09nYLBIUua42Dy7z292m9EU,707
|
|
179
179
|
tests/types/test_urls.py,sha256=JVmzJ0DKDBle_xLjmOHn0hgDTCpLmljrcfbOM1GSGRw,1170
|
|
180
|
-
followthemoney-3.
|
|
181
|
-
followthemoney-3.
|
|
182
|
-
followthemoney-3.
|
|
183
|
-
followthemoney-3.
|
|
184
|
-
followthemoney-3.
|
|
185
|
-
followthemoney-3.
|
|
186
|
-
followthemoney-3.
|
|
180
|
+
followthemoney-3.6.0.dist-info/LICENSE,sha256=Jln3uF70A9AQySyrP9JAW6sQTubLoKVQunvuJqISv7w,1098
|
|
181
|
+
followthemoney-3.6.0.dist-info/METADATA,sha256=WO2TZ3GZpkAnhwWOT8LYGaQJjbFIJQVEQc1c6HeBxRc,4494
|
|
182
|
+
followthemoney-3.6.0.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
|
|
183
|
+
followthemoney-3.6.0.dist-info/entry_points.txt,sha256=wpgi-5-jyqCy-yw0eYZbnhBuPja_q3RJmiEl7NymXtQ,593
|
|
184
|
+
followthemoney-3.6.0.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
185
|
+
followthemoney-3.6.0.dist-info/top_level.txt,sha256=O33_kGPehy6-69B_k01UgMK55_JOhwqe2de7ND23b-Y,21
|
|
186
|
+
followthemoney-3.6.0.dist-info/RECORD,,
|
tests/types/test_dates.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import unittest
|
|
3
|
-
from datetime import datetime
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
4
|
|
|
5
5
|
from followthemoney.types import registry
|
|
6
6
|
|
|
@@ -15,7 +15,7 @@ class DatesTest(unittest.TestCase):
|
|
|
15
15
|
self.assertTrue(dates.validate("2017-04-04T10:30:29+0200"))
|
|
16
16
|
self.assertTrue(dates.validate("2017-04-04T10:30:29+03:00"))
|
|
17
17
|
self.assertTrue(dates.validate("2017-04-04T10:30:29-04:00"))
|
|
18
|
-
self.assertTrue(dates.validate(datetime.
|
|
18
|
+
self.assertTrue(dates.validate(datetime.now(timezone.utc).isoformat()))
|
|
19
19
|
self.assertFalse(dates.validate("01-02-2003"))
|
|
20
20
|
self.assertFalse(dates.validate("Thursday 21 March 2017"))
|
|
21
21
|
|
|
@@ -46,13 +46,13 @@ class DatesTest(unittest.TestCase):
|
|
|
46
46
|
self.assertEqual(dates.clean("2017-5-2T10:00:00"), "2017-05-02T10:00:00")
|
|
47
47
|
|
|
48
48
|
def test_convert_datetime(self):
|
|
49
|
-
dt = datetime.
|
|
49
|
+
dt = datetime.now(timezone.utc)
|
|
50
50
|
iso, _ = dt.isoformat().split(".", 1)
|
|
51
51
|
self.assertEqual(dates.clean(dt), iso)
|
|
52
52
|
self.assertTrue(dates.validate(iso))
|
|
53
53
|
|
|
54
|
-
dt = datetime.
|
|
55
|
-
iso = dt.isoformat()
|
|
54
|
+
dt = datetime.now(timezone.utc)
|
|
55
|
+
iso = dt.isoformat()[:19]
|
|
56
56
|
self.assertEqual(dates.clean(dt), iso)
|
|
57
57
|
|
|
58
58
|
def test_parse_date(self):
|
tests/types/test_iban.py
CHANGED
|
@@ -15,6 +15,7 @@ class IbansTest(unittest.TestCase):
|
|
|
15
15
|
rdf = ibans.rdf("GB29NWBK60161331926819")
|
|
16
16
|
assert "iban:GB29NWBK60161331926819" in rdf
|
|
17
17
|
nid = ibans.node_id("gb29NWBK60161331926819")
|
|
18
|
+
assert nid is not None
|
|
18
19
|
assert "iban:GB" in nid
|
|
19
20
|
|
|
20
21
|
def test_domain_validity(self):
|
|
@@ -22,7 +23,7 @@ class IbansTest(unittest.TestCase):
|
|
|
22
23
|
self.assertTrue(ibans.validate("GB29NWBK60161331926819"))
|
|
23
24
|
self.assertFalse(ibans.validate("GB28 NWBK 6016 1331 9268 19"))
|
|
24
25
|
self.assertFalse(ibans.validate("GB29NWBKN0161331926819"))
|
|
25
|
-
self.assertFalse(ibans.validate(
|
|
26
|
+
self.assertFalse(ibans.validate(""))
|
|
26
27
|
self.assertTrue(ibans.validate("AL35202111090000000001234567"))
|
|
27
28
|
self.assertTrue(ibans.validate("AD1400080001001234567890"))
|
|
28
29
|
self.assertTrue(ibans.validate("AT483200000012345864"))
|