AtomLinter / linter-pylint

Atom linter plugin for Python, using pylint.
60 stars 48 forks source link

Switching between pylint executables for py2 and py3 #14

Closed tlaundal closed 9 years ago

tlaundal commented 10 years ago

I find my self working with both python 2 and python 3, and it would be convenient if you could switch between pylint for python3 and pylint2 for python 2.

In the package settings you could set the name of the executable for python 3 and for python2, and then there could be a shortcut to change between them?

dmnd commented 10 years ago

It's kind of awkward to have to manually switch linters like this.

Maybe we could pick the correct linter based on virtualenv somehow? Right now virtualenv and Atom don't play very well together though. Atom will pick up whatever environment was present when it was started up, but it's not changeable without restarting the editor. As far as I know virtualenv doesn't have something like rbenv's .ruby-version file though. Maybe autoenv?

Anyway, in the short term I'm happy to accept a PR that just calls a different linter.

tlaundal commented 10 years ago

I don't know enough js/coffescript to make a PR.

The problem with virtualenv is that it is not always used. Most likely, it would not be a problem to require it though. The best quick fix would be to just take the name of the pylint executeable as a config option, I think. What we could do in addition is to parse python --version to get the python version. So it will work if the user uses a virtualenv, and if he does not.

dmnd commented 10 years ago

:+1: on using python --version to pick the right linter executable

On 11 August 2014 12:30, Tobias notifications@github.com wrote:

I don't know enough js/coffescript to make a PR.

The problem with virtualenv is that it is not always used. Most likely, it would not be a problem to require it though. The best quick fix would be to just take the name of the pylint executeable as a config option, I think. What we could do in addition is to parse python --version to get the python version. So it will work if the user uses a virtualenv, and if he does not.

— Reply to this email directly or view it on GitHub https://github.com/AtomLinter/linter-pylint/issues/14#issuecomment-51828590 .

dmnd commented 9 years ago

Closing this as #24 addresses it somewhat. If that's not convenient enough we can reopen.

merlijn-sebrechts commented 8 years ago

I'd like to have official support for Python2 and Python3 at the same time. Currently I hacked around this issue using this askubuntu answer: http://askubuntu.com/a/419728/172367

In short, pylint is a small script that checks the first line of the file for python3 and executes either pylint2 or pylint3 based upon that first line.

Arcanemagus commented 8 years ago

@galgalesh How exactly do you propose to accomplish that?

pylint (the regular executable, not your script) automatically switches which version of Python it is checking against based on the python executable it is running under... which is the default for the environment. You can't change that on the fly as it is set at launch.

You can work around that limitation with scripts that force the version of python it is launching like you have linked to, and it's certainly possible to accomplish something similar in here, but it would require at least the following configuration options:

Then the logic for detecting the file mode would need to be implemented in the linter, and the ability to handle one or the other python versions not being present.

The biggest problem that I see with this is that your script relies on "python3" being present in the first line of the file, which is not a requirement, merely a convention you are following, so that isn't a reliable method to determine the mode of a file.

tl;dr: It's a very complex problem that isn't as simple as it seems like you think it is.

merlijn-sebrechts commented 8 years ago

Hi Landon

I understand this is a complex problem. Thank you for your thorough analysis of the problem. I think this is definitely a problem worth tackling seeing as a lot of people will start to make the move from 2 to 3 now that the upcoming Ubuntu LTS release will support Python 3 by default.

I do not know what methods Atom uses at the moment to guess the language of a buffer. I suspect it might be best to rely on the Atom functionality to figure out the language. I suspect it might be possible to extend this functionality to use a number of different methods to guess the Python version used. Figuring out the language from the shebang is a common practice, nano for example does this. So it might be a good idea to add this functionality to that part of Atom.

Now for the loading of pylint in different python versions. I think the best approach here would be to use the console_scripts entry point. This way we circumvent the OS specific differences completely, creating code that is a lot easier to test and debug. From what I understand we would still need the following config options:

I'm not even sure if it is required to add the python3 and python2 config options since it seems logical to me that these should be in the path. A user can easily override the path if his use-case requires changing the python executable.

What do you think?

Arcanemagus commented 8 years ago

Python 2 and Python 3 are the same language, Atom doesn't (and shouldn't!) discriminate between the two.

I'm not sure what you mean by "console_scripts entry point", is that part of pylint's internals? In any case you would still need the python v2 and python v3 paths separated out since "python" can point to either version, depending on what is installed. (On my work computer it loads Python v2, my laptop at home it loads Python v3...)

If you are thinking that "a user can easily override the path" is a valid solution then we are already golden since that is how it currently would need to work :stuck_out_tongue:.

steelbrain commented 8 years ago

@galgalesh If I understand your problem correctly, I don't think we should be doing this on Atom side. Here's what happens when you try to lint a file with this package in Atom

  1. You save the file
  2. This package uses the executablePath config or pylint as the executable path
  3. If executable path is an absolute path it's spawned, otherwise spawned after a lookup in $PATH
  4. The pylint executable checks the version of python it's being run on and lints your file accordingly

Now the solution I have in mind for this is for you to create a pylint bash middleware, which checks the shebang of the file/stdin contents being linted and spawns pylint2 or pylint3 accordingly, then you can specify that executable as the pylint executable in this package's settings.

Supporting special cases for each file type and applying different grammars gets ugly and hard-to-maintain in the long-run and shouldn't be the way of editors IMHO. That being said, Python is one of the most popular languages and it requires workarounds like this one. We could all collaborate and create one middleware for pylint that works for all of us and maybe even ship it along this package and make it an option.

Let me know what you think of this solution

Arcanemagus commented 8 years ago

If you are going to go that far, you might as well just bake in support to pylint to allow overriding the mode with a flag or detecting based on the file instead of auto-detecting the version based on the Python executable.

After all it will know far more about what is allowed or not in specific Python versions :wink:.

steelbrain commented 8 years ago

@Arcanemagus I definately agree with you on making pylint detect the python version based on file shebang instead of the python it was executed from.

Also looks like they moved to github and their repo is quite active, https://github.com/PyCQA/pylint

merlijn-sebrechts commented 8 years ago

Baking this support into Pylint is not possible since Pylint uses the running Python interpreter to get version-specific information. This means that even if pylint can detect the version, pylint running in python2 cannot check python3 code and the other way around. Apart from that pylint2 and pylint3 are two seperate python modules. Each module only supports a single version of python.

The Bash middleware is a good workaround. This answer is a good solution for Ubuntu. We might be able to port this to Mac and Windows.

However, I think it would be better if we could bake support for stuff like this into Atom. linter-pylint is not the only package having this problem, execute-type packages such as atom-runner and script also have to guess the python version. They both do this based on the shebang. It would be great if we could find a solution that could be used by all these packages.

Arcanemagus commented 8 years ago

@galgalesh I think you missed my earlier point that Python code is not required to have a shebang, in fact almost all of the code that I work on does not have that.

Even if the code has it, it's not a guarantee of anything. Somebody could have symlinked /bin/foo to their installed python and be using that in their scripts as the executable defined in the #, you cannot rely on that for anything.

It may be a hacky solution that works for your specific setup, but this linter needs to work for every case that it possibly can.

merlijn-sebrechts commented 8 years ago

The idea is that -if- a shebang is present, we might as well use it to provide a better experience. This has been common practice for a lot of editors, for example nano. Aside from the shebang, I think users are very willing to prepend python3 files with #python3 if it enables them to have linting enabled for both python 2 and 3. I know I have been doing this myself since I discovered the workaround.

To be clear, pylint would not rely on the shebang being present or being meaningful. A meaningless or no shebang would result in the same behavior as pylint has right now. Worst case scenario, someone has a python2 file that starts with *python3*. In this case, the user would either have to disable the guessing behavior or change the first line of his file.

2016-02-11 18:26 GMT+01:00 Landon Abney notifications@github.com:

@galgalesh https://github.com/galgalesh I think you missed my earlier point that Python code is not required to have a shebang, in fact almost all of the code that I work on does not have that.

Even if the code has it, it's not a guarantee of anything. Somebody could have symlinked /bin/foo to their installed python and be using that in their scripts as the executable defined in the #, you cannot rely on that for anything.

— Reply to this email directly or view it on GitHub https://github.com/AtomLinter/linter-pylint/issues/14#issuecomment-182966617 .