feat: sync SDK with Etsy API spec — stop sending removed personalization fields - #41
Merged
Merged
Conversation
Etsy removed is_personalizable, personalization_is_required, personalization_char_count_max and personalization_instructions from the createDraftListing and updateListing request bodies (2026-09 spec). Personalization now lives on the dedicated personalization endpoints, which the SDK already implements. The SDK already warned when these fields were set, but still serialized and transmitted them. They are now stored under underscore-prefixed names that todict excludes, so they never reach the wire. The constructor kwargs and the DeprecationWarning are kept so existing callers don't break, and read access is preserved via properties. Remove the kwargs in the next major version. Also route request body drift through the audit suppression pipeline as a value-bearing `body_drift` finding type, matching enum_staleness and param_drift. Body drift previously bypassed specs/audit-ignore.json entirely, so an accepted finding could only be left as permanent noise. Suppression is scoped to named fields, so newly drifted fields on an already-suppressed operation still surface. Audit: 105/105 operations, 100% coverage, 0 active findings, 0 stale ignores.
- compute_body_findings: restore the original subtraction semantics in the no-model-class branch. Path/query param names are now excluded from the "extra" direction only, as before. Subtracting them from the shared field set made a body field that shares a path-param name (taxonomy_id, shipping_profile_id, shop_section_id, return_policy_id) falsely report as "In spec but not SDK". - Personalization fields: add setters alongside the properties. Making them getter-only broke post-construction assignment with AttributeError, which the back-compat goal was meant to avoid. A write now stores the value and warns, exactly like the constructor kwarg, and still never serializes. _warn_if_personalization_used takes the stacklevel so both paths blame the caller's line. Uses a feat: prefix so the merge produces a minor version bump: the branch changes wire behavior for callers that relied on the four personalization fields being transmitted. Etsy already removed them from the request bodies, so they were being rejected regardless, but the change warrants more than a patch bump.
Contributor
Test Coverage ReportOverall: 100% (1726/1726 statements covered) Coverage by file
Updated by PR Tests |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Full SDK audit against the latest Etsy OAS spec (2026-09). Coverage is 105/105 operations, 100%, with 0 active findings and 0 stale ignores after this branch.
Found 0 Must Fix, 1 Should Fix, 4 Informational items. The one real change:
Etsy removed
is_personalizable,personalization_is_required,personalization_char_count_maxandpersonalization_instructionsfrom thecreateDraftListingandupdateListingrequest bodies. Personalization now lives on the dedicated personalization endpoints, which this SDK already implements (get_listing_personalization,update_listing_personalization,delete_listing_personalization).The SDK already warned when these fields were set, but still serialized and transmitted them.
Callers who set these four fields will no longer have them sent to the API. They are now stored under underscore-prefixed names that
todictexcludes, so they never reach the wire.Etsy already removed them from the request bodies, so they were being rejected regardless — this stops sending data the API no longer accepts. Source compatibility is fully preserved:
DeprecationWarningpointing at the caller's line.The kwargs are slated for removal in the next major version. This branch uses a
feat:prefix on HEAD so the merge produces a minor version bump rather than a patch, given the wire-behavior change.Audit tooling
Request body drift previously bypassed
specs/audit-ignore.jsonentirely, so a reviewed and accepted body-drift finding could only be left as permanent report noise. It now flows through the same suppression pipeline as the other finding types, as a value-bearingbody_drifttype:compute_body_findingsis behavior-preserving; verified by diffing the full generated report against the previous implementation (byte-identical).Two
body_driftentries were added for the accepted personalization finding, bringing the ignore file to 21 entries.Suppression re-verification
All 19 pre-existing suppressions were re-read against current code and spec, and re-confirmed valid — 0 removed, 0 stale, 0 newly surfaced enum values:
param_drift(legacy, 8 ops)warn_removed_legacy_paramstill called at all 8 sites; value discardedextra_method(deprecated aliases)DeprecationWarningenum_staleness(State.REMOVED)enum_staleness(Includesshipping/inventory)getListingsByShopenum_staleness(holiday_id)Test plan
pytest— 433 passed (was 408; 25 new tests).get_dict()on both models, while other fields serialize normally.DeprecationWarningfires once per construction, blames the caller's line on both the constructor and setter paths, and stays silent for falsy values.compute_body_findings: both drift directions,listing_type→typealias normalization, multipart skip, and no false drift for body fields sharing a path-param name.body_driftsuppression: value-scoped hiding, newly drifted fields staying active, stale detection, direction matching.python scripts/audit_sdk.py --spec specs/latest.json— 100% coverage, 0 active findings, 0 stale ignores.python scripts/check_version_consistency.py— versions consistent.specs/baseline.jsonupdated to the current spec;diff_spec.pynow reports no changes.🤖 Generated with Claude Code