-
-
Notifications
You must be signed in to change notification settings - Fork 9
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
ConfigUpdater.get returns string literal if fallback provided #124
Comments
Thanks for posting this issue @bdbenim. This behaviour is really inconsistent. I think there are two possibilities. Either we do not allow passing a default option (and by this being not consistent to the The latter alternative makes more sense to me. What do you think @abravalheri? @bdbenim Would you be interested in providing a PR to fix this bug? |
The documentation seems to be outdated. The signature, however, shows the correct information: @overload # type: ignore[override]
def get(self, section: str, option: str) -> Option:
...
@overload
def get(self, section: str, option: str, fallback: T) -> Union[Option, T]:
... I belive we have 3 options here: A. Fix the docs to match the signatures. The problem with (B) is that it would be a backward incompatible change, so we have to bump the version and it may break users existing code. I suppose that even if we just do (A) users life are not that complicated as they can always write: example = conf.get("section", "nonexistant", fallback=Option("nonexistant", value="2")) (A bit verbose, but explicit). I am OK either way, but if we go for (B), it would be nice to check around github/grep.app to see if it would not break anyone's code. |
@FlorianWilhelm I wouldn't mind taking a shot at fixing it and providing a PR. @abravalheri I see what you mean, and I agree that option (B) is potentially a breaking change. I'm trying think of the edge cases in my mind, and I suspect that it might not actually break anything, since any call to I'm of course selfishly inclined toward option (B), but option (C) I think would satisfy me without breaking anyone else's code. Something like: @overload # type: ignore[override]
def get(self, section: str, option: str) -> Option:
...
@overload
def get(self, section: str, option: str, fallback: T) -> Union[Option, T]:
...
@overload
def get(self, section: str, option: str, fallbackLiteral: T) -> Option:
... The third version could return Option(option, fallbackLiteral) if the option isn't found in the section. Thoughts? |
I gave it a shot in #125 and it seems to work. I couldn't get the unit tests to run in my development environment, but did some testing of my own in a script. The existing behaviour is unchanged as far as I can tell, but if the new parameter |
Thanks for the PR @bdenim and thanks for explaining the different alternatives @abravalheri. I am not quite sure if the alternative C doesn't make the API too complicated as the return type now depends on a true/false flag. For me the simplest solution is B, which has the downside of breaking the API and we would need to jump to v4, which I guess is fine and configupdater users are power users anyway and hopefully apply semantic versioning. I think alternative A is also not bad (didn't know this was possible) as it solves the problem even though it is cumbersome and one would only need to fix the docs and maybe add this example to the docs because it might not be obvious. In summery, my preference is B > A > C. But @abravalheri has the final word on this :-) |
Sorry for the delay guys. To be honest my preference is A > C > B 😅, mainly because of the semantics of the My impression when I read The proposal to use (I am not a native speaker, so this opinion, of course, has to be taken with a grain of salt). The other problem is: how do we know that the majority of users want to get I think option A sidesteps the difficulties. I don't want to strong arm anyone, so for now I will simply write a PR to correct the docs, but we can leave this discussion open until we reach a consensus. Hopefully #127 improves the text. Please feel free to add suggestions directly to the PR. P.S.: Most of this problem derives from the fact that the original |
Description of your problem
The output of the
get()
method is a different type depending on whether or not it returns the fallback option, meaning that it cannot be reliably assumed to be an object of typeOption
as expected.Output:
Please provide any additional information below.
According to this documentation, the
get
method should return an object of typeOption
. However, if a fallback value is provided, the literal value of this fallback is returned. I would expect the behaviour of examples 2 and 3 to be the same, where if I provide a fallback value then it will be treated as an option in the respective section and returned as such. The ability to provide a fallback is pointless since I still have to check the output and do something different depending on whether or not the key was found in that sectionVersions and main components
The text was updated successfully, but these errors were encountered: