예제 #1
0
    def register(self, func, name=None, nArgs=None, moduleName=None):
        name = name or func.__name__
        if name in self._functions:
            self.debug('Registering new functionality for already known '
                       'function named %r.' % name)

        moduleName = moduleName or 'calculator-registered-method'
        nArgs = countArgs(func, 1) if nArgs is None else nArgs
        self._functions[name] = Function(moduleName, name, func, nArgs)
예제 #2
0
    def importCallables(self, module):
        moduleName = module.__name__
        exec('import ' + moduleName, globals(), self._variables)
        callables = inspect.getmembers(module, callable)

        for name, func in callables:
            if name.startswith('_'):
                continue

            try:
                if issubclass(func, BaseException):
                    continue
            except TypeError:
                pass

            nArgs = countArgs(func)

            if nArgs is None:
                continue

            path = '%s.%s' % (moduleName, name)

            if path in self.OVERRIDES:
                self.debug('Not importing %r' % path)
                continue

            if path in self._functions:
                if path not in ('decimal.Decimal', 'builtins.float'):
                    self.err('Function %r already exists' % path)
            else:
                # Add the function to our functions dict along with a
                # default number of positional parameters it expects. This
                # allows the user to call it and have the arguments taken
                # from the stack (the number of arguments used can always
                # be specified on the command line (e.g., :3)
                exec('self._functions["%s"] = Function("%s", "%s", %s, %d)' %
                     (path, moduleName, name, path, nArgs))

            # Import the function by name to allow the user to use it in a
            # command with an explicit argument, instead of applying it to
            # whatever is on the stack.
            if name in self._variables:
                self.debug('name %s already defined! Ignoring %s' %
                           (name, path))
            else:
                exec('from %s import %s' % (moduleName, name), globals(),
                     self._variables)
                if name not in self._variables:
                    self.err('name %s not now defined!!!' % name)
                assert name not in self._functions
                self._functions[name] = self._functions[path]
예제 #3
0
    def _tryVariable(self, command, modifiers, count):
        if modifiers.forceCommand:
            return False, self.NO_VALUE

        if command in self._variables:
            self.debug('%r is a variable (value %r)' %
                       (command, self._variables[command]))
            value = self._variables[command]
            if callable(value):
                if not modifiers.push:
                    return self._runFunction(
                        command, modifiers, count,
                        Function('<stdin>', value.__name__, value,
                                 countArgs(value, 1)))
            else:
                if modifiers.push:
                    value = Variable(command, self._variables)
            if count is None:
                count = 1
            self._finalize([value] * count, modifiers, extend=True)
            return True, value
        else:
            self.debug('%r is not a variable' % command)
            return False, self.NO_VALUE
예제 #4
0
 def testZero(self):
     "A function that takes zero arguments must be processed correctly"
     self.assertEqual(0, countArgs(lambda: 3))
예제 #5
0
 def testLogWithDefault(self):
     """The signature of math.log can't be inspected (at least in Python
        3.7). Pass a default value."""
     self.assertEqual(3, countArgs(log, 3))
예제 #6
0
 def testLog(self):
     "The signature of math.log can't be inspected (at least in Python 3.7)"
     self.assertEqual(None, countArgs(log))
예제 #7
0
 def testTwo(self):
     "A function that takes two arguments must be processed correctly"
     self.assertEqual(2, countArgs(lambda x, y: 3))
예제 #8
0
 def testOne(self):
     "A function that takes one argument must be processed correctly"
     self.assertEqual(1, countArgs(lambda x: 3))
예제 #9
0
 def defaultArgCount(func):
     return countArgs(func, 1)