6 # Decorator the specifies bjam-side prototype for a Python function
17 f.bjam_signature = (["name"], ["sources", "*"], ["requirements", "*"],
18 ["default_build", "*"], ["usage_requirements", "*"])
23 def __init__(self, function):
24 self.function = function
27 def __call__(self, *args):
29 return self.cache[args]
31 v = self.function(*args)
35 def __get__(self, instance, type):
36 return types.MethodType(self, instance, type)
39 if s and s[0] == '"' and s[-1] == '"':
44 _extract_jamfile_and_rule = re.compile("(Jamfile<.*>)%(.*)")
46 def qualify_jam_action(action_name, context_module):
48 if action_name.startswith("###"):
49 # Callable exported from Python. Don't touch
51 elif _extract_jamfile_and_rule.match(action_name):
52 # Rule is already in indirect format
55 ix = action_name.find('.')
56 if ix != -1 and action_name[:ix] == context_module:
57 return context_module + '%' + action_name[ix+1:]
59 return context_module + '%' + action_name
62 def set_jam_action(name, *args):
64 m = _extract_jamfile_and_rule.match(name)
66 args = ("set-update-action-in-module", m.group(1), m.group(2)) + args
68 args = ("set-update-action", name) + args
70 return bjam.call(*args)
73 def call_jam_function(name, *args):
75 m = _extract_jamfile_and_rule.match(name)
77 args = ("call-in-module", m.group(1), m.group(2)) + args
78 return bjam.call(*args)
80 return bjam.call(*((name,) + args))
86 def value_to_jam(value, methods=False):
87 """Makes a token to refer to a Python value inside Jam language code.
89 The token is merely a string that can be passed around in Jam code and
90 eventually passed back. For example, we might want to pass PropertySet
91 instance to a tag function and it might eventually call back
92 to virtual_target.add_suffix_and_prefix, passing the same instance.
94 For values that are classes, we'll also make class methods callable
97 Note that this is necessary to make a bit more of existing Jamfiles work.
98 This trick should not be used to much, or else the performance benefits of
99 Python port will be eaten.
104 r = __python_to_jam.get(value, None)
108 exported_name = '###_' + str(__value_id)
109 __value_id = __value_id + 1
110 __python_to_jam[value] = exported_name
111 __jam_to_python[exported_name] = value
113 if methods and type(value) == types.InstanceType:
114 for field_name in dir(value):
115 field = getattr(value, field_name)
116 if callable(field) and not field_name.startswith("__"):
117 bjam.import_rule("", exported_name + "." + field_name, field)
121 def record_jam_to_value_mapping(jam_value, python_value):
122 __jam_to_python[jam_value] = python_value
124 def jam_to_value_maybe(jam_value):
126 if type(jam_value) == type(""):
127 return __jam_to_python.get(jam_value, jam_value)
132 i = filename.find('.')