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
replace logger.warning with warnings.warn #1040
Conversation
Codecov Report
@@ Coverage Diff @@
## main #1040 +/- ##
=======================================
Coverage 98.35% 98.36%
=======================================
Files 126 126
Lines 13098 13123 +25
=======================================
+ Hits 12883 12908 +25
Misses 215 215
Continue to review full report at Codecov.
|
I will consider this PR done and ready to merge unless someone points out to warnings worth changing. |
@systemshift Please pull in the latest changes from the |
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 am approaching this with the idea that if the user should do something differently we will use warnings.warn
, but if there is nothing the user can/should do then we will use logger.warn
.
Here are the warnings I think should be changed:
featuretools/utils/gen_utils.py
L73 - change this tologger.warn
as there is nothing the user can do if the saved schema is no longer supportedfeaturetools/computational_backends/calculate_feature_matrix
L560 - change tologger.warn
as this isn't caused by the userfeaturetools/entityset/entity.py
L549 - usewarnings.warn
as the user can fix this by setting the last time indexfeaturetools/entityset/entity.py
L578 - usewarnings.warn
as the user can fix this by specifying the index columnfeaturetools/entityset/entity.py
L588 - usewarnings.warn
as the user can fix this by specifying the parameters correctlyfeaturetools/feature_base
feature_base.py` L174 - remove commented out warning that is not usedfeaturetools/primitives/options_utils.py
L63 - usewarnings.warn
as this can be fixed if the user does not specify redundant primitive options
"primitive class (%s), primitive instance will not use generic " \ | ||
"primitive class %s, primitive instance will not use generic " \ |
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.
This one was really hard to work around, using ()
in a string seems to break something with pytest.warn
. Tried using string literals but no luck.
Would like to know if someone knows how to work around this issue.
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 don't think it is critical to have the parentheses here, but I'm also not sure how to work around this exactly either.
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.
using escapes on the parentheses -- "\(%s\)" -- in the warning_msg
string should work. The string is interpreted as a regex so a regular parentheses won't get the match we want
if warning_text: | ||
with pytest.warns(UserWarning) as record: | ||
deserialize.description_to_entityset(dictionary) | ||
assert record[0].message.args[0] == warning_text | ||
# TODO Refactor this function and both parent functions to run tests with a less complex implementation | ||
earlier_schema_warning = 'is no longer supported by this version' | ||
if earlier_schema_warning in str(warning_text): | ||
logger = logging.getLogger('featuretools') | ||
logger.propagate = True | ||
deserialize.description_to_entityset(dictionary) | ||
assert warning_text in caplog.text | ||
logger.propagate = False |
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.
Before we were checking that a UserWarning
got raised for both earlier and later schema versions with the assert statement inside the pytest.warns
context manager. Now we changed one of these to be logged instead.
With these code changes here, we are only testing that warning is logged for the earlier schema test. We are no longer testing that the UserWarning
still gets raised for the later schema test. To test that we need to add a later scheme condition to the if-else block to verify the warning gets raised as it did before.
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.
One way you could refactor this would be to split _check_schema_version
into three different functions. You could do something like _check_schema_raises_warning
to check that the UserWarning
gets raised inside test_later_schema_version
. Then have _check_schema_logs_warning
to test logging for the test_earlier_schema_version
test. In both of those new utility functions we could use a third _get_schema_dictionary
function to build and return the dictionary that will be needed by both of the new check functions.
Another idea would be to create a new parameter that gets passed to _check_schema_version
to indicate whether we should check for a UserWarning
or a logged warning instead of relying on the value of the warning text to make that determination.
This seems like it is getting more complicated than I anticipated though. @rwedge Do you have any thoughts on the best approach here?
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 think keep _check_schema_version
as a single function, add a new parameter to it to indicate if it is expected to warn / log / neither, and use warning_text
for matching purposes
if warning_text: | ||
with pytest.warns(UserWarning) as record: | ||
FeaturesDeserializer(dictionary) | ||
|
||
assert record[0].message.args[0] == warning_text | ||
# TODO Refactor this function and both parent functions to run tests with a less complex implementation | ||
earlier_schema_warning = 'is no longer supported by this version' | ||
if earlier_schema_warning in str(warning_text): | ||
logger = logging.getLogger('featuretools') | ||
logger.propagate = True | ||
FeaturesDeserializer(dictionary) | ||
assert warning_text in caplog.text | ||
logger.propagate = False |
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.
Similar to the entityset test, we need to make sure we are testing for the UserWarning
for the later schema version test.
"primitive class (%s), primitive instance will not use generic " \ | ||
"primitive class %s, primitive instance will not use generic " \ |
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 don't think it is critical to have the parentheses here, but I'm also not sure how to work around this exactly either.
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 making these changes, @systemshift! I identified a few cases where warnings weren't be tested before, it would be great to add explicit warning checking to these tests.
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.
Looks good! Thanks for the contribution!
Pull Request Description
Based on #1014 and the linked stack overflow thread discussion.
I started with the intent where
warnings.warn()
should be used for designing a library(which featuretools is) to warn the user when it is not used correctly. Where aslogger.warning()
is more suitable for apps where the wrong input is user data.So most of
warnings.warn()
seem to be used as they should be, with a few cases where logger was used and I feltwarnings.warn()
made more sense.Now there are a few cases of
logger.warning()
that looked off, but I did not want to change them, so I would like someone to review the remaininglogger.warning()
cases to see if it should still be there and not replaced.After creating the pull request: in order to pass the changelog_updated check you will need to update the "Future Release" section of
docs/source/changelog.rst
to include this pull request.