-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
bpo-41086: Add exception for uninstantiated interpolation (configparser) #21062
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
Conversation
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept this contribution by verifying everyone involved has signed the PSF contributor agreement (CLA). Recognized GitHub usernameWe couldn't find a bugs.python.org (b.p.o) account corresponding to the following GitHub usernames: This might be simply due to a missing "GitHub Name" entry in one's b.p.o account settings. This is necessary for legal reasons before we can look at this contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. You can check yourself to see if the CLA has been received. Thanks again for the contribution, we look forward to reviewing it! |
Odd, that the Ubuntu check is failing, because this was built and tested on Ubuntu. So it works on my local and it looks like the errors are unrelated to work that I did. Hopefully one of the reviews can help. |
Lib/configparser.py
Outdated
@@ -633,6 +642,8 @@ def __init__(self, defaults=None, dict_type=_default_dict, | |||
self._interpolation = self._DEFAULT_INTERPOLATION | |||
if self._interpolation is None: | |||
self._interpolation = Interpolation() | |||
if isinstance(self._interpolation, type): | |||
raise InterpolationIsNotInstantiatedError() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the parameter is to be checked, then I think the check should be that interpolation is an instance of Interpolation (rather than that is is not an instance of type). That way you would catch other bad args.
The exception would be InterpolationTypeError or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the suggestions, I've accepted them locally, but they cause some need for changes in the English text/explanations associated with the code. I'll made updates to those and post back once I get better text in there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In response to the feedback, the exception now is InterpolationTypeError and some of the comment text and the commit message has been updated to reflect this. The patch was also rebased onto main as there was a comment on https://bugs.python.org/issue41086 about not backporting and a conflict in the __all__
which the rebase has resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iritkatriel , sorry to send a notification, but I wanted to check if I corrected things per your suggestion?
b4808ee
to
f593811
Compare
The current feedback when users try to pass an uninstantiated interpolation into a ConfigParser is an error message that does not help users solve the problem. This current error of `TypeError: before_set() missing 1 required positional argument: 'value'` does not display until the parser is used, which usually results in the assumption that instantiation of the parser was done correctly. The new exception of InterpolationTypeError, will be raised on the line where the ConfigParser is instantiated. This will result in users see the line that has the error in their backtrace for faster debugging. There have been a number of bugs created in the issue tracker, which could have been addressed by: https://bugs.python.org/issue26831 and https://bugs.python.org/issue26469
f593811
to
5548184
Compare
Lib/configparser.py
Outdated
|
||
Giving users faster and more clear feedback on how to fix a common error | ||
""" | ||
def __init__(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other exceptions in the module call Error.init, this one should follow this pattern.
Lib/configparser.py
Outdated
class InterpolationTypeError(Error): | ||
"""Raised when the _interpolation is not an instance of Interpolation | ||
|
||
Giving users faster and more clear feedback on how to fix a common error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The last line of this docstring isn't really providing useful information.
Lib/test/test_configparser.py
Outdated
@@ -1048,6 +1048,12 @@ def test_set_malformatted_interpolation(self): | |||
self.assertEqual(cf.get("sect", "option2"), "foo%%bar") | |||
|
|||
|
|||
class ConfigParserTestCaseInterpolationIsInstantiated(unittest.TestCase): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd make this ConfigParserTestCaseInvalidInterpolationType and add a couple of tests for other invalid types (say, an int and a string. You can do this in a loop), something like:
for value in [configparser.ExtendedInterpolation, 42, "a string]:
with self.subTest(value = value):
with self.assertRaises(TypeError):
configparser.ConfigParser(interpolation=value)
Lib/configparser.py
Outdated
@@ -279,6 +279,13 @@ class InterpolationSyntaxError(InterpolationError): | |||
which substitutions are made does not conform to the required syntax. | |||
""" | |||
|
|||
class InterpolationTypeError(Error): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you add a new exception type then you need to add it to the documentation as well. TBH, I don't think you need a new exception type here. You could just raise a TypeError.
Lib/test/test_configparser.py
Outdated
@@ -1048,6 +1048,12 @@ def test_set_malformatted_interpolation(self): | |||
self.assertEqual(cf.get("sect", "option2"), "foo%%bar") | |||
|
|||
|
|||
class ConfigParserTestCaseInterpolationIsInstantiated(unittest.TestCase): | |||
def test_error_on_uninstantiated_interpolation(self): | |||
with self.assertRaises(configparser.InterpolationTypeError) as context: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with self.assertRaises(configparser.InterpolationTypeError) as context: | |
with self.assertRaises(configparser.InterpolationTypeError): |
Lib/test/test_configparser.py
Outdated
class ConfigParserTestCaseInterpolationIsInstantiated(unittest.TestCase): | ||
def test_error_on_uninstantiated_interpolation(self): | ||
with self.assertRaises(configparser.InterpolationTypeError) as context: | ||
cf = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cf = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation) | |
configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation) |
@@ -0,0 +1 @@ | |||
Added validation check of instantiation on ConfigParser's interpolation parameter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added validation check of instantiation on ConfigParser's interpolation parameter. | |
Make the :class:`configparser.ConfigParser` constructor raise :exc:`TypeError` if the ``interpolation`` parameter is not of type :class:`configparser.Interpolation`. |
@scrummyin Thank you for the patch. I reviewed it and made some comments. However, I don't know whether the documentation would need changing. I can see in the docstring that the interpolation parameter is expected to be a subtype of Intrerpolation, but this not mentioned in the doc, so I don't know if it's ok to just block duck typing here. @ambv - since you wrote the docstring, any thoughts? |
Per feedback from @iritkatriel, the custom InterpolationTypeError has been dropped in favour of a TypeError with a custom message, and the unittests have been expanded.
@iritkatriel , I resolved most of your suggestions by removing the custom Error and switching it to TypeError. In addition, I also took the suggestions of adding more test coverage and the better news message. I've added a new commit for that work, and would be happy to squash the commits anyway you see fit. For now I left it as a new commit, in hopes that will facilitate future reviews. |
Thanks! ✨ 🍰 ✨ |
The current feedback when users try to pass an uninstantiated
interpolation into a ConfigParser is an error message that does not help
users solve the problem. This current error of
TypeError: before_set() missing 1 required positional argument: 'value'
does not display untilthe parser is used, which usually results in the assumption that
instantiation of the parser was done correctly. The new exception of
InterpolationIsNotInstantiatedError, will be raised on the line where
the ConfigParser is instantiated. This will result in users see the line
that has the error in their backtrace for faster debugging.
There have been a number of bugs created in the issue tracker, which
could have been addressed by:
https://bugs.python.org/issue26831 and https://bugs.python.org/issue26469
https://bugs.python.org/issue41086