[PATCH] setup: add flag to build_ext to control building zstd

Gregory Szorc gregory.szorc at gmail.com
Fri Nov 18 04:14:23 UTC 2016


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1479442150 28800
#      Thu Nov 17 20:09:10 2016 -0800
# Node ID 0c36116df0e58677f78ff5ca19ed0e496fc12c11
# Parent  41a8106789cae9716c39d8381fa5da1d3ea0d74b
setup: add flag to build_ext to control building zstd

Downstream packagers will inevitably want to disable building the
vendored python-zstandard Python package. Rather than force them
to patch setup.py, let's give them a knob to use.

distutils Command classes support defining custom options. It requires
setting certain class attributes (yes, class attributes: instance
attributes don't work because the class type is consulted before it
is instantiated).

We already have a custom child class of build_ext, so we set these
class attributes, implement some scaffolding, and override
build_extensions to filter the Extension instance for the zstd
extension if the `--no-zstd` argument is specified.

Example usage:

  $ python setup.py build_ext --no-zstd

diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -276,7 +276,30 @@ class hgdist(Distribution):
         # too late for some cases
         return not self.pure and Distribution.has_ext_modules(self)
 
+# This is ugly as a one-liner. So use a variable.
+buildextnegops = dict(getattr(build_ext, 'negative_options', {}))
+buildextnegops['no-zstd'] = 'zstd'
+
 class hgbuildext(build_ext):
+    user_options = build_ext.user_options + [
+        ('zstd', None, 'compile zstd bindings [default]'),
+        ('no-zstd', None, 'do not compile zstd bindings'),
+    ]
+
+    boolean_options = build_ext.boolean_options + ['zstd']
+    negative_opt = buildextnegops
+
+    def initialize_options(self):
+        self.zstd = True
+        return build_ext.initialize_options(self)
+
+    def build_extensions(self):
+        # Filter out zstd if disabled via argument.
+        if not self.zstd:
+            self.extensions = [e for e in self.extensions
+                               if e.name != 'mercurial.zstd']
+
+        return build_ext.build_extensions(self)
 
     def build_extension(self, ext):
         try:


More information about the Mercurial-devel mailing list