Rev 13: setup.py's that import modules are now supported by plugin-info, though in http://people.canonical.com/~robertc/baz2.0/plugins/plugin_info/trunk
Robert Collins
robertc at robertcollins.net
Mon Mar 1 04:37:58 GMT 2010
At http://people.canonical.com/~robertc/baz2.0/plugins/plugin_info/trunk
------------------------------------------------------------
revno: 13
revision-id: robertc at robertcollins.net-20100301043749-jtpu8aenalcmxs5q
parent: robertc at robertcollins.net-20100301021719-d1udrsm29naaaqgf
committer: Robert Collins <robertc at robertcollins.net>
branch nick: trunk
timestamp: Mon 2010-03-01 15:37:49 +1100
message:
setup.py's that import modules are now supported by plugin-info, though
those modules should be as shallow as possible to avoid interactions.
=== modified file 'NEWS'
--- a/NEWS 2010-03-01 01:32:52 +0000
+++ b/NEWS 2010-03-01 04:37:49 +0000
@@ -24,6 +24,10 @@
BUGFIXES:
+ * setup.py's that import modules are now supported by plugin-info, though
+ those modules should be as shallow as possible to avoid interactions.
+ (Robert Collins)
+
API BREAKS:
TESTING:
=== modified file 'extract.py'
--- a/extract.py 2010-03-01 01:32:52 +0000
+++ b/extract.py 2010-03-01 04:37:49 +0000
@@ -28,6 +28,8 @@
'PluginInfo',
]
+import sys
+
from bzrlib import branch, directory_service, osutils
@@ -54,14 +56,29 @@
:param path: The path the plugin can be found at.
:return: A PluginInfo for the plugin at path.
"""
- source_file = open(path + '/setup.py', 'rb')
+ # setup a fake 'package' that this setup can import siblings from
+ package = MyPackage(path)
+ source_path = path + '/setup.py'
+ source_file = open(source_path, 'rb')
try:
source = source_file.read()
finally:
source_file.close()
code = compile(source, 'setup.py', 'exec')
- eval_globals = {}
- module = eval(code, eval_globals)
+ eval_globals = {'__file__':source_path,
+ '__name__':'setup',
+ '__package__':package.__name__}
+ sys.modules[package.__name__] = package
+ try:
+ module = eval(code, eval_globals)
+ finally:
+ del sys.modules[package.__name__]
+ to_unload = []
+ for module in sys.modules.keys():
+ if module.startswith(package.__name__ + '.'):
+ to_unload.append(module)
+ for module in to_unload:
+ del sys.modules[module]
result = PluginInfo()
result.name = eval_globals.get('bzr_plugin_name', None)
result.commands = eval_globals.get('bzr_commands', [])
@@ -141,3 +158,13 @@
result.append('plugin.repository_formats = %s\n' % (self.repository_formats,))
result.append('plugin.transports = %s\n' % (self.transports,))
return ''.join(result)
+
+
+class MyPackage(object):
+ """A package to isolate (a little) imports."""
+
+ def __init__(self, dir):
+ setattr(self, '__file__', dir + '/__init__.py')
+ setattr(self, '__name__', 'setup_plugin_info')
+ setattr(self, '__package__', 'setup_plugin_info')
+ setattr(self, '__path__', [dir])
=== modified file 'tests/test_extract.py'
--- a/tests/test_extract.py 2010-03-01 01:32:52 +0000
+++ b/tests/test_extract.py 2010-03-01 04:37:49 +0000
@@ -18,6 +18,7 @@
"""Tests for extracting data from a plugin."""
from copy import copy
+import sys
from bzrlib import directory_service
from bzrlib.plugins.plugin_info.extract import *
@@ -191,6 +192,17 @@
expected_plugin.location = 'foo--bar'
self.assertEqual(expected_plugin, plugin)
+ def test_extract_imports_sibling(self):
+ self.build_tree(['foo--bar/'])
+ self.build_tree_contents([('foo--bar/info.py', self.sample_setup()),
+ ('foo--bar/setup.py', 'from info import *\n')])
+ imported = list(sys.modules.keys())
+ plugin = extract_info_local('foo--bar')
+ expected_plugin = self.expected_plugin()
+ expected_plugin.location = 'foo--bar'
+ self.assertEqual(expected_plugin, plugin)
+ self.assertEqual(imported, sys.modules.keys())
+
def test_extract_info_branch(self):
tree = self.setup_plugin()
expected_plugin = self.expected_plugin()
More information about the bazaar-commits
mailing list