Friday, March 23, 2012

PyScripter v2.5.3 released

PyScripter version 2.5.3 was released at http://pyscripter.googlecode.com.  This is another bug-fix release.  It fixes two issues in version 2.5.

  • Unit test discovery was broken 
  • Find in files was broken in the x64 version.

See previous post for the new features and bug fixes in version 2.5

Tuesday, March 20, 2012

PyScripter v2.5.2 released

PyScripter version 2.5.2 was released at http://pyscripter.googlecode.com.  This just a bug-fix release.  It fixes a regression in version 2.5 due to which GUI scripts would not show up. (Issue 625).

Monday, March 19, 2012

PyScripter v2.5.1 released

PyScripter version 2.5.1 was released at http://pyscripter.googlecode.com.  This just a bug-fix release.  It fixes two issues in version 2.5.

  • Word-wrap in the editor caused problems
  • Navigation with the Code Explorer was broken.

See previous post for the new features and bug fixes in version 2.5.

Sunday, March 18, 2012

PyScripter v2.5 released

PyScripter version 2.5 was released at http://pyscripter.googlecode.com

Friday, March 9, 2012

Please let me interrupt you

The standard way of interrupting a long running script in a Python shell is to press Ctrl+C which signals a keyboard interrupt and the interpreter raises a KeyboardInterrupt exception.  I was trying for a while to find a way to raise a KeyboardInterrupt execption at the remote python engine without much success.  The way IDLE handles this, is by running a separate thread in the server, which waits for such a signal to arrive from IDLE and then uses the interrupt_main function of the threading module.  I thought that having a separate thread just for this purpose would slow down the execution of scripts and the PyScripter solution of reinitializing the engine was good enough.

Resently, a user has posted an issue about this at PyScripter’s bug tracker and I had another look at the problem.  So I found a solution using Windows API and avoiding run overheads,  For the benefit of Windows hackers I show the code below:

function CtrlHandler( fdwCtrlType : dword): LongBool; stdcall;
begin
  Result := True;
end;

AttachConsole := GetProcAddress (GetModuleHandle ('kernel32.dll'), 'AttachConsole');
if Assigned(AttachConsole) then
try
  OSCheck(AttachConsole(fRemotePython.ServerProcess.ProcessInfo.dwProcessId));
  OSCheck(SetConsoleCtrlHandler(@CtrlHandler, True));
  try
    OSCheck(GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0));
    Sleep(100);
  finally
    OSCheck(SetConsoleCtrlHandler(@CtrlHandler, False));
    OSCheck(FreeConsole);
  end;
except
end;

Note that the CtrlHandler is needed to avoid killing PyScripter itself.  It took me a while to work out this piece of code since, I could not find such code sample (only pieces of the puzzle) in the Internet.  The only solution I found involved injecting code into the server process.

So starting from the forthcoming version 2.5, the Abort command will result in a KeyboardInterrupt exeption in script is run or debugged.  So there is no need to reinitialize the engine to stop a script.  After the script stops you can enter the Post-Mortem mode to see what the script was doing when it received the Keyboard interrupt.

I could have added a shortcut Ctrl+C to the interpreter for raising a Keyboard interrupt, but the Ctrl-C shortcut in GUI applications is associated with the copy command.  So the Abort command will achieve the same thing as pressing Ctrl+C in Python Shell.  When a scrip is stopped at a breakpoint, the Abort command will work as before.