22from __future__ import division
33
44import os
5+ import sys
56
67from pwnlib .context import context
78
@@ -109,47 +110,17 @@ def get_context_from_dirpath(directory):
109110 return {'os' : osys , 'arch' : arch }
110111
111112def make_function (funcname , filename , directory ):
113+ import functools
112114 import inspect
113115 path = os .path .join (directory , filename )
114116 template = lookup_template (path )
115117
116- args , varargs , keywords , defaults = inspect .getargspec (template .module .render_body )
117-
118- defaults = defaults or []
119-
120- if len (defaults ) < len (args ) and args [0 ] == 'context' :
121- args .pop (0 )
122-
123- args_used = args [:]
124-
125- for n , default in enumerate (defaults , len (args ) - len (defaults )):
126- args [n ] = '%s = %r' % (args [n ], default )
127-
128- if varargs :
129- args .append ('*' + varargs )
130- args_used .append ('*' + varargs )
131-
132- if keywords not in ['pageargs' , None ]:
133- args .append ('**' + keywords )
134- args_used .append ('**' + keywords )
135-
136- docstring = inspect .cleandoc (template .module .__doc__ or '' )
137- args = ', ' .join (args )
138- args_used = ', ' .join (args_used )
139118 local_ctx = get_context_from_dirpath (directory )
140119
141- # This is a slight hack to get the right signature for the function
142- # It would be possible to simply create an (*args, **kwargs) wrapper,
143- # but what would not have the right signature.
144- # While we are at it, we insert the docstring too
145- T = r'''
146- def wrap(template, render_global):
147- import pwnlib
148- def %(funcname)s(%(args)s):
149- %(docstring)r
120+ def res (* args , ** kwargs ):
150121 with render_global .go_inside () as was_inside :
151- with pwnlib. context.context. local(**%( local_ctx)s ):
152- lines = template.render(%(args_used)s ).split('\n')
122+ with context .local (** local_ctx ):
123+ lines = template .render (* args , ** kwargs ).split ('\n ' )
153124 for i , line in enumerate (lines ):
154125 def islabelchar (c ):
155126 return c .isalnum () or c == '.' or c == '_'
@@ -168,19 +139,16 @@ def islabelchar(c):
168139 return s
169140 else :
170141 return s + '\n '
171- return %(funcname)s
172- ''' % locals ()
173-
174- g = {}
175- exec (T , g , g )
176- wrap = g ['wrap' ]
177142
178143 # Setting _relpath is a slight hack only used to get better documentation
179- res = wrap (template , render_global )
180144 res ._relpath = path
181145 res .__module__ = 'pwnlib.shellcraft.' + os .path .dirname (path ).replace ('/' ,'.' )
182-
183- import sys , functools
146+ res .__name__ = res .__qualname__ = funcname
147+ res .__doc__ = inspect .cleandoc (template .module .__doc__ or '' )
148+ if hasattr (inspect , 'signature' ):
149+ sig = inspect .signature (template .module .render_body )
150+ sig = sig .replace (parameters = list (sig .parameters .values ())[1 :- 1 ])
151+ res .__signature__ = sig
184152
185153 @functools .wraps (res )
186154 def function (* a ):
0 commit comments