Skip to content

v5.31.2

Choose a tag to compare

@dgunning dgunning released this 15 May 15:17
· 150 commits to main since this release

Fixed

  • FundReport.options_data() crashed with TypeError: bad operand type for abs(): 'NoneType' on N-PORT filings whose nested forwards had null USD amountsedgar/funds/reports.py:1011-1012 cast fwd.amount_sold / fwd.amount_purchased through abs() when the corresponding currency_* field equalled 'USD', but valid N-PORT XBRL can pair a stated USD currency with a null amount — every option-on-forward in such a filing tripped the crash before any data was returned. The documented public API was effectively unusable for any fund whose options referenced such a forward (reproducer: GOF NPORT-P). Both assignments now guard on amount_* is not None; the exchange-rate calculation just below was already safe via Python's short-circuiting. Defensive grep across the file confirmed lines 1011-1012 were the only unguarded abs() calls. (#811, reporter @HristoRaykov)

  • viewer.concept_rows[i].numeric_value silently returned a prior-year value when the primary reporting period had no fact for the rowConceptRow.numeric_value (and the sibling Concept.value accessor on the concept graph) returned parse_numeric(next(iter(self.values.values()))) — the first entry of the values dict, which was populated only for periods that had a non-empty cell. When the primary (leftmost) reporting period had no value, the singular accessor silently returned whichever period happened to be first in the dict, masking missing-period as a prior-year value. Most visible on the ABT 2019 10-K income statement: concept_rows[16] (us-gaap_IncomeLossFromDiscontinuedOperationsNetOfTax) returned 34.0 (the 2018 value) because ABT had no 2019 discontinued-ops fact. Tracks primary_period on ConceptRow (populated by the R*.htm parser from period_headers[0]) and resolves numeric_value against it explicitly, returning None when the primary period has no value. Concept.value in concept_graph.py got the same fix — same antipattern, same underlying row data, user-visible via the concept graph's Rich/text rendering. (#810, reporter @mpreiss9)

  • FundFeeNotice crashed with AttributeError: 'list' object has no attribute 'get' on per-class 24F-2NT filingsxmltodict-style parsing returns repeated annualFilingInfo blocks as a list, but every typed accessor (fund_name, series, aggregate_sales, etc.) called .get() on the result. ~2% of recent 24F-2NT filings — including all five BNY Mellon family filings — file one block per share class, so the first call into the data object raised before any data was returned. The data model now iterates every annualFilingInfo block: typed financial properties (aggregate_sales, net_sales, redemptions_current_year, registration_fee, total_due, …) sum across blocks; metadata properties (fund_name, fiscal_year_end, investment_company_act_file_number) read from block[0] (identical across blocks); series deduplicates by seriesId. A new FundClassFee dataclass + is_per_class flag + class_fees list expose the per-share-class breakdown. The _parse_float helper now also handles accounting-parens notation (NNN)-NNN, which appears in redemptionCreditsAvailableForUseInFutureYears. Backwards-compatible: every existing property keeps the same return shape; the fund total invariant aggregate_sales == sum(cf.aggregate_sales for cf in class_fees) is verified against BNY Mellon Research Growth Fund. (edgartools-8ohs)

  • viewer.concept_report.currency_scaling returned wrong scales for filers using non-Apple header formatsConceptReport.currency_scaling was derived from a narrow text match on the R*.htm <th class='tl'> header ($ in millions / $in millions). Filers using In Millions, (in millions), USD ($) in Millions, or Dollars in Millions silently fell through to the default of 1, producing scaling that disagreed across statements within a single filing (ALGN balance sheet vs income statement) and wrong values for whole multi-year ranges (ABNB showing 1 for 2023/2024 when the actual scale is millions). ViewerReport.currency_scaling now derives the scale from the XBRL decimals attribute on monetary facts mapped to the report's role in the presentation linkbase — filer-mandated and uniform (-6 → millions, -3 → thousands, 0 → units). The text-match value is retained as a fallback when XBRL is unavailable. The resolved scale is mirrored back onto ConceptReport.currency_scaling so existing code reading it via the concept-report path also benefits. Same precedent as GH #799 (level enrichment from XBRL). (#807, reporter @mpreiss9)