Skip to content

v5.59.0

Choose a tag to compare

@dgunning dgunning released this 26 Sep 11:14
0f752b2

The headline is filing sections. Seven fixes change how 10-K and 10-Q items are found through the table of contents. Items no longer return a neighbouring section, a summary, or each other's text: FirstEnergy's Item 7 no longer returns Item 8, Southern Co.'s Item 7A no longer duplicates Item 7, and Citi's FY2022 Item 7A no longer opens on Item 1. Tables in those sections render cell by cell instead of fusing numbers ("20217,294,800"). Alongside that: a 13F with a couple of holdings could be valued 1,000× too high without a warning, SGML downloads no longer cache an empty filing header when the SEC errors or refuses a request, and four XBRL fixes, including balance-sheet debt reported under combined concepts.

Upgrading. Several of these change values or behaviour you may rely on:

  • 10-K/10-Q section text changes on affected filings. Items resolved through the table of contents now return their own text. Where tables appear in a section, cells are separated, so pinned section lengths move. No letter or digit is lost across 70 tracked filings.
  • doc.text() keeps content it used to drop. Short figures such as "$85" and a cell's own label ahead of its <div>s are now included.
  • Filing.sgml() and Filing.header raise on HTTP errors. A 5xx, 403 or 429 now propagates, where it used to return a header with every field None. The 429 keeps its retry_after. A later call on the same Filing retries.
  • 13F value units. A near-even sub-dollar split (0.35–0.65) now defers to the filing's schema. A thousands conversion decided from fewer than 10 priceable rows emits Ambiguous13FValueUnitWarning, so code that promotes warnings to errors may see it.
  • 10-K friendly section names resolve whichever detector found the section. sections['risk_factors'] works when the section is keyed part_i_item_1a, and 'mda' in sections is true when Item 7 exists.
  • EDGAR_ACCESS_MODE and NORMAL/CAUTION/CRAWL emit DeprecationWarning. They never changed how edgartools talks to the SEC; use EDGAR_RATE_LIMIT_PER_SEC and EDGAR_HTTP_TIMEOUT. They are removed in 6.0.
  • balance_sheet() gains debt lines for filers reporting under combined or short-term debt concepts.

Changed

  • Notes.from_xbrl() without a FilingSummary now returns disclosure-category stems with their Tables, Policies and Details. The fallback builder only accepted note-category roles, and a family that hangs from a *DisclosureAbstract is classified disclosure, so XBRL.from_directory() callers got an empty concept index. gahc goes from 0 notes to 7, aapl from 0 to 16. (GH #1218)

Deprecated

  • EDGAR_ACCESS_MODE and the NORMAL/CAUTION/CRAWL modes are deprecated and have no effect. They advertised a timeout, connection-limit and retry policy that was never wired into the HTTP client; nothing in the package read edgar_mode, so all 3 modes behaved identically. Use EDGAR_RATE_LIMIT_PER_SEC and EDGAR_HTTP_TIMEOUT. The names still import and now warn; removed in 6.0. (GH #1326)

Fixed

  • A 13F with a couple of holdings could be valued 1,000× too high, silently. One sub-dollar warrant in a two-row amendment put exactly half the implied prices under $1, so its values were read as thousands despite a dollars schema: MFN Partners' Q4 2025 13F-HR/A showed $24.92 billion instead of $24.92 million. A near-even split now defers to the filing's schema, and a thin-sample 1000× conversion warns. (GH #1336)
  • Section text fused adjacent table cells. Sections found through the table of contents glued each row's cells together, so Regions' Item 5 read 20217,294,800 for the year 2021 and a 7,294,800 share count; 144 such tokens across 70 fixtures are now 0. Tables render with the cells doc.text() shows, and doc.text() itself now keeps short figures such as Regions' "$85" and cell labels it used to drop. (bead edgartools-wzgu)
  • HTTP 403 and 429 no longer leave a cached empty filing header. Filing.sgml() and Filing.header now propagate every status-bearing HTTP error in both error modes, preserving the original 429 retry_after value. After an injected refusal, a later successful download on the same filing recovers Apple's 2024-09-28 report period; content-error homepage fallback is unchanged.
  • 10-K sections came back wrong when a TOC row put the item label and title in one cell. FirstEnergy's FY2025 10-K links only page numbers, so its TOC parse kept 3 of 23 items and obj["Item 7"] returned Item 8's financial statements (306,341 chars) instead of the MD&A. Such rows now keep their item label. Patch by @sf1tzp. (GH #1347)
  • Items that start on the same printed page no longer return each other's text. When a TOC links page numbers, keys such as Item 7 and Item 7A sliced to one span; they are now separated by their headings, so Southern Co's obj['Item 7A'] returns its 347-char cross-reference instead of Item 7's 282,239 chars. Prospectus markdown() now also stops at the financial statements, as text() did. (GH #1345, bead edgartools-rc46)
  • A TOC sub-heading row could claim a 10-K item, returning a summary as the item and letting the item before it swallow the real one. "Summary of Risk Factors" and "Index to Financial Statements" rows no longer keyword-match Item 1A and Item 8; on Hertz's FY2024 10-K, Item 1A is now the 100,175-char Risk Factors section instead of an 8,524-char summary. (GH #1344)
  • 10-Q TOC labels reading "Part I, Item 2" were read as the Part alone, so every item was dropped. Edison International's Q3 2025 10-Q returned 3 sections with Part I Items 1, 3 and 4 missing and a 346,454-char Item 2; it now maps all 9, with Item 2 at 89,652 chars. Only a label that is wholly "Part X, Item N" counts, so cross-reference prose cannot claim a key. (GH #1348)
  • Cross-reference 10-K items could return a neighbouring section. Printed page numbers were equated with page-break counts, so filings with unnumbered front matter were sliced early: Citigroup's FY2022 Item 7A opened three pages early on Item 1's human-capital section. The offset is now calibrated from the printed footers and is a no-op when they are aligned. (GH #1346)
  • SGML server failures no longer cache an empty filing header. Filing.sgml() and Filing.header propagate HTTP 5xx errors in both default and strict error modes, leaving the same filing retryable. An injected 503 followed by Apple's checked-in 2024 10-K now recovers its 2024-09-28 report period on the second call.
  • A member filed on two different axes lost one of its rows. JPMorgan's 2012 10-K reports VIE loans on both dei:LegalEntityAxis and a classification axis; the member hierarchy keyed rows by member alone, so the LegalEntity row — carrying the more precise $82.723B against the other's $82.7B — was dropped. A member on two axes is no longer reordered.
  • A note family split when a filing spelled only some of its roles with a leading Disclosure marker. UNP names most of one family DisclosureDebtDetails1 but two members DebtDetails6, so those surfaced as spurious top-level notes while the real Debt note lost two Details. The marker is now ignored when matching a stem, taking UNP from 20 notes to 18 and 318 reachable concepts to 336.
  • Filing.html() raised AttributeError instead of returning None when a filing's homepage listed no primary document. The homepage property is optional and comes back None for some filings, but two call sites used it unguarded, so the scheduled build went red on a PDF-primary APP NTC filing. Both are guarded now.
  • A disclosure's Tables and Details roles were returned by xbrl.notes() while their parent was returned by xbrl.disclosures(). In a filing that falls back to role names only the family stem hangs from a *DisclosureAbstract, so gahc's ConvertiblePromissoryNotesPayable moved alone and its 4 children stayed notes. A child now follows its nearest stem when that stem declares a disclosure; no other role in the 7 committed fixtures changes. (GH #1218)
  • Statement.get_raw_data(view="detailed") dropped NVIDIA's reportable-segment revenue. On the FY2026 10-K (0001045810-26-000021) the default view kept Compute & Networking $193.479B and Graphics $22.459B; DETAILED returned neither and showed ProductOrService Compute/Networking instead. Member hierarchy keyed rows by the first axis, so two-axis facts collided once Data Center's children entered the set. Hierarchy now nests only single-axis members. (GH #1331)
  • A submodule imported from a thread while another thread imports edgar could fail. Importing edgar once on the main thread before starting threads avoids it; this is now documented under Common Pitfalls. A structural fix through lazy submodule loading is planned for 6.0. (GH #1325)
  • Four documentation claims named things that do not exist or are out of date. set_rate_limit() and enable_local_storage() appeared in the performance, SEC-compliance and Form 4 guides but are not in the package; the working names are EDGAR_RATE_LIMIT_PER_SEC (set before import; the default is 9, not 10) and use_local_storage(). The configuration page said submissions are cached up to 10 minutes; MAX_SUBMISSIONS_AGE_SECONDS has been 30 seconds since #471.
  • PortfolioInvestments.from_xbrl() cut the first word off a borrower's name when the filer labelled a range member with it. BXSL's FY2025 10-K (0001736035-26-000004) returned Street Buyer, Inc. 2 with industry='High' for its four High Street Buyer, Inc. positions: BXSL labels srt:MaximumMember "High", and every member label was an industry candidate. The five srt:RangeAxis members no longer are; across 12 filings and 8,212 positions only those rows change. (GH #1324)
  • balance_sheet() dropped debt reported under combined or short-term concepts. Filers using LongTermDebtAndCapitalLeaseObligations, DebtCurrent or ShortTermBorrowings lost the line entirely: CSX's balance sheet showed no debt, and now shows $18.165B long-term plus $708M current. (PR #1330, thanks @wittling)

Performance

  • parse_investment_identifier() recompiled up to 933 regexes on every call. Six sites built patterns from INVESTMENT_TYPES per call, past the 512 re caches, so a piped Company | Type identifier never hit the cache. They are now compiled once and cached: parsing BXSL's 703 identifiers on its Q2 2026 10-Q (0001736035-26-000016) drops from 40.8 s to 1.1 s, every field identical. (GH #1342)
  • to_dataframe(*columns) no longer builds the full fact width before projecting. Selecting columns now narrows the frame at construction instead of at the end, so a two-column call on the JPM 10-K fixture drops from 7.59 MiB to 0.71 MiB peak and from 78 ms to 8 ms, with a byte-identical frame. (GH #1181)