-
-
Notifications
You must be signed in to change notification settings - Fork 18k
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
TST: Parametrize simple yield tests #15406
Conversation
@@ -31,24 +31,18 @@ def setup(self): | |||
'pandas/io/tests/parser/data/salaries.csv') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test might be broken; I don't see this file, with or without the compressed extension.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i fixed this in master - make sure to rebase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually u r right
let me push a fix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#15407 pushing shortly
@@ -11,8 +11,6 @@ | |||
from pandas.computation.engines import _engines | |||
import pandas.computation.expr as expr | |||
|
|||
ENGINES_PARSERS = list(product(_engines, expr._parsers)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be cleaner to make this a fixture
then parameterize
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's only one parametrized function in this file, so maybe it's not so useful here.
@@ -774,16 +774,19 @@ def check_chained_cmp_op(self, lhs, cmp1, mid, cmp2, rhs): | |||
f = lambda *args, **kwargs: np.random.randn() | |||
|
|||
|
|||
ENGINES_PARSERS = list(product(_engines, expr._parsers)) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be useful here though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made the change, but I'll wait until the network test is corrected before updating.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@QuLogic thanks.
just testing my fix out now
@QuLogic thanks for starting on this! If it helps, you can (temporarily) remove the line
in |
Thanks @TomAugspurger; somehow I'm still getting warnings anyway (in most cases). |
|
||
def check_binop_typecasting(self, engine, parser, op, dt): | ||
@pytest.mark.parametrize('engine', _engines) | ||
@pytest.mark.parametrize('parser', expr._parsers) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of repeating @pytest.mark.parametrize('parser', expr._parsers)
, you could have a single fixture in the module, and pytest will push those through to each testing function:
@pytest.fixture(params=_engines)
def engine(request):
return request.param
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes; see above comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup - to be clear - with this you could remove every line that's @pytest.mark.parametrize('parser', expr._parsers)
in this file - I think about 25 lines
@QuLogic ok merged. give your changes a rebase and try. |
@pytest.mark.parametrize('mode', ['explicit', 'infer']) | ||
@pytest.mark.parametrize('engine', ['python', 'c']) | ||
def test_compressed_urls(self, compression, extension, mode, engine): | ||
if extension == '.xz': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh you changed this too. fine with your changes as well (of course the tm.network issue still there though).
47756be
to
a1ad150
Compare
@QuLogic I think you have a linting error and
|
FYI the warnings are now showing on windows (had to fix the build for other reasons): https://ci.appveyor.com/project/jreback/pandas/build/1.0.3009/job/4xo1hvnr0kb2jjo6 so in next PR should fix these :< |
Oops, I guess The xdist thing is a bug in pytest-xdist pytest-dev/pytest#920; we have this workaround. |
@QuLogic ahh if you want to add that work-around for xdist to |
yeah the flake checker on travis picks up these types of things but for some reason it doesn't locally. not sure why. |
reason='numexpr enabled->{enabled}, ' | ||
'installed->{installed}'.format( | ||
enabled=_USE_NUMEXPR, | ||
installed=_NUMEXPR_INSTALLED))(engine) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cosmetic + not worth changing, but for future pytesters - this sort of thing can go in the function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MaximilianR can you show an example of what you mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pytest.fixture(params=_engines)
def engine(request):
if engine == 'numexpr' and not _USE_NUMEXPR:
pytest.skip(reason='numexpr enabled->{enabled}, '
'installed->{installed}'.format(
enabled=_USE_NUMEXPR,
installed=_NUMEXPR_INSTALLED))(engine)
return request.param
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure that's reasonable.
I have always tried to see if there is a way to make a parameterized yielder
def create_things():
return list(range(5))
@pytest.mark.parametrize('t', create_things())
def test_thing(t):
...
where I really want to do:
@pytest.fixture
def things(request):
for in i range(5):
yield i
@pytest.mark.parametrize('t', things):
def test_thing(t):
....
note that this is NOT a yield fixture, but something that I need a function to generate the 'things' that I want to parametrize (rather than a simple list of strings).
I think pytest_generate_tests
hook would do it, but seems overly complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I very much agree - I've had the same inclination for a while now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you could have:
def things():
for in i range(5):
yield i
@pytest.mark.parametrize('t', things())
def test_thing(t):
....
but then it's not a fixture, which defeats it a bit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally I'd want:
@pytest.fixture
def things():
for in i range(5):
yield i
def test_thing(things):
....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MaximilianR There is a slight difference in your method; the one I have will mark the skip at collection time, while yours requires running the fixture to find out about the skip. It's a rather minor difference though.
Also, @jreback your first code block works fine. In fact, pytest
will understand the generator, so you don't need the list
:
def create_things():
return range(5)
@pytest.mark.parametrize('t', create_things())
def test_thing(t):
...
works fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @QuLogic just tried it out ....looks much nicer!
try: | ||
return compat.import_lzma() | ||
except ImportError: | ||
import pytest | ||
pytest.skip('need backports.lzma to run') | ||
return False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above re cosmetic
But pytest has its own importorskip
which can do these
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes these should be changed to use pexpect = pytest.importorskip('pexpect')
should be simpler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't use it here because there's a 2 vs 3 import in compat
, though I guess it could be in an if PY3
instead of try
/except
like it is now.
Simple meaning those that loop through a constant and are not in a unittest class.
a1ad150
to
8368772
Compare
@QuLogic this looks good. windows completed, so ping on green on travis. |
https://travis-ci.org/pandas-dev/pandas/jobs/202066838 hmm, can you add in the PYTHONHASHSEED setting? (ci/scripts_multiple.py) |
d1e5bcd
to
b002752
Compare
Codecov Report
@@ Coverage Diff @@
## master #15406 +/- ##
==========================================
+ Coverage 90.36% 90.37% +<.01%
==========================================
Files 135 135
Lines 49438 49440 +2
==========================================
+ Hits 44675 44680 +5
+ Misses 4763 4760 -3
Continue to review full report at Codecov.
|
thanks @QuLogic nice fixes! keep em coming! |
Do you squash locally or something? Seems odd PR is closed instead of merged... |
no this is merged ! you don't need to squash generally as it's done in merge |
@QuLogic looks like: frame/test_query_eval.py is not giving any yield errors AFAICT |
It does use |
@QuLogic ahh ok. yeah the need for subclassing |
xref pandas-dev#15341 Author: Elliott Sales de Andrade <[email protected]> Closes pandas-dev#15406 from QuLogic/pytest-simple-yield and squashes the following commits: b002752 [Elliott Sales de Andrade] TST: Set PYTHONHASHSEED so xdist doesn't break. 8368772 [Elliott Sales de Andrade] TST: Use fixtures for engine/parser where possible. c6cd346 [Elliott Sales de Andrade] TST: Parametrize remaining simple yield tests. 47bf1a1 [Elliott Sales de Andrade] TST: Replace ENGINES_PARSERS by parametrize.
Simple
yield
tests are those that dofor x in y: yield test, x
wherey
is some constant list/tuple. It also requires the tests to be in a simple class that doesn't subclassunittest
's classes (because parametrization doesn't work there).There are still
yield
tests inbut I haven't changed them since they don't conform to the requirements above.
This is also not an attempt to parametrize any and all test loops.
git diff upstream/master | flake8 --diff