Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Lib/test/test_imp.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ def requires_load_dynamic(meth):
meth = support.cpython_only(meth)
return unittest.skipIf(not hasattr(imp, 'load_dynamic'),
'imp.load_dynamic() required')(meth)
def requires_create_dynamic(meth):
Copy link
Contributor

Choose a reason for hiding this comment

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

Readability improvement: blank line before the function

"""Decorator to skip a test if not running under CPython or lacking
imp.create_dynamic()."""
Copy link
Member

Choose a reason for hiding this comment

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

Let me be clear that my recommendation here is not critical. Rather it is a reflection of my belief that little suboptimal things add up over time to become pain points. Docstrings (including in test code) are one of those things we cut corners on sometimes.

While there is precedent (unfortunately) for docstrings formatted this way, I'd rather this docstring were a bit more idiomatic. It's better to take a little time now to strengthen a healthier precedent. This is a case where a little bit of extra time spent adds up over time to make a positive difference. I don't mean to be pedantic here about a relatively insignificant style point or to waste anyone's time, but instead want to encourage a more thoughtful approach with regard to the little things. :) With that out of the way...

I'd expect a docstring here like one of the following (and including some shortening):

# one line """Decorator to skip a test if not running under CPython or lacking imp.create_dynamic().""" 

or

# one line with separate quotation mark lines """ Decorator to skip a test if not running under CPython or lacking imp.create_dynamic(). """ 

or

# split into multiple lines (my preference) """A decorator to skip tests that rely on imp.create_dynamic(). Not all Python implementations necessarily provide imp.create_dynamic(). This decorators causes decorated tests to be skipped through the normal unittest mechanism. """ 
meth = support.cpython_only(meth)
return unittest.skipIf(not hasattr(imp, 'create_dynamic'),
'imp.create_dynamic() required')(meth)
Copy link
Member

Choose a reason for hiding this comment

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

FWIW, as a reader it's easy to miss something when more than one thing is happening on a line. It might be more clear to break this up:

deco = unittest.skipIf(not hasattr(imp, 'create_dynamic'), 'imp.create_dynamic() required') return deco(meth) 

or even

supported = hasattr(imp, 'create_dynamic') deco = unittest.skipIf(not supported, 'imp.create_dynamic() required') return deco(meth) 


@unittest.skipIf(_thread is None, '_thread module is required')
Expand Down Expand Up @@ -318,6 +324,16 @@ def test_load_source(self):
with self.assertRaisesRegex(ValueError, 'embedded null'):
imp.load_source(__name__, __file__ + "\0")

@requires_create_dynamic
def test_issue31315(self):
# There shouldn't be an assertion failure in imp.create_dynamic(),
# when spec.name is not a string.
class BadSpec:
name = 42
Copy link
Member

Choose a reason for hiding this comment

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

Use something more realistic. A bytes object or None.

origin = 'foo'
Copy link
Member

Choose a reason for hiding this comment

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

If origin is not a string SystemError can be raised. This should be fixed too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

what code causes a SystemError?
I got a TypeError: bad argument type for built-in operation both on my Windows and Ubuntu.

Copy link
Member

Choose a reason for hiding this comment

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

Your are right. I thought _PyUnicode_AsUnicode() raises SystemError, but it raises TypeError. No additional check is needed.

with self.assertRaises(TypeError):
imp.create_dynamic(BadSpec())


class ReloadTests(unittest.TestCase):

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix an assertion failure in imp.create_dynamic(), when spec.name is not a
string. Patch by Oren Milman.
5 changes: 5 additions & 0 deletions Python/importdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
if (name_unicode == NULL) {
return NULL;
}
if (!PyUnicode_Check(name_unicode)) {
PyErr_SetString(PyExc_TypeError,
"spec.name must be a string");
goto error;
}

name = get_encoded_name(name_unicode, &hook_prefix);
if (name == NULL) {
Expand Down