Python warning configuration not working - python

So, I get the following output while running the tests for my Django project:
WARNING 2013-04-25 17:55:29,977 18482 29789392 py.warnings:3 <module>() /home/sean/dev/project/testenv/local/lib/python2.7/site-packages/django/conf/urls/defaults.py:3: DeprecationWarning: django.conf.urls.defaults is deprecated; use django.conf.urls instead
DeprecationWarning)
WARNING 2013-04-25 17:55:29,986 18482 29789392 py.warnings:10 <module>() /home/sean/dev/project/testenv/local/lib/python2.7/site-packages/django/utils/copycompat.py:10: DeprecationWarning: django.utils.copycompat is deprecated; use the native copy module instead
DeprecationWarning)
I'd like to figure out where in my code, or in what dependencies, these are originating.
http://docs.python.org/2/library/warnings.html
According to this, I can do the following to make Warnings be thrown as Exception and get a traceback:
At the top of my manage.py, before any other code is called:
import warnings
warnings.filterwarnings(
'error', r".*",
Warning, r'.*')
This causes "PendingDeprecationWarning: django.utils.simplejson is deprecated; use json instead." to be thrown, so I used:
import warnings
warnings.filterwarnings(
'error', r".*",
Warning, r'.*')
warnings.filterwarnings(
'ignore', r".*",
Warning, r'django\.utils\.simplejson')
But it's still printing out the previous DeprecationWarnings and not raising them as errors like it's supposed to.
Edit:
Also, I tried putting print and pdb statements at the beginning of warnings.warn_explicit(), the place where the filter logic happens, and they never get called.

You could run the tests or the local django server with the -W error option:
$ python -W error manage.py runserver
or
$ python -W error manage.py test
That will treat warnings as errors.

Related

nosetests: --nologcapture still captures INFO messages

With the code
import unittest
import logging
class LoggingTest(unittest.TestCase):
def test_that_logs(self):
logging.warning("Hello")
logging.info("World")
for a in xrange(100000000000000000):
pass
I get this unexpected output:
$ nosetests --version
nosetests version 1.3.7
$ nosetests log_from_nosetest.py --nocapture --nologcapture
WARNING:root:Hello
^C
----------------------------------------------------------------------
Ran 1 test in 105.376s
OK
As can be seen. The WARNING log level message is printed, but not the INFO level one.
I've tried using the --logging-level setting but without success.
It seems a missing feature. If --nologcapture is set, nose simply ignores all logging setup, e.g. --logging-level is not used at all. You can remedy that with a
logging.basicConfig(level=logging.INFO)
in your code - not sure if that's what you want, because this kind of setup shouldn't be in library-code at all. It would be fine within the test-setup though.
This is because the default log level is warning. Set it with
logging.getLogger('').setLevel(logging.INFO)

How to suppress the deprecation warnings in Django?

Every time I'm using the django-admin command — even on TAB–completion — it throws a RemovedInDjango19Warning (and a lot more if I use the test command). How can I suppress those warnings?
I'm using Django 1.8 with Python 3.4 (in a virtual environment). As far as I can tell, all those warnings come from libraries not from my code.
Examples
Here are some examples:
…/lib/python3.4/importlib/_bootstrap.py:321: RemovedInDjango19Warning: django.contrib.contenttypes.generic is deprecated and will be removed in Django 1.9. Its contents have been moved to the fields, forms, and admin submodules of django.contrib.contenttypes.
return f(*args, **kwds)
…/lib/python3.4/site-packages/django/contrib/admin/util.py:7: RemovedInDjango19Warning: The django.contrib.admin.util module has been renamed. Use django.contrib.admin.utils instead.
"Use django.contrib.admin.utils instead.", RemovedInDjango19Warning)
…/lib/python3.4/site-packages/django/templatetags/future.py:25: RemovedInDjango19Warning: Loading the ``url`` tag from the ``future`` library is deprecated and will be removed in Django 1.9. Use the default ``url`` tag instead.
RemovedInDjango19Warning)
Update
Since Django version 1.11 (release notes) deprecating warnings are no longer loud by default. So I guess this won't be an issue anymore, since 1.11 is the last version to support Python 2 and also features long-term support.
Adding a logging filter to settings.py can suppress these console warnings (at least for manage.py commands in Django 1.7, Python 3.4).
A filter can selectively suppress warnings. The following code creates a new "suppress_deprecated" filter for the console and appends it to the default logging filters. Add this block to settings.py to configure the LOGGING variable:
import logging, copy
from django.utils.log import DEFAULT_LOGGING
LOGGING = copy.deepcopy(DEFAULT_LOGGING)
LOGGING['filters']['suppress_deprecated'] = {
'()': 'mysite.settings.SuppressDeprecated'
}
LOGGING['handlers']['console']['filters'].append('suppress_deprecated')
class SuppressDeprecated(logging.Filter):
def filter(self, record):
WARNINGS_TO_SUPPRESS = [
'RemovedInDjango18Warning',
'RemovedInDjango19Warning'
]
# Return false to suppress message.
return not any([warn in record.getMessage() for warn in WARNINGS_TO_SUPPRESS])
The 'mysite.settings.SuppressDeprecated' string needs to change if the root website module (or filter location and/or name) is different.
In django 1.7, a new setting was introduced SILENCED_SYSTEM_CHECKS to suppress warnings
A list of identifiers of messages generated by the system check
framework (i.e. ["models.W001"]) that you wish to permanently
acknowledge and ignore. Silenced warnings will no longer be output to
the console; silenced errors will still be printed, but will not
prevent management commands from running.
Documentation could be found here
Here is a list of all the checks to suppress
Example:
If you wish to suppress the TEMPLATES_ warning,
The standalone TEMPLATE_* settings were deprecated in Django 1.8
your settings would be:
SILENCED_SYSTEM_CHECKS = ["1_8.W001"]
I'll leave this for newcomers:
As for django 1.11 deprecating warnings are no longer loud by default. To activate them run python -Wd manage.py runserver for example.
source
In manage.py, add this to the top line --
#!/usr/bin/env PYTHONWARNINGS=ignore python
This will suppress all warnings, which I agree can in some situations be undesirable if you're using a lot of third party libraries.
Disclaimer: Recommended only after you've already seen the warnings at least 1,000 too many times already, and should be removed when you upgrade Django.
Note: this may have some undesirable effects on some platforms, eg swallowing more output than just warnings.
Nothing of the above have worked for me, django 1.9. I fixed this by adding the following lines to settings.py:
import logging
def filter_deprecation_warnings(record):
warnings_to_suppress = [
'RemovedInDjango110Warning'
]
# Return false to suppress message.
return not any([warn in record.getMessage()
for warn in warnings_to_suppress])
warn_logger = logging.getLogger('py.warnings')
warn_logger.addFilter(filter_deprecation_warnings)
While reviewing deprecation warnings in other dependencies of my Django 1.8 project, using
python -Wd manage.py runserver
, I was able to filter out Django deprecation warnings by temporarily adding
import warnings
from django.utils.deprecation import RemovedInDjango110Warning
warnings.filterwarnings(action="ignore", category=RemovedInDjango110Warning)
to my settings.py (can presumably be in any module that's loaded at startup). I couldn't figure out how to include the filter as an extra -W option, i.e.
python -Wd -Wi::RemovedInDjango110Warning manage.py runserver
resulted in Invalid -W option ignored: unknown warning category: 'RemovedInDjango110Warning'.
For a quick command-line interface only solution, preface manage.py with python -W ignore when executing, as in:
python -W ignore manage.py runserver
-or-
python -W ignore manage.py shell_plus
-or-
python -W ignore manage.py makemigrations
This is working for me now, to suppress all of the Django 1.10 deprecation warnings while running Django 1.9.
For some reason the solution provided by Fred Schleifer didn't work for me in Django 1.9, so I had to find a different solution.
In settings.py, I set up a custom LOGGING_CONFIG function:
LOGGING_CONFIG = 'my_project.logging_utils.configure'
Then I defined my custom my_project.logging_utils module like so:
from logging.config import dictConfig
import warnings
from django.utils.deprecation import RemovedInDjango110Warning
IGNORE_DJANGO_110_WARNINGS = {
# This is a specific warning raised by a third-party library.
r'rest_framework_swagger\.urls': r'django\.conf\.urls\.patterns\(\) is deprecated.*'
}
def configure(settings):
dictConfig(settings)
for module, message in IGNORE_DJANGO_110_WARNINGS.items():
warnings.filterwarnings(
action='ignore',
category=RemovedInDjango110Warning,
module=module,
message=message
)
The IGNORE_DJANGO_110_WARNINGS dict contains a mapping from module names to regular expressions of warnings raised by them. I chose to be very specific in the kinds of warnings I suppressed, as I still wanted to see ones that I didn't expect. As individual third-party libraries are updated, I'll remove their associated entries from the dict.
# in settings.py
import warnings
from django.utils.deprecation import RemovedInDjango20Warning
DEBUG = True
if DEBUG:
warnings.simplefilter('default')
warnings.filterwarnings('ignore', category=RemovedInDjango20Warning)
# use it if you annoyed by DeprecationWarning
warnings.filterwarnings('ignore', category=DeprecationWarning)
This standart django script add TAB–completion for you bash - https://github.com/django/django/blob/master/extras/django_bash_completion
PYTHONWARNINGS is not defined - error in console. Add export PYTHONWARNINGS="ignore" and unset PYTHONWARNINGS in _django_completion()
Original function:
_django_completion()
{
COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
DJANGO_AUTO_COMPLETE=1 $1 ) )
}
My version. Do not break the basic behavior in other cases.
_django_completion()
{
export PYTHONWARNINGS="ignore"
COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
DJANGO_AUTO_COMPLETE=1 $1 ) )
unset PYTHONWARNINGS
}
Django puts warnings through the standard python warnings module. If your python project throws warnings and they're "acceptable" for the moment, just use warnings.filterwarnings() or warnings.simplefilter(). I'm not sure where the "best" place for these are, but I've dropped them into my common_settings.py file (For me, this is a unchanging, checked-in file, that is imported by local_settings.py).
Eg:
warnings.filterwarnings(action="ignore", category=RemovedInDjango110Warning, module='django.template.utils', lineno=37)
Alas the comment about silencing the system checks won't work, here, since your example isn't throwing a system-check error.
I currently encounter this same issue when using Django 1.8. Instead of completely suppress those warnings, we decide to show them only in DEBUG mode.
We can add console handler in logging settings and use this handler to catch py.warnings. Here is the code snippet,
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue'
},
...
},
'handlers': {
'console': {
'level': 'DEBUG',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'standard',
},
...
},
'loggers': {
'py.warnings': {
'handlers': ['console', ],
'level': 'INFO',
'propagate': False
},
...
}
The complete Django settings file: https://github.com/haiwen/seahub/blob/21c827c68047e13700fe102d22a3f5515b22af89/seahub/settings.py#L484
Time to add another one suggestion here, which worked for me. Django 3.2, but should work on any version.
What worked for me is assuming that the developers would be clever enough to output these to python stderr, not stdout. They were!
So..., just redirect stderr to via a standard bash 2>/dev/null
django-admin findstatic teststatic.css 2>/dev/null
Found 'teststatic.css' here:
/Users/me/kds2/py2/bemyerp/websec/static/websec/nodelinks/teststatic.css
/Users/me/kds2/py2/bemyerp/dist/teststatic.css
Of course, bear in mind your context and what this redirection does: suppressing ANY error message. For example, if django-admin is missing, that error message will also disappear (run missing-django-admin findstatic teststatic.css 2>/dev/null to see the effect).
what I was trying to filter out...
HINT: Use django.db.models.JSONField instead.
pssystem.TagType: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'.
HINT: Configure the DEFAULT_AUTO_FIELD setting or the AppConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.
Found 'teststatic.css' here:
/Users/me/kds2/py2/bemyerp/websec/static/websec/nodelinks/teststatic.css
/Users/me/kds2/py2/bemyerp/dist/teststatic.css
Things tried without success:
(I am not saying these never work, only that they didn't filter the particular messages I was getting and wanted to avoid, in my environment.
python -W ignore manage.py findstatic teststatic.css
PYTHONWARNINGS=ignore django-admin findstatic teststatic.css
PYTHONWARNINGS=ignore python manage.py findstatic teststatic.css
python -Wd manage.py findstatic teststatic.css
env: Django 3.2, using Python 3.10 with virtualenv

Remove Python UserWarning

I just finished installing my MySQLdb package for Python 2.6, and now when I import it using import MySQLdb, a user warning appear will appear
/usr/lib/python2.6/site-packages/setuptools-0.8-py2.6.egg/pkg_resources.py:1054:
UserWarning: /home/sgpromot/.python-eggs is writable by group/others and vulnerable
to attack when used with get_resource_filename. Consider a more secure location
(set with .set_extraction_path or the PYTHON_EGG_CACHE environment variable).
warnings.warn(msg, UserWarning)
Is there a way how to get rid of this?
You can change ~/.python-eggs to not be writeable by group/everyone. I think this works:
chmod g-wx,o-wx ~/.python-eggs
You can suppress warnings using the -W ignore:
python -W ignore yourscript.py
If you want to supress warnings in your script (quote from docs):
If you are using code that you know will raise a warning, such as a deprecated function, but do not want to see the warning, then it is possible to suppress the warning using the catch_warnings context manager:
import warnings
def fxn():
warnings.warn("deprecated", DeprecationWarning)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
fxn()
While within the context manager all warnings will simply be ignored. This allows you to use known-deprecated code without having to see the warning while not suppressing the warning for other code that might not be aware of its use of deprecated code. Note: this can only be guaranteed in a single-threaded application. If two or more threads use the catch_warnings context manager at the same time, the behavior is undefined.
If you just want to flat out ignore warnings, you can use filterwarnings:
import warnings
warnings.filterwarnings("ignore")

Python Programming error . 'import sitecustomize' failed; use -v for traceback

Anything that I code I get this same error. import sitecustomize failed; use -v for traceback. What am I doing wrong?
Do what the error message tells you to do; run Python from the command line with the -v command line switch to get a traceback. There is an error in the sitecustomize.py module and you need to fix that.
Alternatively, set the PYTHONVERBOSE environment variable to get the same effect.

Turn off sqlalchemy warnings in nosetests

I'm trying to suppress all sqlalchemy warnings while running my test suite with nosetests. I read Turn off a warning in sqlalchemy
.............................../Users/ca/.pythonbrew/venvs/Python-2.7.3/api/lib/python2.7/site-packages/SQLAlchemy-0.7.5-py2.7-macosx-10.7-x86_64.egg/sqlalchemy/engine/default.py:330: Warning: Field 'random_id' doesn't have a default value
cursor.execute(statement, parameters)
I included this in my package's __init__.py file:
def setup_package():
"""Setup the test during the whole session.
Run by nosetests
"""
# Suppress all SQLAlchemy warnings
warnings.filterwarnings("ignore", category=sa_exc.SAWarning)
With the proper imports. I know it is run by nosetests because I tried some other stuff which raised error. The only thing is that it has no effect whatsoever. Warnings are still displayed.
Any idea?
Thanks!
It seems that nose overwrites whatever you set with:
warnings.filterwarnings("ignore")
However you can filter warnings during nose test with a command line option to nose. e.g.:
$ nosetests --logging-filter=SAWarning
I found that this still may not work under all circumstances. If this is the case you can try:
$ python -W ignore `which nosetests`

Categories

Resources