Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Python: Dev

Allowing to run certain regression tests in subprocesses

 

 

Python dev RSS feed   Index | Next | Previous | View Threaded


eliben at gmail

Aug 3, 2013, 4:36 PM

Post #1 of 11 (75 views)
Permalink
Allowing to run certain regression tests in subprocesses

Hi All,

Today the issue of cross-test global env dependencies showed its ugly
head again for me. I recall a previous discussion
(http://mail.python.org/pipermail/python-dev/2013-January/123409.html)
but there were many more over the years.

The core problem is that some tests modify the global env
(particularly importing modules) and this sometimes has adverse
effects on other tests, because test.regrtest runs all tests in a
single process. In the discussion linked above, the particular culprit
test__all__ was judged as a candidate to be moved to a subprocess.

I want to propose adding a capability to our test harness to run
specific tests in subprocesses. Each test will have some simple way of
asking to be run in a subprocess, and regrtest will concur (even when
running -j1). test__all__ can go there, and it can help solve other
problems.

My particular case is trying to write a test for
http://bugs.python.org/issue14988 - wherein I have to simulate a
situation of non-existent pyexpat. It's not hard to write a test for
it, but when run in tandem with other tests (where C extensions loaded
pyexpat) it becomes seemingly impossible to set up. This should not be
the case - there's nothing wrong with wanting to simulate this case,
and there's nothing wrong in Python and the stdlib - it's purely an
artifact of the way our regression suite works.

Thoughts?

Eli
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


eliben at gmail

Aug 3, 2013, 4:47 PM

Post #2 of 11 (71 views)
Permalink
Re: Allowing to run certain regression tests in subprocesses [In reply to]

On Sat, Aug 3, 2013 at 4:36 PM, Eli Bendersky <eliben [at] gmail> wrote:
> Hi All,
>
> Today the issue of cross-test global env dependencies showed its ugly
> head again for me. I recall a previous discussion
> (http://mail.python.org/pipermail/python-dev/2013-January/123409.html)
> but there were many more over the years.
>
> The core problem is that some tests modify the global env
> (particularly importing modules) and this sometimes has adverse
> effects on other tests, because test.regrtest runs all tests in a
> single process. In the discussion linked above, the particular culprit
> test__all__ was judged as a candidate to be moved to a subprocess.
>
> I want to propose adding a capability to our test harness to run
> specific tests in subprocesses. Each test will have some simple way of
> asking to be run in a subprocess, and regrtest will concur (even when
> running -j1). test__all__ can go there, and it can help solve other
> problems.
>
> My particular case is trying to write a test for
> http://bugs.python.org/issue14988 - wherein I have to simulate a
> situation of non-existent pyexpat. It's not hard to write a test for
> it, but when run in tandem with other tests (where C extensions loaded
> pyexpat) it becomes seemingly impossible to set up. This should not be
> the case - there's nothing wrong with wanting to simulate this case,
> and there's nothing wrong in Python and the stdlib - it's purely an
> artifact of the way our regression suite works.
>
> Thoughts?
>
> Eli

FWIW the problem is also discussed here:
http://bugs.python.org/issue1674555, w.r.t. test_site

Eli
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


rdmurray at bitdance

Aug 3, 2013, 6:57 PM

Post #3 of 11 (68 views)
Permalink
Re: Allowing to run certain regression tests in subprocesses [In reply to]

On Sat, 03 Aug 2013 16:47:37 -0700, Eli Bendersky <eliben [at] gmail> wrote:
> On Sat, Aug 3, 2013 at 4:36 PM, Eli Bendersky <eliben [at] gmail> wrote:
> > Hi All,
> >
> > Today the issue of cross-test global env dependencies showed its ugly
> > head again for me. I recall a previous discussion
> > (http://mail.python.org/pipermail/python-dev/2013-January/123409.html)
> > but there were many more over the years.
> >
> > The core problem is that some tests modify the global env
> > (particularly importing modules) and this sometimes has adverse
> > effects on other tests, because test.regrtest runs all tests in a
> > single process. In the discussion linked above, the particular culprit
> > test__all__ was judged as a candidate to be moved to a subprocess.
> >
> > I want to propose adding a capability to our test harness to run
> > specific tests in subprocesses. Each test will have some simple way of
> > asking to be run in a subprocess, and regrtest will concur (even when
> > running -j1). test__all__ can go there, and it can help solve other
> > problems.
> >
> > My particular case is trying to write a test for
> > http://bugs.python.org/issue14988 - wherein I have to simulate a
> > situation of non-existent pyexpat. It's not hard to write a test for
> > it, but when run in tandem with other tests (where C extensions loaded
> > pyexpat) it becomes seemingly impossible to set up. This should not be
> > the case - there's nothing wrong with wanting to simulate this case,
> > and there's nothing wrong in Python and the stdlib - it's purely an
> > artifact of the way our regression suite works.
> >
> > Thoughts?
> >
> > Eli
>
> FWIW the problem is also discussed here:
> http://bugs.python.org/issue1674555, w.r.t. test_site

Can't you just launch a subprocess from the test itself using script_helpers?

--David
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


ncoghlan at gmail

Aug 3, 2013, 6:59 PM

Post #4 of 11 (68 views)
Permalink
Re: Allowing to run certain regression tests in subprocesses [In reply to]

On 4 Aug 2013 09:43, "Eli Bendersky" <eliben [at] gmail> wrote:
>
> Hi All,
>
> Today the issue of cross-test global env dependencies showed its ugly
> head again for me. I recall a previous discussion
> (http://mail.python.org/pipermail/python-dev/2013-January/123409.html)
> but there were many more over the years.
>
> The core problem is that some tests modify the global env
> (particularly importing modules) and this sometimes has adverse
> effects on other tests, because test.regrtest runs all tests in a
> single process. In the discussion linked above, the particular culprit
> test__all__ was judged as a candidate to be moved to a subprocess.
>
> I want to propose adding a capability to our test harness to run
> specific tests in subprocesses. Each test will have some simple way of
> asking to be run in a subprocess, and regrtest will concur (even when
> running -j1). test__all__ can go there, and it can help solve other
> problems.
>
> My particular case is trying to write a test for
> http://bugs.python.org/issue14988 - wherein I have to simulate a
> situation of non-existent pyexpat. It's not hard to write a test for
> it, but when run in tandem with other tests (where C extensions loaded
> pyexpat) it becomes seemingly impossible to set up. This should not be
> the case - there's nothing wrong with wanting to simulate this case,
> and there's nothing wrong in Python and the stdlib - it's purely an
> artifact of the way our regression suite works.

I'm not actively opposed to the suggested idea, but is there a specific
reason "test.support.import_fresh_module" doesn't work for this test?

Cheers,
Nick.

>
> Thoughts?
>
> Eli
> _______________________________________________
> Python-Dev mailing list
> Python-Dev [at] python
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
http://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com


eliben at gmail

Aug 3, 2013, 7:03 PM

Post #5 of 11 (68 views)
Permalink
Re: Allowing to run certain regression tests in subprocesses [In reply to]

On Sat, Aug 3, 2013 at 6:59 PM, Nick Coghlan <ncoghlan [at] gmail> wrote:
>
> On 4 Aug 2013 09:43, "Eli Bendersky" <eliben [at] gmail> wrote:
>>
>> Hi All,
>>
>> Today the issue of cross-test global env dependencies showed its ugly
>> head again for me. I recall a previous discussion
>> (http://mail.python.org/pipermail/python-dev/2013-January/123409.html)
>> but there were many more over the years.
>>
>> The core problem is that some tests modify the global env
>> (particularly importing modules) and this sometimes has adverse
>> effects on other tests, because test.regrtest runs all tests in a
>> single process. In the discussion linked above, the particular culprit
>> test__all__ was judged as a candidate to be moved to a subprocess.
>>
>> I want to propose adding a capability to our test harness to run
>> specific tests in subprocesses. Each test will have some simple way of
>> asking to be run in a subprocess, and regrtest will concur (even when
>> running -j1). test__all__ can go there, and it can help solve other
>> problems.
>>
>> My particular case is trying to write a test for
>> http://bugs.python.org/issue14988 - wherein I have to simulate a
>> situation of non-existent pyexpat. It's not hard to write a test for
>> it, but when run in tandem with other tests (where C extensions loaded
>> pyexpat) it becomes seemingly impossible to set up. This should not be
>> the case - there's nothing wrong with wanting to simulate this case,
>> and there's nothing wrong in Python and the stdlib - it's purely an
>> artifact of the way our regression suite works.
>
> I'm not actively opposed to the suggested idea, but is there a specific
> reason "test.support.import_fresh_module" doesn't work for this test?

I'm not an expert on this topic, but I believe there's a problem
unloading code that was loaded by C extensions. import_fresh_module is
thus powerless here (which also appears to be the case empirically).

Eli
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


ncoghlan at gmail

Aug 3, 2013, 7:08 PM

Post #6 of 11 (69 views)
Permalink
Re: Allowing to run certain regression tests in subprocesses [In reply to]

On 4 Aug 2013 12:03, "Eli Bendersky" <eliben [at] gmail> wrote:
>
> On Sat, Aug 3, 2013 at 6:59 PM, Nick Coghlan <ncoghlan [at] gmail> wrote:
> >
> > On 4 Aug 2013 09:43, "Eli Bendersky" <eliben [at] gmail> wrote:
> >>
> >> Hi All,
> >>
> >> Today the issue of cross-test global env dependencies showed its ugly
> >> head again for me. I recall a previous discussion
> >> (http://mail.python.org/pipermail/python-dev/2013-January/123409.html)
> >> but there were many more over the years.
> >>
> >> The core problem is that some tests modify the global env
> >> (particularly importing modules) and this sometimes has adverse
> >> effects on other tests, because test.regrtest runs all tests in a
> >> single process. In the discussion linked above, the particular culprit
> >> test__all__ was judged as a candidate to be moved to a subprocess.
> >>
> >> I want to propose adding a capability to our test harness to run
> >> specific tests in subprocesses. Each test will have some simple way of
> >> asking to be run in a subprocess, and regrtest will concur (even when
> >> running -j1). test__all__ can go there, and it can help solve other
> >> problems.
> >>
> >> My particular case is trying to write a test for
> >> http://bugs.python.org/issue14988 - wherein I have to simulate a
> >> situation of non-existent pyexpat. It's not hard to write a test for
> >> it, but when run in tandem with other tests (where C extensions loaded
> >> pyexpat) it becomes seemingly impossible to set up. This should not be
> >> the case - there's nothing wrong with wanting to simulate this case,
> >> and there's nothing wrong in Python and the stdlib - it's purely an
> >> artifact of the way our regression suite works.
> >
> > I'm not actively opposed to the suggested idea, but is there a specific
> > reason "test.support.import_fresh_module" doesn't work for this test?
>
> I'm not an expert on this topic, but I believe there's a problem
> unloading code that was loaded by C extensions. import_fresh_module is
> thus powerless here (which also appears to be the case empirically).

Sure, it's just unusual to have a case where "importing is blocked by
adding None to sys.modules" differs from "not actually available", so I'd
like to understand the situation better.

Cheers,
Nick.
>
> Eli


rdmurray at bitdance

Aug 4, 2013, 5:44 AM

Post #7 of 11 (66 views)
Permalink
Re: Allowing to run certain regression tests in subprocesses [In reply to]

On Sat, 03 Aug 2013 19:04:21 -0700, Eli Bendersky <eliben [at] gmail> wrote:
> On Sat, Aug 3, 2013 at 6:57 PM, R. David Murray <rdmurray [at] bitdance> wrote:
> > On Sat, 03 Aug 2013 16:47:37 -0700, Eli Bendersky <eliben [at] gmail> wrote:
> >> On Sat, Aug 3, 2013 at 4:36 PM, Eli Bendersky <eliben [at] gmail> wrote:
> >> > Hi All,
> >> >
> >> > Today the issue of cross-test global env dependencies showed its ugly
> >> > head again for me. I recall a previous discussion
> >> > (http://mail.python.org/pipermail/python-dev/2013-January/123409.html)
> >> > but there were many more over the years.
> >> >
> >> > The core problem is that some tests modify the global env
> >> > (particularly importing modules) and this sometimes has adverse
> >> > effects on other tests, because test.regrtest runs all tests in a
> >> > single process. In the discussion linked above, the particular culprit
> >> > test__all__ was judged as a candidate to be moved to a subprocess.
> >> >
> >> > I want to propose adding a capability to our test harness to run
> >> > specific tests in subprocesses. Each test will have some simple way of
> >> > asking to be run in a subprocess, and regrtest will concur (even when
> >> > running -j1). test__all__ can go there, and it can help solve other
> >> > problems.
> >> >
> >> > My particular case is trying to write a test for
> >> > http://bugs.python.org/issue14988 - wherein I have to simulate a
> >> > situation of non-existent pyexpat. It's not hard to write a test for
> >> > it, but when run in tandem with other tests (where C extensions loaded
> >> > pyexpat) it becomes seemingly impossible to set up. This should not be
> >> > the case - there's nothing wrong with wanting to simulate this case,
> >> > and there's nothing wrong in Python and the stdlib - it's purely an
> >> > artifact of the way our regression suite works.
> >> >
> >> > Thoughts?
> >> >
> >> > Eli
> >>
> >> FWIW the problem is also discussed here:
> >> http://bugs.python.org/issue1674555, w.r.t. test_site
> >
> > Can't you just launch a subprocess from the test itself using script_helpers?
> >
>
> I can, but such launching will be necessarily duplicated across all
> tests that need this functionality (test_site, test___all__, etc).
> Since regrtest already has functionality for launching whole
> test-suites in subprocesses, it makes sense to reuse it, no?

In the case of test_site and test___all___ we are talking about running
the entire test file in a subprocess. It sounds like you are only
talking about running one individual test function in a subprocess,
for which using script_helpers seems the more natural solution.

--David
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


eliben at gmail

Aug 4, 2013, 5:54 AM

Post #8 of 11 (66 views)
Permalink
Re: Allowing to run certain regression tests in subprocesses [In reply to]

On Sun, Aug 4, 2013 at 5:44 AM, R. David Murray <rdmurray [at] bitdance> wrote:
> On Sat, 03 Aug 2013 19:04:21 -0700, Eli Bendersky <eliben [at] gmail> wrote:
>> On Sat, Aug 3, 2013 at 6:57 PM, R. David Murray <rdmurray [at] bitdance> wrote:
>> > On Sat, 03 Aug 2013 16:47:37 -0700, Eli Bendersky <eliben [at] gmail> wrote:
>> >> On Sat, Aug 3, 2013 at 4:36 PM, Eli Bendersky <eliben [at] gmail> wrote:
>> >> > Hi All,
>> >> >
>> >> > Today the issue of cross-test global env dependencies showed its ugly
>> >> > head again for me. I recall a previous discussion
>> >> > (http://mail.python.org/pipermail/python-dev/2013-January/123409.html)
>> >> > but there were many more over the years.
>> >> >
>> >> > The core problem is that some tests modify the global env
>> >> > (particularly importing modules) and this sometimes has adverse
>> >> > effects on other tests, because test.regrtest runs all tests in a
>> >> > single process. In the discussion linked above, the particular culprit
>> >> > test__all__ was judged as a candidate to be moved to a subprocess.
>> >> >
>> >> > I want to propose adding a capability to our test harness to run
>> >> > specific tests in subprocesses. Each test will have some simple way of
>> >> > asking to be run in a subprocess, and regrtest will concur (even when
>> >> > running -j1). test__all__ can go there, and it can help solve other
>> >> > problems.
>> >> >
>> >> > My particular case is trying to write a test for
>> >> > http://bugs.python.org/issue14988 - wherein I have to simulate a
>> >> > situation of non-existent pyexpat. It's not hard to write a test for
>> >> > it, but when run in tandem with other tests (where C extensions loaded
>> >> > pyexpat) it becomes seemingly impossible to set up. This should not be
>> >> > the case - there's nothing wrong with wanting to simulate this case,
>> >> > and there's nothing wrong in Python and the stdlib - it's purely an
>> >> > artifact of the way our regression suite works.
>> >> >
>> >> > Thoughts?
>> >> >
>> >> > Eli
>> >>
>> >> FWIW the problem is also discussed here:
>> >> http://bugs.python.org/issue1674555, w.r.t. test_site
>> >
>> > Can't you just launch a subprocess from the test itself using script_helpers?
>> >
>>
>> I can, but such launching will be necessarily duplicated across all
>> tests that need this functionality (test_site, test___all__, etc).
>> Since regrtest already has functionality for launching whole
>> test-suites in subprocesses, it makes sense to reuse it, no?
>
> In the case of test_site and test___all___ we are talking about running
> the entire test file in a subprocess. It sounds like you are only
> talking about running one individual test function in a subprocess,
> for which using script_helpers seems the more natural solution.

I was actually planning to split this into a separate test file to
make the process separation more apparent. And regardless, the
question sent to the list is about the generic approach, not my
particular problem. Issues of folks struggling with inter-test
dependencies through global state modification come up very often.

Eli
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


eliben at gmail

Aug 4, 2013, 6:40 AM

Post #9 of 11 (65 views)
Permalink
Re: Allowing to run certain regression tests in subprocesses [In reply to]

On Sat, Aug 3, 2013 at 7:08 PM, Nick Coghlan <ncoghlan [at] gmail> wrote:
>
> On 4 Aug 2013 12:03, "Eli Bendersky" <eliben [at] gmail> wrote:
>>
>> On Sat, Aug 3, 2013 at 6:59 PM, Nick Coghlan <ncoghlan [at] gmail> wrote:
>> >
>> > On 4 Aug 2013 09:43, "Eli Bendersky" <eliben [at] gmail> wrote:
>> >>
>> >> Hi All,
>> >>
>> >> Today the issue of cross-test global env dependencies showed its ugly
>> >> head again for me. I recall a previous discussion
>> >> (http://mail.python.org/pipermail/python-dev/2013-January/123409.html)
>> >> but there were many more over the years.
>> >>
>> >> The core problem is that some tests modify the global env
>> >> (particularly importing modules) and this sometimes has adverse
>> >> effects on other tests, because test.regrtest runs all tests in a
>> >> single process. In the discussion linked above, the particular culprit
>> >> test__all__ was judged as a candidate to be moved to a subprocess.
>> >>
>> >> I want to propose adding a capability to our test harness to run
>> >> specific tests in subprocesses. Each test will have some simple way of
>> >> asking to be run in a subprocess, and regrtest will concur (even when
>> >> running -j1). test__all__ can go there, and it can help solve other
>> >> problems.
>> >>
>> >> My particular case is trying to write a test for
>> >> http://bugs.python.org/issue14988 - wherein I have to simulate a
>> >> situation of non-existent pyexpat. It's not hard to write a test for
>> >> it, but when run in tandem with other tests (where C extensions loaded
>> >> pyexpat) it becomes seemingly impossible to set up. This should not be
>> >> the case - there's nothing wrong with wanting to simulate this case,
>> >> and there's nothing wrong in Python and the stdlib - it's purely an
>> >> artifact of the way our regression suite works.
>> >
>> > I'm not actively opposed to the suggested idea, but is there a specific
>> > reason "test.support.import_fresh_module" doesn't work for this test?
>>
>> I'm not an expert on this topic, but I believe there's a problem
>> unloading code that was loaded by C extensions. import_fresh_module is
>> thus powerless here (which also appears to be the case empirically).
>
> Sure, it's just unusual to have a case where "importing is blocked by adding
> None to sys.modules" differs from "not actually available", so I'd like to
> understand the situation better.

I must admit I'm confused by the behavior of import_fresh_module too.

Snippet #1 raises the expected ImportError:

sys.modules['pyexpat'] = None
import _elementtree

However, snippet #2 succeeds importing:

ET = import_fresh_module('_elementtree', blocked=['pyexpat'])
print(ET)

I believe this happens because import_fresh_module does an import of
the 'name' it's given before even looking at the blocked list. Then,
it assigns None to sys.modules for the blocked names and re-imports
the module. So in essence, this is somewhat equivalent to snippet #3:

modname = '_elementtree'
__import__(modname)
del sys.modules[modname]
for m in sys.modules:
if modname == m or m.startswith(modname + '.'):
del sys.modules[m]
sys.modules['pyexpat'] = None
ET = importlib.import_module(modname)
print(ET)

Which also succeeds.

I fear I'm not familiar enough with the logic of importing to
understand what's going on, but it has been my impression that this
problem is occasionally encountered with import_fresh_module and C
code that imports stuff (the import of pyexpat is done by C code in
this case).

CC'ing Brett.

Eli
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


ncoghlan at gmail

Aug 4, 2013, 7:26 AM

Post #10 of 11 (65 views)
Permalink
Re: Allowing to run certain regression tests in subprocesses [In reply to]

On 4 August 2013 23:40, Eli Bendersky <eliben [at] gmail> wrote:
> On Sat, Aug 3, 2013 at 7:08 PM, Nick Coghlan <ncoghlan [at] gmail> wrote:
>> Sure, it's just unusual to have a case where "importing is blocked by adding
>> None to sys.modules" differs from "not actually available", so I'd like to
>> understand the situation better.
>
> I must admit I'm confused by the behavior of import_fresh_module too.
>
> Snippet #1 raises the expected ImportError:
>
> sys.modules['pyexpat'] = None
> import _elementtree
>
> However, snippet #2 succeeds importing:
>
> ET = import_fresh_module('_elementtree', blocked=['pyexpat'])
> print(ET)

/me goes and looks

That function was much simpler when it was first created :P

Still, I'm fairly confident the complexity of that dance isn't
relevant to the problem you're seeing.

> I believe this happens because import_fresh_module does an import of
> the 'name' it's given before even looking at the blocked list. Then,
> it assigns None to sys.modules for the blocked names and re-imports
> the module. So in essence, this is somewhat equivalent to snippet #3:
>
> modname = '_elementtree'
> __import__(modname)
> del sys.modules[modname]
> for m in sys.modules:
> if modname == m or m.startswith(modname + '.'):
> del sys.modules[m]
> sys.modules['pyexpat'] = None
> ET = importlib.import_module(modname)
> print(ET)
>
> Which also succeeds.
>
> I fear I'm not familiar enough with the logic of importing to
> understand what's going on, but it has been my impression that this
> problem is occasionally encountered with import_fresh_module and C
> code that imports stuff (the import of pyexpat is done by C code in
> this case).

I had missed it was a C module doing the import. Looking into the
_elementtree.c source, the problem in this case is the fact that a
shared library that doesn't use PEP 3121 style per-module state is
only loaded and initialised once, so reimporting it gets the same
module back (from the extension loading cache), even if the Python
level reference has been removed from sys.modules. Non PEP 3121 C
extension modules thus don't work properly with
test.support.import_fresh_module (as there's an extra level of caching
involved that *can't* be cleared from Python, because it would break
things).

To fix this, _elementree would need to move the pyexpat C API pointer
to per-module state, rather than using a static variable (see
http://docs.python.org/3/c-api/module.html#initializing-c-modules).
With per-module state defined, the import machine should rerun the
init function when the fresh import happens, thus creating a new copy
of the module. However, this isn't an entirely trivial change for
_elementree, since:

1. Getting from the XMLParser instance back to the module where it was
defined in order to retrieve the capsule pointer via
PyModule_GetState() isn't entirely trivial in C. You'd likely do it
once in the init method, store the result in an XMLParser attribute,
and then tweak the EXPAT() using functions to include an appropriate
local variable definition at the start of the method implementation.

2. expat_set_error would need to be updated to accept the pyexpat
capsule pointer as a function parameter

Cheers,
Nick.

--
Nick Coghlan | ncoghlan [at] gmail | Brisbane, Australia
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com


eliben at gmail

Aug 4, 2013, 4:06 PM

Post #11 of 11 (60 views)
Permalink
Re: Allowing to run certain regression tests in subprocesses [In reply to]

On Sun, Aug 4, 2013 at 7:26 AM, Nick Coghlan <ncoghlan [at] gmail> wrote:
> On 4 August 2013 23:40, Eli Bendersky <eliben [at] gmail> wrote:
>> On Sat, Aug 3, 2013 at 7:08 PM, Nick Coghlan <ncoghlan [at] gmail> wrote:
>>> Sure, it's just unusual to have a case where "importing is blocked by adding
>>> None to sys.modules" differs from "not actually available", so I'd like to
>>> understand the situation better.
>>
>> I must admit I'm confused by the behavior of import_fresh_module too.
>>
>> Snippet #1 raises the expected ImportError:
>>
>> sys.modules['pyexpat'] = None
>> import _elementtree
>>
>> However, snippet #2 succeeds importing:
>>
>> ET = import_fresh_module('_elementtree', blocked=['pyexpat'])
>> print(ET)
>
> /me goes and looks
>
> That function was much simpler when it was first created :P
>
> Still, I'm fairly confident the complexity of that dance isn't
> relevant to the problem you're seeing.
>
>> I believe this happens because import_fresh_module does an import of
>> the 'name' it's given before even looking at the blocked list. Then,
>> it assigns None to sys.modules for the blocked names and re-imports
>> the module. So in essence, this is somewhat equivalent to snippet #3:
>>
>> modname = '_elementtree'
>> __import__(modname)
>> del sys.modules[modname]
>> for m in sys.modules:
>> if modname == m or m.startswith(modname + '.'):
>> del sys.modules[m]
>> sys.modules['pyexpat'] = None
>> ET = importlib.import_module(modname)
>> print(ET)
>>
>> Which also succeeds.
>>
>> I fear I'm not familiar enough with the logic of importing to
>> understand what's going on, but it has been my impression that this
>> problem is occasionally encountered with import_fresh_module and C
>> code that imports stuff (the import of pyexpat is done by C code in
>> this case).
>
> I had missed it was a C module doing the import. Looking into the
> _elementtree.c source, the problem in this case is the fact that a
> shared library that doesn't use PEP 3121 style per-module state is
> only loaded and initialised once, so reimporting it gets the same
> module back (from the extension loading cache), even if the Python
> level reference has been removed from sys.modules. Non PEP 3121 C
> extension modules thus don't work properly with
> test.support.import_fresh_module (as there's an extra level of caching
> involved that *can't* be cleared from Python, because it would break
> things).
>
> To fix this, _elementree would need to move the pyexpat C API pointer
> to per-module state, rather than using a static variable (see
> http://docs.python.org/3/c-api/module.html#initializing-c-modules).
> With per-module state defined, the import machine should rerun the
> init function when the fresh import happens, thus creating a new copy
> of the module. However, this isn't an entirely trivial change for
> _elementree, since:
>
> 1. Getting from the XMLParser instance back to the module where it was
> defined in order to retrieve the capsule pointer via
> PyModule_GetState() isn't entirely trivial in C. You'd likely do it
> once in the init method, store the result in an XMLParser attribute,
> and then tweak the EXPAT() using functions to include an appropriate
> local variable definition at the start of the method implementation.
>
> 2. expat_set_error would need to be updated to accept the pyexpat
> capsule pointer as a function parameter
>

Thanks Nick; I suspected something of the sort is going on here, but
you provide some interesting leads to look at. I'll probably open an
issue to track this at some point.

Eli
_______________________________________________
Python-Dev mailing list
Python-Dev [at] python
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com

Python dev RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.