Skip to content

v5.60.0

Latest

Choose a tag to compare

@dgunning dgunning released this 02 Oct 18:29
1e7a61b

The last 5.x release before 6.0. It brings the ownership family to the top level (from edgar import Form4, Schedule13D), adds a timeout to the current-filings feed, and fixes 19 defects: most of them in BDC portfolio figures and Schedule 13D/G ownership, plus section text and grep.

6.0 is next (planned 2026-11-09). It drops Python 3.10 and turns several warnings you may already see in 5.x into errors. Running this release with warnings visible shows what will change for your code, and the upgrade guide says what to do about each one. Fixes made from now until 6.0 ship in 6.0.

Upgrading. Nothing is renamed or removed, but some values change because they were wrong:

  • BDC portfolio totals go down. portfolio_investments() no longer counts holdings twice, and joint-venture holdings, range facts and subtotals no longer inflate totals. Against the filed balance sheet, BCSF went from +90.5% to 0.0% and NMFC from +24.8% to +0.9%.
  • NonAccrualResult.num_nonaccrual is None, not 0, when a filing gives only a portfolio-level non-accrual figure or none at all.
  • Schedule 13D/G comparisons with joint filers use the largest reported holding, as total_shares does, instead of summing every reporting person. Some shares_change values change as a result.
  • Section text is whitespace-normalized. Hard-wrapped paragraphs no longer keep their line breaks, so text you pinned may differ by whitespace only.
  • An 8-K with no SIGNATURES heading now ends its last item at the signature statement; the signature block moves to a signatures section.
  • Filing.grep(document="EX-10.1") searches only EX-10.1, not EX-10.10 through EX-10.19 as well. Counts that included those exhibits drop.
  • MCP edgar_fund returns AMBIGUOUS_BDC with up to five candidates when a name matches several BDCs, instead of silently picking one.

Added

  • get_current_filings(), iter_current_filings_pages() and get_all_current_filings() take a timeout. A slow feed page can get 90s without changing the 30s default for every other request, and a timed-out page still gets all 5 attempts where a process-wide 60s timeout allowed one. (GH #1391, bead edgartools-7xtb)
  • from edgar import Form4, Schedule13D now works for the whole ownership family. Form3, Form4, Form5, Form144, Schedule13D and Schedule13G are top-level names, identical to their subpackage classes and loaded on first use, so import edgar time is unchanged (596 ms vs 602 ms). The filing.obj() import table in the API docs had four rows that raised ImportError; all thirteen now import, and a test keeps them that way.
  • A guard that fails when cassette replay stops reaching edgartools' HTTP stack. A vcrpy/httpx upgrade that breaks interception used to make every cassette test fetch live and still pass. Three fast tests now replay a cassette for a dead address through get_with_retry (sync and async); with vcr's httpcore patch removed, all three fail.
  • A gate that fails a pull request which stages a 6.0 change without updating the upgrade guide. Deprecations, will-raise warnings and "removed in 6.0" notes must now touch docs/upgrade/6.0.md in the same PR; replayed over the 265 commits since the guide existed, it flags the four PRs that shipped staging with no guide entry, including #1201. Adds a PR template with the Definition of Done checklist.
  • ReportingPerson.reported() and OwnershipComparison.reported_shares_change tell an unreported ownership figure from a reported 0. The 5.x fields still hold a placeholder 0 for a figure the filing leaves out and name it in ReportingPerson.unreported_fields; reported(), reported_shares_change and reported_percent_change return None for it, as the fields will in 6.0. (GH #1379)

Fixed

  • Schedule 13 OwnershipComparison summed joint filers, while total_shares took the largest one. A fund and its adviser reporting one 10,000,000-share position compared as 20,000,000. The comparison now uses the same max, and the new aggregation_basis (single, identical, parent_sums_children, ambiguous) says when it may fall short: GAMCO's Nevro 13D is 1,322,950 by max and 2,123,900 by its own Item 5(a). (bead edgartools-qsk4)
  • BDC portfolios summed above the balance sheet from joint-venture holdings, range facts and subtotals the 6xxb rules missed. BCSF went from +90.5% to 0.0%, NMFC +24.8% to +0.9%, OBDC +6.4% to 0.0%. FSK's +11.5% was netting: the new unfunded_commitments_fair_value (-1,448.1M) is added back, giving +0.3%. DERA summary_by_company() gains total_source (filed or summed). (bead edgartools-3vad)
  • MCP edgar_fund silently picked one BDC when a name matched several. "Golub" returned GOLUB CAPITAL BDC though four Golub BDCs score 99.4-100. A name now resolves only on one match equal to it (ignoring a suffix like Corp or Inc., so "Ares Capital" is still ARES CAPITAL CORP) or a clear top hit; otherwise the tool returns AMBIGUOUS_BDC with up to five candidates and their CIKs. (bead edgartools-1c6z)
  • Filing.grep(document="EX-10.1") also searched EX-10.10 through EX-10.19. In SeeQC's S-1 it returned 378 matches for "agreement" where EX-10.1 holds 133. An exact filename or document type now wins, and a substring match applies only when nothing matches exactly, so document="EX-10" still selects every EX-10 exhibit. (bead edgartools-5qqy)
  • A literal grep returned shifted matches after a character whose lowercase is longer. Positions were found in the lowercased text and applied to the original, so four "İ" before "going concern" returned "g concern dou". Literal matches are now found in the original text, case-insensitively. (bead edgartools-6th2)
  • BDCEntity.is_active would have turned False for BDCs the newest SEC report dropped, though they still file. Their rows come from the 2025 report, so Ares Capital's activity date stopped at 2025-05-29 and would leave the 18-month window around 2026-11-29. For these 22 BDCs, is_active now checks the company's own filings once the report date expires; the new in_latest_report flag marks them. (bead edgartools-huul)
  • MCP bdc_portfolio investment records named no borrower. Every record had only type, fair value, cost and rate because the builder read a name field PortfolioInvestment does not have. Records now carry company_name, identifier, principal, PIK rate, spread and percent of net assets, with None for a missing figure; MAIN's first record is "MSC Adviser I, LLC", $255.0M. (bead edgartools-rd23)
  • NonAccrualResult.num_nonaccrual reported 0 when a filing gave only a portfolio-level non-accrual figure, or none. WhiteHorse Finance files $10.6M of non-accrual investments for 2025 with no per-investment detail and showed 0; the count is now None unless the filing itemizes, and the new evidence_level says which (investment, aggregate, none). (bead edgartools-vblr)
  • An 8-K with no SIGNATURES heading no longer folds its signature block into the last item. When the block opens straight with "Pursuant to the requirements of the Securities Exchange Act of 1934 ... caused this report to be signed", that sentence now ends the item. In a 90-document 8-K sample this cleaned the last item of 3 filings and changed nothing else.
  • Hard-wrapped paragraph text no longer keeps its line breaks — HTMLParser now collapses whitespace runs inside a text node to one space, as a browser does, while <br> and <pre> still break lines. Item 7 of Google's FY2004 10-K had about 500 mid-sentence newlines. (#1370)
  • BDC portfolio_investments() no longer counts holdings twice. Company totals, tranche parents and a second schedule's copies of a row were read as holdings, so rows summed 2-48% above the filer's own total on every BDC checked; MAIN's FY2025 10-K summed to $6.30B against a reported $5.52B and now reconciles within 0.2%. Foreign-currency values no longer replace USD ones, and new reported_total_fair_value and reconciliation_gap show any remaining difference.
  • TenK keeps both items of a combined heading such as "Items 1 and 2. Business and Properties". A TOC link reading "Items 1 and 2" (or "Items 1. and 2.", "Items 7. and 7A.") was dropped, so tenk.business was None on Viper, Devon, Freeport and Cheniere. The section is now keyed as the first item, lists both in Section.covered_items, and answers for either. Talos no longer shows a 1,311-character "Properties" fragment as Item 2. (GH #1382, #1383)
  • OwnershipComparison.get_summary() warnings now point at the caller. It emitted two FutureWarnings attributed to amendments.py, so Python showed them once per process wherever it was called from; it now emits one, at the caller's line. A filing with an empty <reportingPersons> now displays its ownership as "not reported" instead of 0, matching the comparison. (GH #1379)
  • OwnershipComparison.is_liquidating reported a sale against a Schedule 13D/G filing that gives no share figures. A 13D/A or 13G/A may omit them and a pre-2025 header-only filing has none, but they were read as 0: an amendment omitting them on the Aadi Bioscience 13D in the test data sold all 4,535,000 shares. The direction flags are now False when the change is unknown, and shares_change and percent_change warn that they return None in 6.0. (GH #1379)
  • edgar.ownership.core.is_numeric() raised TypeError for pandas string and nullable numeric columns. The reported Arnaboldi Form 4 has UnderlyingShares of 0 [F1]; its value calculation now returns None instead of raising. Ownership share totals also return None for unreadable text rather than raising. (GH #1368, thanks @manantlerio)
  • EntityFacts.get_total_liabilities() returned total assets for filers with no standalone liabilities total. Its last fallback was LiabilitiesAndStockholdersEquity, which always equals total assets: NIKE's FY2026 figure came back as $38.41 billion against $23.545 billion of liabilities, and 16 of 51 large US filers were affected. It now returns None there, matching Financials.get_total_liabilities(). (GH #1279)
  • PortfolioInvestment.company_name returned the instrument (First Lien, Ordinary Shares) when the filer tagged the company as a member. On PSEC's FY2026 10-K (0001287032-26-000269) 142 of 248 identifiers named an instrument. A member candidate that fills the whole first pipe segment is now the company, not a prefix to strip. (GH #1373)
  • PortfolioInvestment.company_name named a schedule heading or sub-sector instead of the company on category-led identifiers. On CGBD's Q2 2026 10-Q (0001544206-26-000055) 348 of 352 positions read Investment, Credit Fund or a sub-sector such as Durable; SLRC and PFX were hit too. Only the axis prefix is stripped now, and leading heading segments are skipped. (GH #1372)
  • Form4.shares_traded raised AttributeError on a derivative-only filing. market_trades is None when the non-derivative table has no transactions, and the accessor read .Shares off it without the None/empty guard its neighbours already had: Vertex's 2020-10-19 Form 4 parsed and returned its derivative transaction but crashed on shares_traded, which now reports 0 market trades. (GH #1359)