Merge lp:~vila/bzr/712474-module-available into lp:bzr

Proposed by Vincent Ladeuil
Status: Merged
Approved by: John A Meinel
Approved revision: no longer in the source branch.
Merged at revision: 6076
Proposed branch: lp:~vila/bzr/712474-module-available
Merge into: lp:bzr
Diff against target: 40 lines (+14/-4)
2 files modified
bzrlib/tests/features.py (+10/-4)
doc/en/release-notes/bzr-2.5.txt (+4/-0)
To merge this branch: bzr merge lp:~vila/bzr/712474-module-available
Reviewer Review Type Date Requested Status
John A Meinel Approve
bzr-core Pending
Review via email: mp+48474@code.launchpad.net

Commit message

ModuleAvailableFeature don't try to imported already imported modules.

Description of the change

__import__ doesn't check that a module has already been imported, don't use it.

See the bug report for a real life use case (bzr-svn plugin).

To post a comment you must log in.
Revision history for this message
Martin Packman (gz) wrote :

I think checking sys.modules should do instead, something like:

    sentinel = object()
    module = sys.modules.get(self.module_name)
    if module is None:
        return False
    if module is sentinel:
        try:
            module = __import__(self.module_name, {}, {}, [''])
        except ImportError: # import can raise other things, but that's a bug
            return False
    return True

That should save me worrying needlessly about exec on an interpolated string.

Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2/3/2011 9:44 AM, Martin [gz] wrote:
> I think checking sys.modules should do instead, something like:
>
> sentinel = object()
> module = sys.modules.get(self.module_name)
> if module is None:
> return False
> if module is sentinel:
> try:
> module = __import__(self.module_name, {}, {}, [''])
> except ImportError: # import can raise other things, but that's a bug
> return False
> return True
>
> That should save me worrying needlessly about exec on an interpolated string.

I think you wanted

module = sys.modules.get(self.module_name, sentinel)

And regardless, this should probably be pulled out into a separate
helper function. I think the bzrlib.plugin code would like something
like this. Though we can see how related it is.

John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk1Kz4sACgkQJdeBCYSNAAPLjgCfaPi842OVTWonJ6f9yKDI6gCg
udAAoKV/XVWEaH+Srs7NS/bsm0VqwA+u
=ZTnz
-----END PGP SIGNATURE-----

Revision history for this message
John A Meinel (jameinel) wrote :

We'd really like to get away from "exec 'import %s'" if you can have it done a different way. I'm not particularly worried about code injection because importing a plugin can do whatever the heck it wants anyway.

review: Needs Fixing
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

ping?

Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 8/16/2011 4:21 PM, Vincent Ladeuil wrote:
> You have been requested to review the proposed merge of
> lp:~vila/bzr/712474-module-available into lp:bzr.
>
> For more details, see:
> https://code.launchpad.net/~vila/bzr/712474-module-available/+merge/48474
>
> __import__ doesn't check that a module has already been imported,
> don't use it.
>
> See the bug report for a real life use case (bzr-svn plugin).
>
>

Your cover letter is a bit incorrect. You're still using "__import__"
you're just guarding it with a check that the module isn't already imported.

 merge: approve

John
=:->

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk5KgpwACgkQJdeBCYSNAAN9OgCeIiAvxAQ57XRprJEOikfhFbff
4akAniys+2FQugggnC0uV2pLm4ISxJYQ
=Sf+E
-----END PGP SIGNATURE-----

review: Approve
Revision history for this message
Vincent Ladeuil (vila) wrote :

> Your cover letter is a bit incorrect. You're still using "__import__"

But never twice for the same module.

> you're just guarding it with a check that the module isn't already imported.

Indeed. Anyway, rephrased to avoid confusion.

Revision history for this message
Vincent Ladeuil (vila) wrote :

Ha, *cover* letter, yeah sorry, I didn't update it.

Revision history for this message
Vincent Ladeuil (vila) wrote :

sent to pqm by email

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/tests/features.py'
2--- bzrlib/tests/features.py 2011-08-11 10:09:27 +0000
3+++ bzrlib/tests/features.py 2011-08-16 15:21:51 +0000
4@@ -166,11 +166,17 @@
5 self.module_name = module_name
6
7 def _probe(self):
8- try:
9- self._module = __import__(self.module_name, {}, {}, [''])
10+ sentinel = object()
11+ module = sys.modules.get(self.module_name, sentinel)
12+ if module is sentinel:
13+ try:
14+ self._module = __import__(self.module_name, {}, {}, [''])
15+ return True
16+ except ImportError:
17+ return False
18+ else:
19+ self._module = module
20 return True
21- except ImportError:
22- return False
23
24 @property
25 def module(self):
26
27=== modified file 'doc/en/release-notes/bzr-2.5.txt'
28--- doc/en/release-notes/bzr-2.5.txt 2011-08-16 09:33:16 +0000
29+++ doc/en/release-notes/bzr-2.5.txt 2011-08-16 15:21:51 +0000
30@@ -196,6 +196,10 @@
31 * ``LockDir`` can now be run when the local hostname is ``localhost``.
32 (Jelmer Vernooij, #825994)
33
34+* ``ModuleAvailableFeature`` won't try to import already imported modules,
35+ allowing it to be used for modules with side-effects.
36+ (Vincent Ladeuil, #712474)
37+
38 * `TestCaseWithMemoryTransport` is faster now: `_check_safety_net` now
39 just compares the bytes in the dirstate file to its pristine state,
40 rather than opening the WorkingTree and calling ``last_revision()``.