<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def call( self, scheme, service, arg1, arg2=None, arg3=None, timeout=None, retry_on=None, retry_limit=None, routing_delegate=None, hostport=None, shard_key=None, tracing_span=None, trace=None, # to trace or not, defaults to self._dep_tchannel.trace caller_name=None, ):
 """Make low-level requests to TChannel services. **Note:** Usually you would interact with a higher-level arg scheme like :py:class:`tchannel.schemes.JsonArgScheme` or :py:class:`tchannel.schemes.ThriftArgScheme`. """


        # TODO - don't use asserts for public API
        assert format, "format is required"
        assert service, "service is required"
        assert arg1, "arg1 is required"

        # default args
        if arg2 is None:
            arg2 = ""
        if arg3 is None:
            arg3 = ""
        if timeout is None:
            timeout = DEFAULT_TIMEOUT
        if retry_on is None:
            retry_on = retry.DEFAULT
        if retry_limit is None:
            retry_limit = retry.DEFAULT_RETRY_LIMIT

        # TODO - allow filters/steps for serialization, tracing, etc...

        tracing.apply_trace_flag(tracing_span, trace, self._dep_tchannel.trace)

        # calls tchannel.tornado.peer.PeerClientOperation.__init__
        operation = self._dep_tchannel.request(
            service=service,
            hostport=hostport,
            arg_scheme=scheme,
            retry=retry_on,
            tracing_span=tracing_span
        )

        # fire operation
        transport_headers = {
            transport.SCHEME: scheme,
            transport.CALLER_NAME: caller_name or self.name,
        }
        if shard_key:
            transport_headers[transport.SHARD_KEY] = shard_key
        if routing_delegate:
            transport_headers[transport.ROUTING_DELEGATE] = routing_delegate

        response = yield operation.send(
            arg1=arg1,
            arg2=arg2,
            arg3=arg3,
            headers=transport_headers,
            retry_limit=retry_limit,
            ttl=timeout,
        )

        # unwrap response
        body = yield response.get_body()
        headers = yield response.get_header()
        t = TransportHeaders.from_dict(response.headers)
        result = Response(
            body=body,
            headers=headers,
            transport=t,
            status=response.code,
        )

        raise gen.Return(result)