[Python-ideas] Prevent importing yourself?
Terry Reedy
tjreedy at udel.edu
Wed Feb 3 16:16:48 EST 2016
On 1/30/2016 1:58 AM, Sjoerd Job Postmus wrote:
> Yes, indeed. That's what I was thinking of. I decided to write up a quick hack that added the filename to the exception string.
>
> sjoerdjob$ ../python mod_a.py
> Traceback (most recent call last):
> File "mod_a.py", line 4, in <module>
> print(parse(JSON_DATA))
> File "/home/sjoerdjob/dev/cpython/tmp/mod_b.py", line 4, in parse
> return json.loads(blob)
> AttributeError: module 'json' (loaded from /home/sjoerdjob/dev/cpython/tmp/json.py) has no attribute 'loads'
Would it help is we added an AttributeError subclass,
ModuleAttributeError and raise that instead module_getattro?
> Here's the patch, in case anyone is interested.
>
> diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
> index 24c5f4c..5cc144a 100644
> --- a/Objects/moduleobject.c
> +++ b/Objects/moduleobject.c
> @@ -654,17 +654,25 @@ module_repr(PyModuleObject *m)
> static PyObject*
> module_getattro(PyModuleObject *m, PyObject *name)
> {
> - PyObject *attr, *mod_name;
> + PyObject *attr, *mod_name, *mod_file;
> attr = PyObject_GenericGetAttr((PyObject *)m, name);
> if (attr || !PyErr_ExceptionMatches(PyExc_AttributeError))
> return attr;
> PyErr_Clear();
> if (m->md_dict) {
> _Py_IDENTIFIER(__name__);
> mod_name = _PyDict_GetItemId(m->md_dict, &PyId___name__);
> if (mod_name) {
> - PyErr_Format(PyExc_AttributeError,
> + _Py_IDENTIFIER(__file__);
> + mod_file = _PyDict_GetItemId(m->md_dict, &PyId___file__);
> + if (mod_file && PyUnicode_Check(mod_file)) {
> + PyErr_Format(PyExc_AttributeError,
> + "module '%U' (loaded from %U) has no attribute '%U'", mod_name, mod_file, name);
> + } else {
> + PyErr_Format(PyExc_AttributeError,
> "module '%U' has no attribute '%U'", mod_name, name);
> + }
> return NULL;
> }
> else if (PyErr_Occurred()) {
>
> Unfortunately, I do think this might impose **some** performance issue, but on
> the other hand, I'd be inclined to think that attribute-errors on module
> objects are not that likely to begin with, except for typos and issues
> like these. (And of course the case that you have to support older
> versions of Python with a slower implementation, but you most often see
> those checks being done at the module-level, so it would only impact
> load-time and not running-time.)
>
> The added benefit would be quicker debugging when finally having posted
> to a forum: "Ah, I see from the message that the path of the module is
> not likely a standard-library path. Maybe you have a name collision?
> Check for files or directories named '<module name here>(.py)' in your
> working directory / project / ... .
>
>>
>>> (Of course, another option would be to look for other modules of the
>>> same name when you get an attribute-error on a module to aid debugging,
>>> but I think that's too heavy-weight.)
>>
>> If that could be done only when the exception escapes to top level and dumps s traceback, that might be reasonable. And it would _definitely_ be helpful. But I don't think it's possible without major changes.
>
> No, indeed, that was also my expectation: helpful, but too big a hassle
> to be worth it.
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
--
Terry Jan Reedy
More information about the Python-ideas
mailing list