This commit is contained in:
Thomas Nagy 2016-11-26 11:51:20 +01:00
parent ac55bf5bf7
commit 1318c5f2d6
No known key found for this signature in database
GPG Key ID: 49B4C67C05277AAA
3 changed files with 92 additions and 10 deletions

82
tests/general/wscript Normal file
View File

@ -0,0 +1,82 @@
#! /usr/bin/env python
# encoding: utf-8
# Thomas Nagy, 2016 (ita)
top = '.'
out = 'build'
import functools
from waflib import Utils, Logs
def configure(conf):
pass
def fun1():
return 0
def fun2(arg1, arg2):
return 1
def fun(arg1, arg2, task, one=1, two=2):
print(arg1, arg2, task, one, two)
par1 = functools.partial(fun, 'arg1')
par2 = functools.partial(par1, 'arg2', one=11, two=22)
def fun3():
return 32
par3 = functools.partial(par1, 'arg2', one=11, two=22)
def build(bld):
bld.failure = 0
def disp(color, result):
Logs.pprint(color, result)
if color == 'RED':
bld.failure=1
def stop_status(bld):
if bld.failure:
bld.fatal('One or several test failed, check the outputs above')
bld.add_post_fun(stop_status)
def simple_hash(fun):
status = ''
try:
Utils.h_cmd(fun)
except Exception as e:
status = str(e)
return status
def hash_test(name, fun):
ret = simple_hash(fun)
if not ret:
color = "GREEN"
else:
color = "RED"
ret = ret or 'ok'
disp(color, '%s\t\t%s' % (name, ret))
hash_test('simple function 1', fun1)
hash_test('simple function 2', fun1)
hash_test('simple partial', par1)
hash_test('nested partial', par2)
def hash_twice(name, fun):
try:
ret1 = Utils.h_cmd(fun)
ret2 = Utils.h_cmd(fun)
except Exception as e:
msg = str(e)
color = 'RED'
else:
if ret1 == ret2:
msg = 'ok %r' % ret1
color = 'GREEN'
else:
msg = '%r != %r' % (ret1, ret2)
color = 'RED'
disp(color, '%s\t\t%s' % (name, msg))
hash_twice('consistent on fun3', fun3)
hash_twice('consistent on par3', par3)

View File

@ -10,8 +10,7 @@ The instances can have various parameters, but the creation of task nodes (Task.
is deferred. To achieve this, various methods are called from the method "apply"
"""
import copy, re, os
from functools import partial
import copy, re, os, functools
from waflib import Task, Utils, Logs, Errors, ConfigSet, Node
feats = Utils.defaultdict(set)
@ -635,11 +634,11 @@ def process_rule(self):
if getattr(self, 'cwd', None):
tsk.cwd = self.cwd
if type(tsk.run) is partial:
if type(tsk.run) is functools.partial:
# Python documentation says: "partial objects defined in classes
# behave like static methods and do not transform into bound
# methods during instance attribute look-up."
tsk.run = partial(tsk.run, tsk)
tsk.run = functools.partial(tsk.run, tsk)
@feature('seq')

View File

@ -9,8 +9,7 @@ The portability fixes try to provide a consistent behavior of the Waf API
through Python versions 2.5 to 3.X and across different platforms (win32, linux, etc)
"""
import os, sys, errno, traceback, inspect, re, datetime, platform, base64, signal
import functools
import os, sys, errno, traceback, inspect, re, datetime, platform, base64, signal, functools
try:
import cPickle
@ -581,6 +580,12 @@ def h_fun(fun):
try:
return fun.code
except AttributeError:
if isinstance(fun, functools.partial):
code = list(fun.args)
code.extend(fun.keywords.items())
code.append(h_fun(fun.func))
fun.code = h_list(code)
return fun.code
try:
h = inspect.getsource(fun)
except EnvironmentError:
@ -606,10 +611,6 @@ def h_cmd(ins):
elif isinstance(ins, list) or isinstance(ins, tuple):
# or a list of functions/strings
ret = str([h_cmd(x) for x in ins])
elif isinstance(ins, functools.partial):
ret = str([h_list(ins.args),
h_list(tuple(ins.keywords.items())),
h_fun(ins.func)])
else:
# or just a python function
ret = str(h_fun(ins))