From d9aa35c57445a6b140df3ed042ddafb22ad98ed2 Mon Sep 17 00:00:00 2001 From: Leandro Regueiro Date: Tue, 6 Sep 2022 19:50:07 +0200 Subject: [PATCH 1/4] get_cc_module: Explicitly return None --- stdnum/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdnum/util.py b/stdnum/util.py index 11b58dd7..6c9571d1 100644 --- a/stdnum/util.py +++ b/stdnum/util.py @@ -237,7 +237,7 @@ def get_cc_module(cc, name): mod = __import__('stdnum.%s' % cc, globals(), locals(), [str(name)]) return getattr(mod, name, None) except ImportError: - return + return None # this is a cache of SOAP clients From abb8f9666059a525541f162d86adf2dc0bb4fc11 Mon Sep 17 00:00:00 2001 From: Leandro Regueiro Date: Tue, 6 Sep 2022 19:42:36 +0200 Subject: [PATCH 2/4] vatin: Compile regex for faster performance --- stdnum/vatin.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/stdnum/vatin.py b/stdnum/vatin.py index a8553d2c..1b3e68e0 100644 --- a/stdnum/vatin.py +++ b/stdnum/vatin.py @@ -53,6 +53,10 @@ from stdnum.util import clean, get_cc_module +# regular expression for matching country codes. +_country_code_re = re.compile(r'^[a-z]{2}$') + + # Cache of country code modules _country_modules = dict() @@ -61,7 +65,7 @@ def _get_cc_module(cc): """Get the VAT number module based on the country code.""" # Greece uses a "wrong" country code, special case for Northern Ireland cc = cc.lower().replace('el', 'gr').replace('xi', 'gb') - if not re.match(r'^[a-z]{2}$', cc): + if not _country_code_re.match(cc): raise InvalidFormat() if cc not in _country_modules: _country_modules[cc] = get_cc_module(cc, 'vat') From 470ecbaac48de7c3cc858ffdf271ca89b2da1b87 Mon Sep 17 00:00:00 2001 From: Leandro Regueiro Date: Tue, 6 Sep 2022 20:00:36 +0200 Subject: [PATCH 3/4] vatin: Add a few more tests for is_valid --- tests/test_vatin.doctest | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/test_vatin.doctest b/tests/test_vatin.doctest index 4d785c31..44dc38df 100644 --- a/tests/test_vatin.doctest +++ b/tests/test_vatin.doctest @@ -78,3 +78,21 @@ InvalidComponent: ... Traceback (most recent call last): ... InvalidComponent: ... + + +Check is_valid for several scenarios: + +>>> vatin.is_valid('FR 40 303 265 045') +True +>>> vatin.is_valid('FR 40 303') +False +>>> vatin.is_valid('FR') +False +>>> vatin.is_valid('') +False +>>> vatin.is_valid('00') +False +>>> vatin.is_valid('XX') +False +>>> vatin.is_valid('US') +False From c1cb6133b2f30af5b11b63ebc10d23d4812a438d Mon Sep 17 00:00:00 2001 From: Leandro Regueiro Date: Tue, 6 Sep 2022 19:55:28 +0200 Subject: [PATCH 4/4] vatin: Use more generic exception instead of ValidationError children --- stdnum/vatin.py | 8 +++++--- tests/test_vatin.doctest | 8 ++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/stdnum/vatin.py b/stdnum/vatin.py index 1b3e68e0..5a5bdb58 100644 --- a/stdnum/vatin.py +++ b/stdnum/vatin.py @@ -44,7 +44,7 @@ >>> validate('XX') Traceback (most recent call last): ... -InvalidComponent: ... +ImportError: ... """ import re @@ -66,11 +66,11 @@ def _get_cc_module(cc): # Greece uses a "wrong" country code, special case for Northern Ireland cc = cc.lower().replace('el', 'gr').replace('xi', 'gb') if not _country_code_re.match(cc): - raise InvalidFormat() + raise ImportError() if cc not in _country_modules: _country_modules[cc] = get_cc_module(cc, 'vat') if not _country_modules[cc]: - raise InvalidComponent() # unknown/unsupported country code + raise ImportError() return _country_modules[cc] @@ -98,5 +98,7 @@ def is_valid(number): """Check if the number is a valid VAT number.""" try: return bool(validate(number)) + except ImportError: + return False except ValidationError: return False diff --git a/tests/test_vatin.doctest b/tests/test_vatin.doctest index 44dc38df..f0d9e0ba 100644 --- a/tests/test_vatin.doctest +++ b/tests/test_vatin.doctest @@ -61,11 +61,11 @@ Try validating not specifying a country: >>> vatin.validate('') Traceback (most recent call last): ... -InvalidFormat: ... +ImportError: ... >>> vatin.validate('00') Traceback (most recent call last): ... -InvalidFormat: ... +ImportError: ... Try to validate for countries with no VAT validation: @@ -73,11 +73,11 @@ Try to validate for countries with no VAT validation: >>> vatin.validate('XX') Traceback (most recent call last): ... -InvalidComponent: ... +ImportError: ... >>> vatin.validate('US') Traceback (most recent call last): ... -InvalidComponent: ... +ImportError: ... Check is_valid for several scenarios: