home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Multimedia / k3d-setup-0.7.11.0.exe / lib / site-packages / cgkit / GUI / call.py < prev    next >
Encoding:
Python Source  |  2007-01-11  |  5.5 KB  |  163 lines

  1. # ***** BEGIN LICENSE BLOCK *****
  2. # Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. #
  4. # The contents of this file are subject to the Mozilla Public License Version
  5. # 1.1 (the "License"); you may not use this file except in compliance with
  6. # the License. You may obtain a copy of the License at
  7. # http://www.mozilla.org/MPL/
  8. #
  9. # Software distributed under the License is distributed on an "AS IS" basis,
  10. # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. # for the specific language governing rights and limitations under the
  12. # License.
  13. #
  14. # The Original Code is the Python Computer Graphics Kit.
  15. #
  16. # The Initial Developer of the Original Code is Matthias Baas.
  17. # Portions created by the Initial Developer are Copyright (C) 2004
  18. # the Initial Developer. All Rights Reserved.
  19. #
  20. # Contributor(s):
  21. #
  22. # Alternatively, the contents of this file may be used under the terms of
  23. # either the GNU General Public License Version 2 or later (the "GPL"), or
  24. # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  25. # in which case the provisions of the GPL or the LGPL are applicable instead
  26. # of those above. If you wish to allow use of your version of this file only
  27. # under the terms of either the GPL or the LGPL, and not to allow others to
  28. # use your version of this file under the terms of the MPL, indicate your
  29. # decision by deleting the provisions above and replace them with the notice
  30. # and other provisions required by the GPL or the LGPL. If you do not delete
  31. # the provisions above, a recipient may use your version of this file under
  32. # the terms of any one of the MPL, the GPL or the LGPL.
  33. #
  34. # ***** END LICENSE BLOCK *****
  35. # $Id: call.py,v 1.1.1.1 2004/12/12 14:31:33 mbaas Exp $
  36.  
  37. ## \file call.py
  38. ## Contains the Call class.
  39.  
  40. import string, types
  41.  
  42.  
  43. # Call
  44. class Call:
  45.     """Call adapter.
  46.  
  47.     This class can either be used to wrap a string or a callable
  48.     object with a fixed set of arguments (positional and keyword
  49.     arguments).  When the %Call object is called (without any
  50.     arguments) it executes the string or calls the wrapped function
  51.     with the stored arguments.
  52.  
  53.     Objects of this class can be compared using == or != and they're
  54.     hashable (so can be used in dictionaries, etc.)
  55.  
  56.     The purpose of this class is to provide an adapter for GUI commands
  57.     which take no arguments.
  58.  
  59.     Example:
  60.  
  61.     \code
  62.  
  63.     def foo(a, b, c=0):
  64.         print "a:%s  b:%s  c:%s"%(a,b,c)
  65.  
  66.     >>> f = Call(foo, 1, 2, c=3)
  67.     
  68.     # Call foo with the specified arguments
  69.     >>> f()
  70.     a:1  b:2  c:3
  71.     
  72.     # Print a readable description of the command object
  73.     >>> print f
  74.     foo(1, 2, c=3)
  75.  
  76.     \endcode
  77.  
  78.     """
  79.     
  80.     def __init__(self, func, *args, **keyargs):
  81.         """Constructor.
  82.  
  83.         You must provide the callable object as first argument. All
  84.         additional arguments will be passed to the callable object
  85.         when its called.
  86.  
  87.         If \a func is a string then there may be one additional argument
  88.         that specifies a dictionary which should be used as global
  89.         (and local) namespace. The dictionary may be specified as positional
  90.         argument following the string or as keyword argument "globals".
  91.  
  92.         The constructor sets the variable __doc__ to a reasonable value.
  93.         It'll be either the function doc string if there is one or the
  94.         command string itself.
  95.  
  96.         \param func (\c callable or \c str) The function that should be called
  97.         \param *args  The positional arguments (default = no args)
  98.         \param **keyargs  The keyword arguments (default = no keyword args)
  99.         """
  100.         if isinstance(func, types.StringTypes):
  101.             self._func = func
  102.             self._args = None
  103.             self._keyargs = None
  104.             compilestr = func
  105.             if "globals" in keyargs:
  106.                 self._globals = keyargs["globals"]
  107.             elif len(args)==1:
  108.                 self._globals = args[0]
  109.             self.__doc__ = None
  110.         elif callable(func):
  111.             self._func = func
  112.             self._args = args
  113.             self._keyargs = keyargs
  114.             compilestr = "apply(self._func, self._args, self._keyargs)"
  115.             self.__doc__ = getattr(func, "__doc__", None)
  116.         else:
  117.             raise TypeError, "The 'func' argument must be a string or a callable object."
  118.  
  119.         self._code = compile(compilestr, "<command: '%s'>"%str(self), "exec")
  120.         if self.__doc__==None or self.__doc__=="":
  121.             self.__doc__ = str(self)
  122.  
  123.     def __str__(self):
  124.         if callable(self._func):
  125.             res = getattr(self._func, "__name__", "<unknown>")
  126.             args = map(lambda x: str(x), self._args)
  127.             args += map(lambda x: "%s=%s"%(x,self._keyargs[x]), self._keyargs)
  128.             res = "%s(%s)"%(res,string.join(args,", "))
  129.         else:
  130.             res = self._func
  131.         return res
  132.  
  133.     def __repr__(self):
  134.         return "<Call cmd='%s'>"%str(self)
  135.  
  136.     def __call__(self):
  137.         if hasattr(self, "_globals"):
  138.             exec self._code in self._globals
  139.         else:
  140.             exec self._code
  141.  
  142.     def __eq__(self, other):
  143.         if not isinstance(other, Call):
  144.             return False
  145.  
  146.         return (self._func==other._func and
  147.                 self._args==other._args and
  148.                 self._keyargs==other._keyargs)
  149.  
  150.     def __ne__(self, other):
  151.         if not isinstance(other, Call):
  152.             return True
  153.  
  154.         return (self._func!=other._func or
  155.                 self._args!=other._args or
  156.                 self._keyargs!=other._keyargs)
  157.  
  158.     def __hash__(self):
  159.         return hash(self._code)
  160. #        return hash(self._func) ^ hash(self._args)
  161.  
  162.  
  163.