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,
)
|