Skip to content

internal_modules_to_public - #450

Open
Niccolum wants to merge 1 commit into
reagento:mainfrom
Niccolum:internal_modules_to_public
Open

internal_modules_to_public#450
Niccolum wants to merge 1 commit into
reagento:mainfrom
Niccolum:internal_modules_to_public

Conversation

@Niccolum

Copy link
Copy Markdown
Contributor

No description provided.

@github-actions

Copy link
Copy Markdown

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  src/adaptix/provider
  __init__.py
Project Total  

This report was generated by python-coverage-comment-action

@Niccolum
Niccolum force-pushed the internal_modules_to_public branch from 2234e2f to 6ad46d0 Compare July 14, 2026 19:08
@sonarqubecloud

Copy link
Copy Markdown

@Niccolum

Copy link
Copy Markdown
Contributor Author

Hi! I maintain dature, a type-safe config loader built entirely on top of adaptix's custom-Provider mechanism. I'd like to propose making a handful of currently-internal symbols public, and I want to explain why — because I think dature's usage maps cleanly onto extension points you already support.

The core issue: adaptix makes the abstract extension surface public — Provider, Mediator, Request, CannotProvide, loc-stack matching, Chain. That's an open invitation to write custom providers. But the moment I write a real one, every concrete type I need lives under adaptix._internal. So I'm forced to import from a private module to use a documented extension point, and any patch release can break me. Today I funnel all of it through one compat module and re-pin on every adaptix bump — which works, but it'd be much healthier as a public contract.

Here's exactly what dature needs and what for:

Request-handler providers — dature's skip-invalid-field and field-aliasing features are Providers that implement get_request_handlers() and wrap the loader. Those need:

  • RequestHandlerRegisterRecord — the return type of get_request_handlers() (can't type the method without it)
  • LoaderRequest — the request they register against (the public counterpart to the already-public Loader)
  • AlwaysTrueRequestChecker — both are cross-cutting, so they match every loader; this is a pure reusable primitive that'd sit naturally next to your other public checkers

Model-construction providers — dature's constructor override (call an internal factory instead of the raw dataclass) and optional-field probe (load a model but yield only the fields that succeeded) subclass ModelLoaderProvider and override provide_loader / _fetch_shape. Those need:

  • ModelLoaderProvider — the base class for the single most common provider kind
  • LocatedRequest — already the parameter type of provide_loader, so it's effectively part of the public method contract already
  • provide_generic_resolved_shape + InputShapeRequest — the sanctioned way to fetch the resolved shape; any _fetch_shape override starts here

Shape rewriting — both of the above rebuild the shape with replace(...):

  • InputShape — the object being mutated
  • Param, ParamKind — to rebuild the constructor's params (dature forces KW_ONLY when redirecting construction)
  • DefaultValue — the only concrete default-value impl your field machinery accepts; needed to mark a field optional (replace(f, is_required=False, default=DefaultValue(...)))

None of this reaches past the public API for convenience — it's the concrete types adaptix itself forces into the signatures of Provider and ModelLoaderProvider. Exposing them (e.g. from adaptix.provider) would let libraries like dature depend on a versioned surface, so an adaptix upgrade becomes a changelog entry rather than a broken import.

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.

1 participant