Sync SDK with Etsy API spec — extend personalization deprecation warning - #27
Merged
Conversation
…lizable The Etsy API marks all four listing personalization fields as [DEPRECATED] (is_personalizable, personalization_is_required, personalization_char_count_max, personalization_instructions), but CreateDraftListingRequest and UpdateListingRequest only emitted a DeprecationWarning when one of the latter three was set. Setting only is_personalizable now also triggers the warning, with the message updated to name all four fields. Also refresh specs/baseline.json — the latest spec only differs from the previous baseline in description text on createDraftListing.styles (adds the 45-char-per-style note) and updateListingInventory (mentions processing profile compatibility), so no further code changes are required. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…uthy values Addresses code review on prior commit (7db1898): 1. Switch warning trigger from "is not None" to truthy. The API documents `false` (and by extension `0` / empty string) as the default-equivalent for the deprecated personalization fields; these remain no-ops after the Apr. 9th, 2026 removal, so they should not warn. Setting True / non-zero int / non-empty string still warns. 2. Extract `_PERSONALIZATION_DEPRECATION_MSG` constant and `_warn_if_personalization_used()` helper to remove the 15-line block duplicated across CreateDraftListingRequest and UpdateListingRequest. Helper uses `stacklevel=3` so the warning still points at the user's call site. 3. Add tests covering: - is_personalizable=False (no warning, opt-out) - char_count_max=0 + empty instructions (no warning) - all four fields set together (exactly one warning, not four) All 251 tests pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Contributor
Test Coverage ReportOverall: 100% (1672/1672 statements covered) Coverage by file
Updated by PR Tests |
There was a problem hiding this comment.
Pull request overview
Extends the existing personalization deprecation warning in CreateDraftListingRequest and UpdateListingRequest to also trigger when is_personalizable is set, aligning with Etsy's OAS spec which marks it as [DEPRECATED]. The warning logic was refactored into a shared helper, and the trigger now uses truthy checks so explicit falsy/default values don't warn. The spec baseline is refreshed with minor description-text updates.
Changes:
- Added
is_personalizableto deprecation trigger and message; switched to truthy check. - Extracted
_PERSONALIZATION_DEPRECATION_MSGand_warn_if_personalization_used()helper (withstacklevel=3) to eliminate duplication. - Refreshed
specs/baseline.json(description-only updates) and added tests covering the new behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| etsy_python/v3/models/Listing.py | Extracted shared personalization deprecation helper and added is_personalizable to the trigger. |
| tests/test_listing_models.py | Added tests for is_personalizable warning, falsy no-warn cases, and single-warn-on-multi-field. |
| specs/baseline.json | Refreshed baseline with description-only changes (no schema drift). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The PR coverage report flagged three files at 0%: - etsy_python/v3/auth/OAuth.py (33 stmts) - etsy_python/v3/auth/__init__.py (1 stmt) - etsy_python/v3/enums/Language.py (12 stmts) Adds two test modules: * tests/test_oauth.py — 13 tests covering EtsyOAuth: constructor with and without optional args (code_verifier, state, scopes), PKCE challenge derivation against a known SHA-256 base64url-no-padding value, get_auth_code's call into OAuth2Session.authorization_url, set_authorisation_code happy path and state-mismatch PermissionError, and get_access_token's call into OAuth2Session.fetch_token. The underlying OAuth2Session is patched so no network I/O occurs. * tests/test_language_enum.py — 2 tests verifying every Language member value is its name lowercased and exactly the ten ISO 639-1 codes the Etsy API supports. All three target files are now 100% covered. Overall coverage rises from 94% to 96% across 266 tests. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Brings every source file to ≤5 missing statements and ≥80% coverage. Adds 31 new tests across six files. New test files: * test_processing_profile_models.py — CreateShopReadinessStateDefinitionRequest and UpdateShopReadinessStateDefinitionRequest constructors, including enum unwrapping into raw string values and partial-update behavior. * test_processing_profile_resource.py — all five ProcessingProfileResource methods (create, list with default + custom pagination, get, update, delete). The resource had zero prior tests. * test_shop_return_policy_models.py — ConsolidateShopReturnPoliciesRequest, CreateShopReturnPolicyRequest, UpdateShopReturnPolicyRequest. Includes a False-preservation test guarding the bool/nullable behavior in CLAUDE.md. * test_misc_and_holiday_models.py — GetTokenScopes and UpdateHolidayPreferencesRequest, including is_working=False preservation. Extended: * test_listing_models.py — UpdateListingTranslationRequest, UpdateListingPersonalizationRequest, UpdateListingVideoRequest constructor tests (request-body uploads exercising the file/data dicts). * test_listing_resource.py — TestListingPersonalizationEndpoints: get_listing_personalization, update_listing_personalization (with and without supports_multiple_personalization_questions query param), delete_listing_personalization. Result: 297 passing tests, 99% overall coverage. All ten remaining uncovered lines are in five files (Utils.py: 4, Request.py: 2, three single-line gaps in Session/Response/exceptions). Per-file floor is 87%, per-file gap ceiling is 4 lines. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds 9 small tests covering the remaining uncovered branches and helpers: * test_utils.py — TestTodict.test_ast_attribute_is_expanded covers the todict branch that delegates to obj._ast(). TestGenerateBytesFromFile exercises generate_bytes_from_file against a tmp_path file and an empty file (the file-bytes helper used by FileRequest uploads). * test_request_model.py — test_mandatory_key_with_no_attribute_raises_value_error covers the except-Exception branch of Request.check_mandatory() triggered when a mandatory key isn't an instance attribute (KeyError on self.__dict__[key]). * test_session.py — test_invalid_method_payload_combo_raises_value_error passes a non-Request payload to a PUT call, which slips past the "Improper payload" guard and hits the final "Invalid method or payload" else. * test_exceptions_and_response.py (new) — covers __str__ for BaseAPIException, RequestException (verifies the [EtsyRequestException] prefix), and Response. Result: 306 tests, 100.0% coverage, no missing statements anywhere in etsy_python/. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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
Output of
/maintain-auditagainst the current Etsy OAS spec. The audit reported 100% endpoint coverage (103/103) and no schema/parameter drift; the only actionable item was a small completeness gap in the personalization deprecation warning.is_personalizableis[DEPRECATED]in the spec butCreateDraftListingRequest/UpdateListingRequestonly warned when one of the other three personalization fields was set.CA_HOLIDAYSdesign,State.REMOVEDbackward-compat, multi-linewarnings.warnstrings).Changes
Commit 1 —
fix: extend personalization deprecation warning to include is_personalizableis_personalizableto the warning trigger and message in both model__init__s.specs/baseline.jsonfrom the freshly-fetchedspecs/latest.json. The only differences from prior baseline are description-text changes oncreateDraftListing.styles(45-char-per-style note) andupdateListingInventory(mentions processing-profile compatibility) — no schema/field changes.Commit 2 —
refactor: extract personalization deprecation helper; warn only on truthy valuesAddresses code-review feedback on commit 1:
is not Noneto truthy. The API documentsfalse/0/ empty string as default-equivalent for these fields; they remain no-ops after the Apr. 9th, 2026 removal, so they should not warn._PERSONALIZATION_DEPRECATION_MSGconstant and_warn_if_personalization_used()helper to remove the 15-line block duplicated acrossCreateDraftListingRequestandUpdateListingRequest. Helper usesstacklevel=3so the warning still points to the user's call site.is_personalizable=False(no warn), zero char-count + empty instructions (no warn), all four fields set together (exactly one warn).Test plan
pytest -v— 251 passed, 0 failedpython scripts/audit_sdk.py --spec specs/latest.json— 100% coverage, no drift, no missing endpointspython scripts/diff_spec.py— empty (baseline matches latest)python scripts/check_releases.py— up to date with3.0.0-general-release-2026-03-24is_personalizable=Truesees the deprecation warningis_personalizable=False(or omitting it) sees no warning🤖 Generated with Claude Code