diff --git a/fin_defs/__init__.py b/fin_defs/__init__.py index f31883c..bf2e80e 100644 --- a/fin_defs/__init__.py +++ b/fin_defs/__init__.py @@ -17,7 +17,6 @@ Defined hierarchy: """ from ._version import __version__ - from .data import * __all__ = [ @@ -27,4 +26,3 @@ __all__ = [ 'StockExchange', '__version__', ] - diff --git a/fin_defs/data.py b/fin_defs/data.py index ac77ce7..bf2be56 100644 --- a/fin_defs/data.py +++ b/fin_defs/data.py @@ -5,6 +5,7 @@ import re from collections.abc import Mapping from decimal import Decimal + def parse_id_attr_key_value_pair(attr_datum: str) -> tuple[str, str | int] | None: attr_datum = attr_datum.strip() if attr_datum == '': diff --git a/fin_defs/parse_price.py b/fin_defs/parse_price.py index 509783e..c9dd2a0 100644 --- a/fin_defs/parse_price.py +++ b/fin_defs/parse_price.py @@ -2,7 +2,13 @@ import logging import re from decimal import Decimal -from .data import DKK, USD, Asset, AssetAmount, FiatCurrency, CURRENCY_CODES, CURRENCY_SYMBOLS +from .data import ( + CURRENCY_CODES, + CURRENCY_SYMBOLS, + Asset, + AssetAmount, + FiatCurrency, +) logger = logging.getLogger(__name__) @@ -29,33 +35,40 @@ RE_CURRENCY_SYMBOLS = ( r'(?P[' + ''.join(re.escape(c) for c in CURRENCY_SYMBOLS.values()) + '])' ) -RE_SYM_AMOUNT_CODE = re.compile(RE_CURRENCY_SYMBOLS - + r'\s*' - + RE_PRODUCT_PRICE_AMOUNT - + r'(?:\s+' - + RE_CURRENCY_CODES - + r')?', flags=re.IGNORECASE) +RE_SYM_AMOUNT_CODE = re.compile( + RE_CURRENCY_SYMBOLS + + r'\s*' + + RE_PRODUCT_PRICE_AMOUNT + + r'(?:\s+' + + RE_CURRENCY_CODES + + r')?', + flags=re.IGNORECASE, +) RE_AMOUNT_SYM_CODE = re.compile( - RE_PRODUCT_PRICE_AMOUNT - + r'\s*' - + RE_CURRENCY_SYMBOLS - + r'(?:\s+' - + RE_CURRENCY_CODES - + ')?' - , flags=re.IGNORECASE) + RE_PRODUCT_PRICE_AMOUNT + + r'\s*' + + RE_CURRENCY_SYMBOLS + + r'(?:\s+' + + RE_CURRENCY_CODES + + ')?', + flags=re.IGNORECASE, +) RE_AMOUNT_CODE = re.compile( - RE_PRODUCT_PRICE_AMOUNT + r'\s+' + RE_CURRENCY_CODES - , flags=re.IGNORECASE) + RE_PRODUCT_PRICE_AMOUNT + r'\s+' + RE_CURRENCY_CODES, + flags=re.IGNORECASE, +) RE_KR_AMOUNT = re.compile( - r'kr\.?\s*(' + RE_PRODUCT_PRICE_AMOUNT + ')', - flags=re.IGNORECASE) + r'kr\.?\s*(' + RE_PRODUCT_PRICE_AMOUNT + ')', + flags=re.IGNORECASE, +) -RE_AMOUNT_KR= re.compile( - '(' + RE_PRODUCT_PRICE_AMOUNT + r')\s*kr\.?', - flags=re.IGNORECASE) +RE_AMOUNT_KR = re.compile( + '(' + RE_PRODUCT_PRICE_AMOUNT + r')\s*kr\.?', + flags=re.IGNORECASE, +) def parse_price(text: str, default_currency: Asset) -> AssetAmount | None: @@ -84,6 +97,8 @@ def parse_price(text: str, default_currency: Asset) -> AssetAmount | None: else: return None - currency = CURRENCY_CODES[code.upper()] if code else FiatCurrency.from_currency_symbol(sym) + currency = ( + CURRENCY_CODES[code.upper()] if code else FiatCurrency.from_currency_symbol(sym) + ) assert currency is not None return AssetAmount(currency, parse_amount(amount_text)) diff --git a/setup.py b/setup.py index 6338b36..4583e88 100644 --- a/setup.py +++ b/setup.py @@ -30,6 +30,7 @@ Defined hierarchy: PACKAGE_DESCRIPTION_SHORT = """ Python library defining base types for financial processing.""".strip() + def parse_version_file(text: str) -> str: match = re.match(r'^__version__\s*=\s*(["\'])([\d\.]+)\1$', text) if match is None: @@ -37,6 +38,7 @@ def parse_version_file(text: str) -> str: raise Exception(msg) return match.group(2) + with open(PACKAGE_NAME + '/_version.py') as f: version = parse_version_file(f.read()) diff --git a/test/test_parse_price.py b/test/test_parse_price.py index fa39886..92ebfe9 100644 --- a/test/test_parse_price.py +++ b/test/test_parse_price.py @@ -1,11 +1,15 @@ -import pytest from decimal import Decimal + +import pytest + from fin_defs import DKK, USD, AssetAmount, FiatCurrency from fin_defs.parse_price import parse_price + def dkk(amount): return AssetAmount(DKK, Decimal(amount)) + PRICES_PARSABLE = [ ('DKK100', dkk(100)), ('100;-', dkk(100)), @@ -23,14 +27,16 @@ PRICES_PARSABLE = [ ] PRICES_UNPARSABLE = [ - '007', + '007', ] + @pytest.mark.parametrize(('price_string', 'parsed_amount'), PRICES_PARSABLE) def test_parse_price(price_string: str, parsed_amount: AssetAmount): result = parse_price(price_string, FiatCurrency.JPY) assert result == parsed_amount + @pytest.mark.parametrize('price_string', PRICES_UNPARSABLE) def test_parse_unparsable(price_string: str): assert parse_price(price_string, USD) is None @@ -39,6 +45,7 @@ def test_parse_unparsable(price_string: str): def parse_asset_amount(text: str) -> AssetAmount: return parse_price(text, FiatCurrency.JPY) + def test_parse_asset_amount_dkk(): assert parse_asset_amount('1338 DKK').amount == 1338 assert parse_asset_amount('1338,00 DKK').amount == 1338 @@ -54,10 +61,10 @@ def test_parse_asset_amount_dkk(): assert parse_asset_amount('kr. 825.00').amount == 825 assert parse_asset_amount('kr. 825.00').asset == DKK + def test_parse_asset_amount_usd(): assert parse_asset_amount('$99').amount == 99 assert parse_asset_amount('$99').asset == USD assert parse_asset_amount('99$ USD').amount == 99 assert parse_asset_amount('99$ USD').asset == USD -