[wingide-users] 3.1.2 and PyLint

Gustavo Tabares gustavotabares at gmail.com
Thu Jul 24 14:41:43 MDT 2008


Hello,

This did not fix my particular problem. I tried it on OSX and Windows.

Gustavo

On Thu, Jul 24, 2008 at 3:43 PM, Wingware Support <support at wingware.com>
wrote:

> Gustavo Tabares wrote:
>
>> Hi all,
>>
>> I recently upgraded to Wing 3.1.2 and I'm having problems with the PyLint
>> integration. In my PyLint Panel configuration file I have this:
>>
>> args = --rcfile='mycfg.cfg'
>>
>> It doesn't appear to be reading my configuration file after upgrading from
>> 3.1.1. <http://3.1.1.> I'm seeing some warnings that I usually do not see
>> (specifically about line length).
>>
>
> I'm attaching the latest version that I've been working with; there have
> been changes in how argument parsing works that have caused problems. I'd
> like to get feedback on this before releasing it generally.  To use it, find
> the scripts subdirectory of your Wing installation, rename the current
> pylintpanel.py to pylintpanel.py.orig, copy in the new pylintpanel.py, and
> then start or restart Wing.
>
> Thanks,
>
> John
>
> """
> PyLint Panel for Wing IDE 3.x
>
> Copyright (c) 2006-2007 Markus Meyer <meyer at mesw.de>
>
> Permission is hereby granted, free of charge, to any person obtaining a
> copy
> of this software and associated documentation files (the "Software"), to
> deal
> in the Software without restriction, including without limitation the
> rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE
> SOFTWARE.
>
>
> ----------------------------------------------------------------------------
> Change Log
>
> ----------------------------------------------------------------------------
>
> Version 1.0 (2006-10-12)
>
> * First release
>
> Version 1.1 (2007-03-19)
>
> * Fix compatibility issues with newer PyLint versions
> * Fix error message when PyLint returns no errors
>
> Version 1.2 (2008-06-05)  Modifications by Wingware:
>
> * Pass configured environment to the pylint sub-process
>  (includes also PYTHONPATH if it's set in project)
> * Use presence of a settings file to enable/disable for easier upgrades
> * Removed obsolete example args
> * Renamed "preferences" to "configure" in context menu to avoid confusion
> * Renamed command execute_pylint to pylint_execute and pylint_preferences
>  to pylint_configure
> * Changed execution of pylint to be asyncronous
>
> """
>
> import os
> import wingapi
> import time
>
> PYLINTPANEL_VERSION = "1.1"
>
> import re
> _AI = wingapi.CArgInfo
>
> # Scripts can be internationalized with gettext.  Strings to be translated
> # are sent to _() as in the code below.
> import gettext
> _ = gettext.translation('scripts_pylintpanel', fallback = 1).ugettext
>
> # This special attribute is used so that the script manager can translate
> # also docstrings for the commands found here
> _i18n_module = 'scripts_pylintpanel'
>
> ######################################################################
> # Utilities
>
> gMessageCategories = [
>  ("errors", _("Errors"), _("Errors that must be fixed")),
>  ("warnings", _("Warnings"), _("Warnings that could indicate problems")),
>  ("information", _("Info"), _("General informative messages"))
> ]
>
> gTheView = None # Will be set later
>
> ######################################################################
> # Configuration file support
>
> class PylintConfig:
>  def __init__(self):
>    pass
>
>  def get(self, name, default=""):
>    """
>    Get configuration option from configuration file
>    """
>    try:
>      lines = file(self._get_config_file_name(), "rt").readlines()
>    except IOError:
>      return default
>    for line in lines:
>      words = line.split("=", 1)
>      if len(words) == 2:
>        key = words[0].strip()
>        value = words[1].strip()
>        if key == name:
>          return value
>    return default
>
>  def edit(self):
>    """
>    Edit and possibly create configuration file. Currently, this will just
>    open the configuration file inside WingIDE.
>    """
>    try:
>      # Check if config file can be opened
>      cfgfile = file(self._get_config_file_name(), "rt")
>    except IOError:
>      # The config file does not yet exist, create it
>      cfgfile = file(self._get_config_file_name(), "wt")
>      cfgfile.writelines([
>        '#\n',
>        '# PyLint Panel Configuration\n',
>        '#\n',
>        '\n',
>        '# Full path to PyLint executable\n',
>        'command = \n',
>        '#command = /usr/bin/pylint\n',
>        '#command = C:\Python24\Scripts\pylint.bat\n',
>        '\n',
>        '# Additional args to give to PyLint (may be blank)\n',
>        'args = \n',
>        '\n',
>        '# Timeout for execution of pylint command\n',
>        'timeout = 30\n',
>        '\n',
>        '# Save current file before running PyLint on it (1=yes, 0=no)\n',
>        'autosave = 1\n'
>        ])
>    cfgfile.close()
>
>    wingapi.gApplication.OpenEditor(self._get_config_file_name())
>
>  def _get_config_file_name(self):
>    """
>    Get full name and path of config file
>    """
>    dir = wingapi.gApplication.GetUserSettingsDir()
>    return os.path.join(dir, "pylintpanel.cfg")
>
> gTheConfig = PylintConfig()
>
> kResultParseExpr = re.compile("([^:]+):[ ]*([0-9]+):(.*)")
>
>
> ######################################################################
> # Commands
>
> def pylint_configure():
>  """Show the pylint configuration file so it can be edited"""
>  gTheConfig.edit()
>
> def pylint_execute():
>  """Execute pyline for the current editor"""
>
>  if gTheView is None:
>    # Panel is not visible
>    return
>
>  view = gTheView
>  app = wingapi.gApplication
>
>  pylint_command = gTheConfig.get("command", None)
>  pylint_args = gTheConfig.get("args", "")
>  pylint_timeout = gTheConfig.get("timeout", "10000")
>  pylint_autosave = gTheConfig.get("autosave", "1")
>
>  if pylint_command is None:
>    app.ShowMessageDialog(_('Error'), _('PyLint panel configuration file not
> found. ' +
>                          'Choose "Configure" from the context menu to edit
> ' +
>                          'the configuration file.  You will need to install
> pylint '
>                          'separately.'))
>    return
>
>  try:
>    timeout = int(pylint_timeout)
>    autosave = int(pylint_autosave) != 0
>  except ValueError:
>    app.ShowMessageDialog(_("Error"), _("Invalid values specified in
> configuration file"))
>    return
>
>  filename = app.GetActiveEditor().GetDocument().GetFilename()
>  view._lastFilename = filename
>
>  # Save active document before executing PyLint
>  if autosave:
>    app.ExecuteCommand("save")
>
>  # Completion routine that updates the tree when pylint is finished running
>  def _update_tree(result):
>    resultLines = result.split('\n')
>    tree_contents = [ [], [], [] ]
>
>    for line in resultLines:
>      matchobj = kResultParseExpr.match(line)
>      if matchobj is not None:
>        msg_type = matchobj.group(1)
>        msg_line = matchobj.group(2).strip()
>        msg_descr = matchobj.group(3).strip()
>        if msg_type[0] == 'F' or msg_type[0] == 'E':
>          msg_index = 0
>        elif msg_type[0] == 'W':
>          msg_index = 1
>        else:
>          msg_index = 2
>
>        tree_contents[msg_index].append(
>          ((msg_line, msg_type + ": " + msg_descr),))
>
>    view.set_tree_contents(tree_contents)
>
>  # Show pending execution message in tree column title
>  view._ShowStatusMessage(_("Updating for %s") % filename)
>
>  def arg_split(args, sep):
>    cur_part = ''
>    retval = []
>    in_quote = None
>    for c in args:
>      if not in_quote:
>        if c in '\'"':
>          in_quote = c
>          cur_part += c
>        elif c == sep:
>          if cur_part:
>            retval.append(cur_part)
>          cur_part = ''
>        else:
>          cur_part += c
>      elif in_quote == c:
>        in_quote = None
>        cur_part += c
>      else:
>        cur_part += c
>    if cur_part:
>      retval.append(cur_part)
>    return retval
>
>  # Execute PyLint asyncronously
>  cmd = pylint_command
>  args = [cmd, filename.encode(config.kFileSystemEncoding), '--reports=n',
> '--include-ids=yes']
>  args.extend(arg_split(pylint_args, ' '))
>  args = tuple(args)
>  env = app.GetProject().GetEnvironment(filename, set_pypath=True)
>  start_time = time.time()
>  handler = app.AsyncExecuteCommandLineE(cmd, os.path.split(filename)[0],
> env, *args)
>  last_dot = [int(start_time)]
>  dots = []
>
>  def poll():
>    if handler.Iterate():
>      view._ShowStatusMessage('')
>      stdout, stderr, err, status = handler.Terminate()
>      if err:
>        app.ShowMessageDialog(_("PyLint Failed"), _("Error executing PyLint:
>  Command failed with error=%i; stderr:\n%s") % (err, stderr))
>      else:
>        _update_tree(stdout)
>      return False
>    elif time.time() > start_time + timeout:
>      view._ShowStatusMessage('')
>      stdout, stderr, err, status = handler.Terminate()
>      app.ShowMessageDialog(_("PyLint Timed Out"), _("PyLint timed out:
>  Command did not complete within timeout of %i seconds.  Right click on the
> PyLint tool to configure this value.  Output from PyLint:\n\n%s") %
> (timeout, stderr + stdout))
>      return False
>    else:
>      if int(time.time()) > last_dot[0]:
>        dots.append('.')
>        if len(dots) > 3:
>          while dots:
>            dots.pop()
>        view._ShowStatusMessage(_("Updating for %s%s") % (filename,
> ''.join(dots)))
>        last_dot[0] = int(time.time())
>      return True
>
>  wingapi.gApplication.InstallTimeout(100, poll)
>
>
> def _IsAvailable_pylint_execute():
>  app = wingapi.gApplication
>  ed = app.GetActiveEditor()
>  if not ed:
>    return False
>  doc = ed.GetDocument()
>  if not doc:
>    return False
>  filename = doc.GetFilename()
>  if not filename:
>    return False
>  mimetype = doc.GetMimeType()
>  return mimetype == 'text/x-python'
>
> def pylint_show_docs():
>  """Show the Wing IDE documentation section for the PyLint integration"""
>  wingapi.gApplication.ExecuteCommand('show-document',
> section='edit/pylint')
>
>
> ######################################################################
> # XXX This is advanced scripting that accesses Wing IDE internals, which
> # XXX are subject to change from version to version without notice.
>
> from guiutils import wgtk
> from guiutils import dockview
> from guiutils import wingview
> from guiutils import winmgr
>
> from command import commandmgr
> import guimgr.menus
>
> # Note that panel IDs must be globally unique so all user-provided panels
> # MUST add a random uniquifier after '#'.  The panel can still be referred
> # to by the portion of the name before '#' and Wing will warn when there
> # are multiple panel definitions with the same base name (in which case
> # Wing-defined panels win over user-defined panels and otherwise the
> # last user-defined panel type wins when referred to w/o the uniquifier).
> _kPanelID = 'pylintpanel#02EFWRQK9X24'
>
> class _CPylintPanelDefn(dockview.CPanelDefn):
>  """Panel definition for the project manager"""
>
>  def __init__(self, singletons):
>    self.fSingletons = singletons
>    dockview.CPanelDefn.__init__(self, self.fSingletons.fPanelMgr,
>                                 _kPanelID, 'tall', 0)
>    winmgr.CWindowConfig(self.fSingletons.fWinMgr, 'panel:%s' % _kPanelID,
>                         size=(350, 1000))
>
>  def _CreateView(self):
>    return _CPylintView(self.fSingletons)
>
>  def _GetLabel(self, panel_instance):
>    """Get display label to use for the given panel instance"""
>
>    return _('PyLint')
>
>  def _GetTitle(self, panel_instance):
>    """Get full title for the given panel instance"""
>
>    return _('PyLint Panel')
>
> class _CPylintViewCommands(commandmgr.CClassCommandMap):
>  def __init__(self, singletons, view):
>    commandmgr.CClassCommandMap.__init__(self, domain='user',
> package='pylintpanel',
>                                         i18n_module=_i18n_module)
>    assert isinstance(view, _CPylintView)
>
>    self.fSingletons = singletons
>    self.__fView = view
>
> class _CPylintView(wingview.CViewController):
>  """A single template manager view"""
>
>  def __init__(self, singletons):
>    """ Constructor """
>    global gTheView
>
>    # Init inherited
>    wingview.CViewController.__init__(self, ())
>
>    # External managers
>    self.fSingletons = singletons
>
>    self.__fCmdMap = _CPylintViewCommands(self.fSingletons, self)
>
>    self.fTrees = {}
>    self.fLabels = {}
>
>    self.__CreateGui()
>
>    # Remember that this is the default view now
>    gTheView = self
>
>  def _destroy_impl(self):
>    for tree, sview in self.fTrees.values():
>      sview.destroy()
>
>  def set_tree_contents(self, tree_contents):
>    idx = 0
>    for catkey, labeltext, tooltip in gMessageCategories:
>      label = gTheView.fLabels[catkey]
>      label.set_text('%s (%i)' % (labeltext, len(tree_contents[idx])))
>      tree, sview = gTheView.fTrees[catkey]
>      tree.set_contents(tree_contents[idx])
>      idx += 1
>
>  ##########################################################################
>  # Inherited calls from wingview.CViewController
>  ##########################################################################
>
>  def GetDisplayTitle(self):
>    """ Returns the title of this view suitable for display. """
>
>    return _("PyLint Panel")
>
>  def GetCommandMap(self):
>    """ Get the command map object for this view. """
>
>    return self.__fCmdMap
>
>  def BecomeActive(self):
>    pass
>
>  ##########################################################################
>  # Popup menu and actions
>  ##########################################################################
>
>  def __CreateGui(self):
>    notebook = wgtk.Notebook()
>
>    for catkey, label, tooltip in gMessageCategories:
>      tree = wgtk.SimpleTree([wgtk.gobject.TYPE_STRING] * 2,
>                             [wgtk.CellRendererText(),
> wgtk.CellRendererText()],
>                             [_("Line"), _("Message")])
>      tree.unset_flags(wgtk.CAN_FOCUS)
>      tree.set_property('headers-visible', True)
>
>      tree.connect('button-press-event', self.__CB_ButtonPress)
>      sel = tree.get_selection()
>      sel.connect('changed', self.__CB_SelectionChanged)
>      tree.show()
>
>      sview = wgtk.ScrolledWindow()
>      sview.set_policy(wgtk.POLICY_AUTOMATIC, wgtk.POLICY_AUTOMATIC)
>      sview.add(tree)
>      sview.show()
>
>      # Event box is needed to make tooltips work in this context (don't
> ask)
>      tab_event_box = wgtk.TooltipBox()
>      tab_label = wgtk.Label(label)
>      tab_event_box.add(tab_label)
>      tab_event_box.show_all()
>      wgtk.set_tooltip(tab_event_box, tooltip)
>
>      notebook.append_page(sview, tab_event_box)
>      self.__fNotebook = notebook
>
>      self.fTrees[catkey] = (tree, sview)
>      self.fLabels[catkey] = tab_label
>
>    notebook.set_current_page(0)
>    self._SetGtkWidget(notebook)
>
>  def __CreatePopup(self):
>    """Construct popup menu for this object."""
>
>    update_label = _("Update")
>    app = wingapi.gApplication
>    ed = app.GetActiveEditor()
>    if ed:
>      filename = ed.GetDocument().GetFilename()
>      update_label = _("Update for %s") % os.path.basename(filename)
>
>    kPopupDefn = [
>      ( update_label, 'pylint-execute' ),
>      ( _("Configure..."), 'pylint-configure' ),
>      None,
>      ( _("Show PyLint Tool Documentation"), 'pylint-show-docs' ),
>    ]
>
>    # Create menu
>    defnlist = guimgr.menus.GetMenuDefnList(kPopupDefn,
> self.fSingletons.fGuiMgr,
>                                            self.__fCmdMap, is_popup=1,
> static=1)
>    menu = guimgr.menus.CMenu(_("PyLint"), self.fSingletons.fGuiMgr,
>                              defnlist, can_tearoff=0, is_popup=1)
>    return menu
>
>  def __CB_SelectionChanged(self, sel):
>    pos = self.__fNotebook.get_current_page()
>    catkey, label, tdir = gMessageCategories[pos]
>    tree, sview = self.fTrees[catkey]
>    rows = tree.GetSelectedContent()
>
>  def __CB_ButtonPress(self, tree, event):
>    app = wingapi.gApplication
>
>    # Always select the row that the pointer is over
>    event_path_info = tree.get_path_at_pos(int(event.x), int(event.y))
>    if event_path_info is not None:
>      event_path = event_path_info[0]
>      selected_paths = tree.GetSelectedPaths()
>      if event_path not in selected_paths:
>        sel = tree.get_selection()
>        sel.unselect_all()
>        sel.select_path(event_path)
>
>    # Popup menu on right mouse button
>    if event.button == 3:
>      self.__PopupMenu(event, (event.x_root, event.y_root))
>      return 1
>
>    selected = tree.GetSelectedContent()
>    if selected is not None and len(selected) != 0:
>      line = int(selected[0][0])
>      if event.button == 1 and event.type == wgtk.gdk.BUTTON_PRESS:
>        doc = app.OpenEditor(self._lastFilename)
>        doc.ScrollToLine(lineno=line-1, pos='center', select=1)
>
>  def __PopupMenu(self, event, pos):
>    """Callback to display the popup menu"""
>
>    menu = self.__CreatePopup()
>    menu.Popup(event, pos=pos)
>
>  def _ShowStatusMessage(self, msg):
>    for tree, sview in self.fTrees.values():
>      column = tree.get_column(1)
>      if msg:
>        column.set_title(_("Message: %s") % msg)
>      else:
>        column.set_title(_("Message"))
>
> # Register this panel type:  Note that this needs to be at the
> # very end of the module so that all the classes defined here
> # are already available
> import config
> if _kPanelID not in config.kUserPanels:
>  config.kUserPanels.append(_kPanelID)
> _CPylintPanelDefn(wingapi.gApplication.fSingletons)
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: /pipermail/wingide-users/attachments/20080724/8b452f9d/attachment-0001.html


More information about the wingide-users mailing list