Skip to content

bpo-24744: Raises error in pkgutil.walk_packages if path is str#1926

Merged
bitdancer merged 13 commits intopython:masterfrom
CuriousLearner:fix-Issue24744
Jun 13, 2017
Merged

bpo-24744: Raises error in pkgutil.walk_packages if path is str#1926
bitdancer merged 13 commits intopython:masterfrom
CuriousLearner:fix-Issue24744

Conversation

@CuriousLearner
Copy link
Copy Markdown
Member

Attempts to resolve: http://bugs.python.org/issue24744

In the Bug @bitdancer suggested that some sort of error should be raised if path is of type str in pkgutil.walk_packages function.

@bitdancer For the meanwhile I've raised TypeError since that was looking most appropriate to me. Please let me know what kind of error is expected to be raised here and I'll update the PR.

Thanks!

@mention-bot
Copy link
Copy Markdown

@CuriousLearner, thanks for your PR! By analyzing the history of the files in this pull request, we identified @Yhg1s, @ericsnowcurrently and @brettcannon to be potential reviewers.

@bitdancer
Copy link
Copy Markdown
Member

I think ValueError would be better, but it doesn't matter all that much (the two have a very blurry line between them in Python).

A test is needed as well. And we should also add a test that a bytes object also produces some sort of error (we don't care what sort).

@CuriousLearner
Copy link
Copy Markdown
Member Author

@bitdancer what would be the most appropriate place to put the test at?

I can see that there is a test written for pkgutil.walk_packages in Lib/test/test_runner.py by @ncoghlan . Would that file be a good place to add this test?

@bitdancer
Copy link
Copy Markdown
Member

I haven't reviewed the reason for the 'hack' of putting the walk_packages test in test_runner, but since this is only checking the raising of an error on bad input, I'm guessing you can put it in test_pkgutil. Try it :) The long term goal is to move the tests from test_runner to test_pkgutil, so any new tests that can go in test_pkgutil should go there.

@CuriousLearner
Copy link
Copy Markdown
Member Author

Hi @bitdancer, I've updated the branch with changes and also added a test.

However, I'm not sure why the PR is not reflecting it, although it's from the same branch (https://github.com/CuriousLearner/cpython/tree/fix-issue24744) I'm doing the changes in. This seems weird to me.

@CuriousLearner
Copy link
Copy Markdown
Member Author

Never mind, I figured that out, it was a minor naming issue with the branch. The patch would be now updated here.

Please have a look @bitdancer . Let me know if this needs changes.

Thanks!

@ncoghlan
Copy link
Copy Markdown
Contributor

ncoghlan commented Jun 4, 2017

@bitdancer Some of the tests currently in test_runpy are there not because that's the right place for them, but because they re-use some of the testing machinery that's currently in that file. There are a couple of old issues about moving those helpers out into the test.support subpackage, allowing the affected test cases to be moved to test_pkgutil where they belong:

Comment thread Lib/test/test_pkgutil.py Outdated
with self.assertRaises(ValueError) as context:
list(pkgutil.walk_packages(str_input))

self.assertTrue('path must be None or list of paths' in str(context.exception))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think this assertion is needed. All we care about here is that the ValueError gets raised, we really don't care what the error message is. (This is not always true, but in this case I think it is.)

In fact, in this particular case we don't even care whether we get a ValueError or a TypeError, so I'd make the test accept both as passing. That way we're doing the same check for both str and bytes: all we are trying to prove with these tests is that we get an error rather than an empty list.

Comment thread Lib/pkgutil.py Outdated
"""
if path is None:
importers = iter_importers()
elif isinstance(path, str) or isinstance(path, bytes):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

isinstance(path, bytes) is problematic. I was hoping that walk_packages would throw some other error for bytes input (perhaps a TypeError on some string operation), because checking for all the bytes types is a bit of a pain. And testing it, this is in fact true. So the bytes check isn't needed, just the str check. (Yes, the error is a bit mysterious, but if we want to address that, it requires more of a design discussion, and we shouldn't deal with that in this particular issue).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Hi @bitdancer , what is meant by:

checking for all the bytes types

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

bytes, bytearray, array('b') (or whatever the right incantation is), memoryview....

Comment thread Lib/pkgutil.py Outdated
"""
if path is None:
importers = iter_importers()
elif isinstance(path, str) or isinstance(path, bytes):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

bytes, bytearray, array('b') (or whatever the right incantation is), memoryview....

Comment thread Lib/test/test_pkgutil.py Outdated

bytes_input = b'test_dir'
with self.assertRaises(ValueError) as context:
with self.assertRaises(TypeError):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would like both of these to be assertRaises((TypeError, ValueError)).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@bitdancer Fixed. Does this looks good now?

@bitdancer
Copy link
Copy Markdown
Member

It would be better if the two tuples were in the same order, but I wouldn't have bothered you with that except that I'd like to request that you delete the test method docstring. We don't in general use docstrings for test methods in the cpython test suite. If there is important information not included in the test name, you can use a comment. But I'd just rename the test "test_walk_packages_raises_on_string_or_bytes_input".

@CuriousLearner
Copy link
Copy Markdown
Member Author

Sure @bitdancer , I've done the changes :)

Copy link
Copy Markdown
Member

@bitdancer bitdancer left a comment

Choose a reason for hiding this comment

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

I don't see the NEWS entry, I suspect you forgot to 'git add' it.

Comment thread Doc/whatsnew/3.7.rst
* :meth:`pkgutil.walk_packages` now raises ValueError/TypeError if path is
string/bytes object.
Previously an empty list was returned. (Contributed by Sanyam Khurana in
:issue:`24744`.)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please reflow this into a single paragraph. And it should only mention str; it has always raised a TypeError for bytes.

Comment thread Doc/whatsnew/3.7.rst Outdated
:issue:`24744`.)
* :meth:`pkgutil.walk_packages` now raises ValueError if path is a string
object. Previously an empty list was returned. (Contributed by Sanyam
Khurana in :issue:`24744`.)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

'object' is redundant here. Also, mark up "path" as an argument by surrounding it with asterisks.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

FIxed.

Comment thread Misc/NEWS Outdated
-------

- bpo-24744: pkgutil.walk_packages function raises ValueError if path is of
str object type. Patch by Sanyam Khurana.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

... function now raises a ValueError if *path* is a string ...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed.

@bitdancer bitdancer merged commit b9c3da5 into python:master Jun 13, 2017
@CuriousLearner
Copy link
Copy Markdown
Member Author

Thanks @bitdancer :)

@vedgar
Copy link
Copy Markdown
Contributor

vedgar commented Jan 31, 2018

That the line is blurry doesn't mean it should be blurried further in the cases where it's obvious what should be raised.

'path should be either *None* or a *list* of paths to look for modules in.'
>>> ValueError.__doc__
'Inappropriate argument value (of correct type).'
>>> TypeError.__doc__
'Inappropriate argument type.'

May I ask what's the rationale for ValueError?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants