Skip to content

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

Merged
merged 4 commits into from
Feb 17, 2022

Conversation

scrummyin
Copy link
Contributor

@scrummyin scrummyin commented Jun 23, 2020

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
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

@the-knights-who-say-ni
Copy link

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 username

We couldn't find a bugs.python.org (b.p.o) account corresponding to the following GitHub usernames:

@scrummyin

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!

@scrummyin
Copy link
Contributor Author

scrummyin commented Jun 23, 2020

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.

@@ -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()
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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?

@scrummyin scrummyin force-pushed the fix/configparser_interpolation branch from b4808ee to f593811 Compare October 22, 2021 12:39
scrummyin and others added 2 commits October 23, 2021 21:00
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
@scrummyin scrummyin force-pushed the fix/configparser_interpolation branch from f593811 to 5548184 Compare October 24, 2021 01:01

Giving users faster and more clear feedback on how to fix a common error
"""
def __init__(self):
Copy link
Member

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.

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
Copy link
Member

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.

@@ -1048,6 +1048,12 @@ def test_set_malformatted_interpolation(self):
self.assertEqual(cf.get("sect", "option2"), "foo%%bar")


class ConfigParserTestCaseInterpolationIsInstantiated(unittest.TestCase):
Copy link
Member

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)

@@ -279,6 +279,13 @@ class InterpolationSyntaxError(InterpolationError):
which substitutions are made does not conform to the required syntax.
"""

class InterpolationTypeError(Error):
Copy link
Member

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.

@@ -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:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
with self.assertRaises(configparser.InterpolationTypeError) as context:
with self.assertRaises(configparser.InterpolationTypeError):

class ConfigParserTestCaseInterpolationIsInstantiated(unittest.TestCase):
def test_error_on_uninstantiated_interpolation(self):
with self.assertRaises(configparser.InterpolationTypeError) as context:
cf = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
cf = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation)
configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation)

@@ -0,0 +1 @@
Added validation check of instantiation on ConfigParser's interpolation parameter.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
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`.

@iritkatriel
Copy link
Member

@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.
@scrummyin
Copy link
Contributor Author

@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.

@ambv ambv merged commit fc115c9 into python:main Feb 17, 2022
@ambv
Copy link
Contributor

ambv commented Feb 17, 2022

Thanks! ✨ 🍰 ✨

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.

5 participants