summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin McCarthy <me@kevinmccarthy.org>2014-06-22 14:33:58 -1000
committerKevin McCarthy <me@kevinmccarthy.org>2014-06-22 15:32:29 -1000
commitb07a50bfddda1cbb10faa64dc096ca9d855c483c (patch)
tree7a81fd5595f07ee8f19fa5860cac722a4f919aca
parent715c59738e3643f579b913921e90cf3b6bfc66e3 (diff)
downloadpbr-b07a50bfddda1cbb10faa64dc096ca9d855c483c.tar.gz
Restore Monkeypatched Distribution Instance
pbr is monkeypatching the Distribution intstance in setuptools, which is OK I guess, but then it never puts it back how it left it. As a consequence, whenever pbr installs before another project in a setup.py, it breaks setuptools for everything that comes after it. This patch will restore the Distribution instance. Closes-Bug: 1324784 Change-Id: I20fbf255c634685e82f7b11987d2725de8280b9d
-rw-r--r--pbr/core.py115
1 files changed, 66 insertions, 49 deletions
diff --git a/pbr/core.py b/pbr/core.py
index f622ad0..0aff652 100644
--- a/pbr/core.py
+++ b/pbr/core.py
@@ -49,7 +49,17 @@ from setuptools import dist
from pbr import util
-core.Distribution = dist._get_unpatched(core.Distribution)
+_saved_core_distribution = core.Distribution
+
+
+def _monkeypatch_distribution():
+ core.Distribution = dist._get_unpatched(core.Distribution)
+
+
+def _restore_distribution_monkeypatch():
+ core.Distribution = _saved_core_distribution
+
+
if sys.version_info[0] == 3:
string_type = str
integer_types = (int,)
@@ -76,52 +86,59 @@ def pbr(dist, attr, value):
not work well with distributions that do use a `Distribution` subclass.
"""
- if not value:
- return
- if isinstance(value, string_type):
- path = os.path.abspath(value)
- else:
- path = os.path.abspath('setup.cfg')
- if not os.path.exists(path):
- raise errors.DistutilsFileError(
- 'The setup.cfg file %s does not exist.' % path)
-
- # Converts the setup.cfg file to setup() arguments
try:
- attrs = util.cfg_to_args(path)
- except Exception:
- e = sys.exc_info()[1]
- raise errors.DistutilsSetupError(
- 'Error parsing %s: %s: %s' % (path, e.__class__.__name__, e))
-
- # Repeat some of the Distribution initialization code with the newly
- # provided attrs
- if attrs:
- # Skips 'options' and 'licence' support which are rarely used; may add
- # back in later if demanded
- for key, val in attrs.items():
- if hasattr(dist.metadata, 'set_' + key):
- getattr(dist.metadata, 'set_' + key)(val)
- elif hasattr(dist.metadata, key):
- setattr(dist.metadata, key, val)
- elif hasattr(dist, key):
- setattr(dist, key, val)
- else:
- msg = 'Unknown distribution option: %s' % repr(key)
- warnings.warn(msg)
-
- # Re-finalize the underlying Distribution
- core.Distribution.finalize_options(dist)
-
- # This bit comes out of distribute/setuptools
- if isinstance(dist.metadata.version, integer_types + (float,)):
- # Some people apparently take "version number" too literally :)
- dist.metadata.version = str(dist.metadata.version)
-
- # This bit of hackery is necessary so that the Distribution will ignore
- # normally unsupport command options (namely pre-hooks and post-hooks).
- # dist.command_options is normally a dict mapping command names to dicts of
- # their options. Now it will be a defaultdict that returns IgnoreDicts for
- # the each command's options so we can pass through the unsupported options
- ignore = ['pre_hook.*', 'post_hook.*']
- dist.command_options = util.DefaultGetDict(lambda: util.IgnoreDict(ignore))
+ _monkeypatch_distribution()
+ if not value:
+ return
+ if isinstance(value, string_type):
+ path = os.path.abspath(value)
+ else:
+ path = os.path.abspath('setup.cfg')
+ if not os.path.exists(path):
+ raise errors.DistutilsFileError(
+ 'The setup.cfg file %s does not exist.' % path)
+
+ # Converts the setup.cfg file to setup() arguments
+ try:
+ attrs = util.cfg_to_args(path)
+ except Exception:
+ e = sys.exc_info()[1]
+ raise errors.DistutilsSetupError(
+ 'Error parsing %s: %s: %s' % (path, e.__class__.__name__, e))
+
+ # Repeat some of the Distribution initialization code with the newly
+ # provided attrs
+ if attrs:
+ # Skips 'options' and 'licence' support which are rarely used; may
+ # add back in later if demanded
+ for key, val in attrs.items():
+ if hasattr(dist.metadata, 'set_' + key):
+ getattr(dist.metadata, 'set_' + key)(val)
+ elif hasattr(dist.metadata, key):
+ setattr(dist.metadata, key, val)
+ elif hasattr(dist, key):
+ setattr(dist, key, val)
+ else:
+ msg = 'Unknown distribution option: %s' % repr(key)
+ warnings.warn(msg)
+
+ # Re-finalize the underlying Distribution
+ core.Distribution.finalize_options(dist)
+
+ # This bit comes out of distribute/setuptools
+ if isinstance(dist.metadata.version, integer_types + (float,)):
+ # Some people apparently take "version number" too literally :)
+ dist.metadata.version = str(dist.metadata.version)
+
+ # This bit of hackery is necessary so that the Distribution will ignore
+ # normally unsupport command options (namely pre-hooks and post-hooks).
+ # dist.command_options is normally a dict mapping command names to
+ # dicts of their options. Now it will be a defaultdict that returns
+ # IgnoreDicts for the each command's options so we can pass through the
+ # unsupported options
+ ignore = ['pre_hook.*', 'post_hook.*']
+ dist.command_options = util.DefaultGetDict(
+ lambda: util.IgnoreDict(ignore)
+ )
+ finally:
+ _restore_distribution_monkeypatch()