def getPythonPath(obj):
    """Return the path of the object in standard Python notation.

    This method should try very hard to return a string, even if it is not a
    valid Python path.
    """
    if obj is None:
        return None

    # Even for methods `im_class` and `__module__` is not allowed to be
    # accessed (which is probably not a bad idea). So, we remove the security
    # proxies for this check.
    naked = removeSecurityProxy(obj)
    qname = ''
    if isinstance(getattr(naked, '__qualname__', None), str):
        # Python 3 (being sure to protect against non-str __qualname__
        # that we could get on some versions of Cython. See
        # https://github.com/zopefoundation/zope.app.apidoc/issues/25).
        # This makes unbound functions inside classes do the same
        # thing as they do an Python 2: return just their class name.
        qname = naked.__qualname__
        qname = qname.split('.')[0]
    if hasattr(naked, 'im_class'):
        # Python 2, unbound methods
        naked = naked.im_class
    if isinstance(naked, types.MethodType):
        naked = type(naked.__self__)
    module = getattr(naked, '__module__', _marker)
    if module is _marker:
        return naked.__name__
    return '%s.%s' %(module, qname or naked.__name__)
def renderText(text, module=None, format=None, dedent=True):
    # dedent is ignored, we always dedent
    if not text:
        return u''

    if module is not None:
        if isinstance(module, six.string_types):
            module = sys.modules.get(module, None)
        if format is None:
            format = getDocFormat(module)

    if format is None:
        format = 'zope.source.rest'

    assert format in _format_dict.values()

    if isinstance(text, bytes):
        text = text.decode('utf-8', 'replace')

    try:
        text = dedentString(text)
    except TypeError as e:
        return u'Failed to render non-text (%r): %s' % (text, e,)

    source = createObject(format, text)

    renderer = getMultiAdapter((source, TestRequest()))
    return renderer.render()
 def getMenuLink(self, node):
     """Return the HTML link of the node that is displayed in the menu."""
     obj = node.context
     apidoc_url = findAPIDocumentationRootURL(self.context, self.request)
     if isinstance(obj, Utility):
         iface = getParent(obj)
         return '%s/Utility/%s/%s/index.html' % (apidoc_url, getName(iface), getName(obj))
     if isinstance(obj, UtilityInterface):
         return '%s/Interface/%s/index.html' % (apidoc_url, getName(obj))
Beispiel #4
0
    def testCorrectFactories(self):
        path = os.path.join(test_directory, 'testfiles')
        request = TestRequest()
        resource = DirectoryResourceFactory(path, checker, 'files')(request)

        image = resource['test.gif']
        self.assert_(proxy.isinstance(image, FileResource))
        template = resource['test.pt']
        self.assert_(proxy.isinstance(template, PageTemplateResource))
        file = resource['test.txt']
        self.assert_(proxy.isinstance(file, FileResource))
        file = resource['png']
        self.assert_(proxy.isinstance(file, FileResource))
def _simpleGetFunctionSignature(func, ignore_self=False):
    """Return the signature of a function or method."""
    _checkFunctionType(func)

    try:
        args, varargs, varkw, defaults = inspect.getargspec(func)
    except TypeError:
        # On Python 2, inspect.getargspec can't handle certain types
        # of callable things, like object.__init__ (<slot wrapper '__init__'> is not
        # a python function), but it *can* handle them on Python 3.
        # Punt on Python 2
        return '(<unknown>)'

    placeholder = object()
    sig = '('
    # By filling up the default tuple, we now have equal indeces for args and
    # default.
    if defaults is not None:
        defaults = (placeholder,) * (len(args) - len(defaults)) + defaults
    else:
        defaults = (placeholder,) * len(args)

    str_args = []

    for name, default in zip(args, defaults):
        # Neglect self, since it is always there and not part of the signature.
        # This way the implementation and interface signatures should match.
        if name == 'self' and (isinstance(func, types.MethodType) or ignore_self):
            # NOTE: this is actually covered, and removing the condition will break
            # tests. The coverage report doesn't show it, though, for some reason.
            continue # pragma: no cover

        # Make sure the name is a string
        if isinstance(name, (tuple, list)):
            name = '(' + ', '.join(name) + ')'
        elif not isinstance(name, str): # pragma: no cover
            name = repr(name)

        if default is placeholder:
            str_args.append(name)
        else:
            str_args.append(name + '=' + repr(default))

    if varargs:
        str_args.append('*' + varargs)
    if varkw:
        str_args.append('**' + varkw)

    sig += ', '.join(str_args)
    return sig + ')'
Beispiel #6
0
    def attributes(self):
        context = removeSecurityProxy(self.context)
        attrs = [{'name': (ns and context.prefixes[ns]+':' or '') + name,
                  'value': value, 'url': None, 'values': []}
                 for (ns, name), value in context.attrs.items()]

        names = context.schema.names(True)
        rootURL = absoluteURL(findDocModule(self), self.request)
        for attr in attrs:
            name = (attr['name'] in names) and attr['name'] or attr['name']+'_'
            field = context.schema.get(name)

            if isinstance(field, (GlobalObject, GlobalInterface)):
                attr['url'] = self.objectURL(attr['value'], field, rootURL)

            elif isinstance(field, Tokens):
                field = field.value_type
                values = attr['value'].strip().split()
                if len(values) == 1:
                    attr['value'] = values[0]
                    attr['url'] = self.objectURL(values[0], field, rootURL)
                else:
                    for value in values:
                        if isinstance(field,
                                           (GlobalObject, GlobalInterface)):
                            url = self.objectURL(value, field, rootURL)
                        else:
                            break
                        attr['values'].append({'value': value, 'url': url})

        # Make sure that the attributes are in the same order they are defined
        # in the schema.
        fieldNames = getFieldNamesInOrder(context.schema)
        fieldNames = [name.endswith('_') and name[:-1] or name
                      for name in fieldNames]
        attrs.sort(lambda x, y: _compareAttrs(x, y, fieldNames))

        if not IRootDirective.providedBy(context):
            return attrs

        xmlns = []
        for uri, prefix in context.prefixes.items():
            name = prefix and ':'+prefix or ''
            xmlns.append({'name': 'xmlns'+name,
                          'value': uri,
                          'url': None,
                          'values': []})

        xmlns.sort(lambda x, y: cmp(x['name'], y['name']))
        return xmlns + attrs
    def setBody(self, body):
        """Sets the body of the response"""
        # A SOAP view can return a Fault directly to indicate an error.
        if isinstance(body, Fault):
            self._error = body

        if not self._error:
            try:
                target = self._request._target
                body = premarshal(body)
                output = StringIO()
                result = body

                if hasattr(result, 'typecode'):
                    tc = result.typecode
                else:
                    tc = TC.Any(aslist=1, pname=target + 'Response')
                    result = [result]

                SoapWriter(output).serialize(result, tc)
                output.seek(0)

                if not self._status_set:
                    self.setStatus(200)
                self.setHeader('content-type', 'text/xml')
                self._body = output.read()
                self._updateContentLength()
                return

            except Exception, e:
                self._error = ZSI.FaultFromException(e, 0)
Beispiel #8
0
    def setResult(self, result):
        """Sets the result of the response

        Sets the return body equal to the (string) argument "body". Also
        updates the "content-length" return header.

        If the body is a 2-element tuple, then it will be treated
        as (title,body)

        If is_error is true then the HTML will be formatted as a Zope error
        message instead of a generic HTML page.
        """
        body = premarshal(result)
        if isinstance(body, xmlrpclib.Fault):
            # Convert Fault object to XML-RPC response.
            body = xmlrpclib.dumps(body, methodresponse=True)
        else:
            # Marshall our body as an XML-RPC response. Strings will be sent
            # as strings, integers as integers, etc.  We do *not* convert
            # everything to a string first.
            try:
                body = xmlrpclib.dumps((body,), methodresponse=True,
                                       allow_none=True)
            except:
                # We really want to catch all exceptions at this point!
                self.handleException(sys.exc_info())
                return

        headers = [('content-type', 'text/xml;charset=utf-8'),
                   ('content-length', str(len(body)))]
        self._headers.update(dict((k, [v]) for (k, v) in headers))
        super(XMLRPCResponse, self).setResult(DirectResult((body,)))
Beispiel #9
0
    def setResult(self, result):
        """Sets the result of the response

        Sets the return body equal to the (string) argument "body". Also
        updates the "content-length" return header.

        If the body is a 2-element tuple, then it will be treated
        as (title,body)

        If is_error is true then the HTML will be formatted as a Zope error
        message instead of a generic HTML page.
        """
        body = premarshal(result)
        if isinstance(body, xmlrpclib.Fault):
            # Convert Fault object to XML-RPC response.
            body = xmlrpclib.dumps(body, methodresponse=True)
        else:
            # Marshall our body as an XML-RPC response. Strings will be sent
            # as strings, integers as integers, etc.  We do *not* convert
            # everything to a string first.
            try:
                body = xmlrpclib.dumps((body,), methodresponse=True,
                                       allow_none=True)
            except:
                # We really want to catch all exceptions at this point!
                self.handleException(sys.exc_info())
                return

        super(XMLRPCResponse, self).setResult(
            DirectResult((body,),
                         [('content-type', 'text/xml;charset=utf-8'),
                          ('content-length', str(len(body)))])
            )
Beispiel #10
0
 def getMenuTitle(self, node):
     """Return the title of the node that is displayed in the menu."""
     if isinstance(node.context, TypeInterface):
         iface = node.context.interface
     else:
         iface = node.context
     # Interfaces have no security declarations, so we have to unwrap.
     return removeSecurityProxy(iface).getName()
 def getMenuTitle(self, node):
     """Return the title of the node that is displayed in the menu."""
     obj = node.context
     if isinstance(obj, UtilityInterface):
         return getName(obj).split('.')[-1]
     if obj.name == NONAME:
         return 'no name'
     return obj.name
Beispiel #12
0
 def getMenuTitle(self, node):
     """Return the title of the node that is displayed in the menu."""
     obj = node.context
     if isinstance(obj, Namespace):
         name = obj.getShortName()
         if name == 'ALL':
             return 'All Namespaces'
         return name
     return getName(obj)
Beispiel #13
0
 def getMenuLink(self, node):
     """Return the HTML link of the node that is displayed in the menu."""
     obj = node.context
     if isinstance(obj, Directive):
         ns = getParent(obj)
         apidoc_url = findAPIDocumentationRootURL(self.context, self.request)
         return '%s/ZCML/%s/%s/index.html' % (
             apidoc_url, getName(ns), getName(obj))
     return None
Beispiel #14
0
def handle_class(dotted_path, ob=None):
    """Determine, whether the given path/obj references a Python class.
    """
    if ob is None:
        try:
            ob = resolve(dotted_path)
        except ImportError:
            return None
    if not isinstance(ob, (types.ClassType, type)):
        return None
    return DocGrokClass(dotted_path)
Beispiel #15
0
def handle_interface(dotted_path, ob=None):
    """Determine, whether the given path/obj references an interface.
    """
    if ob is None:
        try:
            ob = resolve(dotted_path)
        except ImportError:
            return None
    if not isinstance(removeAllProxies(ob), InterfaceClass):
        return None
    return DocGrokInterface(dotted_path)
Beispiel #16
0
    def handleException(self, exc_info):
        """Handle Errors during publsihing and wrap it in XML-RPC XML

        >>> import sys
        >>> resp = XMLRPCResponse()
        >>> try:
        ...     raise AttributeError('xyz')
        ... except:
        ...     exc_info = sys.exc_info()
        ...     resp.handleException(exc_info)

        >>> resp.getStatusString()
        '200 Ok'
        >>> resp.getHeader('content-type')
        'text/xml;charset=utf-8'
        >>> body = ''.join(resp.consumeBody())
        >>> 'Unexpected Zope exception: AttributeError: xyz' in body
        True
        """
        t, value = exc_info[:2]
        s = '%s: %s' % (getattr(t, '__name__', t), value)

        # Create an appropriate Fault object. Unfortunately, we throw away
        # most of the debugging information. More useful error reporting is
        # left as an exercise for the reader.
        Fault = xmlrpclib.Fault
        fault_text = None
        try:
            if isinstance(value, Fault):
                fault_text = value
            elif isinstance(value, Exception):
                fault_text = Fault(-1, "Unexpected Zope exception: " + s)
            else:
                fault_text = Fault(-2, "Unexpected Zope error value: " + s)
        except:
            fault_text = Fault(-3, "Unknown Zope fault type")

        # Do the damage.
        self.setResult(fault_text)
        # XML-RPC prefers a status of 200 ("ok") even when reporting errors.
        self.setStatus(200)
Beispiel #17
0
    def handleException(self, exc_info):
        """Handle Errors during publsihing and wrap it in XML-RPC XML

        >>> import sys
        >>> resp = XMLRPCResponse()
        >>> try:
        ...     raise AttributeError('xyz')
        ... except:
        ...     exc_info = sys.exc_info()
        ...     resp.handleException(exc_info)

        >>> resp.getStatusString()
        '200 OK'
        >>> resp.getHeader('content-type')
        'text/xml;charset=utf-8'
        >>> body = ''.join(resp.consumeBody())
        >>> 'Unexpected Zope exception: AttributeError: xyz' in body
        True
        """
        t, value = exc_info[:2]
        s = '%s: %s' % (getattr(t, '__name__', t), value)

        # Create an appropriate Fault object. Unfortunately, we throw away
        # most of the debugging information. More useful error reporting is
        # left as an exercise for the reader.
        Fault = xmlrpclib.Fault
        fault_text = None
        try:
            if isinstance(value, Fault):
                fault_text = value
            elif isinstance(value, Exception):
                fault_text = Fault(-1, "Unexpected Zope exception: " + s)
            else:
                fault_text = Fault(-2, "Unexpected Zope error value: " + s)
        except:
            fault_text = Fault(-3, "Unknown Zope fault type")

        # Do the damage.
        self.setResult(fault_text)
        # XML-RPC prefers a status of 200 ("ok") even when reporting errors.
        self.setStatus(200)
Beispiel #18
0
def getFunctionSignature(func):
    """Return the signature of a function or method."""
    if not isinstance(func, (types.FunctionType, types.MethodType)):
        raise TypeError("func must be a function or method")

    args, varargs, varkw, defaults = inspect.getargspec(func)
    placeholder = object()
    sig = '('
    # By filling up the default tuple, we now have equal indeces for args and
    # default.
    if defaults is not None:
        defaults = (placeholder,)*(len(args)-len(defaults)) + defaults
    else:
        defaults = (placeholder,)*len(args)

    str_args = []

    for name, default in zip(args, defaults):
        # Neglect self, since it is always there and not part of the signature.
        # This way the implementation and interface signatures should match.
        if name == 'self' and type(func) == types.MethodType:
            continue

        # Make sure the name is a string
        if isinstance(name, (tuple, list)):
            name = '(' + ', '.join(name) + ')'
        elif not isinstance(name, str):
            name = repr(name)

        if default is placeholder:
            str_args.append(name)
        else:
            str_args.append(name + '=' + repr(default))

    if varargs:
        str_args.append('*'+varargs)
    if varkw:
        str_args.append('**'+varkw)

    sig += ', '.join(str_args)
    return sig + ')'
Beispiel #19
0
 def getFileInfo(self):
     """Get the file where the directive was declared."""
     # ZCML directive `info` objects do not have security declarations, so
     # everything is forbidden by default. We need to remove the security
     # proxies in order to get to the data.
     info = removeSecurityProxy(self.context.info)
     if isinstance(info, ParserInfo):
         return {'file': relativizePath(info.file),
                 'line': info.line,
                 'column': info.column,
                 'eline': info.eline,
                 'ecolumn': info.ecolumn}
     return None
Beispiel #20
0
    def testFactory(self):
        f = configfile('''
<permission id="zope.Foo" title="Zope Foo Permission" />
<class class="zope.security.tests.exampleclass.ExampleClass">
    <factory
      id="test.Example"
      title="Example content"
      description="Example description"
       />
</class>''')
        xmlconfig(f)
        obj = zope.component.createObject('test.Example')
        self.failUnless(proxy.isinstance(obj, exampleclass.ExampleClass))
    def testFactory(self):
        f = configfile('''
<permission id="zope.Foo" title="Zope Foo Permission" />
<class class="zope.security.tests.exampleclass.ExampleClass">
    <factory
      id="test.Example"
      title="Example content"
      description="Example description"
       />
</class>''')
        xmlconfig(f)
        obj = zope.component.createObject('test.Example')
        self.failUnless(proxy.isinstance(obj, exampleclass.ExampleClass))
Beispiel #22
0
    def setResult(self, result):
        """Sets the result of the response

        Sets the return body equal to the (string) argument "body". Also
        updates the "content-length" return header.

        If the body is a 2-element tuple, then it will be treated
        as (title,body)

        If is_error is true then the HTML will be formatted as a Zope error
        message instead of a generic HTML page.
        """
        body = premarshal(result)
        if isinstance(body, xmlrpclib.Fault):
            # Convert Fault object to XML-RPC response.
            body = xmlrpclib.dumps(body, methodresponse=True)
        else:
            # Marshall our body as an XML-RPC response. Strings will be sent
            # as strings, integers as integers, etc.  We do *not* convert
            # everything to a string first.
            try:
                body = xmlrpclib.dumps((body,), methodresponse=True,
                                       allow_none=True)
            except:
                # We really want to catch all exceptions at this point!
                self.handleException(sys.exc_info())
                return

        # HTTP response payloads are byte strings, and methods like
        # consumeBody rely on that, but xmlrpc.client.dumps produces
        # native strings, which is incorrect on Python 3.
        if not isinstance(body, bytes):
            body = body.encode('utf-8')

        headers = [('content-type', 'text/xml;charset=utf-8'),
                   ('content-length', str(len(body)))]
        self._headers.update(dict((k, [v]) for (k, v) in headers))
        super(XMLRPCResponse, self).setResult(DirectResult((body,)))
    def testPluggableFactories(self):
        path = os.path.join(test_directory, 'testfiles')
        request = TestRequest()
        resource = DirectoryResourceFactory(path, checker, 'files')(request)

        class ImageResource(object):
            def __init__(self, image, request):
                pass

        class ImageResourceFactory(object):
            def __init__(self, path, checker, name):
                pass
            def __call__(self, request):
                return ImageResource(None, request)

        from zope.browserresource.interfaces import IResourceFactoryFactory
        provideUtility(ImageResourceFactory, IResourceFactoryFactory, 'gif')

        image = resource['test.gif']
        self.assertTrue(proxy.isinstance(image, ImageResource))

        file = resource['test.txt']
        self.assertTrue(proxy.isinstance(file, FileResource))
 def handleException(self, exc_info):
     """Handle exceptions that occur during processing."""
     type, value = exc_info[:2]
     content = "".join(traceback.format_tb(exc_info[-1]))
     if IUnauthorized.providedBy(value):
         self.setStatus(401)
         self.setBody("")
         #XXXself._body = ""
         #self._updateContentLength()
         return
     if not isinstance(value, Fault):
         value = ZSI.FaultFromException(u"%s : %s" % (value, content), 0)
     self.setStatus(500)
     self.setBody(value)
Beispiel #25
0
def renderText(text, module=None, format=None, dedent=True):
    if not text:
        return u''

    if module is not None:
        if isinstance(module, (str, unicode)):
            module = sys.modules.get(module, None)
        if format is None:
            format = getDocFormat(module)

    if format is None:
        format = 'zope.source.rest'

    assert format in _format_dict.values()

    text = dedentString(text)

    if not isinstance(text, unicode):
        text = text.decode('latin-1', 'replace')
    source = createObject(format, text)

    renderer = getMultiAdapter((source, TestRequest()))
    return renderer.render()
    def testPluggableFactories(self):
        path = os.path.join(test_directory, 'testfiles')
        request = TestRequest()
        resource = DirectoryResourceFactory(path, checker, 'files')(request)

        class ImageResource(object):
            def __init__(self, image, request):
                pass

        class ImageResourceFactory(object):
            def __init__(self, path, checker, name):
                pass

            def __call__(self, request):
                return ImageResource(None, request)

        from zope.browserresource.interfaces import IResourceFactoryFactory
        provideUtility(ImageResourceFactory, IResourceFactoryFactory, 'gif')

        image = resource['test.gif']
        self.assertTrue(proxy.isinstance(image, ImageResource))

        file = resource['test.txt']
        self.assertTrue(proxy.isinstance(file, FileResource))
 def testURL3Level(self):
     request = TestRequest()
     request._vh_root = support.site
     ob.__parent__ = support.site
     ob.__name__ = 'ob'
     path = os.path.join(test_directory, 'testfiles')
     files = DirectoryResourceFactory(path, checker, 'test_files')(request)
     files.__parent__ = ob
     file = files['test.gif']
     self.assertEqual(file(), 'http://127.0.0.1/@@/test_files/test.gif')
     subdir = files['subdir']
     self.assertTrue(proxy.isinstance(subdir, DirectoryResource))
     file = subdir['test.gif']
     self.assertEqual(file(),
                      'http://127.0.0.1/@@/test_files/subdir/test.gif')
 def testURL3Level(self):
     request = TestRequest()
     request._vh_root = support.site
     ob.__parent__ = support.site
     ob.__name__ = 'ob'
     path = os.path.join(test_directory, 'testfiles')
     files = DirectoryResourceFactory(path, checker, 'test_files')(request)
     files.__parent__ = ob
     file = files['test.gif']
     self.assertEqual(file(), 'http://127.0.0.1/@@/test_files/test.gif')
     subdir = files['subdir']
     self.assertTrue(proxy.isinstance(subdir, DirectoryResource))
     file = subdir['test.gif']
     self.assertEqual(file(),
                       'http://127.0.0.1/@@/test_files/subdir/test.gif')
    def testFactory(self):
        from zope.component import createObject
        from zope.configuration.xmlconfig import xmlconfig
        from zope.security import proxy
        from zope.security.tests import exampleclass
        self.meta()
        f = configfile('''
<permission id="zope.Foo" title="Zope Foo Permission" />
<class class="zope.security.tests.exampleclass.ExampleClass">
    <factory
      id="test.Example"
      title="Example content"
      description="Example description"
       />
</class>''')
        xmlconfig(f)
        obj = createObject('test.Example')
        self.assertTrue(proxy.isinstance(obj, exampleclass.ExampleClass))
Beispiel #30
0
    def _prepareResult(self, result):
        # we've asked json to return unicode; result should be unicode
        encoding = getCharsetUsingRequest(self._request) or 'utf-8'
        enc = encoding.lower()
        if not enc in interfaces.JSON_CHARSETS:
            encoding = 'utf-8'
        # encode outgoing boundary.
        if isinstance(result, unicode):
            body = result.encode(encoding)
            charset = encoding
        else:
            # something's wrong. JSON did not return unicode.
            raise TypeError("JSON did not return unicode (%s)" % type(result))

        # set content type
        self.setHeader('content-type', "application/x-javascript;charset=%s"
                       % charset)
        return body
    def testFactory(self):
        from zope.component import createObject
        from zope.configuration.xmlconfig import xmlconfig
        from zope.security import proxy
        from zope.security.tests import exampleclass
        self.meta()
        f = configfile('''
<permission id="zope.Foo" title="Zope Foo Permission" />
<class class="zope.security.tests.exampleclass.ExampleClass">
    <factory
      id="test.Example"
      title="Example content"
      description="Example description"
       />
</class>''')
        xmlconfig(f)
        obj = createObject('test.Example')
        self.assertTrue(proxy.isinstance(obj, exampleclass.ExampleClass))
Beispiel #32
0
def getPythonPath(obj):
    """Return the path of the object in standard Python notation.

    This method should try very hard to return a string, even if it is not a
    valid Python path.
    """
    if obj is None:
        return None

    # Even for methods `im_class` and `__module__` is not allowed to be
    # accessed (which is probably not a bad idea). So, we remove the security
    # proxies for this check.
    naked = removeSecurityProxy(obj)
    name = naked.__name__
    if hasattr(naked, "im_class"):
        naked = naked.im_class
        name = naked.__name__
    # Py3 version:
    if PY3 and isinstance(naked, types.FunctionType):
        name = naked.__qualname__.split('.')[0]
    module = getattr(naked, '__module__', _marker)
    if module is _marker:
        return name
    return '%s.%s' %(module, name)
Beispiel #33
0
def _evalId(id):
    if isinstance(id, Global):
        id = id.__name__
        if id == 'CheckerPublic':
            id = 'zope.Public'
    return id
Beispiel #34
0
    def processInputs(self):
        """take the converted request and make useful args of it."""
        json = zope.component.getUtility(IJSONReader)
        stream = self._body_instream
        input = []
        incoming = stream.read(1000)
        while incoming:
            input.append(incoming)
            incoming = stream.read(1000)
        input = ''.join(input)
        # ensure unicode
        if not isinstance(input, unicode):
            input = self._decode(input)
        try:
            data = json.read(input)
        except:
            # catch any error since we don't know which library is used as
            # parser
            raise exception.ParseError
        # get the params
        params = data.get('params', [])
        if self.jsonId is None:
            self.jsonId = data.get('id', self._jsonId)

        # get the json version. The version 1.0 offers no version argument.
        # The version 1.1 offers a version key and since version 2.0 the
        # version is given with the ``jsonrpc`` key. Let's try to find the
        # version for our request.
        self.jsonVersion = data.get('version', self.jsonVersion)
        self.jsonVersion = data.get('jsonrpc', self.jsonVersion)
        if self.jsonVersion in ['1.0', '1.1', '2.0']:
            # json-rpc 1.0 and 1.1
            if isinstance(params, list):
                args = params
                # version 1.0 and 1.1 uses a list of arguments
                for arg in args:
                    if isinstance(arg, dict):
                        # set every dict key value as form items and support at
                        # least ``:list`` and ``:tuple`` input field name postifx
                        # conversion.
                        for key, d in arg.items():
                            key = str(key)
                            pos = key.rfind(":")
                            if pos > 0:
                                match = self._typeFormat.match(key, pos + 1)
                                if match is not None:
                                    key, type_name = key[:pos], key[pos + 1:]
                                    if type_name == 'list' and not isinstance(d, list):
                                        d = [d]
                                    if type_name == 'tuple' and not isinstance(d, tuple):
                                        d = tuple(d)
                            self.form[key] = d
            elif isinstance(params, dict):
                # process the key/value pair params. This arguments get stored
                # in the request.form argument and we skip it from method calls.
                # This means this library will not support key word arguments
                # for method calls. It will instead store them in the form.
                # This has two reasons.
                # 1. Zope doesn't support kwargs in the publication
                #    implementation. It only supports positional arguments
                # 2. The JSON-RPC specification doesn't allow to use positional
                #     and keyword arguments on one method call
                # 3. Python doesn't allow to convert kwargs to positional
                #    arguments because a dict doesn't provide an order
                # This means you should avoid to call a method with kwargs.
                # just use positional arguments if possible. Or get them from
                # directly from the request or request.form argument in your
                # code. Let me know if this is a real problem for you and you
                # like to implement a different kwarg handling. We have some
                # ideas for add support for this.
                args = params
                # set every dict key value as form items and support at
                # least ``:list`` and ``:tuple`` input field name postifx
                # conversion.
                for key, d in args.items():
                    key = str(key)
                    pos = key.rfind(":")
                    if pos > 0:
                        match = self._typeFormat.match(key, pos + 1)
                        if match is not None:
                            key, type_name = key[:pos], key[pos + 1:]
                            if type_name == 'list' and not isinstance(d, list):
                                d = [d]
                            if type_name == 'tuple' and not isinstance(d, tuple):
                                d = tuple(d)
                    self.form[key] = d
                args = []
            elif params is None:
                args = []
        else:
            raise TypeError(
                'Unsupported JSON-RPC version (%s)' % self.jsonVersion)
        self._args = tuple(args)
        # make environment, cookies, etc., available to request.get()
        super(JSONRPCRequest, self).processInputs()
        self._environ['JSONRPC_MODE'] = True

        # split here on '.' for get path suffix steps
        functionstr = data['method']
        function = functionstr.split('.')
        if function:
            # translate '.' to '/' in function to represent object traversal.
            self.setPathSuffix(function)
Beispiel #35
0
def findAPIDocumentationRootURL(context, request):
    if isinstance(context, APIDocumentation):
        return absoluteURL(context, request)
    else:
        return findAPIDocumentationRootURL(getParent(context), request)
Beispiel #36
0
 def getInfo(self):
     """Get the file where the directive was declared."""
     if isinstance(self.context.info, (str, unicode)):
         return self.context.info
     return None
def findAPIDocumentationRoot(context, request=None):
    if isinstance(context, APIDocumentation):
        return context
    return findAPIDocumentationRoot(getParent(context), request)