Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add allow_sets-kwarg to is_list_like #23065

Merged
merged 21 commits into from
Oct 18, 2018

Conversation

h-vetinari
Copy link
Contributor

@h-vetinari h-vetinari commented Oct 9, 2018

This is an attempt responding to #22486 (comment):

@h-vetinari why don't you try (separate PR) excluding set from is_list_like and see what the implications of that are.

Following some initial discussion in #23061, I decided to go with a variant that does not break anything - i.e. adding a keyword which defaults to the current behaviour. I've added a warning that's only raised if necessary, to note that this behaviour will be changed in the future -- regardless of whether it is deprecated or not, I think that users as well as developers should have to actively choose to include unordered sets (reason i.a. for #23009, and probably some more).

The tedious part of this PR was hunting down all the internal uses of is_list_like and adding the kwarg there to avoid raising the warning. Hope I didn't miss any.

# we do not count strings/unicode/bytes as list-like
not isinstance(obj, string_and_binary_types) and
# exclude zero-dimensional numpy arrays, effectively scalars
not (isinstance(obj, np.ndarray) and obj.ndim == 0))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Aside from adding the kwarg everywhere, this is the only substantial change of this PR.

not isinstance(obj, string_and_binary_types) and
# exclude zero-dimensional numpy arrays, effectively scalars
not (isinstance(obj, np.ndarray) and obj.ndim == 0))
if strict is None and isinstance(obj, set):
Copy link
Member

Choose a reason for hiding this comment

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

I think the isinstance checks should be against something like collections.abc.Set to catch more exotic set variations:

In [2]: x = list('aabbc')

In [3]: s1 = set(x)

In [4]: s2 = frozenset(x)

In [5]: isinstance(s2, set)
Out[5]: False

In [6]: isinstance(s2, collections.abc.Set)
Out[6]: True

In [7]: isinstance(s1, collections.abc.Set)
Out[7]: True

def test_is_list_like_strict():
ll = {1, 'a'}
assert inference.is_list_like(ll, strict=False)
assert not inference.is_list_like(ll, strict=True)
Copy link
Member

Choose a reason for hiding this comment

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

test should cover the strict=None case: verify that the warning is raised, and the behavior is consistent with strict=False

Copy link
Member

Choose a reason for hiding this comment

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

also add issue number

@jreback
Copy link
Contributor

jreback commented Oct 9, 2018

as i believe tom commented this is not likely to be worth changing

not (isinstance(obj, np.ndarray) and obj.ndim == 0))
if strict is None and isinstance(obj, set):
# only raise warning if necessary
warnings.warn('is_list_like will in the future return False for sets. '
Copy link
Member

@jschendel jschendel Oct 9, 2018

Choose a reason for hiding this comment

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

Is there a consensus that we want this to be the default future behavior instead of a non-default option? I'm not convinced. Would be interesting to see how many of the existing uses of is_list_like are valid vs. invalid for sets.

Copy link
Contributor

Choose a reason for hiding this comment

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

this whole idea was just that - just an idea
i don’t think we actually want to add a kwarg at all

the idea was to change it within pandas only (if this is useful)
and not actually change the external api at all

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since list is ordered in python, the name is_list_like suggests the same property. If that's not the case it's good ("explicit is better than implicit") to have to specify it.

Don't see why that shouldn't apply to external API as well (with deprecation cycle etc.)

@codecov
Copy link

codecov bot commented Oct 10, 2018

Codecov Report

Merging #23065 into master will decrease coverage by <.01%.
The diff coverage is 75%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #23065      +/-   ##
==========================================
- Coverage   92.19%   92.18%   -0.01%     
==========================================
  Files         169      169              
  Lines       50954    50956       +2     
==========================================
+ Hits        46975    46976       +1     
- Misses       3979     3980       +1
Flag Coverage Δ
#multiple 90.61% <75%> (-0.01%) ⬇️
#single 42.27% <75%> (ø) ⬆️
Impacted Files Coverage Δ
pandas/core/dtypes/common.py 95.11% <ø> (ø) ⬆️
pandas/core/dtypes/inference.py 98.38% <100%> (ø) ⬆️
pandas/compat/__init__.py 58.36% <50%> (-0.07%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1546c35...ab3ce96. Read the comment docs.

@h-vetinari
Copy link
Contributor Author

as i believe tom commented this is not likely to be worth changing

As I believe Tom commented that this is not worth breaking, but this is not a breaking change.

@jorisvandenbossche
Copy link
Member

@h-vetinari it's maybe not breaking, but you still plan to change the default behaviour (the warning).
Why not only adding the keyword with a default for the current behaviour, and then you can specifically use it there where it is needed to exclude sets.
Then the diff here would be much smaller, and then we can limit the discussion to whether it is worth adding the keyword vs explicitly checking for sets in those few cases.

@h-vetinari
Copy link
Contributor Author

@jorisvandenbossche
Obviously one could add it with the current default - that's easily done. But why not discuss as well if fixing an ambiguous bit of API is worth it?

Since list is ordered in python, the name is_list_like suggests the same property. If that's not the case it's good ("explicit is better than implicit") to have to specify it.

@jreback
Copy link
Contributor

jreback commented Oct 10, 2018

@h-vetinari my point in bringing this up would be to see if this is worth it
it is not, given the amount of confusion this would cause
adding a keyword, while solving the backwards compat problem just adds an api that i don’t think we would want at all; no other is_* have any keywords like this (infer_dtype has one but that is a bit different)

this was a good experiment - maybe i wasn’t clear - trying means reporting what happened, then we have a discussion about it

Copy link
Contributor

@jreback jreback left a comment

Choose a reason for hiding this comment

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

comments

@TomAugspurger
Copy link
Contributor

Summarizing how I see things:

  1. is_list_like is a fundamentally fuzzy concept. It can't do the right thing in every case.
  2. The caller knows more about exactly what they need (just iterable?, ordered?, etc.)

So we can either do things like

if is_list_like(x) and not is_unodered(x):
   ...

or do things like

if is_list_like(x, require_ordered=True):
    pass

Between those to, the keyword to is_list_like seems fine.

I don't think changing the default behavior of considering sets as list-like is worth it.

@h-vetinari
Copy link
Contributor Author

@jreback @TomAugspurger

OK, not changing the default. I see two options:

@jreback
Copy link
Contributor

jreback commented Oct 10, 2018

i think is_ordered_list_like is nicer here (but just make it internal for now, don’t add to api.types)

@pep8speaks
Copy link

pep8speaks commented Oct 10, 2018

Hello @h-vetinari! Thanks for updating the PR.

Line 53:10: E241 multiple spaces after ','
Line 53:38: E241 multiple spaces after ','
Line 54:9: E241 multiple spaces after ','
Line 54:38: E241 multiple spaces after ','
Line 55:12: E241 multiple spaces after ','
Line 55:38: E241 multiple spaces after ','
Line 56:14: E241 multiple spaces after ','
Line 56:38: E241 multiple spaces after ','
Line 57:15: E241 multiple spaces after ','
Line 57:38: E241 multiple spaces after ','
Line 58:13: E241 multiple spaces after ','
Line 58:38: E241 multiple spaces after ','
Line 59:15: E241 multiple spaces after ','
Line 60:12: E241 multiple spaces after ','
Line 61:26: E241 multiple spaces after ','
Line 62:20: E241 multiple spaces after ','
Line 63:19: E241 multiple spaces after ','
Line 63:38: E241 multiple spaces after ','
Line 64:15: E241 multiple spaces after ','
Line 64:38: E241 multiple spaces after ','
Line 65:26: E241 multiple spaces after ','
Line 65:38: E241 multiple spaces after ','
Line 66:22: E241 multiple spaces after ','
Line 66:38: E241 multiple spaces after ','
Line 67:18: E241 multiple spaces after ','
Line 67:38: E241 multiple spaces after ','
Line 68:17: E241 multiple spaces after ','
Line 68:38: E241 multiple spaces after ','
Line 69:24: E241 multiple spaces after ','
Line 69:38: E241 multiple spaces after ','
Line 70:38: E241 multiple spaces after ','
Line 71:17: E241 multiple spaces after ','
Line 71:38: E241 multiple spaces after ','
Line 72:16: E241 multiple spaces after ','
Line 72:38: E241 multiple spaces after ','
Line 73:23: E241 multiple spaces after ','
Line 73:38: E241 multiple spaces after ','
Line 74:18: E241 multiple spaces after ','
Line 74:38: E241 multiple spaces after ','
Line 75:27: E241 multiple spaces after ','
Line 75:38: E241 multiple spaces after ','
Line 76:19: E241 multiple spaces after ','
Line 76:38: E241 multiple spaces after ','
Line 77:27: E241 multiple spaces after ','
Line 77:38: E241 multiple spaces after ','
Line 78:21: E241 multiple spaces after ','
Line 78:38: E241 multiple spaces after ','
Line 79:27: E241 multiple spaces after ','
Line 79:38: E241 multiple spaces after ','
Line 80:23: E241 multiple spaces after ','
Line 80:38: E241 multiple spaces after ','
Line 81:27: E241 multiple spaces after ','
Line 81:38: E241 multiple spaces after ','
Line 82:25: E241 multiple spaces after ','
Line 82:38: E241 multiple spaces after ','
Line 83:18: E241 multiple spaces after ','
Line 84:8: E241 multiple spaces after ','
Line 85:13: E241 multiple spaces after ','
Line 86:10: E241 multiple spaces after ','
Line 87:12: E241 multiple spaces after ','
Line 88:9: E241 multiple spaces after ','
Line 89:10: E241 multiple spaces after ','
Line 90:15: E241 multiple spaces after ','
Line 91:13: E241 multiple spaces after ','
Line 92:11: E241 multiple spaces after ','

Comment last updated on October 17, 2018 at 16:18 Hours UTC

@jorisvandenbossche
Copy link
Member

@h-vetinari is there an actual use case of the checking for ordered dict / dict below 3.6 ? Or just to want to be strict in the checking for orderedness?
Because it also seems very strange to me to handle dicts differently depending on the python version within such a function.

@h-vetinari
Copy link
Contributor Author

h-vetinari commented Oct 10, 2018

@jorisvandenbossche

Well, that's what CPython does. I thought I'd be thorough about the orderedness thing, but I don't care about the dicts here so much.

@jorisvandenbossche
Copy link
Member

Then please remove it. If we don't have a use case, there is no point in trying to be strict for the sake of being it, IMO

@jorisvandenbossche
Copy link
Member

Another thing, I am personally not sure we should use the term "unordered", instead of just being explicit that it is about Sets (because you can eg still sort a set, or convert it to an orderable list, etc. And what if there then comes up another unordered data structure?)

In that sense, I would find a is_list_like(..., include_sets=False) clearer and more explicit.

@h-vetinari
Copy link
Contributor Author

@jorisvandenbossche

Alright, removing dict.

Can you agree with @jreback and @TomAugspurger on whether it's

  • is_ordered_list_like
  • with a kwarg:
    • require_ordered
    • include_sets
    • strict
    • ...

I don't care about which way, but prefer shorter to read/type

@TomAugspurger
Copy link
Contributor

Agreed with @jorisvandenbossche that

  • very specific keyword (so not something like "strict", rather something like "allow_sets").
  • maybe the status quo and doing an explicit isinstance check in those occasions, is also a perfect option

I don't have a preference between adding a kwarg to is_list_like vs. doing those checks independently.

@h-vetinari
Copy link
Contributor Author

@jreback:
could you live with is_list_like(obj, allow_sets=True)? @jorisvandenbossche @TomAugspurger (and myself) would prefer this over is_ordered_list_like.

Adding isinstance(x, set) also would work (though, as @jschendel notes, wouldn't catch frozenset etc.), but is IMO the least preferable solution out of the three, not least re:explicitness (see my comment). The current state of #22486 and #23187 follows this last example, so can check it out there "in real life".

@jreback
Copy link
Contributor

jreback commented Oct 16, 2018

i think allow_sets as a kwarg is ok (default is True)

@h-vetinari
Copy link
Contributor Author

Thanks for the responses / inputs everyone. Changed back to kwarg, renamed it to allow_sets.

@h-vetinari h-vetinari changed the title Add strict-kwarg to is_list_like Add allow_sets-kwarg to is_list_like Oct 16, 2018
is_bool, is_integer, is_float, is_number, is_decimal, is_complex,
is_re, is_re_compilable, is_dict_like, is_string_like, is_file_like,
is_list_like, is_nested_list_like, is_sequence, is_named_tuple,
is_hashable, is_iterator, is_array_like, is_scalar, is_interval)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is somewhat of an artefact of the version with is_ordered_list_like, where I tried to group these methods by similarity (i.e. scalar dtypes, regexes, containers), but I decided to keep it because I think it helps. Can revert that part of course

Copy link
Contributor

Choose a reason for hiding this comment

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

yes, on any change, pls try to do the minimal changeset. This will lessen reviewer burden and make things go faster.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

"yes, please try to do minimal changeset [next time]" or "yes please revert"?

Copy link
Contributor

Choose a reason for hiding this comment

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

Fine as is for now.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok for now, but generally pls don't change unrelated things.

Copy link
Contributor

@jreback jreback left a comment

Choose a reason for hiding this comment

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

needs a whatsnew note

is_bool, is_integer, is_float, is_number, is_decimal, is_complex,
is_re, is_re_compilable, is_dict_like, is_string_like, is_file_like,
is_list_like, is_nested_list_like, is_sequence, is_named_tuple,
is_hashable, is_iterator, is_array_like, is_scalar, is_interval)
Copy link
Contributor

Choose a reason for hiding this comment

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

yes, on any change, pls try to do the minimal changeset. This will lessen reviewer burden and make things go faster.

@@ -259,6 +259,8 @@ def is_list_like(obj):
Parameters
----------
obj : The object to check.
allow_sets : boolean, default True
If this parameter is False, sets will not be considered list-like

Copy link
Contributor

Choose a reason for hiding this comment

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

add a versionadded tag

# exclude zero-dimensional numpy arrays, effectively scalars
not (isinstance(obj, np.ndarray) and obj.ndim == 0))
and not (isinstance(obj, np.ndarray) and obj.ndim == 0)
# exclude sets if allow_sets is False
Copy link
Contributor

Choose a reason for hiding this comment

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

blank line before comments

Copy link
Contributor

Choose a reason for hiding this comment

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

style nit: I don't like the blank lines inside an if condition.

But nothing that needs to be changed now.

def test_is_list_like_fails(ll):
assert not inference.is_list_like(ll)


@pytest.mark.parametrize(
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer to have 2 tests total to avoid the duplication of the args here (IOW 1 for allow_sets=True and 1 for False).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not sure if my solution is what you had in mind, but I gave it a shot

Copy link
Contributor

Choose a reason for hiding this comment

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

I didn't see the earlier version, but I don't think this is what Jeff had in mind. If we want to de-duplicate the arguments, you would need a fixture giving them

@pytest.fixture(params=...)
def maybe_list_like(request):
    return request.param

Each of the params would be a tuple like ([], True), ('2', False), and I guess something like ({}, None) or ({}, 'maybe'}) for set-likes.

Then we would have two tests. In the first we do

obj, expected = ...
if expected:
    expected = True

assert is_list_like(obj) is expected

and in the second

if expected is None:
    expected = False

assert is_list_like(obj, include_sets=False) is expected

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah @TomAugspurger suggestion is good here. The issues is we can't list the args twice.

Copy link
Contributor Author

@h-vetinari h-vetinari left a comment

Choose a reason for hiding this comment

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

Thanks for the review

is_bool, is_integer, is_float, is_number, is_decimal, is_complex,
is_re, is_re_compilable, is_dict_like, is_string_like, is_file_like,
is_list_like, is_nested_list_like, is_sequence, is_named_tuple,
is_hashable, is_iterator, is_array_like, is_scalar, is_interval)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

"yes, please try to do minimal changeset [next time]" or "yes please revert"?

def test_is_list_like_fails(ll):
assert not inference.is_list_like(ll)


@pytest.mark.parametrize(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

not sure if my solution is what you had in mind, but I gave it a shot

Copy link
Contributor

@TomAugspurger TomAugspurger left a comment

Choose a reason for hiding this comment

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

+1 overall, one comment on the test.

is_bool, is_integer, is_float, is_number, is_decimal, is_complex,
is_re, is_re_compilable, is_dict_like, is_string_like, is_file_like,
is_list_like, is_nested_list_like, is_sequence, is_named_tuple,
is_hashable, is_iterator, is_array_like, is_scalar, is_interval)
Copy link
Contributor

Choose a reason for hiding this comment

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

Fine as is for now.

# exclude zero-dimensional numpy arrays, effectively scalars
not (isinstance(obj, np.ndarray) and obj.ndim == 0))
and not (isinstance(obj, np.ndarray) and obj.ndim == 0)
# exclude sets if allow_sets is False
Copy link
Contributor

Choose a reason for hiding this comment

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

style nit: I don't like the blank lines inside an if condition.

But nothing that needs to be changed now.

def test_is_list_like_fails(ll):
assert not inference.is_list_like(ll)


@pytest.mark.parametrize(
Copy link
Contributor

Choose a reason for hiding this comment

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

I didn't see the earlier version, but I don't think this is what Jeff had in mind. If we want to de-duplicate the arguments, you would need a fixture giving them

@pytest.fixture(params=...)
def maybe_list_like(request):
    return request.param

Each of the params would be a tuple like ([], True), ('2', False), and I guess something like ({}, None) or ({}, 'maybe'}) for set-likes.

Then we would have two tests. In the first we do

obj, expected = ...
if expected:
    expected = True

assert is_list_like(obj) is expected

and in the second

if expected is None:
    expected = False

assert is_list_like(obj, include_sets=False) is expected

is_bool, is_integer, is_float, is_number, is_decimal, is_complex,
is_re, is_re_compilable, is_dict_like, is_string_like, is_file_like,
is_list_like, is_nested_list_like, is_sequence, is_named_tuple,
is_hashable, is_iterator, is_array_like, is_scalar, is_interval)
Copy link
Contributor

Choose a reason for hiding this comment

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

ok for now, but generally pls don't change unrelated things.

def test_is_list_like_fails(ll):
assert not inference.is_list_like(ll)


@pytest.mark.parametrize(
Copy link
Contributor

Choose a reason for hiding this comment

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

yeah @TomAugspurger suggestion is good here. The issues is we can't list the args twice.

@h-vetinari
Copy link
Contributor Author

OK, hoping this last commit is more what you guys were after.

I decided to add the ids to have nice output (in error logs, resp. with - v):


pandas/tests/dtypes/test_inference.py::test_is_list_like[list] PASSED    [  0%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[list-empty] PASSED [  0%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[tuple] PASSED   [  1%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[tuple-empty] PASSED [  1%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[dict] PASSED    [  1%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[dict-empty] PASSED [  2%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[set] PASSED     [  2%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[set-empty] PASSED [  2%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[frozenset] PASSED [  3%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[frozenset-empty] PASSED [  3%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[iterator] PASSED [  3%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[iterator-empty] PASSED [  4%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[generator] PASSED [  4%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[generator-empty] PASSED [  4%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[Series] PASSED  [  5%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[Series-empty] PASSED [  5%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[StringMethods] PASSED [  5%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[StringMethods-empty] PASSED [  6%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[Index] PASSED   [  6%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[Index-empty] PASSED [  6%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[DataFrame] PASSED [  7%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[DataFrame-empty] PASSED [  7%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[ndarray-1d] PASSED [  8%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[ndarray-1d-empty] PASSED [  8%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[ndarray-2d] PASSED [  8%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[ndarray-2d-empty] PASSED [  9%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[ndarray-3d] PASSED [  9%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[ndarray-3d-empty] PASSED [  9%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[ndarray-4d] PASSED [ 10%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[ndarray-4d-empty] PASSED [ 10%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[ndarray-0d] PASSED [ 10%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[int] PASSED     [ 11%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[bytes] PASSED   [ 11%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[bytes-empty] PASSED [ 11%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[string] PASSED  [ 12%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[string-empty] PASSED [ 12%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[string-type] PASSED [ 12%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[object] PASSED  [ 13%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[NaN] PASSED     [ 13%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[None] PASSED    [ 13%]
[...]

instead of

pandas/tests/dtypes/test_inference.py::test_is_list_like[maybe_list_like0] PASSED [  0%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[maybe_list_like1] PASSED [  0%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[maybe_list_like2] PASSED [  1%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[maybe_list_like3] PASSED [  1%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[maybe_list_like4] PASSED [  1%]
pandas/tests/dtypes/test_inference.py::test_is_list_like[maybe_list_like5] PASSED [  2%]
[etc...]

Of course it would be possible to have separate lists for the list-likes, the expected value, and the ids, but then its really instable that all three need to be edited simultaneously in case there's any change. That's why I opted for defining everything as tuples, and then doing some zip-ping

@jreback jreback added this to the 0.24.0 milestone Oct 18, 2018
@jreback jreback merged commit 339156e into pandas-dev:master Oct 18, 2018
@jreback
Copy link
Contributor

jreback commented Oct 18, 2018

thanks @h-vetinari

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

Successfully merging this pull request may close these issues.

6 participants