Re: [py-dev] funcarg name clash / conftest load behaviour
Hi Frank, On Fri, Jun 25, 2010 at 10:18 +0200, Frank Hempel wrote:
Hi Holger,
thank you for the immediate reply.
Am 24.06.2010 16:40, schrieb holger krekel:
Are you using the latest 1.3.1 version? It is meant to call the funcarg
Shame on me. I used 1.0.2. Indeed with 1.3.1 the nearest funcarg factories are called. Perfect.
good.
There is just one little thing left where i'm not sure what the benefit is in it. Consider the dir structure as meant in the last mails:
a/conftest.py b/conftest.py
If py.test is started from within the "a"-directory not only the conftest.py's of parent directories of "a" are loaded (as stated in the docs), also the conftest.py of the "b"-directory is loaded. I intuitively wouldn't consider "b" a parent of "a". Also the tests from "b" are not run of course. Does it makes sense to load "b"'s conftest.py too in this situation?
I agree it's a bit suprising. I'll explain why also to clarify it for myself :) * py.test sees the command line arg b/test_hello.py * it performs collection starting from the directory where 'b' is contained, call it ROOTDIR * collecting ROOTDIR will collect all matching subdirs and files, so 'a' and 'b' * [HERE] collecting the 'b' subdir will consult b/conftest.py to allow it to influence the directory collection objects (it will call the pytest_collect_directory(...) hook to be precise) * after all subdirs/files have been collected the one matching the name 'b' is dived into * ... I think [HERE] is the issue: we could say that a conftest.py cannot determine the directory collection object of its containing directory (only of the subdirs) so for collecting 'b' the conftest.py would not need to be loaded. It's an edge case and so far i have been wary to change it for backward-compat reasons. However, i'd like to try to get rid of the py.test.collect.Directory subclass customization possibility alltogether and rather provide a simple hook which directly implements directory collection, it would simplify internal code and as a side effect remove the surprise you encountered. (because no attempt to collect anything under 'b' would be made and thus no a/conftest.py consulted when calling py.test on 'a') best, holger
On Fri, Jun 25, 2010 at 10:55 +0200, holger krekel wrote:
However, i'd like to try to get rid of the py.test.collect.Directory subclass customization possibility alltogether and rather provide a simple hook which directly implements directory collection, it would simplify internal code and as a side effect remove the surprise you encountered. (because no attempt to collect anything under 'b' would be made and thus no a/conftest.py consulted when calling py.test on 'a')
um, ... fixed: because no attempt to collect anything under 'b' would be made and thus no b/conftest.py consulted when calling py.test on 'a' all those little a's and b's :) holger
Am 25.06.2010 10:55, schrieb holger krekel:
There is just one little thing left where i'm not sure what the benefit is in it. Consider the dir structure as meant in the last mails:
a/conftest.py b/conftest.py
If py.test is started from within the "a"-directory not only the conftest.py's of parent directories of "a" are loaded (as stated in the docs), also the conftest.py of the "b"-directory is loaded. I intuitively wouldn't consider "b" a parent of "a". Also the tests from "b" are not run of course. Does it makes sense to load "b"'s conftest.py too in this situation?
I agree it's a bit suprising. I'll explain why also to clarify it for myself :)
* py.test sees the command line arg b/test_hello.py * it performs collection starting from the directory where 'b' is contained, call it ROOTDIR * collecting ROOTDIR will collect all matching subdirs and files, so 'a' and 'b' * [HERE] collecting the 'b' subdir will consult b/conftest.py to allow it to influence the directory collection objects (it will call the pytest_collect_directory(...) hook to be precise) * after all subdirs/files have been collected the one matching the name 'b' is dived into * ...
This process I was expecting when calling "py.test" (without arguments or with 'b/test_hello.py') from the ROOTDIR, as i think in your explaination you meant having py.test being called from ROOTDIR because the argument 'b/test_hello.py' you mentioned has 'b/' in it, right?. When calling py.test (without arguments or 'test_hello.py') from within the 'b'-directory i would expect that the collecting will only be done for that 'b'-directory and its child directories. To make sure we are talking about the same a's and b's ;) the dir structure is: ~/ROOTDIR/ a/ conftest.py test_hello.py b/ contest.py test_hello.py on the cmd line i do: ~$ cd ROOTDIR/b ~/ROOTDIR/b$ py.test ================ test session starts ================ platform linux2 -- Python 2.5.5 -- pytest-1.3.1 test object 1: ~/ROOTDIR/b test_hello.py . ============= 1 passed in 0.01 seconds ============== if both conftest.py's have a pytest_configure and pytest_unconfigure, they will be called in this order: configure of b configure of a unconfigure of a unconfigure of b I agree that both 'a' and 'b' should be inspected when calling py.test from ROOTDIR, but when calling it within 'a' or 'b'...? ...i hope i don't bother you if i misunderstood your explaination (sorry in that case). but that you wrote "* py.test sees the command line arg b/test_hello.py" made me wonder whether you misunderstood me in the way that you thought i meant calling py.test from ROOTDIR. Thank you, Best regards, Frank
On Fri, Jun 25, 2010 at 11:44 +0200, Frank Hempel wrote:
Am 25.06.2010 10:55, schrieb holger krekel:
There is just one little thing left where i'm not sure what the benefit is in it. Consider the dir structure as meant in the last mails:
a/conftest.py b/conftest.py
If py.test is started from within the "a"-directory not only the conftest.py's of parent directories of "a" are loaded (as stated in the docs), also the conftest.py of the "b"-directory is loaded. I intuitively wouldn't consider "b" a parent of "a". Also the tests from "b" are not run of course. Does it makes sense to load "b"'s conftest.py too in this situation?
I agree it's a bit suprising. I'll explain why also to clarify it for myself :)
* py.test sees the command line arg b/test_hello.py * it performs collection starting from the directory where 'b' is contained, call it ROOTDIR * collecting ROOTDIR will collect all matching subdirs and files, so 'a' and 'b' * [HERE] collecting the 'b' subdir will consult b/conftest.py to allow it to influence the directory collection objects (it will call the pytest_collect_directory(...) hook to be precise) * after all subdirs/files have been collected the one matching the name 'b' is dived into * ...
This process I was expecting when calling "py.test" (without arguments or with 'b/test_hello.py') from the ROOTDIR, as i think in your explaination you meant having py.test being called from ROOTDIR because the argument 'b/test_hello.py' you mentioned has 'b/' in it, right?.
I understand the confusion but indeed, i really meant py.test b/test_hello.py will cause a collection of the ROOTDIR (containing 'b' and 'a'). py.test always collects from the root now matter how you call it. Otherwise collection customizations would not work uniformly. If you call py.test --collectonly you can see the collection result, btw.
... if both conftest.py's have a pytest_configure and pytest_unconfigure, they will be called in this order:
configure of b configure of a unconfigure of a unconfigure of b
I agree that both 'a' and 'b' should be inspected when calling py.test from ROOTDIR, but when calling it within 'a' or 'b'...?
I understand your surprise which is why i told the background story and how i'd like to fix it.
...i hope i don't bother you if i misunderstood your explaination (sorry in that case). but that you wrote "* py.test sees the command line arg b/test_hello.py" made me wonder whether you misunderstood me in the way that you thought i meant calling py.test from ROOTDIR.
you are welcome and thanks for trying to clarify. best, holger
Am 25.06.2010 12:05, schrieb holger krekel:
I understand the confusion but indeed, i really meant
py.test b/test_hello.py
will cause a collection of the ROOTDIR (containing 'b' and 'a'). py.test always collects from the root now matter how you call it.
This backs with my expectations. This means for our play-case: No matter whether I execute ~/ROOTDIR$ py.test or ~/ROOTDIR$ py.test b/test_hello.py it always inspects 'a' and 'b'. That's ok. But my concern is not about how i call it (from ROOTDIR) but _from_ _where_ i call it. Because when i enter the 'b' directory and doing ~/ROOTDIR/b$ py.test it will still examine ~/ROOTDIR/a. By the way ROOTDIR does not contain a __init__.py in this example, what at first I guessed would be the cause to let py.test take all neighbor directories into account. What i found out is, that py.test walks up one directory from where it was started and then examines the directories found regardless whether if found __init__.py on that upper level or not. Only the walking up stops when there is no __init__.py found, but the last walk-up step (or the first step where no __init__.py was found) is still used for collecting. Another example: ~/ROOTDIR/ a/ __init__.py c/ test_hello.py b/ conftest.py and I change dir to ~/ROOTDIR/a/c and call py.test from there. Then it walks from 'c' up to 'a', looking for a __init__.py. Because it found one then it walks up to ROOTDIR, does not find __init__.py there, but nevertheless takes 'b' into consideration. If we remove a/__init__.py and call py.test from ~ROOTDIR/a/c again then it only walks from 'c' up to 'a', does not find __init__.py and stops walking up. So the point what makes me surprise is, that the collection process takes directories from an upper dir-level into account even when there was no __init__.py found on that level. I hope I could make my concern clearer now. Thanks, Regards, Frank
Am 25.06.2010 13:05, schrieb Frank Hempel:
... there is no __init__.py found, but the last walk-up step (or the first step where no __init__.py was found) is still used for collecting.
...'collecting' was the wrong word. I meant examination which is loading of conftest.py. Tests are not collected of course. Regards, Frank
On Fri, Jun 25, 2010 at 13:05 +0200, Frank Hempel wrote:
Am 25.06.2010 12:05, schrieb holger krekel:
I understand the confusion but indeed, i really meant
py.test b/test_hello.py
will cause a collection of the ROOTDIR (containing 'b' and 'a'). py.test always collects from the root now matter how you call it.
This backs with my expectations. This means for our play-case: No matter whether I execute ~/ROOTDIR$ py.test or ~/ROOTDIR$ py.test b/test_hello.py it always inspects 'a' and 'b'. That's ok.
But my concern is not about how i call it (from ROOTDIR) but _from_ _where_ i call it.
It is basically equivalent if you have a CWD of 'b' and call "py.test" or if you are one dir up and call "py.test b". This is what i meant with "no matter how you call it".
Because when i enter the 'b' directory and doing ~/ROOTDIR/b$ py.test it will still examine ~/ROOTDIR/a. By the way ROOTDIR does not contain a __init__.py in this example, what at first I guessed would be the cause to let py.test take all neighbor directories into account. What i found out is, that py.test walks up one directory from where it was started and then examines the directories found regardless whether if found __init__.py on that upper level or not. Only the walking up stops when there is no __init__.py found, but the last walk-up step (or the first step where no __init__.py was found) is still used for collecting.
Yes, it's true and documented here (only indirectly though): http://codespeak.net/py/dist/test/customize.html#id22
Another example:
~/ROOTDIR/ a/ __init__.py c/ test_hello.py b/ conftest.py
and I change dir to ~/ROOTDIR/a/c and call py.test from there. Then it walks from 'c' up to 'a', looking for a __init__.py. Because it found one then it walks up to ROOTDIR, does not find __init__.py there, but nevertheless takes 'b' into consideration. If we remove a/__init__.py and call py.test from ~ROOTDIR/a/c again then it only walks from 'c' up to 'a', does not find __init__.py and stops walking up.
Yes, what you are seeing is the algorithm behind finding the ROOTDIR.
So the point what makes me surprise is, that the collection process takes directories from an upper dir-level into account even when there was no __init__.py found on that level.
It internally needs to perform a collection on the ROOTDIR in order to "select" 'a'. In fact, the reason behind all this is that py.test tries to construct a *canonical* collection tree up to the command line specified argument and this three starts from the ROOTDIR / root node which is indeed determined as the last non-init-containing directory.
I hope I could make my concern clearer now.
I think so - your analysis is right - i guess i didn't succeed yet in explaining the logic/reasoning behind the current behaviour, hope it's clearer now. best, holger
Am 25.06.2010 16:19, schrieb holger krekel:
It internally needs to perform a collection on the ROOTDIR in order to "select" 'a'. In fact, the reason behind all this is that py.test tries to construct a *canonical* collection tree up to the command line specified argument and this three starts from the ROOTDIR / root node which is indeed determined as the last non-init-containing directory.
I hope I could make my concern clearer now.
I think so - your analysis is right - i guess i didn't succeed yet in explaining the logic/reasoning behind the current behaviour, hope it's clearer now.
Ok. Thanks so far for taking the time and explaining this. Nevertheless i'm not absolutely happy with the situation that all directories of the "first non-init-containing directory" (should be called first, right?) are considered for conftest-loading. Because without changing anything to one's project 'a' it can make a difference in the sense of tests passing or failing for the project 'a' in dependency of what other project folders one puts side-by-side to 'a'. One not too unlikely side effect could be: the pytest_configure function of each conftest.py (the one of folder 'a' and of 'b') sets something to sys.path with a commonly used statement like "sys.path.insert(*0*, ...)". When testing project 'a' and with the fact that the order of the conftest-loadings is that "b"'s will be loaded after "a"'s, the sys.path.insertion of 'b' will take precedence. Regardless of the fact the the project 'b' might have have nothing to do with project 'a', it just sits side-by-side in the filesystem. And i'm actually not complaining th order. For my expectaion "b"'s conftest should not be loaded at all if i'm testing 'a' and the containing directory of 'a' and 'b' does not contain an __init__.py. ...do you agree with that :) ? Thanks again, Best regards, Frank
best, holger
On Fri, Jun 25, 2010 at 18:02 +0200, Frank Hempel wrote:
Am 25.06.2010 16:19, schrieb holger krekel:
It internally needs to perform a collection on the ROOTDIR in order to "select" 'a'. In fact, the reason behind all this is that py.test tries to construct a *canonical* collection tree up to the command line specified argument and this three starts from the ROOTDIR / root node which is indeed determined as the last non-init-containing directory.
I hope I could make my concern clearer now.
I think so - your analysis is right - i guess i didn't succeed yet in explaining the logic/reasoning behind the current behaviour, hope it's clearer now.
Ok. Thanks so far for taking the time and explaining this.
Nevertheless i'm not absolutely happy with the situation that all directories of the "first non-init-containing directory" (should be called first, right?) are considered for conftest-loading. Because without changing anything to one's project 'a' it can make a difference in the sense of tests passing or failing for the project 'a' in dependency of what other project folders one puts side-by-side to 'a'. One not too unlikely side effect could be: the pytest_configure function of each conftest.py (the one of folder 'a' and of 'b') sets something to sys.path with a commonly used statement like "sys.path.insert(*0*, ...)". When testing project 'a' and with the fact that the order of the conftest-loadings is that "b"'s will be loaded after "a"'s, the sys.path.insertion of 'b' will take precedence. Regardless of the fact the the project 'b' might have have nothing to do with project 'a', it just sits side-by-side in the filesystem. And i'm actually not complaining th order. For my expectaion "b"'s conftest should not be loaded at all if i'm testing 'a' and the containing directory of 'a' and 'b' does not contain an __init__.py.
...do you agree with that :) ?
Somewhat although i consider it bad practise to do sys.path manipulations in pytest_configure. It probably also means that you can get trouble when you run things from the root dir and both the 'a' and 'b' tests are run. Anyway, i agree it'd be nicer if py.test would not implicitely load the sibling directory's conftest.py. Could you care to file an "enhancement" issue in the bitbucket tracker? If you add a test case that you'd like to work that'd be good. I am not sure i fix it for the soon upcoming minor release but i definitely give it a try for 1.4. best, holger
Am 25.06.2010 19:11, schrieb holger krekel:
On Fri, Jun 25, 2010 at 18:02 +0200, Frank Hempel wrote:
Am 25.06.2010 16:19, schrieb holger krekel:
Somewhat although i consider it bad practise to do sys.path manipulations in pytest_configure. It probably also means that you can get trouble when you run things from the root dir and both the 'a' and 'b' tests are run.
I agree with your opinion. I just could not get something more stupid into mind... ;)
Anyway, i agree it'd be nicer if py.test would not implicitely load the sibling directory's conftest.py. Could you care to file an "enhancement" issue in the bitbucket tracker? If you add a test case that you'd like to work that'd be good. I am not sure i fix it for the soon upcoming minor release but i definitely give it a try for 1.4.
I will do that. Thank's for your agreement :) Best Regards, Frank
Hi Frank, The issue109 is from you, i think. See http://bitbucket.org/hpk42/py-trunk/issue/109/implicit-loading-of-sibling-di... I realize you are subscribed "Anonymous" to the issue so you probably didn't see my question: where is the patch? best, holger On Fri, Jun 25, 2010 at 19:28 +0200, Frank Hempel wrote:
Am 25.06.2010 19:11, schrieb holger krekel:
On Fri, Jun 25, 2010 at 18:02 +0200, Frank Hempel wrote:
Am 25.06.2010 16:19, schrieb holger krekel:
Somewhat although i consider it bad practise to do sys.path manipulations in pytest_configure. It probably also means that you can get trouble when you run things from the root dir and both the 'a' and 'b' tests are run.
I agree with your opinion. I just could not get something more stupid into mind... ;)
Anyway, i agree it'd be nicer if py.test would not implicitely load the sibling directory's conftest.py. Could you care to file an "enhancement" issue in the bitbucket tracker? If you add a test case that you'd like to work that'd be good. I am not sure i fix it for the soon upcoming minor release but i definitely give it a try for 1.4.
I will do that. Thank's for your agreement :)
Best Regards, Frank _______________________________________________ py-dev mailing list py-dev@codespeak.net http://codespeak.net/mailman/listinfo/py-dev
--
Am 29.07.2010 13:04, schrieb holger krekel:
Hi Frank,
The issue109 is from you, i think. See
http://bitbucket.org/hpk42/py-trunk/issue/109/implicit-loading-of-sibling-di...
I realize you are subscribed "Anonymous" to the issue so you probably didn't see my question: where is the patch?
Back then I posted it as anonymous comment. Meanwhile I managed it to register at bitbucket :) so I attached the reviewed patch as a file. Thanks, Best regards, Frank
participants (2)
-
Frank Hempel -
holger krekel