Patchwork setup: add flag to build_ext to control building zstd

login
register
mail settings
Submitter Gregory Szorc
Date Nov. 18, 2016, 4:14 a.m.
Message ID <0c36116df0e58677f78f.1479442463@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/17635/
State Accepted
Headers show

Comments

Gregory Szorc - Nov. 18, 2016, 4:14 a.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@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
Augie Fackler - Nov. 19, 2016, 1:41 a.m.
On Thu, Nov 17, 2016 at 08:14:23PM -0800, Gregory Szorc wrote:
> # HG changeset patch
> # User Gregory Szorc <gregory.szorc@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

queued

>
> 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:
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

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: