docs: def query(self, msg_type, query, *parameters, **options):
          '''Performs a query against a q service.
          
          In typical use case, `query` is the name of the function to call and 
          `parameters` are its parameters. When `parameters` list is empty, the 
          query can be an arbitrary q expression (e.g. ``0 +/ til 100``).
          
          Calls a anonymous function with a single parameter:
          
              >>> q.query(qconnection.MessageType.SYNC,'{til x}', 10)
          
          Executes a q expression:
          
              >>> q.query(qconnection.MessageType.SYNC,'til 10')
          
          :Parameters:
           - `msg_type` (one of the constants defined in :class:`.MessageType`) - 
             type of the query to be executed
           - `query` (`string`) - query to be executed
           - `parameters` (`list` or `None`) - parameters for the query
          :Options:
           - `single_char_strings` (`boolean`) - if ``True`` single char Python 
             strings are encoded as q strings instead of chars, 
             **Default**: ``False``
          
          :raises: :class:`.QConnectionException`, :class:`.QWriterException`
          '''
          if not self._connection:
              raise QConnectionException('Connection is not established.')
  
          if parameters and len(parameters) > 8:
              raise QWriterException('Too many parameters.')
  
          if not parameters or len(parameters) == 0:
              self._writer.write(query, msg_type, **self._options.union_dict(**options))
          else:
              self._writer.write([query] + list(parameters), msg_type, **self._options.union_dict(**options))