summarylogtreecommitdiffstats
path: root/create_extension.patch
blob: 10153fea0834c3a60938651661a78b74e0ec3758 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
commit 9797efe065d50638b0cd19219e6b1f3f5edaddab
Author: Jeroen Demeyer <jdemeyer@cage.ugent.be>
Date:   Fri Nov 25 11:07:44 2016 +0100

    Add support for create_extension() hook

diff --git a/Cython/Build/Dependencies.py b/Cython/Build/Dependencies.py
index 6c2827d..aedbad3 100644
--- a/Cython/Build/Dependencies.py
+++ b/Cython/Build/Dependencies.py
@@ -637,6 +637,20 @@ def create_dependency_tree(ctx=None, quiet=False):
     return _dep_tree
 
 
+# If this changes, change also docs/src/reference/compilation.rst
+# which mentions this function
+def default_create_extension(template, kwds):
+    if 'depends' in kwds:
+        include_dirs = kwds.get('include_dirs', []) + ["."]
+        depends = resolve_depends(kwds['depends'], include_dirs)
+        kwds['depends'] = sorted(set(depends + template.depends))
+
+    t = template.__class__
+    ext = t(**kwds)
+    metadata = dict(distutils=kwds, module_name=kwds['name'])
+    return (ext, metadata)
+
+
 # This may be useful for advanced users?
 def create_extension_list(patterns, exclude=None, ctx=None, aliases=None, quiet=False, language=None,
                           exclude_failures=False):
@@ -669,13 +683,16 @@ def create_extension_list(patterns, exclude=None, ctx=None, aliases=None, quiet=
         Extension_distutils = Extension
         class Extension_setuptools(Extension): pass
 
+    # if no create_extension() function is defined, use a simple
+    # default function.
+    create_extension = ctx.options.create_extension or default_create_extension
+
     for pattern in patterns:
         if isinstance(pattern, str):
             filepattern = pattern
-            template = None
+            template = Extension(pattern, [])  # Fake Extension without sources
             name = '*'
             base = None
-            exn_type = Extension
             ext_language = language
         elif isinstance(pattern, (Extension_distutils, Extension_setuptools)):
             cython_sources = [s for s in pattern.sources
@@ -693,7 +710,6 @@ def create_extension_list(patterns, exclude=None, ctx=None, aliases=None, quiet=
             template = pattern
             name = template.name
             base = DistutilsInfo(exn=template)
-            exn_type = template.__class__
             ext_language = None  # do not override whatever the Extension says
         else:
             msg = str("pattern is not of type str nor subclass of Extension (%s)"
@@ -727,39 +743,29 @@ def create_extension_list(patterns, exclude=None, ctx=None, aliases=None, quiet=
                         if key not in kwds:
                             kwds[key] = value
 
+                kwds['name'] = module_name
+
                 sources = [file]
-                if template is not None:
-                    sources += [m for m in template.sources if m != filepattern]
+                sources += [m for m in template.sources if m != filepattern]
                 if 'sources' in kwds:
                     # allow users to add .c files etc.
                     for source in kwds['sources']:
                         source = encode_filename_in_py2(source)
                         if source not in sources:
                             sources.append(source)
-                    extra_sources = kwds['sources']
-                    del kwds['sources']
-                else:
-                    extra_sources = None
-                if 'depends' in kwds:
-                    depends = resolve_depends(kwds['depends'], (kwds.get('include_dirs') or []) + ["."])
-                    if template is not None:
-                        # Always include everything from the template.
-                        depends = set(template.depends).union(depends)
-                    # Sort depends to make the metadata dump in the
-                    # Cython-generated C code predictable.
-                    kwds['depends'] = sorted(depends)
+                kwds['sources'] = sources
 
                 if ext_language and 'language' not in kwds:
                     kwds['language'] = ext_language
 
-                module_list.append(exn_type(
-                        name=module_name,
-                        sources=sources,
-                        **kwds))
-                if extra_sources:
-                    kwds['sources'] = extra_sources
-                module_metadata[module_name] = {'distutils': kwds, 'module_name': module_name}
-                m = module_list[-1]
+                # Create the new extension
+                m, metadata = create_extension(template, kwds)
+                module_list.append(m)
+
+                # Store metadata (this will be written as JSON in the
+                # generated C file but otherwise has no purpose)
+                module_metadata[module_name] = metadata
+
                 if file not in m.sources:
                     # Old setuptools unconditionally replaces .pyx with .c
                     m.sources.remove(file.rsplit('.')[0] + '.c')
diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py
index 3ba87d1..7ecd015 100644
--- a/Cython/Compiler/Main.py
+++ b/Cython/Compiler/Main.py
@@ -753,4 +753,5 @@ default_options = dict(
     output_dir=None,
     build_dir=None,
     cache=None,
+    create_extension=None,
 )