Re: IDLE extension to integrate 3rd party checkers and analyzers

Terry Reedy <[email protected]>
Newsgroups gmane.comp.python.idle
Message-ID <[email protected]>
On 7/2/2014 3:07 PM, Terry Reedy wrote:
> On 7/2/2014 2:57 AM, Saimadhav Heblikar wrote:
>> Preface: The existing approach of using subprocess
>> http://bugs.python.org/issue21880
>> did not yield good result on 3 major platforms.
>
> Are there problems on Mac? I have not completely given up on subprocess
> on Windows for other uses,

The following work to print output to the shell window.

import subprocess as s
p = s.Popen([r'pyflakes', r'c:\programs\python34\lib\turtle.py'],
             stdout=s.PIPE, stderr=s.PIPE)
o,e = p.communicate()
for line in o.decode().splitlines(): print(line)

One of us should print the args variable in your patch to see how it 
might be different than the above. And then try to print the equivalent 
of o.

On installed python, started from the icon, a blank console window is 
flashed. It is not pleasant. I suspect it might have something to do 
with sys.__stdout__ in the user process being None instead of something, 
as with the repository version.

  but for checking code in a Text widget, I
> think a direct approach is better anyway.

> Here is how trivial the interfacing is for pyflakes.
> ====================
> class CW:  # CheckerWindow with .write, for instance
>      def __init__(self):
>          # self.text = Text() (or passed in param)
>          self.text = []
>
>      def write(self, chunk):
>          # self.text.insert('insert', chunk)
>          self.text.append(chunk)
>      def get(self):  # for this demo
>          # self.text.get('1.end') or whatever
>          return ''.join(self.text)
> cw = CW()
>
> # Specific interface: import and call
> from pyflakes import api, reporter
>
> # Call as it mightbe configured.
> # "api.check({code}, {fname}, reporter.Reporter({stream}, {stream}))"
> # where 'stream' is an object with a .write method.
> # Let ew be the EditorWindow being checked. Then use above with
> # .format(code=ew.text.get('1.end'), fname=ew.???, stream = cw)
> # The two args to Reporter are warning and error streams.
> # Errors incluce compile() SyntaxErrors, as in second example below.
> # A separate error stream could 'color' error text if desired.
> # It could also separate counting of warnings from errors
>
> api.check('a = b\n', 'tem.py', reporter.Reporter(cw, cw))
> cw.write('----\n')
> api.check('a =\n', 'tem.py', reporter.Reporter(cw, cw))
>
> print(cw.get())  # view result in CW
>  >>>
> tem.py:1: undefined name 'b'
> ----
> tem.py:1:4: invalid syntax
> a =
>     ^
> =====================================
>
> I believe that any properly written Python-coded checker/analyzer should
> provide such an interface, so the input and output can be passed back
> and forth as Python strings without encoding to or decoding from bytes
> (in Py3) or writing to or reading from external files.
>
> I would like to see a revised patch on 21880 that runs pyflakes this way
> so we have a working example for discussion of the ui, the dialogs and
> output window.

This suggests a possible 'send' api.

In Idle:
from x import check  # where x is defined in the checker config.
check(path, code, stream, estream)

path = full path or just filename from editor(can right-click goto 
file/line deal with <untitled> as a name?)
code = None for full path, code string for filename
(e)steam = objects with .write (and any other methods that end up being 
needed) for normal and error output.

For pyflakes, the imported interface file would be
---
import api, reporter
def check(path, code, stream, estream):
     report = reporter(stream, estread)
     if code is not None:
         api.check(code, path, report)
     else:
         api.checkRecursive([path], report

-- 
Terry Jan Reedy
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.