Repository: gitpython-developers/GitPython

Issue #1762: Git.execute output_stream is not documented to suppress kill_after_timeout, but does
Created: 2023-12-10T08:30:22Z
When calling Git.execute, including indirectly through the dynamic methods of a Git object, passing a non-None value of output_stream suppresses the effect of kill_after_timeout. The threading.Timer object is created with the local kill_process function as its callback, but start is never called on it.

  
    
      GitPython/git/cmd.py
    
    
        Lines 1050 to 1079
      in
      a58a6be
    
  
  
    

        
          
           if output_stream is None: 
        

        
          
               if kill_after_timeout is not None: 
        

        
          
                   watchdog.start() 
        

        
          
               stdout_value, stderr_value = proc.communicate() 
        

        
          
               if kill_after_timeout is not None: 
        

        
          
                   watchdog.cancel() 
        

        
          
                   if kill_check.is_set(): 
        

        
          
                       stderr_value = 'Timeout: the command "%s" did not complete in %d ' "secs." % ( 
        

        
          
                           " ".join(redacted_command), 
        

        
          
                           kill_after_timeout, 
        

        
          
                       ) 
        

        
          
                       if not universal_newlines: 
        

        
          
                           stderr_value = stderr_value.encode(defenc) 
        

        
          
               # Strip trailing "\n". 
        

        
          
               if stdout_value.endswith(newline) and strip_newline_in_stdout:  # type: ignore 
        

        
          
                   stdout_value = stdout_value[:-1] 
        

        
          
               if stderr_value.endswith(newline):  # type: ignore 
        

        
          
                   stderr_value = stderr_value[:-1] 
        

        
          
            
        

        
          
               status = proc.returncode 
        

        
          
           else: 
        

        
          
               max_chunk_size = max_chunk_size if max_chunk_size and max_chunk_size > 0 else io.DEFAULT_BUFFER_SIZE 
        

        
          
               stream_copy(proc.stdout, output_stream, max_chunk_size) 
        

        
          
               stdout_value = proc.stdout.read() 
        

        
          
               stderr_value = proc.stderr.read() 
        

        
          
               # Strip trailing "\n". 
        

        
          
               if stderr_value.endswith(newline):  # type: ignore 
        

        
          
                   stderr_value = stderr_value[:-1] 
        

        
          
               status = proc.wait() 
        

        
          
           # END stdout handling 
        
    
  


This situation appears not entirely intentional, because:

The "watchdog" Timer is created, even though it is never used.
The docstring, even as it documents that as_process suppresses kill_after_timeout (and that as_process suppresses output_stream), does not mention any effect of output_stream on kill_after_timeout.

So either kill_after_timeout should be honored even when output_stream is used, or the docstring should be updated to mention that it does not (and the code possibly modified to not create the Timer object in the case that it is unused).
I am not sure which change should be made, so I'm opening this rather than a PR to propose one of them.
This is effectively separate from #1756. (One quality this shares with #1756 is that it is relevant only to the behavior of Git.execute and functions that use it. Functions that use handle_process_output are unaffected; its kill_after_timeout is implemented differently with nonequivalent behavior and separate code. handle_process_output also does not take an output_stream argument.)

Duplicate issue #1845: Unclear rationale for pipe usage in `output_stream` doc
Created: 2024-02-24T18:40:27Z
The Git.execute method docstring includes this in the description of its output_stream parameter:

  
    
      GitPython/git/cmd.py
    
    
        Lines 990 to 991
      in
      1e044ea
    
  
  
    

        
          
                       This feature only has any effect if `as_process` is False. Processes will 
        

        
          
                       always be created with a pipe due to issues with subprocess. 
        
    
  


I think this is referring to the subprocess module, which could be clarified by changing subprocess to :mod:`subprocess`. But I'm not sure what issues this is referring to, or what information it seeks to impart to the reader.
To be clear, I'm not arguing that output_stream shouldn't use a pipe. Instead, I think this part of the docstring should be clarified (and I am unsure how to do so).
If this intends to be general, and vagueness is acceptable, yet it is considered better to have this "due to" clause than simply remove it, and the issue really is in subprocess itself, then it could be changed to:
due to limitations of :mod:`subprocess`
But I hope something more specific can be said.
The full context is:

  
    
      GitPython/git/cmd.py
    
    
        Lines 987 to 994
      in
      1e044ea
    
  
  
    

        
          
                   :param output_stream: 
        

        
          
                       If set to a file-like object, data produced by the git command will be 
        

        
          
                       output to the given stream directly. 
        

        
          
                       This feature only has any effect if `as_process` is False. Processes will 
        

        
          
                       always be created with a pipe due to issues with subprocess. 
        

        
          
                       This merely is a workaround as data will be copied from the 
        

        
          
                       output pipe to the given output stream directly. 
        

        
          
                       Judging from the implementation, you shouldn't use this parameter!

Closing comment (2024-02-26T18:07:47Z): I'm wondering if the motivation for the extra text is to prevent users from being misled by the phrase "will be output to the given stream directly," especially by its use of "directly," and if some rephrasing, or added note, should accompany the removal of that text.
(This is sort of conceptually related to #1762, but improving this docstring probably need not wait on that.)