1 module contract.boilerplate;
2 
3 import python.boilerplate;
4 import python.raw: isPython2, isPython3;
5 
6 /**
7    A string mixin to reduce boilerplate when creating a Python module.
8    Takes a module name and a variadic list of C functions to make
9    available.
10  */
11 string createModuleMixin(Module module_, alias cfunctions, alias aggregates)()
12     if(isPython3)
13 {
14     if(!__ctfe) return null;
15 
16     import std.format: format;
17 
18     enum ret = q{
19         import python.raw: PyDateTime_CAPI;
20         // This is declared as an extern C variable in python.bindings.
21         // We declare it here to avoid linker errors.
22         export __gshared extern(C) PyDateTime_CAPI* PyDateTimeAPI;
23 
24         import python: ModuleInitRet;
25 
26         extern(C) export ModuleInitRet PyInit_%s() {
27             import python.raw: pyDateTimeImport;
28             import python.cooked: createModule;
29             import python.boilerplate: Module, CFunctions, Aggregates;
30             import core.runtime: rt_init;
31 
32             rt_init;
33 
34             pyDateTimeImport;
35 
36             return createModule!(
37                 Module("%s"),
38                 CFunctions!(
39                     %s
40                 ),
41                 Aggregates!(
42                     %s
43                 )
44             );
45         }
46     }.format(module_.name, module_.name, cfunctions.stringifySymbols, aggregates.stringifyTypes);
47 
48     return ret;
49 }
50 
51 string createModuleMixin(Module module_, alias cfunctions, alias aggregates)()
52     if(isPython2)
53 {
54     if(!__ctfe) return null;
55 
56     import std.format: format;
57 
58     enum ret = q{
59         import python.raw: PyDateTime_CAPI;
60 
61         // This is declared as an extern C variable in python.bindings.
62         // We declare it here to avoid linker errors.
63         export __gshared extern(C) PyDateTime_CAPI* PyDateTimeAPI;
64 
65         extern(C) export void init%s() {
66             import python.raw: pyDateTimeImport;
67             import python.cooked: initModule;
68             import python.boilerplate: Module, CFunctions, Aggregates;
69             import core.runtime: rt_init;
70 
71             rt_init;
72 
73             pyDateTimeImport;
74             initModule!(
75                 Module("%s"),
76                 CFunctions!(
77                     %s
78                 ),
79                 Aggregates!(
80                     %s
81                 ),
82             );
83         }
84     }.format(module_.name, module_.name, cfunctions.stringifySymbols, aggregates.stringifyTypes);
85 
86     return ret;
87 }