Skip to content

refactor: snake_case primary, camelCase aliases for spec-faithful methods#25

Merged
chad-loder merged 1 commit into
mainfrom
refactor/snake-primary-camel-alias
May 13, 2026
Merged

refactor: snake_case primary, camelCase aliases for spec-faithful methods#25
chad-loder merged 1 commit into
mainfrom
refactor/snake-primary-camel-alias

Conversation

@chad-loder
Copy link
Copy Markdown
Owner

Summary

Promotes PEP-8 snake_case to the canonical spelling on the two methods/properties that previously diverged from PEP-8 to match the WHATWG IDL literally, while keeping the camelCase forms as straight aliases so verbatim-from-spec code still works.

Canonical (new) Alias (kept)
URLPattern.compare_component(...) URLPattern.compareComponent(...)
pat.has_regexp_groups pat.hasRegExpGroups

Both spellings dispatch to the same descriptor — is-identity holds, there's no parallel code path.

Why this shape

In Python wrappers of non-Python APIs, snake_case is almost always primary and camelCase doesn't exist at all — playwright-python uses wait_for_selector not waitForSelector, boto3 uses create_instance, aiohttp uses add_route. The exception is GUI bindings (PyQt, PySide, Tkinter) where the C++/Tcl framework is exposed verbatim. URL-pattern matching is a web-spec wrapper, not a GUI binding, so the ecosystem convention is snake-primary.

But the project has an explicit "literal-text spec portability" value — code that round-trips through MDN / Deno / Bun / Cloudflare-Workers samples should read identically. Keeping compareComponent / hasRegExpGroups as aliases preserves that without inflicting camelCase on PEP-8-strict Python codebases.

How the aliases work

Class-level assignments to the same descriptor:

@staticmethod
def compare_component(component, left, right) -> int: ...

compareComponent = compare_component  # noqa: N815
@property
def has_regexp_groups(self) -> bool: ...

hasRegExpGroups = has_regexp_groups  # noqa: N815

A new test, test_camelcase_aliases_resolve_to_same_callable_and_property, pins the identity contract so a future refactor can't silently re-implement the camel name as a duplicate method.

What changed

  • src/yarlpattern/_pattern.py — primary rename + alias declarations. Old # noqa: N802 on the camel def is gone; the new alias lines carry # noqa: N815.
  • tests/test_pattern.py, tests/test_wpt_compare.py, scripts/generate_compliance_report.py — switched to the canonical spelling. One new alias-identity test.
  • docs/examples/*.md — the four examples that demonstrate specificity ordering use compare_component in their snippets. Readers meet the Pythonic spelling first.
  • README.md — one sentence noting the alias.
  • SPEC_DEVIATIONS.md — the "Method-name capitalisation" entry rewritten to describe the dual-spelling policy instead of the old "we keep camelCase" stance. Stable-API table row labels show snake (alias camel).
  • docs/wpt-compliance.md — regenerated.

Backward compatibility

No breaking change. Every prior usage of URLPattern.compareComponent(...) or pat.hasRegExpGroups continues to work identically.

Test plan

  • uv run pytest -q — 951 passed, 8 skipped (was 950 + 1 new alias-identity test)
  • just lint — all tools green (ruff, mypy, pyright, ty, semgrep, shellcheck, rumdl, codespell, interrogate, validate-pyproject)
  • just docs — strict-mode build green (no broken links, mkdocstrings auto-extracts both spellings)
  • just compliance-report — regenerates as 469 cases, 0 failing
  • Signed commit (ED25519)

…hods

URLPattern's two IDL methods now have PEP-8 snake_case as the canonical
spelling, with the WHATWG camelCase forms preserved as straight aliases.
Both spellings dispatch to the same callable / property — no parallel
code path.

  Canonical (Python)    | Alias (spec / browser JS)
  ----------------------+--------------------------
  compare_component     | compareComponent
  has_regexp_groups     | hasRegExpGroups

This aligns with how Python wraps non-Python APIs almost everywhere:
playwright-python uses ``wait_for_selector`` not ``waitForSelector``;
boto3 uses ``create_instance`` not ``CreateInstance``; aiohttp uses
``add_route``. The clear exception is GUI bindings (PyQt, PySide,
Tkinter) where the underlying C++/Tcl framework is exposed verbatim
— that's not a fit for a web-spec wrapper.

The camel aliases stay so code ported verbatim from the WHATWG spec,
browser JS, Deno, Bun, or Cloudflare-Workers samples reads identically.
They're class-level assignments to the same descriptor (staticmethod for
``compareComponent``, property for ``hasRegExpGroups``), so ``is``
identity holds: ``URLPattern.compareComponent is URLPattern.compare_component``.

Updated:

  - src/yarlpattern/_pattern.py
      compare_component renamed (was compareComponent); compareComponent
      reintroduced as a class-level alias. hasRegExpGroups added as a
      class-level alias to the existing has_regexp_groups property. The
      noqa: N802 on the old camel definition is gone; the new aliases
      carry noqa: N815 (mixedCase variable warning) on the assignment.

  - tests/test_pattern.py, tests/test_wpt_compare.py,
    scripts/generate_compliance_report.py
      Switched call sites to compare_component (canonical). One new
      test, ``test_camelcase_aliases_resolve_to_same_callable_and_property``,
      pins the alias identity contract so a future refactor can't
      silently re-implement the camel name as a duplicate method.

  - docs/examples/*.md
      The four example pages that demonstrated specificity ordering
      now use compare_component in their snippets. Readers see the
      Pythonic spelling first; the alias is documented in SPEC_DEVIATIONS.

  - README.md, SPEC_DEVIATIONS.md
      Brief mention that snake is canonical and camel is the alias for
      verbatim-from-spec portability. SPEC_DEVIATIONS's "Method-name
      capitalisation" entry rewritten to reflect the dual spelling
      rather than the old "we keep camelCase" stance.

  - docs/wpt-compliance.md
      Regenerated; case names referenced internally by the script
      switched along with the rest.

959 tests pass (was 950 + 1 new alias-identity test, modulo the
unchanged conformance counts).
@chad-loder chad-loder enabled auto-merge (squash) May 13, 2026 04:27
@chad-loder chad-loder merged commit 1f22e94 into main May 13, 2026
19 checks passed
@chad-loder chad-loder deleted the refactor/snake-primary-camel-alias branch May 13, 2026 04:29
@chad-loder chad-loder mentioned this pull request May 13, 2026
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant