From 5f0f33b3cea5ec9587c0a8482f420e3936863761 Mon Sep 17 00:00:00 2001 From: blais Date: Sun, 16 Jun 2024 15:57:25 -0400 Subject: [PATCH] Created pyproject.toml to create PyPI release. --- beanprice/price.py | 2 - beanprice/sources/coincap.py | 2 +- beanprice/sources/ratesapi_test.py | 4 +- beanprice/sources/tsp.py | 6 +-- beanprice/sources/yahoo.py | 8 ++- beanprice/sources/yahoo_test.py | 4 +- pyproject.toml | 85 ++++++++++++++++++++++++++++++ 7 files changed, 99 insertions(+), 12 deletions(-) create mode 100644 pyproject.toml diff --git a/beanprice/price.py b/beanprice/price.py index 38fb04a..8ac3871 100644 --- a/beanprice/price.py +++ b/beanprice/price.py @@ -388,8 +388,6 @@ def get_price_jobs_up_to_date(entries, # Look at both latest prices and start dates. lifetimes_map = lifetimes.get_commodity_lifetimes(entries) commodity_map = getters.get_commodity_directives(entries) - price_start_dates = {} - stale_currencies = set() if inactive: for base_quote in currencies: diff --git a/beanprice/sources/coincap.py b/beanprice/sources/coincap.py index 50fb98b..e9e66d3 100644 --- a/beanprice/sources/coincap.py +++ b/beanprice/sources/coincap.py @@ -114,7 +114,7 @@ def get_historical_price(self, ticker: str, time + datetime.timedelta(days=-1), time + datetime.timedelta(days=1)): - if not datapoint.time is None and datapoint.time.date() == time.date(): + if datapoint.time is not None and datapoint.time.date() == time.date(): return datapoint return None diff --git a/beanprice/sources/ratesapi_test.py b/beanprice/sources/ratesapi_test.py index 046af80..96718f4 100644 --- a/beanprice/sources/ratesapi_test.py +++ b/beanprice/sources/ratesapi_test.py @@ -23,12 +23,12 @@ def response(contents, status_code=requests.codes.ok): class RatesapiPriceFetcher(unittest.TestCase): def test_error_invalid_ticker(self): - with self.assertRaises(ValueError) as exc: + with self.assertRaises(ValueError): ratesapi.Source().get_latest_price('INVALID') def test_error_network(self): with response('Foobar', 404): - with self.assertRaises(ValueError) as exc: + with self.assertRaises(ValueError): ratesapi.Source().get_latest_price('EUR-CHF') def test_valid_response(self): diff --git a/beanprice/sources/tsp.py b/beanprice/sources/tsp.py index 514d5d6..9430529 100644 --- a/beanprice/sources/tsp.py +++ b/beanprice/sources/tsp.py @@ -45,7 +45,8 @@ csv.register_dialect('tsp', delimiter=',', quoting=csv.QUOTE_NONE, - quotechar='', + # NOTE(blais): This fails to import in 3.12 (and perhaps before). + # quotechar='', lineterminator='\n') class TSPError(ValueError): @@ -120,7 +121,6 @@ def get_historical_price(self, fund, time): "\n\t".join(TSP_FUND_NAMES))) url = "https://secure.tsp.gov/components/CORS/getSharePricesRaw.html" - fields = ['startdate', 'enddate', 'download', 'Lfunds', 'InvFunds'] payload = { # Grabbing the last fourteen days of data in event the markets were closed. 'startdate' : (time - datetime.timedelta(days=14)).strftime("%Y%m%d"), @@ -132,7 +132,7 @@ def get_historical_price(self, fund, time): response = requests.get(url, params=payload) result = parse_response(response) - trade_day = list(result.items())[0] + trade_day = next(iter(result.items())) prices = trade_day[1] try: diff --git a/beanprice/sources/yahoo.py b/beanprice/sources/yahoo.py index 6f0fd9c..9e327f2 100644 --- a/beanprice/sources/yahoo.py +++ b/beanprice/sources/yahoo.py @@ -114,8 +114,12 @@ def get_latest_price(self, ticker: str) -> Optional[source.SourcePrice]: """See contract in beanprice.source.Source.""" session = requests.Session() - session.headers.update({'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/110.0'}) - session.get('https://fc.yahoo.com') # This populates the correct cookies in the session + session.headers.update({ + 'User-Agent': + 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/110.0' + }) + # This populates the correct cookies in the session + session.get('https://fc.yahoo.com') crumb = session.get('https://query1.finance.yahoo.com/v1/test/getcrumb').text url = "https://query1.finance.yahoo.com/v7/finance/quote" diff --git a/beanprice/sources/yahoo_test.py b/beanprice/sources/yahoo_test.py index e5d34af..485c1c0 100644 --- a/beanprice/sources/yahoo_test.py +++ b/beanprice/sources/yahoo_test.py @@ -193,7 +193,7 @@ def test_parse_response_no_timestamp(self): """)) with self.assertRaises(yahoo.YahooError): with mock.patch('requests.get', return_value=response): - srcprice = yahoo.Source().get_historical_price( + _ = yahoo.Source().get_historical_price( 'XSP.TO', datetime.datetime(2017, 11, 1, 16, 0, 0, tzinfo=tz.tzutc())) @@ -230,7 +230,7 @@ def test_parse_null_prices_in_series(self): with mock.patch('requests.get', return_value=response): srcprice = yahoo.Source().get_historical_price( - 'XSP.TO', datetime.datetime(2022, 2, 28, 16, 0, 0, tzinfo=tz.tzutc())) + 'XSP.TO', datetime.datetime(2022, 2, 28, 16, 0, 0, tzinfo=tz.tzutc())) self.assertTrue(isinstance(srcprice.price, Decimal)) self.assertEqual(Decimal('9.6899995803833'), srcprice.price) timezone = datetime.timezone(datetime.timedelta(hours=-5), 'America/New_York') diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..881543c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,85 @@ +[build-system] +requires = ['setuptools'] +build-backend = 'setuptools.build_meta' + +[project] +name = 'beanprice' +version = '1.2.0' +description = 'Price quotes fetcher for Beancount' +license = { file = 'COPYING' } +readme = 'README.md' +authors = [ + { name = 'Martin Blais', email = 'blais@furius.ca' }, +] +maintainers = [ + { name = 'Martin Blais', email = 'blais@furius.ca' }, +] +keywords = [ + 'accounting', 'ledger', 'beancount', 'price' +] +classifiers = [ + 'License :: OSI Approved :: GNU General Public License v2 (GPLv2)', + 'Programming Language :: Python :: 3 :: Only', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Programming Language :: SQL', + 'Topic :: Office/Business :: Financial :: Accounting', +] +requires-python = '>= 3.8' +dependencies = [ + 'beancount >= 2.3.4', + 'python-dateutil >= 2.6.0', + 'requests >= 2.0', +] + +[project.scripts] +bean-query = 'beanprice.price:main' + +[project.urls] +homepage = 'https://github.com/beancount/beanprice' +issues = 'https://github.com/beancount/beanprice/issues' + +[tool.setuptools.packages] +find = {} + +[tool.coverage.run] +branch = true + +[tool.coverage.report] +exclude_also = [ + 'if typing.TYPE_CHECKING:', +] + +[tool.ruff] +line-length = 92 +target-version = 'py38' + +[tool.ruff.lint] +select = ['E', 'F', 'W', 'UP', 'B', 'C4', 'PL', 'RUF'] + +# TODO(blais): Review these ignores. +ignore = [ + 'RUF013', + 'RUF005', + 'PLW0603', + 'UP014', + 'UP031', + 'B007', + 'B905', + 'C408', + 'E731', + 'PLR0911', + 'PLR0912', + 'PLR0913', + 'PLR0915', + 'PLR1714', + 'PLR2004', + 'PLW2901', + 'RUF012', + 'UP007', + 'UP032', +]