Python addProcessListener Bug - onTextAvailable not called

Hello everyone.

I am creating a plugin for PyCharm Community Edition 2016.3.2. And I encountered this bug which I spend much time on and still havent figured it out.

What I am doing, is that I have a ProjectPlugin class, which is a application component and in its construction I call this: 

connect.subscribe(ExecutionManager.EXECUTION_TOPIC, new ConsoleRunListener(project));

Where the ConsoleRunListener implements ExecutionListener and in the processStarted method I do this: 

processHandler.addProcessListener(new ProcessAdapter() {
@Override
public void onTextAvailable(ProcessEvent event, Key outputType) {

In here I collect every single line that comes using event.getText() method.

I collect these and then send them after the process is Terminated in the processTerminated() method.

All works, except for 1 issue I have spent many hours on and havent figured how to solve it: 

If I run a Python file .py before an Run window exists (so nothing has been run yet), the ProcessListener doesnt work and the onTextAvaible method is not called even once.

This doesnt happen though if I debug the same file, or run/debug Pytest tests. 

Also, If I run the same Python file the second time after anything else has already run (Run window exists with some log text in it), everything works fine.

This behaviour also happens in PyCharm Ultimate Edition 2016.2.4.

I am looking for a fix or workaround. I believe this maybe because of some asynchronous elements of the IDE, but my knowledge in that is limited.

Is there maybe a way to read text from an already opened Run windows with logs in it, so I dont have to collect them everytime line by line? Or a proper way for this to be done?

Thanks for every answer.

Jan

2 comments
Comment actions Permalink

I am additionally having this issue in

PY-2019.2.3
0
Comment actions Permalink

I have come up with a hacky solution for anyone who encounters this problem in the future.

Inside your ExecutionListener, flag the first run if it is the standard python runner. (I just keep a string of the executionId in processStarted)

Destroy the process.  

((PythonProcessHandler) handler).getProcess().destroy();

Inside processTerminated if the executionId == firstProcessId:

ExecutionManager.getInstance(env.getProject()).restartRunProfile(env);

0

Please sign in to leave a comment.