mirror of
https://github.com/python/cpython.git
synced 2025-11-03 11:23:31 +00:00
- Add new Warning class, ImportWarning
- Warn-raise ImportWarning when importing would have picked up a directory as package, if only it'd had an __init__.py. This swaps two tests (for case-ness and __init__-ness), but case-test is not really more expensive, and it's not in a speed-critical section. - Test for the new warning by importing a common non-package directory on sys.path: site-packages - In regrtest.py, silence warnings generated by the build-environment because Modules/ (which is added to sys.path for Setup-created modules) has 'zlib' and '_ctypes' directories without __init__.py's.
This commit is contained in:
parent
2c1e63f8a4
commit
9df4e6f673
6 changed files with 60 additions and 7 deletions
|
|
@ -108,6 +108,7 @@ PyAPI_DATA(PyObject *) PyExc_SyntaxWarning;
|
||||||
PyAPI_DATA(PyObject *) PyExc_OverflowWarning;
|
PyAPI_DATA(PyObject *) PyExc_OverflowWarning;
|
||||||
PyAPI_DATA(PyObject *) PyExc_RuntimeWarning;
|
PyAPI_DATA(PyObject *) PyExc_RuntimeWarning;
|
||||||
PyAPI_DATA(PyObject *) PyExc_FutureWarning;
|
PyAPI_DATA(PyObject *) PyExc_FutureWarning;
|
||||||
|
PyAPI_DATA(PyObject *) PyExc_ImportWarning;
|
||||||
|
|
||||||
|
|
||||||
/* Convenience functions */
|
/* Convenience functions */
|
||||||
|
|
|
||||||
|
|
@ -44,3 +44,4 @@ BaseException
|
||||||
+-- UserWarning
|
+-- UserWarning
|
||||||
+-- FutureWarning
|
+-- FutureWarning
|
||||||
+-- OverflowWarning [not generated by the interpreter]
|
+-- OverflowWarning [not generated by the interpreter]
|
||||||
|
+-- ImportWarning
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,12 @@ if sys.maxint > 0x7fffffff:
|
||||||
warnings.filterwarnings("ignore", "hex/oct constants", FutureWarning,
|
warnings.filterwarnings("ignore", "hex/oct constants", FutureWarning,
|
||||||
"<string>")
|
"<string>")
|
||||||
|
|
||||||
|
# Ignore ImportWarnings that only occur in the source tree,
|
||||||
|
# (because of modules with the same name as source-directories in Modules/)
|
||||||
|
for mod in ("ctypes", "gzip", "test.test_zipimport", "test.test_zlib"):
|
||||||
|
warnings.filterwarnings(module=".*%s$" % (mod,),
|
||||||
|
action="ignore", category=ImportWarning)
|
||||||
|
|
||||||
# MacOSX (a.k.a. Darwin) has a default stack size that is too small
|
# MacOSX (a.k.a. Darwin) has a default stack size that is too small
|
||||||
# for deeply recursive regular expressions. We see this as crashes in
|
# for deeply recursive regular expressions. We see this as crashes in
|
||||||
# the Python test suite when running test_re.py and test_sre.py. The
|
# the Python test suite when running test_re.py and test_sre.py. The
|
||||||
|
|
|
||||||
|
|
@ -205,3 +205,20 @@ def test_import_name_binding():
|
||||||
assert y is test.test_support, y.__name__
|
assert y is test.test_support, y.__name__
|
||||||
|
|
||||||
test_import_name_binding()
|
test_import_name_binding()
|
||||||
|
|
||||||
|
def test_import_initless_directory_warning():
|
||||||
|
import warnings
|
||||||
|
oldfilters = warnings.filters[:]
|
||||||
|
warnings.simplefilter('error', ImportWarning);
|
||||||
|
try:
|
||||||
|
# Just a random non-package directory we always expect to be
|
||||||
|
# somewhere in sys.path...
|
||||||
|
__import__("site-packages")
|
||||||
|
except ImportWarning:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise AssertionError
|
||||||
|
finally:
|
||||||
|
warnings.filters = oldfilters
|
||||||
|
|
||||||
|
test_import_initless_directory_warning()
|
||||||
|
|
|
||||||
|
|
@ -1647,6 +1647,8 @@ PyDoc_STRVAR(FutureWarning__doc__,
|
||||||
"Base class for warnings about constructs that will change semantically "
|
"Base class for warnings about constructs that will change semantically "
|
||||||
"in the future.");
|
"in the future.");
|
||||||
|
|
||||||
|
PyDoc_STRVAR(ImportWarning__doc__,
|
||||||
|
"Base class for warnings about probable mistakes in module imports");
|
||||||
|
|
||||||
|
|
||||||
/* module global functions */
|
/* module global functions */
|
||||||
|
|
@ -1719,6 +1721,7 @@ PyObject *PyExc_SyntaxWarning;
|
||||||
PyObject *PyExc_OverflowWarning;
|
PyObject *PyExc_OverflowWarning;
|
||||||
PyObject *PyExc_RuntimeWarning;
|
PyObject *PyExc_RuntimeWarning;
|
||||||
PyObject *PyExc_FutureWarning;
|
PyObject *PyExc_FutureWarning;
|
||||||
|
PyObject *PyExc_ImportWarning;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1818,6 +1821,8 @@ static struct {
|
||||||
RuntimeWarning__doc__},
|
RuntimeWarning__doc__},
|
||||||
{"FutureWarning", &PyExc_FutureWarning, &PyExc_Warning,
|
{"FutureWarning", &PyExc_FutureWarning, &PyExc_Warning,
|
||||||
FutureWarning__doc__},
|
FutureWarning__doc__},
|
||||||
|
{"ImportWarning", &PyExc_ImportWarning, &PyExc_Warning,
|
||||||
|
ImportWarning__doc__},
|
||||||
/* Sentinel */
|
/* Sentinel */
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1271,20 +1271,43 @@ find_module(char *fullname, char *subname, PyObject *path, char *buf,
|
||||||
#ifdef HAVE_STAT
|
#ifdef HAVE_STAT
|
||||||
if (stat(buf, &statbuf) == 0 && /* it exists */
|
if (stat(buf, &statbuf) == 0 && /* it exists */
|
||||||
S_ISDIR(statbuf.st_mode) && /* it's a directory */
|
S_ISDIR(statbuf.st_mode) && /* it's a directory */
|
||||||
find_init_module(buf) && /* it has __init__.py */
|
case_ok(buf, len, namelen, name)) { /* case matches */
|
||||||
case_ok(buf, len, namelen, name)) { /* and case matches */
|
if (find_init_module(buf)) { /* and has __init__.py */
|
||||||
Py_XDECREF(copy);
|
Py_XDECREF(copy);
|
||||||
return &fd_package;
|
return &fd_package;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
char warnstr[MAXPATHLEN+80];
|
||||||
|
sprintf(warnstr, "Not importing directory "
|
||||||
|
"'%.*s': missing __init__.py",
|
||||||
|
MAXPATHLEN, buf);
|
||||||
|
if (PyErr_Warn(PyExc_ImportWarning,
|
||||||
|
warnstr)) {
|
||||||
|
Py_XDECREF(copy);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
/* XXX How are you going to test for directories? */
|
/* XXX How are you going to test for directories? */
|
||||||
#ifdef RISCOS
|
#ifdef RISCOS
|
||||||
if (isdir(buf) &&
|
if (isdir(buf) &&
|
||||||
find_init_module(buf) &&
|
|
||||||
case_ok(buf, len, namelen, name)) {
|
case_ok(buf, len, namelen, name)) {
|
||||||
|
if (find_init_module(buf)) {
|
||||||
Py_XDECREF(copy);
|
Py_XDECREF(copy);
|
||||||
return &fd_package;
|
return &fd_package;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
char warnstr[MAXPATHLEN+80];
|
||||||
|
sprintf(warnstr, "Not importing directory "
|
||||||
|
"'%.*s': missing __init__.py",
|
||||||
|
MAXPATHLEN, buf);
|
||||||
|
if (PyErr_Warn(PyExc_ImportWarning,
|
||||||
|
warnstr)) {
|
||||||
|
Py_XDECREF(copy);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(PYOS_OS2)
|
#if defined(PYOS_OS2)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue