ref: mapper api overhaul#147
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR redesigns pagination, ordering, and include/exclude field APIs: booleans replaced by IncludeFields (e.g., "all" or field lists), adds global include/exclude support, per-field paginate/order/distinct_on controls, new DTO helpers, and threads factories and cache/no_cache controls through schema and mutation builders. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/strawchemy/schema/factories/base.py (2)
73-77: Remove unusedChildOptionsclass.The
ChildOptionsclass appears to be dead code left over from the refactoring. It's no longer referenced anywhere in the codebase after the migration to explicitpaginateandorderparameters.🔎 Proposed removal
-@dataclasses.dataclass(eq=True, frozen=True) -class ChildOptions: - pagination: DefaultOffsetPagination | bool = False - order_by: bool = False - - class GraphQLDTOFactory(DTOFactory[DeclarativeBase, QueryableAttribute[Any], GraphQLDTOT]):
93-124: Critical:frozensetconversion incorrectly handles the "all" literal.Lines 114-115 convert
orderandpaginatetofrozenset, but when these parameters contain the string"all",frozenset("all")createsfrozenset({'a', 'l'})instead of a proper representation of "all fields".This will cause incorrect behavior when
paginate="all"ororder="all"is used, as the registry will receive a malformed frozenset.🔎 Proposed fix
def _type_info( self, dto: type[StrawchemyDTOT], dto_config: DTOConfig, current_node: Node[Relation[Any, GraphQLDTOT], None] | None, override: bool = False, user_defined: bool = False, order: IncludeFields | None = None, paginate: IncludeFields | None = None, default_pagination: None | DefaultOffsetPagination = None, ) -> RegistryTypeInfo: graphql_type = self.graphql_type(dto_config) model: type[DeclarativeBase] | None = dto.__dto_model__ if issubclass(dto, MappedStrawberryGraphQLDTO) else None # type: ignore[reportGeneralTypeIssues] default_name = self.root_dto_name(model, dto_config, current_node) if model else dto.__name__ + + def to_frozenset(value: IncludeFields | None) -> frozenset[str]: + if value is None: + return frozenset() + if value == "all": + return frozenset(["all"]) + return frozenset(value) + type_info = RegistryTypeInfo( name=dto.__name__, default_name=default_name, graphql_type=graphql_type, override=override, user_defined=user_defined, pagination=default_pagination, - order=frozenset() if order is None else frozenset(order), - paginate=frozenset() if paginate is None else frozenset(paginate), + order=to_frozenset(order), + paginate=to_frozenset(paginate), scope=dto_config.scope, model=model, exclude_from_scope=dto_config.exclude_from_scope, )
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (8)
tests/unit/__snapshots__/test_example_app/test_graphql_schema.gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[all_fields_order_by].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_empty_list].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_specific_fields].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[paginate_all_with_default].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[paginate_and_order_combined].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[paginate_empty_list].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[paginate_specific_fields].gqlis excluded by!**/__snapshots__/**
📒 Files selected for processing (24)
README.mdsrc/strawchemy/dto/types.pysrc/strawchemy/schema/factories/base.pysrc/strawchemy/schema/factories/inputs.pysrc/strawchemy/schema/factories/types.pysrc/strawchemy/schema/field.pysrc/strawchemy/utils/registry.pytests/integration/types/mysql.pytests/integration/types/postgres.pytests/integration/types/sqlite.pytests/unit/dto/test_dto.pytests/unit/mapping/test_schemas.pytests/unit/models.pytests/unit/schemas/order/auto_order_by.pytests/unit/schemas/order/order_empty_list.pytests/unit/schemas/order/order_specific_fields.pytests/unit/schemas/override/override_argument.pytests/unit/schemas/pagination/children_pagination.pytests/unit/schemas/pagination/children_pagination_defaults.pytests/unit/schemas/pagination/paginate_all_with_default.pytests/unit/schemas/pagination/paginate_and_order_combined.pytests/unit/schemas/pagination/paginate_empty_list.pytests/unit/schemas/pagination/paginate_specific_fields.pytests/unit/schemas/pagination/pagination_default_limit.py
🧰 Additional context used
🧬 Code graph analysis (18)
tests/integration/types/sqlite.py (1)
src/strawchemy/transpiler/_query.py (1)
order(100-102)
tests/unit/schemas/override/override_argument.py (2)
tests/fixtures.py (1)
strawchemy(34-35)src/strawchemy/transpiler/_query.py (1)
order(100-102)
tests/unit/models.py (3)
tests/unit/dc_models.py (1)
UUIDBase(14-15)src/strawchemy/dto/base.py (1)
name(318-319)tests/integration/models.py (2)
Fruit(127-146)Color(149-155)
tests/integration/types/postgres.py (4)
tests/fixtures.py (1)
strawchemy(34-35)tests/unit/models.py (2)
Fruit(56-64)Color(81-85)tests/integration/models.py (2)
Fruit(127-146)Color(149-155)src/strawchemy/transpiler/_query.py (1)
order(100-102)
tests/unit/dto/test_dto.py (1)
src/strawchemy/dto/types.py (4)
DTOConfig(115-276)from_include(189-190)Purpose(67-87)is_field_included(273-276)
tests/unit/schemas/order/order_empty_list.py (1)
tests/unit/schemas/order/order_specific_fields.py (2)
ContainerType(12-13)Query(17-18)
tests/unit/schemas/pagination/pagination_default_limit.py (3)
tests/fixtures.py (1)
strawchemy(34-35)tests/unit/models.py (1)
Fruit(56-64)tests/integration/models.py (1)
Fruit(127-146)
tests/integration/types/mysql.py (2)
tests/fixtures.py (1)
strawchemy(34-35)src/strawchemy/transpiler/_query.py (1)
order(100-102)
src/strawchemy/schema/factories/types.py (2)
src/strawchemy/dto/types.py (4)
DTOConfig(115-276)Purpose(67-87)from_include(189-190)is_field_included(273-276)src/strawchemy/schema/pagination.py (1)
DefaultOffsetPagination(9-11)
tests/unit/schemas/pagination/children_pagination.py (3)
tests/fixtures.py (1)
strawchemy(34-35)tests/unit/models.py (1)
Fruit(56-64)tests/integration/models.py (1)
Fruit(127-146)
tests/unit/schemas/pagination/paginate_all_with_default.py (1)
src/strawchemy/schema/pagination.py (1)
DefaultOffsetPagination(9-11)
src/strawchemy/utils/registry.py (2)
src/strawchemy/schema/pagination.py (1)
DefaultOffsetPagination(9-11)src/strawchemy/schema/factories/base.py (1)
graphql_type(323-324)
tests/unit/schemas/pagination/children_pagination_defaults.py (2)
tests/fixtures.py (1)
strawchemy(34-35)src/strawchemy/schema/pagination.py (1)
DefaultOffsetPagination(9-11)
tests/unit/schemas/pagination/paginate_empty_list.py (4)
tests/fixtures.py (1)
strawchemy(34-35)tests/unit/models.py (1)
Container(200-212)tests/unit/schemas/order/order_empty_list.py (2)
ContainerType(12-13)Query(17-18)tests/unit/schemas/pagination/paginate_specific_fields.py (2)
ContainerType(12-13)Query(17-18)
src/strawchemy/schema/factories/inputs.py (2)
src/strawchemy/schema/factories/types.py (1)
_aggregation_field(89-104)src/strawchemy/dto/types.py (1)
copy_with(192-232)
tests/unit/schemas/pagination/paginate_specific_fields.py (3)
tests/fixtures.py (1)
strawchemy(34-35)tests/unit/models.py (1)
Container(200-212)tests/unit/schemas/pagination/paginate_all_with_default.py (1)
Query(18-19)
src/strawchemy/dto/types.py (1)
src/strawchemy/dto/base.py (1)
name(318-319)
tests/unit/schemas/order/auto_order_by.py (3)
tests/unit/models.py (1)
Group(151-159)tests/integration/models.py (1)
Group(158-162)src/strawchemy/transpiler/_query.py (1)
order(100-102)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
- GitHub Check: 🔬 integration-postgres on 3.12
- GitHub Check: 🔬 integration-sqlite on 3.11
- GitHub Check: 🔬 integration-mysql on 3.10
- GitHub Check: 🔬 integration-postgres on 3.14
- GitHub Check: 🔬 integration-mysql on 3.13
- GitHub Check: 🔬 integration-sqlite on 3.10
- GitHub Check: 🔬 integration-sqlite on 3.14
- GitHub Check: 🔬 integration-postgres on 3.10
- GitHub Check: 🔬 integration-postgres on 3.13
- GitHub Check: 🔬 integration-postgres on 3.11
- GitHub Check: 🔬 integration-mysql on 3.12
- GitHub Check: 🔬 integration-sqlite on 3.13
- GitHub Check: 🔬 unit-no-extras on 3.12
- GitHub Check: 🔬 unit on 3.12
- GitHub Check: 🔬 unit-no-extras on 3.10
- GitHub Check: 🔬 unit on 3.10
- GitHub Check: 🔬 unit on 3.13
- GitHub Check: 🔬 unit on 3.11
- GitHub Check: Optimize new code in this PR
🔇 Additional comments (31)
tests/unit/mapping/test_schemas.py (2)
201-202: LGTM! Order test coverage expanded.The two new order test cases (
order_specific_fields,order_empty_list) follow the established pattern and are well-placed with other order tests. Theorder_empty_listcase is particularly valuable for edge case testing.
189-192: LGTM! Comprehensive pagination test coverage added.The four new pagination test cases (
paginate_specific_fields,paginate_empty_list,paginate_and_order_combined,paginate_all_with_default) follow the existing pattern and expand coverage for the refactored pagination API. All corresponding test schema modules exist at the specified paths, and the naming is clear and descriptive.tests/unit/schemas/order/order_empty_list.py (4)
1-6: LGTM: Imports are well-structured.The imports are appropriate for a Strawchemy test schema module, with future annotations enabled for better type hint support.
8-8: LGTM: Strawchemy instance initialization.The PostgreSQL-specific Strawchemy instance is correctly initialized for use in the schema definitions.
16-18: LGTM: Query type definition is correct.The Query type correctly defines a container field returning a list of ContainerType using the Strawchemy field helper.
11-13: This is a test fixture file tested by the centralized snapshot test intests/unit/mapping/test_schemas.py.The schema definition with
order=[]is validated through the parametrizedtest_query_schemasfunction, which generates and compares the GraphQL schema against snapshots. This pattern is consistent across the other schema files in the same directory.Likely an incorrect or invalid review comment.
src/strawchemy/schema/field.py (1)
115-115: LGTM: Minor formatting improvement.The blank line improves readability by visually separating the pagination initialization logic from the subsequent field assignments.
tests/unit/schemas/pagination/paginate_all_with_default.py (1)
1-19: LGTM: Test correctly demonstrates custom pagination defaults.This test file properly demonstrates the new
paginate="all"API with a customDefaultOffsetPaginationconfiguration. The implementation aligns with the PR's objective to provide explicit pagination control.src/strawchemy/utils/registry.py (1)
104-106: LGTM: Enhanced API for granular pagination and ordering control.The refactored
RegistryTypeInfofields replace boolean flags with more flexible configurations:
paginationnow accepts an optionalDefaultOffsetPaginationinstance (rather thanbool | DefaultOffsetPagination)orderandpaginateaccept either"all"or afrozensetof specific field namesThis enables per-field control over pagination and ordering, which is a significant improvement over the previous boolean approach. The use of
frozensetwithdefault_factorycorrectly prevents shared mutable defaults.tests/unit/schemas/order/order_specific_fields.py (1)
1-18: LGTM: Test correctly demonstrates selective field ordering.This test properly showcases the new
orderparameter with an explicit field list["fruits", "vegetables"], enabling ordering for only those specific fields while excluding others (e.g., "colors"). This aligns with the PR's objective to provide granular control over ordering behavior.tests/unit/dto/test_dto.py (1)
269-328: LGTM: Comprehensive test coverage for new DTOConfig methods.The test suite thoroughly covers the new
from_include()andis_field_included()methods with multiple scenarios:
- Different input types (
None,"all",list,set)- Custom
Purposevalues- Edge cases (empty include, non-existent fields)
This comprehensive coverage ensures the new inclusion logic behaves correctly across all use cases.
tests/unit/schemas/pagination/pagination_default_limit.py (1)
11-11: LGTM: Updated to use new explicit pagination API.The change from
child_pagination=Truetopaginate="all"correctly migrates to the new explicit pagination API, making the intent clearer while maintaining the same functionality.src/strawchemy/schema/factories/inputs.py (1)
146-148: LGTM: Correctly enables partial field specification for aggregate filters.Adding
partial=Trueto thedto_config.copy_with()call ensures that aggregate filter fields are treated as optional, which aligns with filter semantics where users should be able to specify only the fields they want to filter on. This change complements thepartial_default=UNSETparameter for proper handling of unspecified filter criteria.tests/unit/models.py (1)
200-213: No action needed—these relationships are intentionally arbitrary and designed for schema generation testing.The
Containermodel's relationships withprimaryjoinconditions are intentionally configured for testing Strawchemy's pagination/ordering schema generation with multiple list relationships. These are snapshot tests (intest_query_schemas) that verify the generated GraphQL schema structure, not integration tests that query actual data. Theviewonly=Truesetting is appropriate, and test fixtures that populate matching data are not required because the relationships are never used to execute queries.tests/unit/schemas/override/override_argument.py (1)
11-11: LGTM! API update is clear and consistent.The change from
child_pagination=True, child_order_by=Truetopaginate="all", order="all"makes the pagination and ordering controls more explicit and flexible.README.md (1)
600-600: LGTM! Documentation updated correctly.The README example now reflects the new
paginate="all"parameter, helping users understand the updated API for enabling pagination on nested relationships.tests/unit/schemas/order/auto_order_by.py (1)
11-11: LGTM! Ordering API update is consistent.The change from
child_order_by=Truetoorder="all"aligns with the new API design, making ordering controls more explicit.tests/integration/types/sqlite.py (1)
153-153: LGTM! Integration test updates are consistent.All three type declarations correctly adopt the new pagination and ordering parameters:
paginate="all"replaceschild_pagination=Trueorder="all"replaceschild_order_by=TrueThe changes are consistent with the broader API refactoring.
Also applies to: 184-184, 196-196
tests/unit/schemas/pagination/children_pagination.py (1)
11-11: LGTM! Pagination test updated correctly.The test now uses
paginate="all"instead ofchild_pagination=True, aligning with the new API.tests/unit/schemas/pagination/children_pagination_defaults.py (1)
12-12: LGTM! New pagination defaults API is clearer.The change introduces separate
paginate="all"anddefault_pagination=DefaultOffsetPagination(...)parameters, which is more explicit than the previous approach wherechild_paginationcould be either a boolean or a pagination config.src/strawchemy/dto/types.py (1)
188-190: LGTM! Helper classmethod is straightforward.The
from_includeclassmethod provides a convenient way to construct aDTOConfigwith an include parameter, defaulting to an empty set whenincludeis None.tests/unit/schemas/pagination/paginate_specific_fields.py (1)
11-13: LGTM! New API enables granular pagination control.This test demonstrates a key improvement in the new API:
paginate=["fruits"]allows enabling pagination on specific fields rather than all-or-nothing. This provides much finer-grained control compared to the previouschild_pagination=True.tests/unit/schemas/pagination/paginate_empty_list.py (1)
1-18: LGTM! Test file correctly demonstrates the newpaginateAPI.The test file follows the established pattern and correctly uses
paginate=[]to demonstrate disabling pagination for all fields.tests/integration/types/postgres.py (1)
162-163: LGTM! Integration test types correctly updated to new pagination/ordering API.The changes consistently replace the old
child_pagination/child_order_byboolean flags with the new explicitpaginateandorderparameters. This aligns with the PR's refactoring goals and matches the pattern used in other integration test files.Also applies to: 193-194, 205-206
tests/unit/schemas/pagination/paginate_and_order_combined.py (1)
1-33: LGTM! Excellent test coverage for combined pagination and ordering scenarios.This test file demonstrates various combinations:
- Different fields for pagination vs ordering
- Overlapping field specifications
- Mixing "all" with specific field lists
This provides good coverage for the new API's flexibility.
tests/integration/types/mysql.py (1)
154-155: LGTM! MySQL integration tests updated consistently with PostgreSQL tests.The changes mirror those in
tests/integration/types/postgres.py, ensuring consistent behavior across database backends.Also applies to: 185-186, 197-198
src/strawchemy/schema/factories/types.py (2)
106-160: LGTM! Refactored method correctly implements per-field pagination and ordering controls.The renamed
_add_fields_argumentsmethod (formerly_update_fields) properly:
- Uses
DTOConfig.from_include()to create configuration objects from theorderandpaginateparameters- Checks field inclusion via
is_field_included()before applying pagination or ordering- Adds JSON path filtering support for JSON/dict fields (lines 134-147)
The implementation correctly handles the various cases:
"all", specific field lists, andNone.
193-251: LGTM! Factory method signature correctly updated with new pagination/ordering parameters.The changes properly:
- Add
default_pagination,order, andpaginateparameters to the factory signature- Pass
"all"values through tosuper().factory()while converting other values toNone(lines 229-231)- Pass original parameter values to
_add_fields_arguments(line 236) and_register_type(lines 246-248)This allows the factory to handle both DTO-level (via super) and field-level (via
_add_fields_arguments) pagination/ordering configuration.src/strawchemy/schema/factories/base.py (3)
210-268: LGTM! Type wrapper correctly threads new pagination and ordering parameters.The
_type_wrappermethod properly:
- Accepts the new
paginate,order, anddefault_paginationparameters (lines 221-223)- Passes them through to the factory call (lines 257-259)
The decorator pattern is correctly maintained.
437-483: LGTM! Publictypemethod correctly exposes new pagination/ordering API.The method signature properly adds the new parameters (lines 448-450) and passes them to
_type_wrapper(lines 470-472), making the new API available to users.
592-634: LGTM! Unmapped DTO factorytypemethod updated consistently.The unmapped factory's
typemethod includes the same parameter additions (lines 601-603) and passes them through correctly (lines 622-624), ensuring API consistency across factory types.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #147 +/- ##
==========================================
- Coverage 94.28% 92.15% -2.14%
==========================================
Files 69 70 +1
Lines 5814 6096 +282
Branches 770 805 +35
==========================================
+ Hits 5482 5618 +136
- Misses 190 329 +139
- Partials 142 149 +7 ☔ View full report in Codecov by Sentry. |
|
Note Docstrings generation - SUCCESS |
Docstrings generation was requested by @gazorby. * #147 (comment) The following files were modified: * `src/strawchemy/dto/types.py` * `src/strawchemy/schema/factories/base.py` * `src/strawchemy/schema/factories/inputs.py` * `src/strawchemy/schema/factories/types.py` * `src/strawchemy/schema/field.py` * `src/strawchemy/utils/registry.py`
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/strawchemy/schema/factories/base.py (1)
83-86: Remove unusedChildOptionsclass or document its purpose.The
ChildOptionsdataclass is defined but never instantiated or referenced anywhere in the codebase—only re-exported as part of the public API. If this is a leftover from refactoring (the comment suggests it may relate to removedchild_paginationandchild_order_bylogic), consider either removing it or documenting why it's retained for external API stability.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[pagination_default_offset].gqlis excluded by!**/__snapshots__/**
📒 Files selected for processing (14)
src/strawchemy/config/base.pysrc/strawchemy/dto/base.pysrc/strawchemy/dto/types.pysrc/strawchemy/dto/utils.pysrc/strawchemy/mapper.pysrc/strawchemy/schema/factories/base.pysrc/strawchemy/schema/factories/enum.pysrc/strawchemy/schema/factories/inputs.pysrc/strawchemy/schema/factories/types.pysrc/strawchemy/schema/field.pysrc/strawchemy/utils/registry.pysrc/strawchemy/validation/pydantic.pytests/unit/mapping/test_schemas.pytests/unit/schemas/pagination/pagination_default_offset.py
🧰 Additional context used
🧬 Code graph analysis (9)
src/strawchemy/mapper.py (1)
src/strawchemy/schema/pagination.py (1)
DefaultOffsetPagination(9-11)
src/strawchemy/validation/pydantic.py (1)
src/strawchemy/dto/types.py (2)
DTOConfig(115-337)Purpose(67-87)
src/strawchemy/utils/registry.py (2)
src/strawchemy/schema/pagination.py (1)
DefaultOffsetPagination(9-11)src/strawchemy/mapper.py (3)
field(167-193)field(196-221)field(223-329)
src/strawchemy/dto/types.py (3)
src/strawchemy/dto/utils.py (1)
field(72-83)src/strawchemy/mapper.py (3)
field(167-193)field(196-221)field(223-329)src/strawchemy/dto/base.py (1)
name(318-319)
src/strawchemy/schema/factories/types.py (1)
src/strawchemy/dto/types.py (4)
DTOConfig(115-337)Purpose(67-87)from_include(189-216)is_field_included(299-337)
src/strawchemy/schema/factories/enum.py (1)
src/strawchemy/dto/types.py (2)
DTOConfig(115-337)Purpose(67-87)
tests/unit/schemas/pagination/pagination_default_offset.py (2)
src/strawchemy/mapper.py (4)
Strawchemy(61-693)field(167-193)field(196-221)field(223-329)src/strawchemy/config/base.py (1)
StrawchemyConfig(18-63)
src/strawchemy/schema/factories/inputs.py (2)
src/strawchemy/schema/factories/types.py (1)
_aggregation_field(89-104)src/strawchemy/dto/types.py (1)
copy_with(218-258)
src/strawchemy/config/base.py (1)
src/strawchemy/schema/field.py (1)
order_by(235-240)
🪛 Ruff (0.14.10)
src/strawchemy/dto/types.py
189-189: Boolean-typed positional argument in function definition
(FBT001)
src/strawchemy/schema/factories/base.py
69-69: Boolean-typed positional argument in function definition
(FBT001)
340-340: Dynamically typed expressions (typing.Any) are disallowed in **kwargs
(ANN401)
647-647: Boolean-typed positional argument in function definition
(FBT001)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
- GitHub Check: 🔬 integration-mysql on 3.13
- GitHub Check: 🔬 integration-postgres on 3.14
- GitHub Check: 🔬 integration-sqlite on 3.12
- GitHub Check: 🔬 integration-mysql on 3.12
- GitHub Check: 🔬 integration-mysql on 3.11
- GitHub Check: 🔬 integration-postgres on 3.13
- GitHub Check: 🔬 unit-no-extras on 3.14
- GitHub Check: 🔬 unit-no-extras on 3.11
- GitHub Check: 🔬 integration-mysql on 3.14
- GitHub Check: 🔬 integration-postgres on 3.12
- GitHub Check: 🔬 integration-sqlite on 3.14
- GitHub Check: 🔬 unit on 3.14
- GitHub Check: 🔬 unit-no-extras on 3.10
- GitHub Check: 🔬 integration-postgres on 3.11
- GitHub Check: 🔬 unit on 3.10
- GitHub Check: 🔬 unit-no-extras on 3.12
- GitHub Check: 🔬 unit-no-extras on 3.13
- GitHub Check: 🔬 unit on 3.11
- GitHub Check: 🔬 unit on 3.13
- GitHub Check: Optimize new code in this PR
🔇 Additional comments (33)
src/strawchemy/schema/field.py (2)
115-116: LGTM: Formatting improvement.The added blank line improves readability by visually separating the pagination logic from the id_field_name assignment.
236-237: LGTM: Formatting improvement.The added blank line improves readability within the cached property.
src/strawchemy/mapper.py (1)
290-296: LGTM: Proper integration of pagination_default_offset.The DefaultOffsetPagination is now constructed with both
limitandoffsetfrom the config whenpagination=True, correctly implementing the new pagination defaults feature.src/strawchemy/dto/utils.py (1)
22-22: LGTM: Type alias updated consistently.The import and parameter type correctly changed from
ExcludeFieldstoFieldIterable, aligning with the broader refactoring across the codebase.Also applies to: 48-48
tests/unit/mapping/test_schemas.py (1)
188-193: LGTM: Comprehensive test coverage for new pagination and order features.The added test scenarios properly cover the new pagination and order API features including default offsets, specific field pagination/ordering, empty lists, and combined scenarios.
Also applies to: 202-203
src/strawchemy/config/base.py (1)
50-57: LGTM: Well-organized configuration additions.The new configuration options are properly grouped with related pagination settings and have sensible defaults:
order_by: bool = Falsefor enabling order by on list resolverspagination_default_offset: int = 0for default pagination offsetThe docstrings are clear and follow the existing style.
tests/unit/schemas/pagination/pagination_default_offset.py (1)
1-18: LGTM: Proper test for pagination_default_offset.The test correctly exercises the new
pagination_default_offset=5configuration option with appropriate type decorators (include="all",paginate="all") and field setup (pagination=True).src/strawchemy/validation/pydantic.py (1)
27-27: LGTM: Consistent type alias update.The import and parameter type correctly updated from
ExcludeFieldstoFieldIterable, maintaining consistency with the broader refactoring effort.Also applies to: 87-87
src/strawchemy/schema/factories/inputs.py (2)
35-35: LGTM: Consistent type alias update.The import and parameter type correctly updated from
ExcludeFieldstoFieldIterable, maintaining consistency with the broader refactoring.Also applies to: 55-55
146-148: Confirmed:partial=Truefor aggregation filters is intentional and documented.The addition of
partial=Truemakes all fields in the aggregation filter DTO optional, which is the intended behavior. This is documented inDTOConfigand follows the same pattern used for aggregate types attypes.py:419. Aggregation filters are naturally optional—developers specify only the filters they need—which aligns with GraphQL filter input conventions. Existing integration tests intests/integration/test_aggregation_filters.pyvalidate this behavior across count, min/max string, sum, and avg aggregations.src/strawchemy/dto/base.py (2)
35-36: LGTM!Import of
FieldIterablealigns with the type system refactor replacingExcludeFields.
688-688: LGTM!The
excludeparameter type updated toFieldIterable | Noneis consistent with the broader API refactor.src/strawchemy/schema/factories/enum.py (1)
13-13: LGTM!Import and type annotation updates for
FieldIterableare consistent with the broader DTO type system refactor.Also applies to: 144-144, 167-167
src/strawchemy/utils/registry.py (2)
104-106: LGTM with observation on type asymmetry.The new
orderandpaginatefields properly support per-field configuration. Note thatorderacceptsLiteral["all"]whilepaginatedoes not—verify this asymmetry is intentional.
114-114: LGTM!The
scoped_idproperty correctly maintains the existing identity tuple structure.src/strawchemy/dto/types.py (4)
26-26: LGTM!The
FieldIterabletype alias is well-defined and properly exported. The updatedIncludeFieldstype correctly extendsFieldIterablewith the"all"literal.Also applies to: 33-34
163-163: LGTM!The
excludefield type updated toFieldIterableis consistent with the new type system.
222-222: LGTM!The
copy_withmethod'sexcludeparameter type correctly updated toFieldIterable | None.
298-337: LGTM!The
is_field_includedimplementation correctly handles all documented cases:
- Returns
Truewheninclude="all"and field not inexclude- Returns
Truewhen field is in specificincludeset and not inexclude- Returns
Falsewhen field is explicitly excludedThe logic
(name in self.include or self.include == "all") and name not in self.excludeproperly respects both include and exclude constraints.src/strawchemy/schema/factories/types.py (4)
23-23: LGTM!Import of
IncludeFieldsaligns with the new per-field inclusion configuration.
106-192: LGTM!The
_add_fields_argumentsmethod is well-designed:
- Clear documentation of the pagination/ordering behavior
- Properly uses
DTOConfig.from_includeto convert field specifications- Uses
is_field_includedto check per-field configuration- JSON path filtering for JSON/dict fields is a nice enhancement
One note: Line 162 uses
default_pagination or True, which means pagination defaults toTruewhendefault_paginationisNone. This seems intentional for enabling pagination without custom limits.
238-284: LGTM!The factory method properly propagates the new
order,paginate, anddefault_paginationparameters. The logic at lines 262-264 to only pass"all"values to nested types (otherwiseNone) correctly scopes the propagation of global settings.
588-602: LGTM!The
InputFactory._cache_keysimplification correctly delegates to the parent implementation while adding mode-specific cache key components.src/strawchemy/schema/factories/base.py (10)
48-55: LGTM!Import reorganization properly moves
DefaultOffsetPaginationintoTYPE_CHECKINGand adds the newFieldIterableandIncludeFieldstypes.
69-76: LGTM!The
_to_frozenset_or_boolhelper correctly convertsIncludeFieldsspecifications to thefrozenset | boolformat expected byRegistryTypeInfo. The match statement handles all cases cleanly.
103-134: LGTM!The
_type_infomethod properly integrates the neworder,paginate, anddefault_paginationparameters intoRegistryTypeInfoconstruction using the_to_frozenset_or_boolhelper.
136-162: LGTM!The
_register_typemethod correctly propagates the new pagination/ordering parameters to_type_info.
196-218: LGTM!The
_configmethod properly acceptsFieldIterablefor theexcludeparameter.
220-278: LGTM!The
_type_wrappermethod properly:
- Accepts the new
paginate,order, anddefault_paginationparameters- Falls back to
self._mapper.configdefaults when parameters areNone(lines 267-269)- Propagates these to the factory call
280-366: LGTM!Good refactoring:
_input_wrappernow delegates tomake_inputfor cleaner code reusemake_inputis a well-structured public helper that can be called directly without the decorator pattern
488-533: LGTM!The
StrawchemyMappedFactory.typemethod properly exposes the newpaginate,order, anddefault_paginationparameters in the public API and propagates them to_type_wrapper.
536-571: LGTM!The
StrawchemyMappedFactory.inputmethod properly acceptsFieldIterableforexclude.
606-684: LGTM!The
StrawchemyUnMappedDTOFactorymethods properly mirror the updates inStrawchemyMappedFactorywith the new pagination/ordering parameters andFieldIterabletype forexclude.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/strawchemy/config/base.py (1)
28-29: Docstring inconsistency with new API.The docstring says
pagination=Truebut the new API usespagination="all". The docstring should be updated to reflect the new semantics.🔎 Proposed fix
- pagination_default_limit: Default pagination limit when `pagination=True`. + pagination_default_limit: Default pagination limit when pagination is enabled.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (2)
tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_default].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[pagination_config_default].gqlis excluded by!**/__snapshots__/**
📒 Files selected for processing (7)
src/strawchemy/config/base.pysrc/strawchemy/mapper.pysrc/strawchemy/schema/field.pysrc/strawchemy/schema/mutation/field_builder.pytests/unit/mapping/test_schemas.pytests/unit/schemas/order/order_config_default.pytests/unit/schemas/pagination/pagination_config_default.py
🧰 Additional context used
🧬 Code graph analysis (4)
src/strawchemy/config/base.py (1)
src/strawchemy/schema/field.py (1)
order_by(238-247)
src/strawchemy/schema/field.py (2)
src/strawchemy/schema/factories/inputs.py (1)
OrderByDTOFactory(346-475)src/strawchemy/dto/strawberry.py (1)
OrderByDTO(451-467)
src/strawchemy/schema/mutation/field_builder.py (1)
src/strawchemy/schema/factories/inputs.py (1)
OrderByDTOFactory(346-475)
tests/unit/schemas/pagination/pagination_config_default.py (3)
tests/fixtures.py (1)
strawchemy(34-35)src/strawchemy/mapper.py (1)
Strawchemy(61-698)src/strawchemy/config/base.py (1)
StrawchemyConfig(18-63)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
- GitHub Check: 🔬 integration-mysql on 3.11
- GitHub Check: 🔬 integration-sqlite on 3.13
- GitHub Check: 🔬 integration-postgres on 3.14
- GitHub Check: 🔬 integration-postgres on 3.12
- GitHub Check: 🔬 unit-no-extras on 3.10
- GitHub Check: 🔬 unit-no-extras on 3.12
- GitHub Check: 🔬 unit-no-extras on 3.11
- GitHub Check: 🔬 integration-postgres on 3.11
- GitHub Check: 🔬 integration-sqlite on 3.12
- GitHub Check: 🔬 integration-mysql on 3.12
- GitHub Check: 🔬 unit on 3.13
- GitHub Check: 🔬 unit on 3.12
- GitHub Check: 🔬 integration-postgres on 3.10
- GitHub Check: 🔬 integration-mysql on 3.10
- GitHub Check: 🔬 unit on 3.10
- GitHub Check: 🔬 unit on 3.14
- GitHub Check: 🔬 unit-no-extras on 3.13
- GitHub Check: 🔬 unit-no-extras on 3.14
- GitHub Check: 🔬 unit on 3.11
- GitHub Check: Optimize new code in this PR
🔇 Additional comments (14)
tests/unit/schemas/order/order_config_default.py (3)
1-6: LGTM!The imports are appropriate for this test schema definition.
8-8: LGTM!The configuration correctly demonstrates the new
order_by="all"global setting, aligning with the PR's refactoring objectives.
11-18: Schema definition is correct and properly integrated.The type definitions are well-structured. FruitType properly uses
@strawchemy.type(Fruit, include="all")to expose all fields, and the Query type correctly defines the fruits field usingstrawchemy.field(). This fixture file is referenced intests/unit/mapping/test_schemas.py:202as a pytest parameter ("order.order_config_default.Query"), confirming it is properly integrated into the test suite.tests/unit/mapping/test_schemas.py (2)
156-161: AI summary inconsistency detected.The AI-generated summary claims changes were made to this test function, but no modifications are visible here. All actual changes are in the
test_query_schemasparameterized test cases (lines 188-193 and 202-204).
188-193: Good expansion of test coverage for pagination and order API.The new test cases appropriately cover various pagination and ordering scenarios that align with the PR's refactoring objectives. The naming is consistent and descriptive. All referenced test schema files exist and the test structure is correct.
src/strawchemy/schema/mutation/field_builder.py (1)
18-18: LGTM!The
OrderByDTOFactoryis correctly added as a required dependency and properly propagated through the mutation field construction. The TYPE_CHECKING import pattern is appropriate for avoiding circular imports.Also applies to: 39-39, 109-109
tests/unit/schemas/pagination/pagination_config_default.py (1)
8-8: LGTM!The test correctly uses the new
pagination="all"API, which aligns with the refactoredStrawchemyConfig.paginationtype ofLiteral["all"] | None.src/strawchemy/config/base.py (1)
50-53: LGTM!The new
paginationandorder_byfields withLiteral["all"] | Nonetyping provide clear, explicit semantics for global configuration. This is a good improvement over boolean flags.src/strawchemy/schema/field.py (3)
79-81: LGTM!The addition of
order_by_factoryparameter and widening oforder_bytype totype[OrderByDTO] | bool | Noneenables both explicit type specification and boolean flag control, which aligns well with the new global configuration pattern.
237-247: LGTM!The
order_byproperty logic correctly handles all precedence cases:
- Explicit
Trueor global config enable → use factoryNonewithout global config → fall back to type's defaultFalse→ explicitly disabled- Custom type → use as-is
The implementation is clean and the precedence is intuitive.
366-366: LGTM!Correctly propagates
order_by_factorywhen copying the field, ensuring cloned fields maintain proper factory reference.src/strawchemy/mapper.py (3)
138-142: LGTM!The
MutationFieldBuilderconstruction now uses explicit keyword arguments, improving readability and correctly wiring the neworder_by_factorydependency.
176-176: LGTM!The
order_byparameter type is consistently updated across all overloads totype[OrderByDTO] | bool | None, enabling both explicit type specification and boolean flag control.Also applies to: 204-204, 232-232
332-332: LGTM!Correctly wires
order_by_factorytoStrawchemyField, completing the dependency injection chain fromStrawchemy→StrawchemyField.
There was a problem hiding this comment.
Actionable comments posted: 3
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
README.mdsrc/strawchemy/dto/types.pysrc/strawchemy/schema/factories/base.py
🧰 Additional context used
🧬 Code graph analysis (2)
src/strawchemy/dto/types.py (2)
src/strawchemy/dto/utils.py (1)
field(72-83)src/strawchemy/dto/base.py (1)
name(318-319)
src/strawchemy/schema/factories/base.py (5)
src/strawchemy/dto/types.py (2)
DTOConfig(115-311)Purpose(67-87)src/strawchemy/schema/pagination.py (1)
DefaultOffsetPagination(9-11)src/strawchemy/dto/utils.py (1)
config(45-69)src/strawchemy/schema/factories/inputs.py (2)
factory(166-193)factory(446-475)src/strawchemy/schema/factories/types.py (3)
factory(226-284)factory(348-377)factory(691-720)
🪛 LanguageTool
README.md
[grammar] ~2105-~2105: Use a hyphen to join words.
Context: ... | Automatically convert snake cased names to camel case in GraphQL sch...
(QB_NEW_EN_HYPHEN)
🪛 Ruff (0.14.10)
src/strawchemy/schema/factories/base.py
340-340: Dynamically typed expressions (typing.Any) are disallowed in **kwargs
(ANN401)
647-647: Boolean-typed positional argument in function definition
(FBT001)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
- GitHub Check: 🔬 integration-mysql on 3.11
- GitHub Check: 🔬 integration-postgres on 3.12
- GitHub Check: 🔬 integration-mysql on 3.13
- GitHub Check: 🔬 integration-sqlite on 3.12
- GitHub Check: 🔬 unit-no-extras on 3.10
- GitHub Check: 🔬 integration-sqlite on 3.14
- GitHub Check: 🔬 integration-sqlite on 3.11
- GitHub Check: 🔬 integration-postgres on 3.13
- GitHub Check: 🔬 unit-no-extras on 3.13
- GitHub Check: 🔬 integration-postgres on 3.11
- GitHub Check: 🔬 integration-postgres on 3.14
- GitHub Check: 🔬 unit-no-extras on 3.12
- GitHub Check: 🔬 integration-mysql on 3.10
- GitHub Check: 🔬 integration-sqlite on 3.13
- GitHub Check: 🔬 unit on 3.14
- GitHub Check: 🔬 integration-postgres on 3.10
- GitHub Check: 🔬 unit on 3.11
- GitHub Check: 🔬 unit on 3.10
- GitHub Check: 🔬 unit on 3.12
- GitHub Check: Optimize new code in this PR
🔇 Additional comments (11)
src/strawchemy/dto/types.py (3)
10-10: LGTM: Import ofSelfis appropriate.The
Selftype fromtyping_extensionsis correctly imported for use in thefrom_includeclassmethod return type annotation.
33-34: LGTM: Type aliases enhance flexibility.The new
FieldIterabletype alias broadens the acceptable field collection types (addingfrozensetandtuple), andIncludeFieldsprovides a clear semantic distinction for inclusion specifications.
292-311: LGTM: Field inclusion logic correctly respects exclude.The implementation correctly checks both inclusion and exclusion rules. When
include == "all", it properly respects theexcludeset by returningFalsefor excluded fields. This addresses the issue raised in previous reviews.src/strawchemy/schema/factories/base.py (5)
103-134: LGTM: Pagination and ordering parameters properly threaded through type registration.The
_type_infomethod correctly accepts and processes the neworder,paginate, anddefault_paginationparameters, using the helper function to normalize them before passing toRegistryTypeInfo.
321-367: LGTM: Newmake_inputmethod provides useful programmatic API.The
make_inputmethod is a well-structured addition that enables programmatic input DTO creation without the decorator pattern. The use of**kwargs(flagged by static analysis as ANN401) is an acceptable pattern in factory methods for extensibility.
220-278: LGTM: Configuration cascade correctly implemented.The
_type_wrapperproperly implements a configuration cascade where field-level parameters (paginate,order,default_pagination) override config-level defaults. This provides flexibility while maintaining sensible defaults.
488-571: LGTM: Public method signatures consistently updated.The
type()andinput()decorator methods have been properly updated with the new pagination and ordering parameters. The signatures are consistent with the internal factory changes and maintain backward compatibility with default values.
103-162: LGTM: Refactoring is systematic and consistent.The pagination and ordering parameter changes are applied consistently across all factory methods (
_type_info,_register_type,_type_wrapper,_input_wrapper,type,input). The transition fromExcludeFieldstoFieldIterableis also uniformly applied throughout.Also applies to: 220-367, 488-571
README.md (3)
571-656: LGTM: Pagination documentation is comprehensive and accurate.The expanded pagination section clearly documents three usage levels (field, config, type) with accurate code examples. The distinction between
pagination(config/field level) andpaginate(type decorator) parameter names is correctly reflected.
658-768: LGTM: Comprehensive ordering documentation added.The new Ordering section provides clear examples across all configuration levels (field, type, config) and demonstrates nested relationship ordering. The examples accurately reflect the new API with
orderandorder_byparameters.
2128-2139: LGTM: Configuration example demonstrates new features correctly.The example accurately shows how to configure global pagination and ordering using
pagination="all"andorder_by="all"along with default pagination limits and offsets.
There was a problem hiding this comment.
Actionable comments posted: 19
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
src/strawchemy/schema/factories/inputs.py (1)
166-194: Missingno_cacheparameter forwarding in_FilterDTOFactory.factory.The
no_cacheparameter is added to the method signature (line 177) but is not forwarded tosuper().factory()call (lines 182-193). This means the cache bypass won't work for_FilterDTOFactorysubclasses.🐛 Proposed fix
def factory( self, model: type[DeclarativeT], dto_config: DTOConfig, base: type[Any] | None = None, name: str | None = None, parent_field_def: DTOFieldDefinition[DeclarativeBase, QueryableAttribute[Any]] | None = None, current_node: Node[Relation[Any, GraphQLFilterDTOT], None] | None = None, raise_if_no_fields: bool = False, tags: set[str] | None = None, backend_kwargs: dict[str, Any] | None = None, no_cache: bool = False, *, aggregate_filters: bool = True, **kwargs: Any, ) -> type[GraphQLFilterDTOT]: return super().factory( model, dto_config, base, name, parent_field_def, current_node, raise_if_no_fields, tags, backend_kwargs, + no_cache, aggregate_filters=aggregate_filters, **kwargs, )src/strawchemy/schema/field.py (1)
420-451:__copy__loses explicitpagination=Falseand may re-enable pagination via config.
Line 444 passespagination=self.pagination, butself.paginationreturnsNonewhen_paginationisFalse, so the copied field will behave as if pagination was never explicitly disabled (and may inherit"all"from config).Proposed fix
@@ def __copy__(self) -> Self: new_field = type(self)( @@ - pagination=self.pagination, + pagination=self._pagination, registry_namespace=self.registry_namespace, execution_options=self._execution_options, config=self._config, order_by_factory=self._order_by_factory, filter_factory=self._filter_factory, distinct_on_factory=self._distinct_on_factory, )src/strawchemy/schema/factories/base.py (3)
410-461:no_cacheis accepted but not forwarded inStrawchemyMappedFactory.factory()(breaksmake_input(..., no_cache=True)).
GraphQLDTOFactory.make_input()passesno_cache=...intoself.factory(...), butStrawchemyMappedFactory.factory()drops it when callingsuper().factory(...). That can re-enable caching / ignore uniquified names, causing type collisions or wrong reuse.Proposed fix
@@ class StrawchemyMappedFactory(GraphQLDTOFactory[MappedGraphQLDTOT]): @@ def factory( @@ - no_cache: bool = False, + no_cache: bool = False, *, mode: GraphQLPurpose | None = None, **kwargs: Any, ) -> type[MappedGraphQLDTOT]: @@ return super().factory( model, dto_config, base, name, parent_field_def, current_node, raise_if_no_fields, tags, backend_kwargs=backend_kwargs, + no_cache=no_cache, mode=mode, **kwargs, )Also applies to: 579-610
648-689: Ruff FBT001: make bool params keyword-only inStrawchemyUnMappedDTOFactory.type()by adding*.
This also brings it in line withStrawchemyMappedFactory.type()which is already keyword-only.Proposed fix
@@ class StrawchemyUnMappedDTOFactory(GraphQLDTOFactory[UnmappedGraphQLDTOT]): @@ def type( self, model: type[T], - include: IncludeFields | None = None, + *, + include: IncludeFields | None = None, exclude: FieldIterable | None = None, partial: bool | None = None, type_map: Mapping[Any, Any] | None = None, aliases: Mapping[str, str] | None = None, alias_generator: Callable[[str], str] | None = None, paginate: IncludeFields | None = None, default_pagination: None | DefaultOffsetPagination = None, filter_input: type[BooleanFilterDTO] | None = None, order_by: IncludeFields | type[OrderByDTO] | None = None, name: str | None = None, description: str | None = None, directives: Sequence[object] | None = (), query_hook: QueryHook[T] | list[QueryHook[T]] | None = None, override: bool = False, purpose: Purpose = Purpose.READ, mode: GraphQLPurpose = "type", ) -> Callable[[type[Any]], type[UnmappedStrawberryGraphQLDTO[T]]]:
95-123: Fix the silent conversion ofNonetofrozenset()fororder,distinct_on, andpaginatefields inRegistryTypeInfo.The current logic converts
Noneto an emptyfrozenset()becauseis_fields_iterable(None)returnsTrue. This breaks the semantic distinction between "not specified" (None) and "explicitly empty" (frozenset()). Additionally, theRegistryTypeInfofield type annotations do not acceptNone—they only acceptfrozenset[str] | Literal["all"] | type[OrderByDTO/EnumDTO]—creating a type mismatch between the method parameters and the dataclass fields.Either:
- Exclude
Nonefromis_fields_iterable()and handle it separately in_type_info(), or- Explicitly document that
Noneparameters are normalized to emptyfrozenset()and update type annotations to reflect this behavior.
🤖 Fix all issues with AI agents
In @examples/testapp/testapp/types.py:
- Line 23: The project mixes two ordering parameters: the type decorator uses
order= (e.g., @strawchemy.type(Ticket, include="all", filter_input=TicketFilter,
order=TicketOrder, override=True)) while field-level calls still use order_by=;
update all strawchemy.field(...) usages to replace order_by= with order= so the
field-level API matches the type-level API (search for strawchemy.field in tests
and examples, e.g., tests/unit/schemas/order/field_order_by_specific_fields.py
and examples/testapp/testapp/types.py references to
Ticket/TicketFilter/TicketOrder).
In @src/strawchemy/config/base.py:
- Around line 51-64: Update the field docstrings to correct their descriptions:
change the docstring for the exclude field (symbol: exclude: FieldIterable |
None) from "Globally included fields." to something like "Globally excluded
fields." and fix the typo in the distinct_on field docstring (symbol:
distinct_on: IncludeFields | None) from "Enable/disable order by onelist
resolvers." to "Enable/disable order by on list resolvers."
In @src/strawchemy/dto/strawberry.py:
- Around line 132-134: DTOKey is missing a __slots__ declaration so instances
still get per-instance __dict__ despite inheriting from _Key; add a class-level
__slots__ = () to the DTOKey class (the DTOKey class definition referenced in
the diff) to prevent per-instance dictionaries and complete the memory
optimization already begun by _Key and the separator ClassVar.
In @src/strawchemy/mapper.py:
- Around line 86-87: Tidy the type annotation namespaces by removing dunder
entries before performing the dict unions: when building TYPING_NS in
dto/base.py (symbol TYPING_NS) filter vars(typing) and vars(types) to exclude
keys that start and end with "__" and use those cleaned dicts for the union;
similarly in mapper.py (symbol _types_namespace) filter vars(mutation_types) to
remove dunder keys and also ensure you union against the already-cleaned
TYPING_NS so both sources are consistently dunder-free.
In @src/strawchemy/schema/factories/base.py:
- Around line 301-373: The make_input signature currently uses an untyped
**kwargs: Any which triggers Ruff ANN401; change the var-keyword param to
**kwargs: object (or to a concrete Unpack[...] type if you have a stable shape)
in the make_input definition and update any related type annotations that depend
on it, and keep the forwarding call to self.factory(model=..., **kwargs) as-is;
specifically edit the make_input function's parameter list (the **kwargs: Any
token) and ensure usages like the call to self.factory remain compatible with
the new **kwargs: object typing.
In @tests/unit/schemas/distinct/distinct_config_all.py:
- Around line 1-18: Add a module-level docstring at the top describing that
distinct_on is PostgreSQL-specific and that configuring StrawchemyConfig(...,
distinct_on="all") enables PostgreSQL's DISTINCT ON semantics for all queries;
reference the StrawchemyConfig instantiation and the Strawchemy type usage
(strawchemy = Strawchemy(StrawchemyConfig("postgresql", distinct_on="all")) and
@strawchemy.type(Color, include="all")) so readers know the scope and expected
behavior when distinct_on="all" is set globally.
In @tests/unit/schemas/distinct/distinct_config_empty.py:
- Line 8: Add a module-level docstring to
tests/unit/schemas/distinct/distinct_config_empty.py explaining that passing
distinct_on=[] intentionally disables distinct_on behavior because empty lists
are falsy in Python; reference that this matches the runtime check in field.py
where `if self._is_strawchemy_type(inner_type) and distinct_on:` treats `[]`
equivalently to `None`, so the test demonstrates the disabled behavior. Ensure
the docstring clearly states intent for future readers and mentions the relevant
symbols `Strawchemy`, `StrawchemyConfig(distinct_on=[])`, and the
`self._is_strawchemy_type` + `distinct_on` check in `field.py`.
In @tests/unit/schemas/distinct/distinct_config_specific_fields.py:
- Around line 11-18: Add a short module-level docstring or a top-of-file comment
explaining that this test demonstrates config-level distinct_on inheritance:
when using the decorator on ColorType (@strawchemy.type(Color, include="all"))
the distinct_on setting defined in the schema/config is applied to the generated
type and therefore affects the Query.colors field; place the comment above the
class definitions (or directly above ColorType) and mention the symbols
ColorType, Query, and distinct_on to make the implicit inheritance behavior
explicit for future readers.
In @tests/unit/schemas/distinct/field_distinct_all.py:
- Around line 11-13: Add a concise docstring to clarify test intent: explain
that this module (or the ColorType class) verifies field-level distinct_on
behavior when using @strawchemy.type(Color, include="all") and that the test
ensures distinct_on="all" is applied to fields; place the docstring at the top
of the module or directly above the ColorType class to document purpose and
expected behavior.
In @tests/unit/schemas/distinct/field_distinct_specific_fields.py:
- Around line 1-18: Add a short module-level docstring at the top of this test
file that explains its purpose: that it verifies field-level distinct_on
behavior when specific fields are provided (e.g., using
strawchemy.field(distinct_on=["name", "hex"]) on the Query.colors field). Place
the docstring above the imports (or immediately after any future __future__
import) and mention the relation to order_config_all.py for consistency.
- Around line 1-18: The test references a non-existent "hex" attribute in the
Color model via the distinct_on=["name", "hex"] argument (see Query.colors using
strawchemy.field); fix by either adding a hex: Mapped[str] field to the Color
model class (so Color has name and hex attributes used by Strawchemy/ColorType)
or by removing "hex" from the distinct_on list in the test so it only uses
existing fields (e.g., distinct_on=["name"]); update the Color model or the
distinct_on usage accordingly to keep names consistent with the Color class and
the ColorType mapping.
In @tests/unit/schemas/order/field_order_by_specific_fields.py:
- Around line 1-18: Add a concise module-level docstring at the top of the test
file describing that this test verifies field-level order_by with specific
fields on relationship/collection fields; reference the testing intent alongside
the key items in the file (the Strawchemy instance "strawchemy", the annotated
type "ContainerType", and the "Query" class that uses
strawchemy.field(order_by=[...])) so readers understand the test purpose without
reading the implementation.
In @tests/unit/schemas/order/order_config_all.py:
- Around line 1-18: Add a module-level docstring at the top of the test file
describing that this module verifies global order_by configuration when
StrawchemyConfig is created with order_by="all" and that FruitType (created via
strawchemy.type on Fruit with include="all") is used in the Query to generate
fields; place a short explanatory string before the imports explaining the
purpose of the test and mentioning the key symbols
StrawchemyConfig("postgresql", order_by="all"), strawchemy, FruitType, and the
Query.fruits field so readers understand the intent of the test.
In @tests/unit/schemas/order/order_config_empty_with_empty_type_override.py:
- Around line 11-13: Add a docstring to the ContainerType class describing the
test scenario: that it verifies behavior when a schema uses include="all" on
Container while a type-level ordering override is explicitly empty (order=[]),
clarifying expected outcome and any edge conditions; place the docstring
immediately under the class declaration for ContainerType and mention the
relationship to Container, include="all", and the empty order override so future
maintainers understand the intent.
In @tests/unit/schemas/order/order_config_specific_fields_with_type_override.py:
- Around line 1-18: Add a top-of-file module docstring explaining that this
schema demonstrates selective field ordering at the type level: ContainerType
(created via Strawchemy("postgresql") and annotated with @strawchemy.type(...,
include="all", order=["fruits", "vegetables"])) only exposes ordering for the
specified relationship fields ("fruits" and "vegetables") while other
relationships like "colors" do not support ordering; ensure the docstring
briefly states the purpose and how to interpret the Query.container field
populated via strawchemy.field().
In @tests/unit/schemas/order/order_config_specific_fields.py:
- Around line 11-18: Add a short explanatory comment or docstring above the test
types to document how config-level order_by inheritance works: mention that the
@strawchemy.type(Fruit, include="all") applied on FruitType inherits ordering
config from Fruit, and that Query.fruits uses FruitType so the test validates
that inherited order_by rules apply; place the note near the FruitType or Query
declaration referencing the symbols Fruit, FruitType, and Query so future
readers understand the intended behavior.
In @tests/unit/schemas/order/order_config_with_field_override.py:
- Around line 1-18: Add a short module-level docstring at the top of this test
describing its intent: explain that the global StrawchemyConfig is set with
order_by=["name"] but the Query.fruits field uses a field-level override
order_by=["sweetness"], and the test verifies that the field-level `order_by` on
strawchemy.field takes precedence; place this docstring above the imports so it
documents the module, mentioning the key symbols StrawchemyConfig, strawchemy,
FruitType, and Query for clarity.
In @tests/unit/schemas/pagination/pagination_config_with_type_override.py:
- Around line 11-18: Add a brief doc note explaining that type-level paginate
overrides config-level pagination using this test as an example: mention that
the @strawchemy.type annotation on Container with paginate=["vegetables"] takes
precedence over any global/config setting like pagination=["fruits"], and point
to the ContainerType class and the Query.container field in the test as the
concrete example demonstrating this precedence; keep the note short, state the
precedence rule clearly, and include the exact symbol names paginate and
pagination so readers can map behavior to code.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (24)
tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[auto_order_by].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[distinct_config_all].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[distinct_config_empty].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[distinct_config_specific_fields].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[distinct_config_with_field_override].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[field_distinct_all].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[field_distinct_specific_fields].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[field_filter_auto_generate].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[field_order_by_all].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[field_order_by_specific_fields].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_all].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_all_with_field_override].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_empty].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_empty_with_empty_type_override].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_specific_fields].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_specific_fields_with_type_override].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_with_field_override].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[paginate_empty].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[pagination_config_empty].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[pagination_config_empty_with_type_override].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[pagination_config_specific_fields].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[pagination_config_with_type_override].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[type_distinct_manual_enum].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[type_order_by_specific_fields].gqlis excluded by!**/__snapshots__/**
📒 Files selected for processing (44)
examples/testapp/testapp/types.pysrc/strawchemy/config/base.pysrc/strawchemy/dto/base.pysrc/strawchemy/dto/strawberry.pysrc/strawchemy/dto/types.pysrc/strawchemy/dto/utils.pysrc/strawchemy/mapper.pysrc/strawchemy/schema/factories/aggregations.pysrc/strawchemy/schema/factories/base.pysrc/strawchemy/schema/factories/enum.pysrc/strawchemy/schema/factories/inputs.pysrc/strawchemy/schema/factories/types.pysrc/strawchemy/schema/field.pysrc/strawchemy/schema/mutation/field_builder.pysrc/strawchemy/utils/registry.pysrc/strawchemy/validation/pydantic.pytests/unit/dto/test_dto.pytests/unit/mapping/test_schemas.pytests/unit/schemas/distinct/__init__.pytests/unit/schemas/distinct/distinct_config_all.pytests/unit/schemas/distinct/distinct_config_empty.pytests/unit/schemas/distinct/distinct_config_specific_fields.pytests/unit/schemas/distinct/distinct_config_with_field_override.pytests/unit/schemas/distinct/field_distinct_all.pytests/unit/schemas/distinct/field_distinct_specific_fields.pytests/unit/schemas/distinct/type_distinct_manual_enum.pytests/unit/schemas/filters/field_filter_auto_generate.pytests/unit/schemas/order/auto_order_by.pytests/unit/schemas/order/field_order_by_all.pytests/unit/schemas/order/field_order_by_specific_fields.pytests/unit/schemas/order/order_config_all.pytests/unit/schemas/order/order_config_all_with_field_override.pytests/unit/schemas/order/order_config_empty.pytests/unit/schemas/order/order_config_empty_with_empty_type_override.pytests/unit/schemas/order/order_config_specific_fields.pytests/unit/schemas/order/order_config_specific_fields_with_type_override.pytests/unit/schemas/order/order_config_with_field_override.pytests/unit/schemas/order/type_order_by.pytests/unit/schemas/order/type_order_by_specific_fields.pytests/unit/schemas/pagination/paginate_empty.pytests/unit/schemas/pagination/pagination_config_empty.pytests/unit/schemas/pagination/pagination_config_empty_with_type_override.pytests/unit/schemas/pagination/pagination_config_specific_fields.pytests/unit/schemas/pagination/pagination_config_with_type_override.py
💤 Files with no reviewable changes (1)
- tests/unit/schemas/order/auto_order_by.py
🧰 Additional context used
🧬 Code graph analysis (33)
tests/unit/dto/test_dto.py (1)
src/strawchemy/dto/types.py (4)
DTOConfig(117-332)from_include(200-220)Purpose(69-89)is_field_included(312-332)
tests/unit/schemas/order/type_order_by_specific_fields.py (3)
tests/unit/schemas/order/type_order_by.py (2)
SQLDataTypesType(16-16)Query(20-21)tests/unit/schemas/order/order_config_specific_fields.py (1)
Query(17-18)tests/unit/schemas/order/field_order_by_specific_fields.py (1)
Query(17-18)
tests/unit/schemas/distinct/field_distinct_all.py (2)
src/strawchemy/mapper.py (4)
Strawchemy(61-691)field(174-200)field(203-228)field(230-327)src/strawchemy/schema/field.py (1)
distinct_on(248-269)
tests/unit/schemas/order/type_order_by.py (1)
tests/unit/schemas/order/field_order_by.py (1)
SQLDataTypesOrderBy(12-12)
tests/unit/schemas/order/order_config_with_field_override.py (3)
tests/fixtures.py (1)
strawchemy(34-35)src/strawchemy/config/base.py (1)
StrawchemyConfig(19-70)src/strawchemy/schema/field.py (1)
order_by(272-301)
tests/unit/schemas/distinct/distinct_config_specific_fields.py (3)
tests/fixtures.py (1)
strawchemy(34-35)src/strawchemy/config/base.py (1)
StrawchemyConfig(19-70)src/strawchemy/schema/field.py (1)
distinct_on(248-269)
tests/unit/schemas/distinct/distinct_config_with_field_override.py (2)
src/strawchemy/config/base.py (1)
StrawchemyConfig(19-70)src/strawchemy/schema/field.py (1)
distinct_on(248-269)
tests/unit/mapping/test_schemas.py (1)
tests/integration/models.py (1)
id(61-67)
src/strawchemy/dto/utils.py (1)
tests/integration/fixtures.py (1)
config(742-746)
src/strawchemy/schema/mutation/field_builder.py (2)
src/strawchemy/schema/factories/types.py (1)
DistinctOnFieldsDTOFactory(457-462)src/strawchemy/schema/factories/inputs.py (2)
BooleanFilterDTOFactory(197-214)OrderByDTOFactory(347-478)
tests/unit/schemas/order/order_config_empty_with_empty_type_override.py (1)
tests/unit/schemas/order/order_config_specific_fields_with_type_override.py (2)
ContainerType(12-13)Query(17-18)
src/strawchemy/schema/factories/types.py (1)
src/strawchemy/dto/types.py (5)
DTOConfig(117-332)Purpose(69-89)is_fields_iterable(353-359)from_include(200-220)is_field_included(312-332)
src/strawchemy/validation/pydantic.py (1)
src/strawchemy/dto/types.py (2)
DTOConfig(117-332)Purpose(69-89)
tests/unit/schemas/distinct/distinct_config_all.py (2)
src/strawchemy/config/base.py (1)
StrawchemyConfig(19-70)src/strawchemy/schema/field.py (1)
distinct_on(248-269)
tests/unit/schemas/order/order_config_all_with_field_override.py (3)
tests/fixtures.py (1)
strawchemy(34-35)src/strawchemy/schema/field.py (1)
order_by(272-301)src/strawchemy/dto/utils.py (1)
field(78-89)
examples/testapp/testapp/types.py (3)
tests/fixtures.py (1)
strawchemy(34-35)examples/testapp/testapp/models.py (2)
Ticket(30-35)Project(52-62)src/strawchemy/transpiler/_query.py (1)
order(100-102)
src/strawchemy/schema/factories/inputs.py (2)
src/strawchemy/schema/factories/types.py (1)
_aggregation_field(90-105)src/strawchemy/dto/types.py (1)
copy_with(222-271)
tests/unit/schemas/pagination/pagination_config_specific_fields.py (4)
tests/fixtures.py (1)
strawchemy(34-35)src/strawchemy/config/base.py (1)
StrawchemyConfig(19-70)tests/unit/models.py (1)
Container(200-212)src/strawchemy/schema/field.py (1)
pagination(239-245)
src/strawchemy/dto/base.py (2)
src/strawchemy/dto/utils.py (1)
field(78-89)src/strawchemy/dto/types.py (1)
Purpose(69-89)
src/strawchemy/config/base.py (2)
tests/fixtures.py (1)
strawchemy(34-35)src/strawchemy/schema/field.py (3)
pagination(239-245)order_by(272-301)distinct_on(248-269)
tests/unit/schemas/filters/field_filter_auto_generate.py (1)
src/strawchemy/mapper.py (4)
Strawchemy(61-691)field(174-200)field(203-228)field(230-327)
src/strawchemy/utils/registry.py (2)
src/strawchemy/dto/strawberry.py (2)
EnumDTO(423-427)OrderByDTO(453-469)src/strawchemy/schema/pagination.py (1)
DefaultOffsetPagination(9-11)
tests/unit/schemas/distinct/field_distinct_specific_fields.py (3)
tests/unit/schemas/distinct/distinct_config_all.py (2)
ColorType(12-13)Query(17-18)tests/unit/schemas/distinct/distinct_config_with_field_override.py (2)
ColorType(12-13)Query(17-18)src/strawchemy/schema/field.py (1)
distinct_on(248-269)
tests/unit/schemas/order/field_order_by_all.py (1)
src/strawchemy/schema/field.py (1)
order_by(272-301)
tests/unit/schemas/distinct/distinct_config_empty.py (2)
src/strawchemy/config/base.py (1)
StrawchemyConfig(19-70)src/strawchemy/schema/field.py (1)
distinct_on(248-269)
src/strawchemy/schema/field.py (7)
src/strawchemy/dto/strawberry.py (5)
BooleanFilterDTO(472-499)EnumDTO(423-427)MappedStrawberryGraphQLDTO(430-430)OrderByDTO(453-469)StrawchemyDTOAttributes(104-111)src/strawchemy/dto/types.py (2)
DTOConfig(117-332)Purpose(69-89)src/strawchemy/schema/factories/types.py (2)
DistinctOnFieldsDTOFactory(457-462)_description(598-605)src/strawchemy/schema/factories/inputs.py (1)
BooleanFilterDTOFactory(197-214)src/strawchemy/schema/pagination.py (1)
DefaultOffsetPagination(9-11)src/strawchemy/dto/utils.py (1)
config(45-75)src/strawchemy/schema/factories/base.py (1)
_config(192-216)
tests/unit/schemas/order/field_order_by_specific_fields.py (1)
src/strawchemy/schema/field.py (1)
order_by(272-301)
tests/unit/schemas/order/order_config_all.py (4)
tests/fixtures.py (1)
strawchemy(34-35)src/strawchemy/mapper.py (4)
Strawchemy(61-691)field(174-200)field(203-228)field(230-327)src/strawchemy/config/base.py (1)
StrawchemyConfig(19-70)src/strawchemy/schema/field.py (1)
order_by(272-301)
tests/unit/schemas/pagination/pagination_config_with_type_override.py (4)
tests/fixtures.py (1)
strawchemy(34-35)tests/unit/models.py (1)
Container(200-212)src/strawchemy/schema/field.py (1)
pagination(239-245)tests/unit/schemas/pagination/pagination_config_empty_with_type_override.py (2)
ContainerType(12-13)Query(17-18)
src/strawchemy/dto/types.py (1)
src/strawchemy/dto/utils.py (1)
field(78-89)
tests/unit/schemas/order/order_config_specific_fields_with_type_override.py (6)
tests/fixtures.py (1)
strawchemy(34-35)tests/unit/models.py (1)
Container(200-212)tests/unit/schemas/order/order_config_all_with_field_override.py (1)
Query(17-18)tests/unit/schemas/order/order_config_empty.py (1)
Query(17-18)tests/unit/schemas/order/order_config_specific_fields.py (1)
Query(17-18)tests/unit/schemas/order/order_config_with_field_override.py (1)
Query(17-18)
src/strawchemy/mapper.py (3)
src/strawchemy/schema/pagination.py (1)
DefaultOffsetPagination(9-11)src/strawchemy/schema/mutation/field_builder.py (1)
MutationFieldBuilder(30-116)src/strawchemy/utils/registry.py (1)
namespace(339-340)
src/strawchemy/schema/factories/base.py (2)
src/strawchemy/dto/types.py (5)
cast_include_fields(336-336)cast_include_fields(340-340)cast_include_fields(343-350)is_fields_iterable(353-359)DTOConfig(117-332)src/strawchemy/schema/pagination.py (1)
DefaultOffsetPagination(9-11)
🪛 Ruff (0.14.10)
src/strawchemy/schema/factories/enum.py
169-169: Boolean-typed positional argument in function definition
(FBT001)
175-175: Boolean-typed positional argument in function definition
(FBT001)
175-175: Boolean default positional argument in function definition
(FBT002)
176-176: Dynamically typed expressions (typing.Any) are disallowed in **kwargs
(ANN401)
src/strawchemy/dto/base.py
638-638: Boolean-typed positional argument in function definition
(FBT001)
638-638: Boolean default positional argument in function definition
(FBT002)
src/strawchemy/dto/types.py
353-353: Dynamically typed expressions (typing.Any) are disallowed in value
(ANN401)
src/strawchemy/schema/factories/base.py
342-342: Dynamically typed expressions (typing.Any) are disallowed in **kwargs
(ANN401)
654-654: Boolean-typed positional argument in function definition
(FBT001)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
- GitHub Check: 🔬 integration-sqlite on 3.10
- GitHub Check: 🔬 integration-postgres on 3.13
- GitHub Check: 🔬 integration-mysql on 3.13
- GitHub Check: 🔬 integration-sqlite on 3.12
- GitHub Check: 🔬 integration-mysql on 3.12
- GitHub Check: 🔬 unit-no-extras on 3.14
- GitHub Check: 🔬 integration-sqlite on 3.13
- GitHub Check: 🔬 unit-no-extras on 3.12
- GitHub Check: 🔬 integration-mysql on 3.10
- GitHub Check: 🔬 integration-mysql on 3.11
- GitHub Check: 🔬 unit on 3.10
- GitHub Check: 🔬 unit on 3.14
- GitHub Check: 🔬 unit-no-extras on 3.10
- GitHub Check: 🔬 unit-no-extras on 3.13
- GitHub Check: 🔬 integration-postgres on 3.11
- GitHub Check: 🔬 unit on 3.12
- GitHub Check: 🔬 unit on 3.13
- GitHub Check: 🔬 unit-no-extras on 3.11
- GitHub Check: 🔬 unit on 3.11
- GitHub Check: Optimize new code in this PR
🔇 Additional comments (62)
tests/unit/schemas/order/type_order_by.py (1)
15-15: Parameter rename is correctly applied and consistent across the codebase.The change from
order_bytoorderin the @strawchemy.type decorator on line 15 is part of a complete and consistent refactoring. A codebase search confirms that all @strawchemy.type decorator calls now use the neworder=parameter, with no remaining instances of the oldorder_by=parameter at the decorator level. Integration tests and other test files consistently use the updated API.tests/unit/schemas/order/order_config_all_with_field_override.py (1)
1-18: No changes needed. This is a test fixture file, not a test module.The schema file serves as a fixture for the parametrized snapshot test in
tests/unit/mapping/test_schemas.py(line 217). Thetest_query_schemasfunction dynamically imports the Query class from this module and validates the generated GraphQL schema via snapshot assertions. The field-level override (order_by=["name"]) is tested as part of this parametrized test suite.tests/unit/schemas/pagination/paginate_empty.py (1)
1-18: This is an intentional schema fixture used by parametrized snapshot tests.This file is part of the test infrastructure: it defines a GraphQL schema that is dynamically imported and tested by
test_query_schemasintests/unit/mapping/test_schemas.pyvia snapshot assertions. The absence of test functions is correct—all pagination schema definition files follow this pattern. Moving it to a fixtures directory would break the parametrization logic that references the explicit module path.Likely an incorrect or invalid review comment.
tests/unit/schemas/filters/field_filter_auto_generate.py (1)
1-18: Verify purpose: confirm if this is an intentional schema fixture or incomplete test.This file contains only GraphQL schema definitions without test functions or assertions. Based on the file name (
field_filter_auto_generate.py), location (tests/unit/schemas/filters/), and content structure, it appears designed as a reusable schema fixture. However, this cannot be confirmed without examining:
- How this file is imported and used by other tests in the suite
- Naming and organizational conventions established in the codebase
- Whether similar files in the same directory follow the same pattern
If this is intentionally a fixture, ensure it's clearly documented or placed in a dedicated fixtures directory. If it's intended as an executable test, add test functions with assertions.
tests/unit/schemas/order/field_order_by_all.py (1)
1-18: This schema fixture is properly integrated into the test suite.The file is used by the parametrized snapshot test
test_query_schemasintests/unit/mapping/test_schemas.py. The test dynamically imports the Query class and validates the generated GraphQL schema against a snapshot. Schema definition files in this directory intentionally contain no test functions—they are fixtures that define the schemas being tested.Likely an incorrect or invalid review comment.
tests/unit/dto/test_dto.py (1)
271-337: LGTM! Comprehensive test coverage for new DTOConfig methods.The test suite thoroughly covers the new
from_include()factory method andis_field_included()logic across various scenarios:
- None/empty, "all", list, and set inputs
- Custom purpose parameter
- Include/exclude interaction
The test logic is sound and aligns well with the method signatures shown in the relevant code snippets.
tests/unit/schemas/order/field_order_by_specific_fields.py (1)
18-18: Remove or resolve the concern about ordering relationship fields.The
fruitsandvegetablesfields in Container are relationship fields, but the Container model is explicitly documented as a "Test model with multiple list relationships for testing paginate/order configuration." The framework appears to intentionally support ordering by relationship field names. The test file is part of a schema snapshot suite validating GraphQL schema generation, not query execution, and there's no evidence this configuration is invalid.Likely an incorrect or invalid review comment.
tests/unit/schemas/distinct/field_distinct_all.py (2)
1-8: LGTM - Clean test setup.The imports and Strawchemy initialization are correct. The shorthand
Strawchemy("postgresql")is concise for test purposes.
16-18: LGTM - Tests field-level distinct_on configuration.The query correctly demonstrates the new API where
distinct_on="all"is specified at the field level, enabling PostgreSQL's DISTINCT ON clause for all fields of the Color model.tests/unit/schemas/distinct/distinct_config_specific_fields.py (1)
1-8: LGTM - Tests config-level distinct_on with specific fields.The configuration correctly sets
distinct_on=["name"]at the global level, which will be inherited by fields that don't specify their own distinct_on parameter.tests/unit/schemas/distinct/distinct_config_empty.py (1)
11-18: LGTM - Standard type and query definitions.The ColorType and Query definitions follow the established pattern and will inherit the empty
distinct_on=[]from the config.tests/unit/schemas/order/order_config_specific_fields.py (1)
1-8: LGTM - Tests config-level order_by with specific fields.The configuration correctly sets
order_by=["name", "sweetness"]at the global level. Both field names correspond to columns on the Fruit model (name: Mapped[str]at line 59 andsweetness: Mapped[int]at line 62 of tests/unit/models.py).tests/unit/schemas/pagination/pagination_config_with_type_override.py (1)
8-8: The naming convention here is intentional and well-documented.paginationis the global configuration parameter inStrawchemyConfig, whilepaginateis the type decorator parameter for field-level overrides. The codebase explicitly defines this pattern in the type factory's fallback logic (line 276 oftypes.py:paginate=paginate if paginate == "all" else self._mapper.config.pagination) and includes clear documentation in the_add_fields_argumentsdocstring explaining both parameters' purposes. This is standard API design for separating global defaults from type-specific configuration.Likely an incorrect or invalid review comment.
tests/unit/schemas/distinct/distinct_config_with_field_override.py (1)
1-18: LGTM! Clean test structure for distinct_on field override.The test clearly demonstrates field-level override of the global
distinct_on="all"configuration by specifyingdistinct_on=["name"]at the field level. The structure is consistent with other test files in the PR.tests/unit/schemas/pagination/pagination_config_empty_with_type_override.py (1)
1-18: LGTM! Type-level pagination override test is well-structured.The test demonstrates type-level pagination control using
paginate=["fruits"]on the type decorator while the global config haspagination=[]. This validates the type-level override mechanism.src/strawchemy/dto/utils.py (2)
49-50: LGTM! Global include/exclude parameters added consistently.The new
global_includeandglobal_excludeparameters follow the same pattern as the existingincludeandexcludeparameters. The truthiness-based conditional assignment is consistent with the existing code style (see lines 59-62).Note: The truthiness check means empty collections (
[]orset()) won't be assigned. This is consistent with existing behavior but means "explicitly no fields" vs "not specified" cannot be distinguished. This appears intentional based on the codebase patterns.Also applies to: 63-66
22-22: TheExcludeFields→FieldIterabletype rename is complete and consistently applied across the codebase. The type is properly imported on line 22 and used consistently in function parameters on lines 48 and 50. No remaining references to the old type name exist.tests/unit/schemas/pagination/pagination_config_empty.py (1)
1-18: LGTM! Baseline test for empty pagination configuration.This test validates the baseline behavior when pagination is globally disabled using
pagination=[]. It complements the override tests by establishing the default behavior.tests/unit/mapping/test_schemas.py (1)
188-229: LGTM! Comprehensive test coverage expansion.The additions significantly expand test coverage for the refactored pagination, ordering, and distinct_on features:
- Pagination tests (11 new): Cover default limits/offsets, field-specific pagination, config-based variations, and combined scenarios
- Ordering tests (11 new): Cover field-level, type-level, and config-based ordering with various override patterns
- Distinct tests (7 new): Cover config-based and field-level distinct_on with different field specifications
The test parameter naming follows consistent conventions and integrates well with the existing test structure.
src/strawchemy/schema/factories/aggregations.py (1)
126-126: LGTM! Clean threading of the no_cache parameter.The
no_cacheparameter is correctly added with a default value ofFalse, maintaining backward compatibility. The parameter is properly threaded through to the parentfactory()call, consistent with the broader cache control pattern introduced in this PR.Also applies to: 141-141
tests/unit/schemas/distinct/distinct_config_all.py (1)
8-8: Thedistinct_onfeature is not PostgreSQL-specific and does not require dialect validation.The implementation already handles
distinct_onacross all supported databases. PostgreSQL uses nativeDISTINCT ON, while MySQL and SQLite automatically fall back to aRANK()window function. The_use_distinct_rank()method in the transpiler manages this logic transparently, and integration tests confirm the feature works correctly across all database types.tests/unit/schemas/order/order_config_with_field_override.py (1)
8-8: This test validates that field-levelorder_byconfigurations override the global configuration.The field definition includes
order_by=["sweetness"], which overrides the globalorder_by=["name"]configuration. The snapshot test validates this override behavior through GraphQL schema generation comparison. If you need to test global order_by behavior when no field-level override is present, refer toorder_config_all.pyororder_config_specific_fields.pyinstead.Likely an incorrect or invalid review comment.
tests/unit/schemas/order/order_config_specific_fields_with_type_override.py (1)
11-11: Verify that selective ordering is properly tested for thecolorsrelationship.The
order=["fruits", "vegetables"]decorator correctly enables ordering only for those two relationships. Based on code analysis, the_add_fields_argumentsmethod filters which relation fields receiveorder_byarguments by checkingorder_config.is_field_included(field.model_field_name). Thecolorsrelationship, which exists on the Container model but is not in the order list, will not receive ordering arguments in the generated GraphQL schema. Ensure the test assertions or generated schema snapshots explicitly validate this behavior.tests/unit/schemas/order/type_order_by_specific_fields.py (3)
1-8: LGTM!The imports and Strawchemy initialization are correct and align with the test module's purpose.
11-12: LGTM!The type definition correctly uses the new
orderparameter with a field list, demonstrating the refactored API for specifying orderable fields.
15-17: LGTM!The Query type definition follows the standard pattern for exposing Strawchemy-backed fields in Strawberry GraphQL schemas.
tests/unit/schemas/order/order_config_empty.py (3)
1-8: LGTM!The test correctly validates that an empty
order_bylist is accepted inStrawchemyConfig, providing useful edge-case coverage.
11-13: LGTM!The type definition correctly relies on the config-level
order_bysetting without a type-level override.
16-18: LGTM!The Query definition follows the established pattern for Strawberry GraphQL schemas.
src/strawchemy/validation/pydantic.py (3)
27-27: LGTM!The import change from
ExcludeFieldstoFieldIterablealigns with the broader type system refactor to unify field-specification types across the DTO layer.
87-87: LGTM!The parameter type change to
FieldIterable | Noneis consistent with the updated import and maintains API compatibility.
112-127: LGTM!The
no_cacheparameter addition follows the broader factory interface pattern and is correctly forwarded to the superclass. The default value ofFalsemaintains backward compatibility.tests/unit/schemas/pagination/pagination_config_specific_fields.py (3)
1-8: LGTM!The test setup correctly demonstrates the new per-field pagination configuration API, enabling pagination only for the "fruits" and "vegetables" relationships.
11-13: LGTM!The type definition correctly relies on the config-level pagination setting, demonstrating how global pagination configuration is applied without type-level overrides.
16-18: LGTM!The Query definition follows the standard Strawberry GraphQL schema pattern.
src/strawchemy/schema/factories/enum.py (4)
11-14: LGTM!The import changes support the new
make_inputmethod and align with the DTO type system refactor to useFieldIterableinstead ofExcludeFields.
145-145: LGTM!The parameter type change to
FieldIterable | Nonemaintains consistency with the updated type system across the codebase.
164-193: LGTM with minor observation!The new
make_inputmethod provides a clean programmatic API for creating enum input types with a WRITE-purpose DTOConfig. The implementation correctly constructs the config and forwards all parameters to the factory method.Note: Static analysis flags the boolean parameters (
partial,no_cache) as positional arguments (FBT001/FBT002). These warnings can be safely ignored as they're optional configuration parameters following the established pattern across the factory API, and changing them to keyword-only would break consistency with the existing codebase.
199-199: LGTM!The parameter type change to
FieldIterable | Noneis consistent with the decorator method and the broader type system refactor.src/strawchemy/schema/mutation/field_builder.py (2)
18-19: LGTM! Factory dependencies properly added.The new factory imports and dataclass fields correctly extend
MutationFieldBuilderwith the necessary factory dependencies (order_by_factory,filter_factory,distinct_on_factory) to support the enhanced pagination and ordering API.Also applies to: 40-42
95-114: Remove this comment - fallback logic is correctly implemented.The
repository_typeparameter is handled with a proper fallback in the parent classStrawchemyField.__init__(line 132 infield.py):self._repository_type = config.repository_type if repository_type is None else repository_type. This ensures that whenNoneis passed, the config's default repository type is used, making the mutation field classes safe and properly defensive against None values.Likely an incorrect or invalid review comment.
src/strawchemy/utils/registry.py (1)
105-108: LGTM! Registry type info extended for pagination and ordering.The new fields (
pagination,order,distinct_on,paginate) correctly extendRegistryTypeInfoto carry pagination and ordering configuration through the type registration system. The use offrozensetas default factory ensures immutability.src/strawchemy/dto/base.py (3)
394-414: LGTM! Global include/exclude logic is correctly implemented.The updated
should_exclude_fieldmethod properly handles the new global inclusion/exclusion semantics:
- Root nodes use explicit
include/exclude- Non-root nodes use
global_include/global_exclude- The
include="all"andglobal_include="all"cases are handled correctly
638-638: LGTM! Cache bypass withno_cacheparameter.The
no_cacheparameter is correctly implemented to bypass the DTO cache when needed. Regarding the static analysis hint (FBT001/FBT002) about boolean positional arguments: this is acceptable here sinceno_cachefollows other positional parameters and maintains consistency with the existing API pattern.Also applies to: 653-653
698-698: LGTM! Type annotation updated toFieldIterable.The
excludeparameter type is correctly updated fromExcludeFieldstoFieldIterable, aligning with the PR's type refactoring.src/strawchemy/schema/factories/inputs.py (1)
55-55: LGTM! Type updates and aggregation field configuration.The
FieldIterabletype annotation and the addition ofpartial=Trueincopy_withfor aggregation fields are correctly implemented.Also applies to: 146-148
src/strawchemy/schema/factories/types.py (3)
107-205: Well-documented refactoring of_add_fields_arguments.The method is comprehensively refactored to handle:
- Ordering arguments via
orderparameter with properDTOConfig.from_includeconversion- Pagination arguments via
paginateparameter- JSON path filtering for JSON/dict fields
The try/except pattern around
EmptyDTOError(lines 170-173) is good defensive coding to handle models with no orderable fields.
239-302: LGTM! Factory method properly extended with new parameters.The factory method correctly:
- Adds
default_pagination,order, andpaginateparameters- Falls back to
self._mapper.configvalues when appropriate (lines 276-278)- Only calls
_add_fields_argumentsfor object types (line 281)- Propagates new parameters to
_register_type
607-621: The cache key implementation is correct and does not have collision risks. Thefactory_kwargsparameter was never used in the parent class's cache key computation (only passed through as a parameter), andmodeis properly included in the tuple returned at line 620, ensuring distinct cache keys for differentmodevalues.src/strawchemy/dto/types.py (5)
35-36: LGTM! Type aliases for field configuration.The
FieldIterableandIncludeFieldstype aliases provide clear, expressive types for the new configuration API.
165-170: LGTM! Global include/exclude fields with proper validation.The new
global_includeandglobal_excludefields extend DTOConfig for tree-wide field control. The__post_init__validation correctly enforces:
- Mutual exclusivity between explicit include sets and exclude sets
- Auto-setting
global_include="all"whenglobal_excludeis specifiedAlso applies to: 184-197
199-220: LGTM! Factory methodfrom_includeis well-documented.The
from_includeclassmethod provides a clean factory interface for creating DTOConfig instances from include specifications. The docstring clearly explains the parameter semantics.
312-332: LGTM!is_field_includedmethod correctly implements inclusion logic.The method properly evaluates field inclusion by checking:
include="all"→ field is included unless inexcludeglobal_include="all"→ field is included unless inglobal_exclude- Otherwise → field must be in combined include sets and not in combined exclude sets
335-359: LGTM! Type-safe utility functions.
cast_include_fields: Properly overloaded for precise return types with correct match-case implementationis_fields_iterable: Type guard function that correctly validates field iterables while rejecting plain stringsThe static analysis hint (ANN401) about
Anyinis_fields_iterableis acceptable since this is a type guard function that needs to accept arbitrary input to validate.src/strawchemy/mapper.py (2)
139-145:MutationFieldBuilderinitialization via explicit keyword args is a net win.
Much harder to break during refactors than positional args.
173-228: No action needed. The only directStrawchemyFieldinstantiation in the codebase (at mapper.py:296) already passes all three required factories:order_by_factory,filter_factory, anddistinct_on_factory. No other call sites require updating.Likely an incorrect or invalid review comment.
src/strawchemy/schema/field.py (2)
81-135: Constructor refactor to factory-driven DTO creation is coherent (and defaults are centralized).
Defaultingid_field_name,execution_options, andrepository_typefrom config makes behavior easier to reason about.
238-246: Pagination defaulting viaconfig.pagination == "all"is OK, but confirm intended precedence ofFalsevsNone.
Right now_pagination=Falsedisables pagination even if config is"all", while_pagination=Noneinherits config. That’s a good model—just ensure it’s the documented one.src/strawchemy/schema/factories/base.py (1)
192-216: Threadingglobal_include/global_excludeinto config is the right direction.
Nice alignment withDTOConfig.__post_init__behavior and global semantics.tests/unit/schemas/order/order_config_empty_with_empty_type_override.py (3)
1-7: LGTM: Imports are appropriate.The imports are correct for this test schema definition. The future annotations import enables forward references for type hints.
16-18: LGTM: Query type follows standard pattern.The Query type correctly uses the Strawberry/Strawchemy integration pattern with
strawchemy.field()for GraphQL field resolution.
8-8: This follows the established pattern across the test suite and requires no changes.Module-level
Strawchemyinstances are the standard design pattern used throughout the codebase in all test schema definition files (100+ instances found acrosstests/unit/schemas/andtests/integration/). Each test module creates its own isolated instance with its specific configuration, which is then imported by test functions. This approach properly isolates schema definitions per test and is the intended design.Likely an incorrect or invalid review comment.
way too many changes
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/strawchemy/schema/factories/inputs.py (1)
51-85:⚠️ Potential issue | 🟠 MajorForward
scopethrough this input wrapper.Line 66 adds
scope, but the_input_wrapper()call never receives it.scope="schema"on filter/order inputs is currently a no-op unless this method converts and forwards the value.Proposed fix
+from strawchemy.schema.factories.base import type_scope_to_dto_scope + class _BaseStrawchemyFilterFactory(StrawchemyUnMappedDTOFactory[UnmappedGraphQLDTOT]): @@ return self._input_wrapper( model=model, include=include, exclude=exclude, partial=partial, type_map=type_map, aliases=aliases, alias_generator=alias_generator, name=name, description=description, directives=directives, override=override, purpose=purpose, + scope=type_scope_to_dto_scope(scope) if scope else None, mode=mode, **kwargs, )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/strawchemy/schema/factories/inputs.py` around lines 51 - 85, The input() wrapper accepts a scope parameter but never forwards it to _input_wrapper(), so supply the scope argument when calling self._input_wrapper; update the call in input(...) to include scope=scope so that the scope value (e.g., "schema") is honored by the underlying _input_wrapper function (refer to the input method and _input_wrapper symbols).src/strawchemy/schema/factories/base.py (1)
661-693:⚠️ Potential issue | 🟠 Major
scopeis ignored for unmapped input decorators.Line 676 adds the public
scopeparameter, but this wrapper never forwards it to_input_wrapper().scope="schema"therefore has no effect forStrawchemyUnMappedDTOFactory.input().Proposed fix
return self._input_wrapper( model=model, include=include, exclude=exclude, partial=partial, type_map=type_map, aliases=aliases, alias_generator=alias_generator, name=name, description=description, directives=directives, override=override, purpose=purpose, + scope=type_scope_to_dto_scope(scope) if scope else None, **kwargs, )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/strawchemy/schema/factories/base.py` around lines 661 - 693, The public parameter scope on the input method is currently ignored because input(self, ..., scope: TypeScope | None = None, ...) does not pass scope into the call to self._input_wrapper; update the input method to forward the scope argument to _input_wrapper (i.e. include scope=scope in the _input_wrapper call) so that providing scope (e.g., "schema") affects StrawchemyUnMappedDTOFactory.input() as intended.src/strawchemy/dto/base.py (1)
651-690:⚠️ Potential issue | 🔴 Critical
no_cache=Truestill poisons the shared cache.Line 654 only skips cache lookup.
_scoped_dto_namesand_dto_cacheare still updated later in the method, so a temporaryno_cachebuild can change the class/name returned by a later cached build.Proposed fix
- if dto_config.scope == "global": + if not no_cache and dto_config.scope == "global": self._scoped_dto_names[self._scoped_cache_key(model, dto_config)] = name @@ - self._dto_cache[cache_key] = dto - - if dto_config.scope is not None: - self._dto_cache[self._scoped_cache_key(model, dto_config)] = dto + if not no_cache: + self._dto_cache[cache_key] = dto + if dto_config.scope is not None: + self._dto_cache[self._scoped_cache_key(model, dto_config)] = dto🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/strawchemy/dto/base.py` around lines 651 - 690, The method currently skips only the cache lookup when no_cache=True but still mutates shared state later, poisoning future cached builds; wrap all writes that register the DTO into shared caches/registries behind a check so they don't run when no_cache is True: guard updates to self._scoped_dto_names (the _scoped_cache_key write), self._dto_cache (both cache_key and scoped cache writes), self.dtos (both name and base.__name__ assignments), and the appends to self._unresolved_refs (the for ref in node.value.forward_refs block) with if not no_cache so temporary builds don't modify global caches/registries; keep backend.update_forward_refs(dto, ...) and node.value.dto assignment behavior as appropriate for in-memory resolution if intended.
♻️ Duplicate comments (1)
src/strawchemy/mapper.py (1)
86-87:⚠️ Potential issue | 🟠 MajorKeep module globals out of the annotation namespace.
vars(mutation_types)brings in every imported symbol and module dunder, not just the mutation DTO types. Because Line 160 unions this namespace overregistry.namespace("object"), any collision is resolved in favor of those module globals instead of the registered GraphQL type. Build_types_namespacefrom explicit mutation exports before merging.Also applies to: 160-160
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/strawchemy/mapper.py` around lines 86 - 87, The current _types_namespace uses vars(mutation_types) which pulls in module globals; change this to only include explicit mutation DTO exports by constructing a filtered dict from mutation_types.__all__ (or, if __all__ is missing, from non-dunder names) and mapping each name to getattr(mutation_types, name), then merge that filtered dict with TYPING_NS (i.e. _types_namespace = TYPING_NS | filtered_exports). Ensure the same filtered_exports are used where registry.namespace("object") is unioned so registered GraphQL types are not shadowed by module globals.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@examples/testapp/testapp/types.py`:
- Around line 69-70: The decorator on MilestoneType uses include={"name"} which
prevents generating the related field projects, so paginate=["projects"] is
unreachable; either add "projects" to the include set in the
`@strawchemy.type`(...) call (so projects is generated and pagination works) or
remove paginate=["projects"] from the decorator; update the `@strawchemy.type`
decorator on MilestoneType accordingly.
In `@src/strawchemy/config/base.py`:
- Around line 73-83: The cached_property usage causes stale derived configs when
StrawchemyConfig is mutated; change order_config, distinct_on_config, and
pagination_config to compute on each access (replace `@cached_property` with plain
`@property` or remove the caching) so DTOConfig.from_include is re-evaluated
against the current pagination, order_by, and distinct_on values, or
alternatively make the StrawchemyConfig dataclass frozen/immutable so
memoization is safe; update the decorators on the methods (order_config,
distinct_on_config, pagination_config) accordingly and ensure callers still use
the same attribute names.
In `@src/strawchemy/dto/base.py`:
- Around line 396-415: The root-branch exclusion logic ignores
global_include/global_exclude; update the node.is_root branch to also respect
globally_included/globally_excluded (same rules as the non-root branch).
Specifically, change the node.is_root clause that sets excluded to combine
explicit and global flags (e.g., excluded = excluded or (explictly_excluded or
globally_excluded or not (explicitly_included or globally_included))). Also fix
the inconsistent variable name for the explicit exclusion/inclusion if needed
(explictly_excluded vs explicitly_excluded) so the correct flags are evaluated.
In `@src/strawchemy/dto/strawberry.py`:
- Line 111: The __strawchemy_distinct_on__ annotation is overly broad (type[Any]
| None); change it to the more specific type returned by _type_distinct_on
(type[EnumDTO] | None) to mirror the patterns used for __strawchemy_order_by__
and __strawchemy_filter__; update the annotation on __strawchemy_distinct_on__
to type[EnumDTO] | None and either import EnumDTO or use a forward-reference
string to avoid circular imports so field.py's existing None-check logic
continues to work as before.
In `@src/strawchemy/schema/factories/types.py`:
- Around line 113-133: The field-local input factories _order_by_input_for_field
and _distinct_on_input_for_field currently call
self._order_by_factory.factory(...) and self._distinct_on_factory.factory(...)
without disabling the shared DTO cache, which can leak temporary types between
fields; update both calls to pass no_cache=True into the factory invocation
(i.e., call factory(field.related_model, DTOConfig(...), if_no_fields="raise",
no_cache=True)) so generated input classes are created per-field and not stored
in the shared cache.
In `@tests/unit/schemas/order/order_config_specific_fields_with_type_override.py`:
- Around line 8-11: The test fixture currently uses overlapping order fields
("fruits") in StrawchemyConfig(order_by=["fruits"]) and `@strawchemy.type`(...,
order=["fruits","vegetables"]) so it won’t detect whether type-level order
overrides or merges; update the global config or the type-level order to be
disjoint (e.g., change StrawchemyConfig(order_by=["colors"]) or change the type
decorator to order=["fruits","vegetables"] while making global only include
"colors") so the global-only relation (like "colors") and the type-only
relations are different and the test can assert that the type-level order on
Container wins.
---
Outside diff comments:
In `@src/strawchemy/dto/base.py`:
- Around line 651-690: The method currently skips only the cache lookup when
no_cache=True but still mutates shared state later, poisoning future cached
builds; wrap all writes that register the DTO into shared caches/registries
behind a check so they don't run when no_cache is True: guard updates to
self._scoped_dto_names (the _scoped_cache_key write), self._dto_cache (both
cache_key and scoped cache writes), self.dtos (both name and base.__name__
assignments), and the appends to self._unresolved_refs (the for ref in
node.value.forward_refs block) with if not no_cache so temporary builds don't
modify global caches/registries; keep backend.update_forward_refs(dto, ...) and
node.value.dto assignment behavior as appropriate for in-memory resolution if
intended.
In `@src/strawchemy/schema/factories/base.py`:
- Around line 661-693: The public parameter scope on the input method is
currently ignored because input(self, ..., scope: TypeScope | None = None, ...)
does not pass scope into the call to self._input_wrapper; update the input
method to forward the scope argument to _input_wrapper (i.e. include scope=scope
in the _input_wrapper call) so that providing scope (e.g., "schema") affects
StrawchemyUnMappedDTOFactory.input() as intended.
In `@src/strawchemy/schema/factories/inputs.py`:
- Around line 51-85: The input() wrapper accepts a scope parameter but never
forwards it to _input_wrapper(), so supply the scope argument when calling
self._input_wrapper; update the call in input(...) to include scope=scope so
that the scope value (e.g., "schema") is honored by the underlying
_input_wrapper function (refer to the input method and _input_wrapper symbols).
---
Duplicate comments:
In `@src/strawchemy/mapper.py`:
- Around line 86-87: The current _types_namespace uses vars(mutation_types)
which pulls in module globals; change this to only include explicit mutation DTO
exports by constructing a filtered dict from mutation_types.__all__ (or, if
__all__ is missing, from non-dunder names) and mapping each name to
getattr(mutation_types, name), then merge that filtered dict with TYPING_NS
(i.e. _types_namespace = TYPING_NS | filtered_exports). Ensure the same
filtered_exports are used where registry.namespace("object") is unioned so
registered GraphQL types are not shadowed by module globals.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: d51562d2-9049-4dd6-a865-6a4a51a715d1
⛔ Files ignored due to path filters (11)
tests/unit/__snapshots__/test_example_app/test_graphql_schema.gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[field_order_by_all].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[field_order_by_specific_fields].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_all].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_all_with_field_override].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_specific_fields].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_specific_fields_with_type_override].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[order_config_with_field_override].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[paginate_and_order_combined].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[pagination_config_with_type_override].gqlis excluded by!**/__snapshots__/**tests/unit/mapping/__snapshots__/test_schemas/test_query_schemas[type_order_by_specific_fields].gqlis excluded by!**/__snapshots__/**
📒 Files selected for processing (16)
examples/testapp/testapp/types.pysrc/strawchemy/config/base.pysrc/strawchemy/dto/base.pysrc/strawchemy/dto/strawberry.pysrc/strawchemy/mapper.pysrc/strawchemy/schema/factories/aggregations.pysrc/strawchemy/schema/factories/base.pysrc/strawchemy/schema/factories/enum.pysrc/strawchemy/schema/factories/inputs.pysrc/strawchemy/schema/factories/types.pysrc/strawchemy/schema/field.pysrc/strawchemy/validation/pydantic.pytests/integration/types/mysql.pytests/integration/types/postgres.pytests/integration/types/sqlite.pytests/unit/schemas/order/order_config_specific_fields_with_type_override.py
This reverts commit d5d145b.
Description
Types of Changes
Issues Fixed or Closed by This PR
Checklist
Summary by CodeRabbit