code: def open_gateway(self):
          
          # ProxyCommand is faster to set up, so do it first.
          if isinstance(self.gateway, string_types):
              # Leverage a dummy SSHConfig to ensure %h/%p/etc are parsed.
              # TODO: use real SSH config once loading one properly is
              # implemented.
              ssh_conf = SSHConfig()
              dummy = "Host {}\n    ProxyCommand {}"
              ssh_conf.parse(StringIO(dummy.format(self.host, self.gateway)))
              return ProxyCommand(ssh_conf.lookup(self.host)["proxycommand"])
          # Handle inner-Connection gateway type here.
          # TODO: logging
          self.gateway.open()
          # TODO: expose the opened channel itself as an attribute? (another
          # possible argument for separating the two gateway types...) e.g. if
          # someone wanted to piggyback on it for other same-interpreter socket
          # needs...
          # TODO: and the inverse? allow users to supply their own socket/like
          # object they got via $WHEREEVER?
          # TODO: how best to expose timeout param? reuse general connection
          # timeout from config?
          return self.gateway.transport.open_channel(
              kind="direct-tcpip",
              dest_addr=(self.host, int(self.port)),
              # NOTE: src_addr needs to be 'empty but not None' values to
              # correctly encode into a network message. Theoretically Paramiko
              # could auto-interpret None sometime & save us the trouble.
              src_addr=("", 0),
          )
docs: Obtain a socket-like object from `gateway`.
  
          :returns:
              A ``direct-tcpip`` `paramiko.channel.Channel`, if `gateway` was a
              `.Connection`; or a `~paramiko.proxy.ProxyCommand`, if `gateway`
              was a string.
  
          .. versionadded:: 2.0