diff --git a/.github/workflows/commit-ibflex.yml b/.github/workflows/commit-ibflex.yml index 0e112a8..db8677f 100644 --- a/.github/workflows/commit-ibflex.yml +++ b/.github/workflows/commit-ibflex.yml @@ -8,16 +8,16 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8] + python-version: ["3.11", "3.12"] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} # - name: Cache pip - # uses: actions/cache@v2 + # uses: actions/cache@v4 # with: # path: ~/.cache/pip # This path is specific to Ubuntu # # Look to see if there is a cache hit for the corresponding requirements file @@ -29,5 +29,5 @@ jobs: run: pip install -r requirements-development.txt - name: Static analysis with mypy run: mypy ibflex tests - - name: Test with nose - run: nosetests -dsv --with-coverage --cover-package ibflex tests/*.py + - name: Test with pytest + run: pytest -v --cov=ibflex tests/ diff --git a/ibflex/Types.py b/ibflex/Types.py index 7f159e0..80deb5f 100644 --- a/ibflex/Types.py +++ b/ibflex/Types.py @@ -468,7 +468,6 @@ class EquitySummaryByReportDateInBase(FlexElement): physDel: Optional[decimal.Decimal] = None physDelLong: Optional[decimal.Decimal] = None physDelShort: Optional[decimal.Decimal] = None - currency: Optional[str] = None insuredBankDepositRedemptionCashComponentLong: Optional[decimal.Decimal] = None insuredBankDepositRedemptionCashComponentShort: Optional[decimal.Decimal] = None incentiveCouponAccrualsLong: Optional[decimal.Decimal] = None @@ -1454,14 +1453,10 @@ class SymbolSummary(FlexElement): commodityType: Optional[str] = None cost: Optional[decimal.Decimal] = None deliveryType: Optional[str] = None - exchOrderId: Optional[str] = None - extExecID: Optional[str] = None fifoPnlRealized: Optional[decimal.Decimal] = None fineness: Optional[decimal.Decimal] = None - holdingPeriodDateTime: Optional[datetime.datetime] = None ibCommission: Optional[decimal.Decimal] = None ibCommissionCurrency: Optional[str] = None - ibExecID: Optional[str] = None ibOrderID: Optional[str] = None initialInvestment: Optional[bool] = None mtmPnl: Optional[decimal.Decimal] = None @@ -1469,15 +1464,9 @@ class SymbolSummary(FlexElement): netCashInBase: Optional[decimal.Decimal] = None notes: Optional[str] = None openCloseIndicator: Optional[enums.OpenClose] = None - openDateTime: Optional[datetime.datetime] = None origOrderID: Optional[str] = None rtn: Optional[str] = None serialNumber: Optional[str] = None - settleDateTarget: Optional[datetime.date] = None - taxes: Optional[decimal.Decimal] = None - tradeMoney: Optional[decimal.Decimal] = None - tradePrice: Optional[decimal.Decimal] = None - transactionID: Optional[str] = None weight: Optional[str] = None whenRealized: Optional[datetime.datetime] = None whenReopened: Optional[datetime.datetime] = None diff --git a/ibflex/parser.py b/ibflex/parser.py index f582187..6d7107c 100755 --- a/ibflex/parser.py +++ b/ibflex/parser.py @@ -12,7 +12,7 @@ import decimal import itertools import functools -from typing import Tuple, Union, Optional, Any, Callable, Iterable +from typing import Tuple, Union, Optional, Any, Callable, Iterable, cast from ibflex import Types, enums, utils @@ -107,7 +107,7 @@ def parse(source) -> Types.FlexQueryResponse: def parse_element( elem: ET.Element -) -> Union[Types.FlexElement, Tuple[Types.FlexElement, ...]]: +) -> Optional[Union[Types.FlexElement, Tuple[Types.FlexElement, ...]]]: """Distinguish XML data element from container element; dispatch accordingly. Flex format stores data as XML element attributes, while container elements @@ -150,8 +150,8 @@ def parse_element_container(elem: ET.Element) -> Tuple[Types.FlexElement, ...]: instances = tuple(parse_data_element(child) for child in elem) if _UNKNOWN_ATTRIBUTE_TOLERANCE: - instances = tuple(inst for inst in instances if inst is not None) - return instances + instances = cast(Tuple[Types.FlexElement, ...], tuple(inst for inst in instances if inst is not None)) + return cast(Tuple[Types.FlexElement, ...], instances) def parse_data_element( @@ -194,6 +194,7 @@ def parse_data_element( if contained_elements: assert elem.tag in ("FlexQueryResponse", "FlexStatement") if _UNKNOWN_ATTRIBUTE_TOLERANCE: + assert known is not None # Filter out unknown or unparseable contained elements contained_elements = { k: v for k, v in contained_elements.items() diff --git a/requirements-development.txt b/requirements-development.txt index d64e4b0..9b268b5 100644 --- a/requirements-development.txt +++ b/requirements-development.txt @@ -8,8 +8,8 @@ requests types-requests # test running -nose -coverage +pytest +pytest-cov pylint mypy black diff --git a/setup.cfg b/setup.cfg index fc1530f..8015f86 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,9 +1,5 @@ -[nosetests] -verbosity=2 -detailed-errors = 1 -with-coverage = 1 -nocapture = 1 -cover-package = ibflex +[tool:pytest] +addopts = -v [flake8] max-line-length = 88