<commit_before>"""rpc.py"""

import itertools
from collections import OrderedDict

id_generator = itertools.count(1) # First generated is 1


def request(method, *args, **kwargs):
    """Returns an rpc notification, (a request not expecting a response.

    Notification examples:
        rpc.notification('go')
        rpc.notification('print', 'Hello world')
        rpc.notification('print', str='Hello world')

    Request examples (requiring a response):
        rpc.request('get', response=True)
        rpc.request('sqrt', 1, response=True)
        rpc.request('add', 1, 2, response=True)
        rpc.request('find', name='Beau', response=True)
        rpc.request('find', name='Beau', age=38, response=True)
    """

    # Get the request id
    request_id = None
    if kwargs.get('response', False):
        request_id = next(id_generator)

    # If 'response' is present in kwargs, pop it out of the dict
    if 'response' in kwargs:
        kwargs.pop('response')

    r = OrderedDict([
        ('jsonrpc', '2.0'),
        ('method', method)
    ])

    # Any params passed?
    if args or kwargs:

        params = None

        # Add any params passed as args
        if args:
            params = list(args)

        # Add any params passed as kwargs
        if kwargs:
            if params:
                params.append(OrderedDict(sorted(kwargs.items())))
            else:
                params = OrderedDict(sorted(kwargs.items()))

        r.update(OrderedDict([
            ('params', params)
        ]))

    # Add id if response=True was passed
    if request_id:
        r.update(OrderedDict([
            ('id', request_id)
        ]))

    return r<commit_msg>Reworked the rpc.request function, adding many doctests<commit_after>"""rpc.py"""

import itertools
import json
from collections import OrderedDict

id_generator = itertools.count(1) # First generated is 1


def request(method, *args, **kwargs):
    """Returns a JSON-RPC 2.0 request, in OrderedDict format. Convert to a json
    string with json.dumps().

    Notifications:

    No arguments
    >>> json.dumps(request('get'))
    '{"jsonrpc": "2.0", "method": "get"}'

    One positional
    >>> json.dumps(request('sqrt', 1))
    '{"jsonrpc": "2.0", "method": "sqrt", "params": [1]}'

    Two positional
    >>> json.dumps(request('add', 1, 2))
    '{"jsonrpc": "2.0", "method": "add", "params": [1, 2]}'

    One keyword
    >>> json.dumps(request('find', name='Foo'))
    '{"jsonrpc": "2.0", "method": "find", "params": {"name": "Foo"}}'

    Two keywords
    Note that keyword arguments are sorted in alphabetical order by the keys.
    This is because they're not received in any order, so we sort them, to be
    sure of *some* order
    >>> json.dumps(request('find', name='Foo', age=42))
    '{"jsonrpc": "2.0", "method": "find", "params": {"age": 42, "name": "Foo"}}'

    Both positional and keyword
    >>> json.dumps(request('find', 'Foo', age=42))
    '{"jsonrpc": "2.0", "method": "find", "params": ["Foo", {"age": 42}]}'

    Dict
    >>> json.dumps(request('find', name='Foo', age=42))
    '{"jsonrpc": "2.0", "method": "find", "params": {"age": 42, "name": "Foo"}}'

    List
    >>> json.dumps(request('find', ['Foo', 42]))
    '{"jsonrpc": "2.0", "method": "find", "params": ["Foo", 42]}'

    Requests (requiring a response):

    >>> json.dumps(request('go', response=True))
    '{"jsonrpc": "2.0", "method": "go", "id": 1}'

    >>> json.dumps(request('go', 'positional', keyword='foo', response=True))
    '{"jsonrpc": "2.0", "method": "go", "params": ["positional", {"keyword": "foo"}], "id": 2}'
    """

    # Get the request id
    request_id = None
    if kwargs.get('response', False):
        request_id = next(id_generator)

    # If 'response' is present in kwargs, pop it out of the dict
    if 'response' in kwargs:
        kwargs.pop('response')


    # jsonrpc, method
    r = OrderedDict([
        ('jsonrpc', '2.0'),
        ('method', method)
    ])


    # Get the params
    params = list()

    if args:
        for i in args:
            params.append(i)

    if kwargs:
        params.append(OrderedDict(sorted(kwargs.items())))

    if len(params):

        if len(params) == 1 and (isinstance(params[0], dict) or isinstance(params[0], list)):
            params = params[0]

        r.update(OrderedDict([
            ('params', params)
        ]))


    # response_id
    if request_id:
        r.update(OrderedDict([
            ('id', request_id)
        ]))

    return r
{'fraction_non_alphanumeric': 0.17106137824063816, 'fraction_numerical': 0.013959672058497673, 'mean_word_length': 2.7, 'pattern_counts': {'":': 37, '<': 3, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '311681', 'n_tokens_mistral': 1491, 'n_tokens_neox': 1400, 'n_words': 405}