Stability of .emacs under flycheck - python

To get flycheck working for Python, I had reached a satisfactory .emacs, which turned out to require no more than:
(require 'flycheck)
(add-hook 'after-init-hook #'global-flycheck-mode)
Now after a bit of looking forward at what Python 3.6 will be like, even a two-liner
class Foo():
pass
gets a whole slew of warnings:
Too few public methods (0/2) [too-few-public-methods]
Class has no __init__ method [no-init]
Old-style class defined. [old-style-class]
Missing class docstring [missing-docstring]
Missing module docstring [missing-docstring]
despite that I'm now firmly back in 2.7 (sudo port select --set python python27).
Emacs gets us used to being context-agnostic. It usually doesn't matter what is on the system; one gets the same behavior if one starts from an unchanged .emacs. What else might have changed in my system to trigger a sudden increase in flycheck warnings?

OK, I found the answer.
flycheck chooses (silently?) flake8, and if that is not found, it falls back on pylint (and subsequently on pycompile).
The problem was that the symlink flake8 had vanished. Here is why/how.
After selecting python36 and back
~/ > sudo port select --set python python36
~/ > sudo port select --set python python27
and after selecting pip36 and back
~/ > sudo port select --set pip pip36
~/ > sudo port select --set pip pip27
the symlink /opt/local/bin/flake8 disappears. Only flake8-2.7 is left.
> ls -l /opt/local/bin/flake8*
lrwxr-xr-x 1 root admin 70 20 Mar 16:35 /opt/local/bin/flake8-2.7 -> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/flake8
What happens, presumably, is that flake8 points to nothing (port select is updated, and the symlink is removed) when you update to Python 3.6 but do not have flake8-36. The symlink cannot be reinstated when you downgrade to Python 2.7 (one of these, perhaps the former, merits a warning—maybe as a minor bug in MacPorts).
~/ > sudo port select --list flake8
Available versions for flake8:
flake8-27
none (active)
The solution is to explicitly point flake8 to flake8-27 when you downgrade.
~/ > sudo port select --set flake8 flake8-27
Selecting 'flake8-27' for 'flake8' succeeded. 'flake8-27' is now active.
And the link comes back and flycheck chooses flake8 over pylint.
> ls -l /opt/local/bin/flake8*
lrwxr-xr-x 1 root admin 25 7 Sep 09:01 /opt/local/bin/flake8 -> /opt/local/bin/flake8-2.7
lrwxr-xr-x 1 root admin 70 20 Mar 16:35 /opt/local/bin/flake8-2.7 -> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/flake8

Might be better to setup minor mode hook or only add to programming mode
(add-hook 'prog-mode-hook 'flycheck-mode)
By setting it to global will enable it in every buffer even in text mode like org mode which is not needed. Also might slow things down. :)

Related

VSCode. Pylance doesn't work via SSH connection

There is a problem: Pylance (IntelliSense) does not work on the remote server. At the same time it works locally. Pylance itself is installed both locally and on the server. Imports are just white and only "Loading..." pops up when I hover over it. "Go to definition" also doesn't work.
Have a such properties:
Python: 3.10.2;
Pylance: 2022.1.3;
Python extension: v2021.12.1559732655;
Remote - SSH: v0.70.0
VSCode: 1.63.2;
Local OS: Windows 10 Pro;
Remote OS: Ubuntu 20.04.3 LTS
Virtualenv as env;
I've already tried a bunch of options:
Installed other versions of Pylance;
Older versions of the Python extension itself;
Updated Python to the latest version from 3.8.10 to 3.10.2;
Changed the language server to Jedi and reverted to Pylance;
Reinstalled extensions, VSCode;
Recreated the environment with new python.
Added to the remote settings.json this settings:
"python.insidersChannel": "daily", "python.languageServer": "Pylance".
"Python: Show output" gives this output:
Experiment 'pythonaacf' is active
Experiment 'pythonTensorboardExperiment' is active
Experiment 'pythonSurveyNotification' is active
Experiment 'PythonPyTorchProfiler' is active
Experiment 'pythonDeprecatePythonPath' is active
> conda info --json
> ~/jupyter_env/bin/python ~/.vscode-server/extensions/ms-python.python-2021.12.1559732655/pythonFiles/interpreterInfo.py
> ~/.anaconda_backup/bin/conda info --json
Python interpreter path: ./jupyter_env/bin/python
> conda --version
> /bin/python ~/.vscode-server/extensions/ms-python.python-2021.12.1559732655/pythonFiles/interpreterInfo.py
> /bin/python2 ~/.vscode-server/extensions/ms-python.python-2021.12.1559732655/pythonFiles/interpreterInfo.py
> /bin/python3 ~/.vscode-server/extensions/ms-python.python-2021.12.1559732655/pythonFiles/interpreterInfo.py
> /bin/python3.10 ~/.vscode-server/extensions/ms-python.python-2021.12.1559732655/pythonFiles/interpreterInfo.py
> /usr/bin/python2 ~/.vscode-server/extensions/ms-python.python-2021.12.1559732655/pythonFiles/interpreterInfo.py
> /usr/bin/python3 ~/.vscode-server/extensions/ms-python.python-2021.12.1559732655/pythonFiles/interpreterInfo.py
> ". /home/db/jupyter_env/bin/activate && echo 'e8b39361-0157-4923-80e1-22d70d46dee6' && python /home/db/.vscode-server/extensions/ms-python.python-2021.12.1559732655/pythonFiles/printEnvVariables.py"
Starting Jedi language server.
> ~/jupyter_env/bin/python -m pylint --msg-template='{line},{column},{category},{symbol}:{msg} --reports=n --output-format=text ~/data/qualityControl/core/data_verification/dataQualityControl.py
cwd: ~/
##########Linting Output - pylint##########
************* Module core.data_verification.dataQualityControl
18,53,error,syntax-error:non-default argument follows default argument (<unknown>, line 18)
Basically, the problem was that if a large workspace is selected in VSCode, it will try to index it all, and until it finishes, the highlighting won't turn on. In my case, I had several AWS buckets mounted and since there was about 100TB of data, the file indexing simply never finished. If I select a specific project folder, however, the problem disappears. So in case of such a problem, try to specify the working directory. Good luck!
This is fixed by setting the python.language.server to pylance
See GitHub issue 11

Problem with changing python statement with python3 in macOS Catalina

By default when I type python in terminal it goes to python using the 2.7.x version. In oldest versions of macOS once I typed 'alias pyhton=python3' it changed forever and every time I typed python it goes to python version 3.
But in macOS Catalina, I need to type the statement every time I open the terminal.
Any suggestion?
First up, confirm what your default "python" links to, so you can reference it, and ensure that which and the shell agree:
user:~> which python
/usr/bin/python
user:~> type python
python is /usr/bin/python
user:~> ls -la /usr/bin/python
lrwxrwxrwx 1 root root 7 Oct 8 13:26 /usr/bin/python -> python2
Now you can either add an alias to override this in your shell... .
Open your ~/.bash_profile file for bash or ~/.zshrc file for zsh (look here for historical reasons behind the files used) as suggested by shahaf, and add a line with the alias — for example, quick method:
echo "alias python=/usr/bin/python3" >> ~/.bash_profile
echo "alias python=/usr/bin/python3" >> ~/.zshrc
The new alias will be set for the next shell you start, or, open a new Terminal window and source the profile file to make it active. Eg. in bash:
source ~/.bash_profile
Or, change the symlink to point by default to python3, and remember the change (I use a simple toggle script, else any install of a missing python2 package can result in complaints about the configure script, which uses the python symlink directly):
#!/bin/bash
TOGGLE=$HOME/.python3Active
if [ ! -e $TOGGLE ]; then
touch $TOGGLE
sudo ln -fs python3 /usr/bin/python
ls -la /usr/bin/python
echo "Press any key to continue..."
read
else
rm $TOGGLE
sudo ln -fs python2 /usr/bin/python
ls -la /usr/bin/python
echo "Press any key to continue..."
read
fi
Catalina now uses zsh as the default rather than Bash.
To verify which shell you are using type echo $0 in the terminal
Add alias python='python3' to $HOME/.zshrc
you will have to edit the terminal's profile file, usually reside under ~/.profile
add the alias line there, this files get loaded when a terminal session is started and export environment variables and methods so they will be accessible in that session
I suggest to use a more robust and powerful terminal enhancement like Z-Shell

Can my Python script distinguish between if it was run as root or if it was run through sudo?

[root#hostname ~]# python script.py # allow this
[user#hostname ~]$ sudo python script.py # deny this
[user#hostname ~]$ sudo -E python script.py # deny this
[user#hostname ~]$ sudo PATH=$PATH python script.py # deny this
[user#hostname ~]$ python script.py # kindly refuse this
I'm trying to achieve the behavior above. Read further if you care why or if the example isn't sufficient enough. Sorry for the sharp tongue, but most of my Stack Exchange questions get hostile questions back instead of answers.
This question arises from requiring an admin to run my script, but the nature of the script requires root's environment variables (and not sudo's).
I've given this some thorough research... below is from this answer
if os.geteuid() == 0:
pass # sufficient to determine if elevated privileges
But then I started needing to access PATH inside of my script. I noticed that
sudo -E env | grep PATH; env | grep PATH
prints different PATH values. I found it was because of the security policy on PATH. I also found the workaround to PATH is sudo PATH=$PATH ...
However, it's not the only policy protected environment variable, and at that point, why push this enumeration of environment variables on the script user? It seems that requiring root explicitly is the best approach, and just warn the admin to use root explicitly from within the script otherwise.
Is there such a way to distinguish between root and sudo with Python?
Despite the reasons discussed to not pursue this solution, I actually did find it for others wondering if it's possible.
[user#hostname ~]$ sudo python
>>> import os
>>> os.environ["SUDO_UID"] # UID of user running sudo
'uid'
And when logged in as root...
[root#hostname ~]# python
>>> import os
>>> try:
... uid = os.environ["SUDO_UID"]
raise AssertionError("Ran with sudo")
... except KeyError, e:
... ... # SUDO_UID, SUDO_USER, etc. not set without sudo
I also found a way to access root's PATH just running with sudo.
path = os.popen("su - -c env | grep ^PATH= | cut -d'=' -f2-").read().strip()
I think I like this solution better than relying on how my script is ran.
You're going to get "hostile questions" because the premise of your issue doesn't make much sense. In general if a command can be run as the root user via sudo then it should not matter whether it was run via sudo (or runas, etc.) or by some other mechanism that has the UID set to root such as an interactive login as the root user. You should not require running a program to be predicated on an interactive login as the root user account rather than via a setuid program like sudo or your program if it were setuid root.
A cheap and dirty solution is to ensure the interactive root login sets a unique env var that is unlikely to be set when your program is run via sudo. That is, however, obviously easy to spoof so if you're doing this for security then that approach is not acceptable.
Use the subprocess module to run commands and check the output:
from subprocess import check_output
uid = check_output(['bash', '-c', 'echo $UID']).decode().strip()
if uid != '0':
sys.exit() # or return
or
user = check_output(['whoami']).decode().strip()
if user != 'root':
sys.exit() # or return
It appears that aside from checking $PATH, root and sudo are indistinguishable.

python setup.py sdist error: Operation not permitted

I'm trying to create a python source package, but it fails when creating hard links for files.
$ python setup.py sdist
running sdist
running check
reading manifest template 'MANIFEST.in'
writing manifest file 'MANIFEST'
making hard links in foo-0.1...
hard linking README.txt -> foo-0.1
error: Operation not permitted
I've tried running the command with sudo, but it produces the same error.
This also produces the same error:
ln foo bar
I'm using vbox to run a virtual instance of ubuntu, which is probably where the problem comes from. Is there a way round using hard links when creating source distributions?
System information:
Ubuntu server 11.04;
VirtualBox 4.14;
osx 10.6.6;
python 2.7.1;
Same issue. I am using vagrant, my host OS is Windows while the Gust OS is Ubuntu. I am not a vim fan, so #simo's answer does not help me much because I really rely on virtual box shared folders to sync changes made by sublime editor to the Ubuntu virtual machine.
Thanks to Fabian Kochem, he found a quick and dirty workaround: post
# if you are not using vagrant, just delete os.link directly,
# The hard link only saves a little disk space, so you should not care
if os.environ.get('USER','') == 'vagrant':
del os.link
I ran into the same issues.
I was able to get it working by moving the python sources from the virtual box shared folder to my debian home folder. No error on sdist anymore.
I hope it helps.
It is unclear from your question what step is failing. Might be the hard linking right before the error. You can try strace to see what system call is failing. That should give a better picture of the problem at least.
This python bug report looks like they're not going to fix this until distutils2. Someone did supply a patch that might be useful to you. You might also be able to mount a directory over NFS and build there. I believe that NFS allows hard linking.
Looks like this was fixed in Python version 2.7.9 - https://hg.python.org/cpython/raw-file/v2.7.9/Misc/NEWS
Issue #8876: distutils now falls back to copying files when hard linking
doesn't work. This allows use with special filesystems such as VirtualBox
shared folders
This is the way I reached a working uwsgi(Ubuntu 14.04, default Python 2.7.6) with Python-2.7.10.
Steps
Before continuing, you must compile new Python with --enable-shared:
$ ./configure --enabled-shared
$ sudo make altinstall
Context: Ubuntu 14.04 with Python 2.7.6 with uwsgi and uwsgi-python-plugin installed with apt-get
Problem: I have a virtualenv for my all with compiled Python-2.7.10
# Previously installed Python-2.7.10 as altinstall
$ python2.7
Python 2.7.10 (default, Nov 25 2015, 11:21:38)
$ source ~/env/bin/activate
$ python
Python 2.7.10 (default, Nov 25 2015, 11:21:38)
Preparing stuff:
$ cd /tmp/
$ git clone https://github.com/unbit/uwsgi.git
$ cd uwsgi
$ make PROFILE=nolang
# On /tmp/uwsgi
$ PYTHON=python ./uwsgi --build-plugin "plugins/python python27"
On ini file:
[uwsgi]
plugins = python27
Results on:
** Starting uWSGI 1.9.17.1-debian (64bit) on [Thu Nov 26 12:56:42 2015] ***
compiled with version: 4.8.2 on 23 March 2014 17:15:32
os: Linux-3.19.0-33-generic #38~14.04.1-Ubuntu SMP Fri Nov 6 18:17:28 UTC 2015
nodename: maquinote
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 12
current working directory: /etc/uwsgi/apps-enabled
detected binary path: /usr/bin/uwsgi-core
your processes number limit is 257565
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: enabled
uwsgi socket 0 bound to UNIX address /var/run/uwsgi/app/pypi-server/socket fd 3
Python version: 2.7.10 (default, Nov 26 2015, 11:44:40) [GCC 4.8.4]
None of the above answers solved my problem. However, I was running the following command in a vagrant shared folder on Centos 6:
python setup.py bdist_bdrpm
And ended up with the error:
ln: creating hard link `xxx': Operation not permitted
error: Bad exit status from /var/tmp/rpm-tmp.S9pTDl (%install)
It turns out that it's a bash file that eventually executes the hard links:
cat /usr/lib/rpm/redhat/brp-python-hardlink
#!/bin/sh
# If using normal root, avoid changing anything.
if [ -z "$RPM_BUILD_ROOT" -o "$RPM_BUILD_ROOT" = "/" ]; then
exit 0
fi
# Hardlink identical *.pyc and *.pyo, originally from PLD's rpm-build-macros
# Modified to use sha1sum instead of cmp to avoid a diffutils dependency.
find "$RPM_BUILD_ROOT" -type f -name "*.pyc" | while read pyc ; do
pyo="$(echo $pyc | sed -e 's/.pyc$/.pyo/')"
if [ -f "$pyo" ] ; then
csha="$(sha1sum -b $pyc | cut -d' ' -f 1)" && \
osha="$(sha1sum -b $pyo | cut -d' ' -f 1)" && \
if [ "$csha" = "$osha" ] ; then
ln -f "$pyc" "$pyo"
fi
fi
done
Therefore you should be able to replace the hard link ln -f "$pyc" "$pyo" with a copy command cp "$pyc" "$pyo" in the above shell script.

Can you have more than one python in terminal?

I'm a bit confused with what is happening to run my django apps. When I use the command python manage.py runserver I don't get the appropriate response from the server. However, when I use python2.6 manage.py runserver the server actually runs.
Can someone help me with this confusion and also suggest to me how I can simplify this problem? Ideally I don't want different versions of python and only want to be able to type python manage.py runserver
Yes. It is fairly common. You can find out the location of an executable with which, and resolve symlinks with ls.
$ ls -l `which python`
lrwxrwxrwx 1 root root 9 Jul 13 18:50 /usr/bin/python -> python2.6
$ ls -l `which python3`
lrwxrwxrwx 1 root root 9 Jul 27 22:24 /usr/bin/python3 -> python3.1
On Debian and some other systems, you may need to resolve multiple symlinks.
$ ls -l `which nc`
lrwxrwxrwx 1 root root 20 Oct 7 15:16 /bin/nc -> /etc/alternatives/nc
$ ls -l /etc/alternatives/nc
lrwxrwxrwx 1 root root 15 Oct 7 15:16 /etc/alternatives/nc -> /bin/nc.openbsd
If you want to only type python and get the version you want, make an alias. Add a line to your .bashrc file (or wherever you keep such lines):
alias python=python2.6
Note that this will not affect scripts: if you run "python" in a script, it will get the old version, not an alias. Aliases are only for interactive use.
Yes, it is possible to have two versions of python. The easiest way I've found to make python execute python2.6 (without breaking the other version for anyone else) is by using an alias. To do this, simply edit the following and add it to your ~/.profile file:
alias python=/path/to/your/python2.6
Log out and back in, and when you run python it should execute the correct binary. If you wish to revert back, simply delete this line from your ~/.profile.
Yes, you can have multiple versions of Python sitting side-by-side on your computer.
It sounds like python on your host is symbolically linked to a version other than python2.6. You can find out this version by running:
python --version
...or...
python -V
...if that does not work.
Setting the default Python version depends on how you installed Python in the first place.
For Mac OS X, see How can I change the default Python version on Snow Leopard?

Categories