Skip to content

Conversation

caseyclements
Copy link
Contributor

https://jira.mongodb.org/browse/PYTHON-3036

When an unknown kwarg was passed to MongoClient, the ConfigurationError wasn't helpful. I use the standard lib package difflib to look for similar known options. It appears to work pretty well.

First contribution to this mongodb. This PR / ticket doubles as SDLC tutorial. I've got a feature branch with a couple tests that I'll now use.

It will now look something like this:

ConfigurationError('Unknown option: auth. Did you mean: authsource, authmechanism, authoidcallowedhosts?') 
@caseyclements caseyclements requested a review from a team as a code owner November 20, 2023 19:47
@caseyclements caseyclements requested review from ShaneHarvey and removed request for a team November 20, 2023 19:47

def test_validate_suggestion(self):
"""Validate kwargs in constructor."""
self.assertRaises(ConfigurationError, MongoClient, auth="standard")
Copy link
Member

@ShaneHarvey ShaneHarvey Nov 20, 2023

Choose a reason for hiding this comment

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

We can replace these two asserts with one that uses with self.assertRaisesRegex(...), for example:

with self.assertRaisesRegex(TypeError, "'MongoClient' object is not iterable"):
_ = client.next()

Copy link
Member

Choose a reason for hiding this comment

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

still todo.

return option, value
except KeyError:
suggestions = get_close_matches(lower, VALIDATORS, cutoff=0.2)
raise_config_error(option, suggestions)
Copy link
Member

Choose a reason for hiding this comment

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

What do you think about refactoring this with the code block below? It seems like they are essentially identical besides the VALIDATORS vs URI_OPTIONS_VALIDATOR_MAP.

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've added a note /hint on camelCase and suggested referring to docstring.
I've also opened a ticket to explore rationalizing the keys to kwargs: https://jira.mongodb.org/browse/PYTHON-4056

Copy link
Member

@ShaneHarvey ShaneHarvey Nov 21, 2023

Choose a reason for hiding this comment

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

Thanks I'll resolve the other comment about camelCase but this comment is still todo.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi. If the original intent hasn't been resolved, would you please elaborate?

Copy link
Member

Choose a reason for hiding this comment

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

Can you refactor this to remove the duplicated code so that there's only one call to try/except + get_close_matches/raise_config_error, eg:

def _get_validator(name, validators): lower = name.lower() try: return validators[lower] except KeyError: suggestions = get_close_matches(lower, validators, cutoff=0.2) raise_config_error(name, suggestions)
Copy link
Contributor Author

@caseyclements caseyclements left a comment

Choose a reason for hiding this comment

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

@ShaneHarvey When you've got a moment, let's review my review :)

return option, value
except KeyError:
suggestions = get_close_matches(lower, VALIDATORS, cutoff=0.2)
raise_config_error(option, suggestions)
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've added a note /hint on camelCase and suggested referring to docstring.
I've also opened a ticket to explore rationalizing the keys to kwargs: https://jira.mongodb.org/browse/PYTHON-4056


def test_validate_suggestion(self):
"""Validate kwargs in constructor."""
self.assertRaises(ConfigurationError, MongoClient, auth="standard")
Copy link
Member

Choose a reason for hiding this comment

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

still todo.

return option, value
except KeyError:
suggestions = get_close_matches(lower, VALIDATORS, cutoff=0.2)
raise_config_error(option, suggestions)
Copy link
Member

@ShaneHarvey ShaneHarvey Nov 21, 2023

Choose a reason for hiding this comment

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

Thanks I'll resolve the other comment about camelCase but this comment is still todo.

for opt, value in options.items():
normed_key = get_normed_key(opt)
try:
validator = URI_OPTIONS_VALIDATOR_MAP.get(normed_key, raise_config_error)
Copy link
Member

@ShaneHarvey ShaneHarvey Nov 29, 2023

Choose a reason for hiding this comment

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

This code should still be using URI_OPTIONS_VALIDATOR_MAP but by calling validate() it now uses VALIDATORS. This is why I suggested the _get_validator function in my earlier comment.


def _get_validator(
key: str, validators: dict[str, Callable[[Any, Any], Any]], normed_key: Optional[str] = None
):
Copy link
Member

Choose a reason for hiding this comment

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

Typecheck is failing due to the missing return type here.

@ShaneHarvey ShaneHarvey merged commit d4dfd4a into mongodb:master Nov 30, 2023
@caseyclements caseyclements deleted the feature/PYTHON-3036 branch December 1, 2023 01:19
caseyclements added a commit to caseyclements/mongo-python-driver that referenced this pull request Dec 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants