def METHOD_NAME(self, query, *, operation_name=None,
                  use_http_post=True,
                  variables=None,
                  globals=None):
    req_data = {
        'query': query
    }
    if operation_name is not None:
        req_data['operationName'] = operation_name
    if use_http_post:
        if variables is not None:
            req_data['variables'] = variables
        if globals is not None:
            req_data['globals'] = globals
        req = urllib.request.Request(self.http_addr, method='POST')
        req.add_header('Content-Type', 'application/json')
        response = urllib.request.urlopen(
            req, json.dumps(req_data).encode(), context=self.tls_context
        )
        resp_data = json.loads(response.read())
    else:
        if variables is not None:
            req_data['variables'] = json.dumps(variables)
        if globals is not None:
            req_data['globals'] = json.dumps(globals)
        response = urllib.request.urlopen(
            f'{self.http_addr}/?{urllib.parse.urlencode(req_data)}',
            context=self.tls_context,
        )
        resp_data = json.loads(response.read())
    if 'data' in resp_data:
        return resp_data['data']
    err = resp_data['errors'][0]
    typename, msg = err['message'].split(':', 1)
    msg = msg.strip()
    try:
        ex_type = getattr(edgedb, typename)
    except AttributeError:
        raise AssertionError(
            f'server returned an invalid exception typename: {typename!r}'
            f'\n  Message: {msg}')
    ex = ex_type(msg)
    if 'locations' in err:
        # XXX Fix this when LSP "location" objects are implemented
        ex._attrs[base_errors.FIELD_LINE_START] = str(
            err['locations'][0]['line']).encode()
        ex._attrs[base_errors.FIELD_COLUMN_START] = str(
            err['locations'][0]['column']).encode()
    raise ex