Skip to content

Conversation

@iverberk
Copy link
Contributor

@iverberk iverberk commented Jan 2, 2026

This PR adds support for dependencies of an unknown type that provide a default value, allowing them to be instantiated even if the type is not known in the registry.

Fixes #94

Copy link
Owner

@maldoinc maldoinc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @iverberk, thanks for this! Just a few minor comments but functionality-wise this is ready to go.


class MyService:
pass
def test_register_factory_with_unknown_dependency_with_default() -> None:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to have some tests that capture the same behavior for configuration injection via Inject(param=)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add them!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the tests satisfactory?

@iverberk iverberk force-pushed the support-default-values branch from 7ef67f4 to 8de5f22 Compare January 2, 2026 21:04
@maldoinc
Copy link
Owner

maldoinc commented Jan 2, 2026

Looks good, thanks! Just need to sort out the linting checks. You can run make lint, make test locally as well.

@iverberk
Copy link
Contributor Author

iverberk commented Jan 3, 2026

linting errors are resolved, at least locally.

@iverberk
Copy link
Contributor Author

iverberk commented Jan 4, 2026

The build breaks on Python < 3.10 due to the pydantic_settings library requirements. What would you propose in this case? I think I needed to add the Python >= 3.10 requirement, otherwise Poetry would fail to resolve the dependencies.

@maldoinc
Copy link
Owner

maldoinc commented Jan 4, 2026

Let's skip the pydantic test case for versions older than py3.10.

@iverberk
Copy link
Contributor Author

iverberk commented Jan 4, 2026

Not sure what is going on with the 3.9 tests? It works locally with 3.9.25.

elif not self.is_type_with_qualifier_known(parameter.klass, qualifier=parameter.qualifier_value):
msg = (
f"Parameter '{name}' of {stringify_type(target)} "
f"depends on an unknown service {stringify_type(parameter.klass)} "
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error comes from the stringify_type function when called with an optional type. You can get the raw type directly like this: stringify_type(analyze_type(parameter.klass).raw_type)

Copy link
Contributor Author

@iverberk iverberk Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want me to update all the stringify_type(target) instances to the new form stringify_type(analyze_type(parameter.klass).raw_type)? I'm unable to reproduce this locally with Python 3.9.25, which makes it a bit hard to verify.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, strange. I tested it with the same version locally and I can reporoduce it. The failing test cases is test_unknown_service_with_default_value

Copy link
Contributor Author

@iverberk iverberk Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As expected, a configuration error on my system. I installed a a second venv for 3.9 but unbeknownst to me, it was still defaulting to the 3.13 one.

@iverberk
Copy link
Contributor Author

iverberk commented Jan 5, 2026

Should we skip the Pydantic check for 3.14 also? Pydantic seems to have a compatibility problem with 3.14 at the moment.

@maldoinc
Copy link
Owner

maldoinc commented Jan 6, 2026

Let's skip that for now.

@maldoinc
Copy link
Owner

maldoinc commented Jan 8, 2026

Some edge case we have not addressed here: *args, **kwargs` which we can ignore as they have implicit default values. Same for untyped parameters as long as they have a default value.

@service
class Thing:
    def __init__(self, 
        foo: Foo | None, 
        x = 1,
        some_config: Annotated[str | None, Inject(param="test_config")] = None, 
        *args: Any, 
        **kwargs: Any
    ) -> None:
        self.foo = foo
        self.bar = bar

@iverberk
Copy link
Contributor Author

I'm not sure I follow what I need to do here. Is your example something that wouldn't work with the new changes? I put it in a testcase and it was happy to provide the dependency. Can you make it a little more specific what is currently missing from the code? Thanks!

@maldoinc
Copy link
Owner

Yeah, the above will fail since some parameters have no type at all, and stuff like args and kwargs that also have "default" values are validated. We can skip these kind of parameters outright during dependency registration.

@iverberk iverberk force-pushed the support-default-values branch from e7ce18a to 9b09f62 Compare January 11, 2026 13:10
@iverberk iverberk force-pushed the support-default-values branch from 9b09f62 to 41c0275 Compare January 11, 2026 13:14
@maldoinc
Copy link
Owner

Looks good, thanks. Just py3.8 lint failing.

@iverberk
Copy link
Contributor Author

Always something :-) Pushed a new commit to fix.

@maldoinc maldoinc merged commit b5e9fd8 into maldoinc:master Jan 11, 2026
8 checks passed
@maldoinc
Copy link
Owner

Thank you @iverberk!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"Wireup dependencies must have types" error when using Pydantic settings base class

2 participants