Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should None be an allowed factory return value? #22

Closed
elfjes opened this issue Aug 8, 2023 · 7 comments
Closed

Should None be an allowed factory return value? #22

elfjes opened this issue Aug 8, 2023 · 7 comments

Comments

@elfjes
Copy link

elfjes commented Aug 8, 2023

currently, Container.get starts with the following

if (svc := self._instantiated.get(svc_type)) is not None:
    return svc

meaning that if a factory has been run, and returns None, this value is not considered cached when requesting it the next time and the factory will be run again, overriding any potential closing logic.

I could imagine a user wanting to do something along the lines of:

def int_factory():
    yield None
    ... # some cleanup logic


qol.register(int, int_factory)

# later
result = qol.get(int)
if result is not None:
    ... # some logic
else:
    ... # some other logic

I'm not sure exactly what a use case for this might be, but the current implementation disallows the user to have None be a meaningful value which is generally considered not a good practice for a library. And it's easy to fix by just substituting the first dictionary lookup default value by a sentinel

@hynek
Copy link
Owner

hynek commented Aug 8, 2023

Noe that's not what it means. self._instantiated is the container's cache and get() is not None means that something is already cached – or am I missing something?

@elfjes
Copy link
Author

elfjes commented Aug 8, 2023

Let's say a user has set up a factory that explicitely returns None for a particular Service (under certain conditions), and wants to cache that value in the Container. Currently, this value is properly being cached in self._instantiated. However, the second time the Service is requested, that first if-statement resolves to False and the cached value is not used. Instead, the instantiation logic is run again, which may result in undesirable behaviour.

Now, what I said before about closing logic was erroneous, since all generators are added to the _on_close list so that all cleanup logic is run. but the above reasoning still stands I think

@hynek
Copy link
Owner

hynek commented Aug 8, 2023

But what would None mean? Should we raise an exception if a factory returns None?

Aren't you overarchingly asking for #12?

@elfjes
Copy link
Author

elfjes commented Aug 8, 2023

That's the thing. I don't think it should be up to the library (ie. svcs) to determine what None means, that's for the application developer to decide. Would you see value in if svcs just transparently accepts a None coming from a factory and subsequently caches and reuses it as if it were any other value? Right now, it doesn't reuse a cached None

@hynek
Copy link
Owner

hynek commented Aug 8, 2023

ah now I got it 😅

currently we're being kinda smart – yeah we should fix that

@hynek hynek closed this as completed in 0104165 Aug 8, 2023
@hynek
Copy link
Owner

hynek commented Aug 8, 2023

fix is in 23.11!

@elfjes
Copy link
Author

elfjes commented Aug 8, 2023

Great ^^

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

No branches or pull requests

2 participants