Skip to content

fix(search): drop an amendment form code whose root form is also listed - #1545

Merged
dgunning merged 1 commit into
dgunning:mainfrom
cristianchiriac:fix-efts-amendment-forms
Oct 15, 2026
Merged

dgunning merged 1 commit into
dgunning:mainfrom
cristianchiriac:fix-efts-amendment-forms

Conversation

@cristianchiriac

Copy link
Copy Markdown
Contributor

What this changes

search_filings(..., forms=[...]) no longer loses every original filing when the list contains an amendment code. EFTS returns amendments only as soon as forms holds a code like S-1/A, for every form in the list, while a root code (S-1) already matches its amendments. The issue measured ["F-1"] → 1 filing and ["F-1", "F-1/A"] → 0 for "YHTE".

_efts_forms() now builds the list sent to EFTS:

  • X/A is dropped when X is also listed, so ["F-1", "F-1/A"] sends F-1 and ["S-1", "S-1/A", "F-1", "F-1/A", "424B4"] sends S-1,F-1,424B4.
  • Amendment-only lists (["S-1/A"], ["S-1/A", "F-1/A"]) and lists without amendments are sent unchanged.
  • An amendment code without its root mixed with other forms (["S-1/A", "F-1"]) is still sent as given, but raises a UserWarning that names the root form to use, because EFTS would leave out the other forms' originals.

Fixes #1544

Verification

  • Regression test for a bug is in tests/issues/regression/test_issue_1544_search_forms_amendments.py, and its docstring links the issue. It stubs get_with_retry (as test_issue_1497.py does) and checks the forms parameter sent to EFTS for each case above, plus the warning. 4 of the 8 cases fail on main.
  • Changelog: changelog.d/1544.fixed.md; assemble_changelog.py --check accepts it.
  • tests/search and test_issue_1497.py (fast): 149 passed.
  • I didn't record a live EFTS cassette. The EFTS behaviour itself is the one measured in the issue.

EFTS returns amendments only as soon as forms holds an amendment code, for
every form in the list, while a root code already matches its amendments.
forms=["F-1", "F-1/A"] therefore returned no F-1 at all. Drop X/A when X
is listed, and warn when an amendment code without its root is mixed with
other forms.

Fixes #1544
@arhancanli

arhancanli commented Oct 14, 2026 •

Copy link
Copy Markdown

I checked the EFTS behaviour this PR relies on against a second form type, using the live endpoint on 2026-10-14 with q="Ford Motor", 2026-01-01 to 2026-10-14:

So the root code does match its amendments for 10-K too, and dropping X/A when X is listed loses nothing there. The fix isn't specific to registration statements.

Review points on the diff, from reading it (I did not run the suite):

  1. _efts_forms only matches a plain form[:-2] in listed. A case-variant like ["10-k", "10-K/A"] keeps the amendment and the user gets the amendments-only result again, silently, since the warning only fires when other non-amendment forms are present too. If search_filings doesn't normalise case upstream, a test for that input would show it.
  2. The new tests cover the "mixed list" warning, but I don't see one for the all-amendments list with a root also present in a different position, e.g. ["S-1/A", "F-1/A", "S-1"] → expected F-1/A,S-1, which also triggers the warning because F-1/A has no root. That is the right behaviour but it's the one combination where the dropped and kept codes interact, so it is worth pinning.

@dgunning
dgunning merged commit 6074fbc into dgunning:main Oct 15, 2026
13 of 14 checks passed
dgunning added a commit that referenced this pull request Oct 15, 2026
…ession lookup (#1554)

Opening a filing from an accession asks EDGAR full-text search first and the
quarterly filing index second (edgartools-vx29). #1498 made an EFTS error body
(HTTP 200, {"errorType": ...}) raise TransportError instead of reading as no
hits, and resolve_accession re-raises transport errors (07lk.10). So when SEC's
search backend failed on its own -- `getaddrinfo EBUSY` on 10-14 and 10-15 --
find(accession) raised for filings the index would have found. Five
regression tests failed that way across #1545, #1548 and #1550.

_filing_from_efts, the caller with a correct fallback, now logs a warning and
returns None on a transport error, so the index is asked. resolve_accession
still raises, and search_filings still raises, since there the error is the
answer. If SEC itself is unreachable, the index fetch raises the same error.

#1498 is unreleased, so no released version had this; no changelog fragment.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

search_filings(forms=[..., "S-1/A"]) silently drops every original filing

3 participants