pylint integration, import error for pip

Apr 2 at 4:04 AM
VS 2012 : Pylint 2.1 Alpha

I have been trying to use the pylint integration and I saw that the Output window reported a failed import of pip. I see that is because it thinks my pylint version is below 1.0.0. It doesn`t report the import error until after this dialog. My assumption is that VS is attempting to download a new version and that step relys on pip or setuptools to complete it. Where I work we have a very specific distributed Python so I dont want to put setuptools or pip in the mix yet.

Is there a way to configure the pylint integration to look at our current version of pylint. When I import pylint.lint and ask it for version it returns 0.2.6. I suspect that is the issue. I could always look to update pylint as well.

I'm wondering if others have faced this issue.
Coordinator
Apr 2 at 6:34 AM
There are two issues here. First, the Pylint command does, indeed, expect pylint>=1.0.0. And second, it does use setuptools (to be specific, pkg_resources.require) to check whether the module is installed, and if it's not installed, it should pop up a dialog asking you to install it (and pip, since it uses that to install packages in general).

Now, luckily, this is one area that is actually a big customization point that does not require any sort of recompile - it's all MSBuild-driven. Have a look at C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Python Tools\Microsoft.PythonTools.targets - in particular, the comment at the very beginning that explains how to use <CreatePythonCommandItem>, and then a section closer to the end of the file that defines a command for Pylint. As you can see, you can easily change how the command is invoked, arguments passed to it, and the regex used to extract warnings/errors from the output (which you might need to adjust for an older Pylint version). The RequiredPackages attribute is the one that triggers the whole version checking / pip install logic, and stripping it will cause the command to run unconditionally (and fail if the module is not actually there).

Now, you can just edit this file directly if you want a simple solution, but there are other options. If this is something that you need for a particular project only, then you can just redefine an MSBuild target with the same name in your .pyproj file, adjusting it as needed - it will override the one from the imported .targets file for that particular project. If you have several such projects, then you can create your own .targets file with an overridden target, and import it from your .pyproj after Microsoft.PythonTools.targets.

You might also find this functionality useful to wire up other tools as VS commands, including your own custom ones. There's also the ability to directly run Python code during the build with <RunPythonCommand>, feeding MSBuild properties into it, and using its console output as input for further build steps. Look at Microsoft.PythonTools.Django.targets for some advanced examples.
Apr 2 at 1:09 PM
fantastic. I did in face discover a file with the <CreatePythonCommandItem> in the Source, I was not able to locate in the local install. I shall look again. Based on the source code, though I assumed it was customizable. I'll do a little more digging and try removing that restriction. Thank you for the response. I'll post if successful.
Apr 2 at 6:19 PM
Update: Yes removing the restriction did let it get farther, however being on a very old pylint, I'm not sure how I could reconfigure this line
Arguments="&quot;--msg-template={abspath}({line},{column}): warning {msg_id}: {msg}&quot; -r n @(Compile, ' ')"
to work in the pylint I have. --msg-template is a pretty new. I am now considering updating our python tools to pylint, and by extension ( asteroid, logilab-common ).

I was able to remove that --msg-template but I do not think PTVS recognizes it in that format.
Coordinator
Apr 2 at 6:25 PM
Parsing of output is guided by ErrorRegex and WarningRegex - adjust them to the output that it produces without --msg-template. The only reason why it's even there is because this makes Pylint generate errors in format that MSBuild also understands, so for command line invocations they are counted as build errors.
Apr 2 at 8:15 PM
You guys are great! With that little bit of info I've been able to get pylint to run with the MSBUILD syntax using a couple of things.
First defined 2 REGEX blocks, one for Errors, one for Warnings
 <PropertyGroup>
    <PythonCommands>$(PythonCommands);PythonRunPyLintCommand</PythonCommands>
    <PyLintWarningRegex>
    <![CDATA[^(?<filename>.+?)\((?<line>\d+)\): \[W\] (?<message>.+?)$]]>
    </PyLintWarningRegex>
    <PyLintErrorRegex>
    <![CDATA[^(?<filename>.+?)\((?<line>\d+)\): \[E\] (?<message>.+?)$]]>
    </PyLintErrorRegex>
  </PropertyGroup>
Second, in my older version of pylint they had a command argument called -f, with that arg and the string 'msvs' pylint will ouput something similar to what we expect in VS. My RE's above leveage that info. Additionally I just passed in my custom -rcfile as well.
<CreatePythonCommandItem Target="pylint.lint"
  TargetType="module"
  Arguments="-r n @(Compile, ' ') -f msvs --rcfile exporter.pylintrc "
  ExecuteIn="output"
  RequiredPackages=""
  WarningRegex="$(PyLintWarningRegex)"
  ErrorRegex="$(PyLintErrorRegex)" >
Thanks again.