def pyname(self): "Returns a Pythonized name for this mapping" if self._pyname: return self._pyname return util.pyname(self.name)
def pycall(self, pars=(), keys=()): """ Returns a string containing the Python statement or expression code for a call to the subroutine. pars is a sequence of strings, each of which is the Pythonized value of a parameter argument to the subroutine. keys is a sequence of sequences, each of which contains two strings. The strings are the Pythonized name and value of a keyword argument to the subroutine. """ # Make copies of the parameter and keyword lists pars = tuple(pars) keys = tuple(keys) # Verify number of parameters npars = len(pars) nrequired = self.npars - self.noptional if npars > self.npars: raise Error(("subroutine '%s' takes at most %d parameters " + "(called with %d)") % (self.name, self.npars, npars)) if npars < nrequired: raise Error(("subroutine '%s' requires at least %d " + "parameters (called with %d)") % (self.name, nrequired, npars)) # # Handle the parameter arguments # # Required input parameters input = ([ pars[i] for i in range(min(nrequired, npars)) if i+1 in self.inpars ]) # Optional input parameters if npars > nrequired: for i in range(nrequired, npars): if i+1 in self.inpars: # Real optional input parameter input.append(pars[i]) elif i+1 in self.outpars: # Flag to indicate that an optional output parameter should be # returned input.append('True') # Output parameters output = [ pars[i] for i in range(npars) if i+1 in self.outpars ] # # Handle the keyword arguments # for (name, value) in keys: uc_name = name.upper() # Try to find a match for the keyword. This is complicated by the # fact that, in IDL, keyword names can be abbreviated as long as they # can still be uniquely identified. matches = [ k for k in self.allkeys if k.startswith(uc_name) ] if len(matches) == 0: # No matches; throw an error raise Error("'%s' is not a valid keyword for subroutine '%s'" % (name, self.name)) elif len(matches) == 1: # Only one match; good uc_name = matches[0] elif uc_name not in matches: # Multiple matches; unless one of the matches is exactly what we # want (i.e. the keyword is a prefix of one or more others), throw # an error raise Error(("identifier '%s' matches multiple keywords " + "for subroutine '%s': %s") % (name, self.name, matches)) # Pythonize the full name name = util.pyname(uc_name) if uc_name in self.inkeys: # Input keyword input.append('%s=%s' % (name, value)) if uc_name in self.outkeys: # Output keyword if uc_name not in self.inkeys: # If the keyword is output only, we need to flag that the value # should be returned input.append('%s=True' % name) output.append(value) # Add any needed extra code add_extra_code(self.extracode) # If there's a custom callfunc, use it to generate the call code if self.callfunc: return self.callfunc(input, output) # Build the input and output strings input = ', '.join(input) if output: output = ', '.join(output) + ' = ' else: output = '' # Return the call code return '%s%s(%s)' % (output, self.pyname(), input)