I am unable to solve the flake8 SyntaxError and although the code executes just fine.
Code without comments
import math
def answer(str_n):
sume = ((str_n * (str_n + 1)) / 2) * math.sqrt(2)
sume = int(sume)
return sume
def answer1(str_n):
sume = 0
for i in range(str_n + 1):
sume += math.floor(i * math.sqrt(2))
# print i,math.floor(i*math.sqrt(2))
return sume
print "Test answer:", answer(77)
print "Actual answer:", answer1(77)
As #jonrsharpe says, and I agree, this is because the code is being run in Python 2, but linted in Python 3.
From the flake8 documentation on error codes:
We report E999 when we fail to compile a file into an Abstract Syntax Tree for the plugins that require it.
So to prove this is correct, using a file called bad_syntax.py and using the same print syntax as above:
print "test answer", len([])
When I run this with Python 2, everything is happy:
james#codebox:/tmp/lint$ python --version
Python 2.7.12
james#codebox:/tmp/lint$ python bad_syntax.py
test answer 0
Linting with flake8 invoked with a Python 2 environment also passes.
But when I lint with Python 3 (this is running in a virtualenv venv with Python 3 installed), the E999 is returned:
(venv) james#codebox:/tmp/lint$ flake8 --version
3.5.0 (mccabe: 0.6.1, pycodestyle: 2.3.1, pyflakes: 1.6.0) CPython 3.5.2 on Linux
(venv) james#codebox:/tmp/lint$ flake8 bad_syntax.py
bad_syntax.py:1:19: E999 SyntaxError: invalid syntax
I do not think that this is a setting that needs changing inside linter-flake8 because Flake8 will use the version of Python that it is run through. My guess would be that Flake8 is being run on Python 3 because it has been installed inside a Python 3 environment, even though the code is being run on Python 2.
Flake8 launcher has Python3 hardcoded as main python.
How to fix:
1) install flake8 package using pip
$ pip install flake8
pip will tell you that flake8 script hasn't been added to path and print path to it (/Library/Frameworks/Python.framework/Versions/2.7/bin/ in my case)
2) tune your IDE (Atom/PyCharm/etc) to use this script with your default Python 2.7 (my example is from PyCharm # MacOS):
PyCharm -> Preferences -> External tools -> "flake8 - current file"
Program: /usr/local/bin/python
Arguments: /Library/Frameworks/Python.framework/Versions/2.7/bin/flake8 --ignore=E501,E124,E127,E128 $FilePath$
Working directory: $FileDir$
[x] open console for tool output
Output filters: $FILE_PATH$\:$LINE$\:.*
It will work correctly without reporting E999.has
Related
I am delivering a Makefile to some people to run some python steps, example:
build:
pip install -r requirements.txt
package:
python3 -m build
The assumption here is that some of the people running the Makefile will have python 3 responding by calling python while some other will have it responding at python3 (some of them will even have an alias that will make both respond). Same happens for pip/pip3 command.
How can I discover which is the name of the interpreters to invoke programmatically through the same Makefile?
I don't want to tell them to change the Makefile manually to fit their system, I want it simply to work.
You can figure out what version of python (or pip?) it is by parsing the output of shell command asking for the version string:
# Variable for the python command (later overwritten if not working)
PYTHON_COMMAND := python
# Get version string (e.g. Python 3.4.5)
PYTHON_VERSION_STRING := $(shell $(PYTHON_COMMAND) -V)
# If PYTHON_VERSION_STRING is empty there probably isn't any 'python'
# on PATH, and you should try set it using 'python3' (or python2) instead.
ifeq $(PYTHON_VERSION_STRING),
PYTHON_COMMAND := python3
PYTHON_VERSION_STRING := $(shell $(PYTHON_COMMAND) -V)
ifeq $(PYTHON_VERSION_STRING),
$(error No Python 3 interpreter found on PATH)
endif
endif
# Split components (changing "." into " ")
PYTHON_VERSION_TOKENS := $(subst ., ,$(PYTHON_VERSION_STRING)) # Python 3 4 5
PYTHON_MAJOR_VERSION := $(word 2,$(PYTHON_VERSION_TOKENS)) # 3
PYTHON_MINOR_VERSION := $(word 3,$(PYTHON_VERSION_TOKENS)) # 4
# What python version pip targets is a little more difficult figuring out from pip
# version, having python version at the end of a string containing a path.
# Better call pip through the python command instead.
PIP_COMMAND := $(PYTHON_COMMAND) -m pip
When I do pylint main.py, I get the following error:
E: 7, 0: invalid syntax (<string>, line 7) (syntax-error)
# main.py
import os
repo = os.environ.get('GITHUB_REPOSITORY')
branch = os.environ.get('GITHUB_REF')
commit = os.environ.get('GITHUB_SHA')
commit_url = f'https://github.com/{repo}/commit/{commit}'
repo_url = f'https://github.com/{repo}/tree/{branch}'
print(commit_url, repo_url)
The code is running as expected but pylint is giving this strange error. I am using Python 3.6.9 on Ubuntu 18.04.
It looks like PyLint isn't happy with your f-strings (introduced in 3.6) and is validating against the syntax of an older Python version. I'd check whether the PyLint you are using is running from the same Python environment your Python you are running the program with. I would guess it's running from your system Python, while your program is running from a virtual environment.
With pylint 2.5.3 and Python 3.8.2 the only complaint PyLint makes is about the lack of a module docstring.
************* Module main
main.py:1:0: C0114: Missing module docstring (missing-module-docstring)
-----------------------------------
Your code has been rated at 8.57/10
Use .format method like below
import os
repo = os.environ.get('GITHUB_REPOSITORY')
branch = os.environ.get('GITHUB_REF')
commit = os.environ.get('GITHUB_SHA')
commit_url = 'https://github.com/{}/commit/{}'.format(repo, commit)
repo_url = 'https://github.com/{}/tree/{}'.format(repo, branch)
print(commit_url, repo_url)
Check here, Python 3 returns "invalid syntax" when trying to perform string interpolation
I have a makefile where I have targets that depend on having some external clients installed (python3, libxml2, etc).
Here is my makefile
.PHONY: test install-packages mac-setup checkenv target help
EXTERNALS = python3 pip3 xmllint pytest pipenv
P := $(foreach exec,$(EXTERNALS),$(if $(shell which $(exec)),missing,$(warning "===>>>WARNING: No required `$(exec)` in PATH, run `make mac-setup` + `make install-packages` <<<===")))
test: ## run all tests in test directory
pipenv run pytest -v --ignore=path payload_files .
install-packages: ##install python packages listed in Pipfile
pipenv install
mac-setup: ## setup mac for testing
brew install libxml2
brew install python3
brew install pipenv
# see https://github.mycompany.com/ea/ea_test_player_unified/blob/master/run-feature.sh
help:
#grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
.DEFAULT_GOAL := help
Notice the line
P := $(foreach exec,$(EXTERNALS),$(if $(shell which $(exec)),missing,$(warning "===>>>WARNING: No required `$(exec)` in PATH, run `make mac-setup` + `make install-packages` <<<===")))
This checks for the binaries required. This works.... however I would rather have a checkenv target that performs this and errors so I can attach it too specific targets like test instead of printing out a WARNING that might be overlooked.
Want:
checkenv: # error if which ${binary} fails or *even better* if if binary --version doesn't return the right version: python3 pip3 xmllint pytest pipenv
I tried various techniques that I found around the web including stackoverflow.... but most use the technique I am using above that don't use a make target or just check for one binary. I tried building a loop through an array of binaries but just couldn't get the syntax correct due to make being a PITA :)
Any suggestions?
Note I'm a python newbie, task is to rewrite some jmeter tests in python....so if you have any thoughts on the above approach feel free to share.
Thanks,
Phil
Don't see what the problem is. It looks very straightforward to me, as make allows using multiple targets on the same line:
EXTERNALS := python3 pip3 xmllint pytest pipenv
python3_version := Python 3.7.3
pip3_version := ...
...
.PHONY: checkenv $(EXTERNALS)
checkenv: $(EXTERNALS)
$(EXTERNALS):
if [ "`$# --version`" != "$($#_version)" ]; then echo "$# check failed"; false; fi
I have the following CMakeLists.txt file, which is instructed to use Python 3.4
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/../cmake/")
project(aConfigd VERSION 1.0)
string(TOLOWER aConfigd project_id)
find_package(PythonInterp 3.4 REQUIRED)
include(FindPythonInterp)
set(PYTHON ${PYTHON_EXECUTABLE})
message(STATUS "\${PYTHON_EXECUTABLE} == ${PYTHON_EXECUTABLE}")
set(pkgdatadir /usr/share/configd)
set(configdir /etc/amy)
set(SONARCONFIGID_SOURCE_DIR etc/configd)
set(SRC_DIR configd/src/)
include(common)
# "${SRC_DIR}/systemd_client.py"
# "${SRC_DIR}/amyconfig_service.py"
"${SRC_DIR}/__init__.py"
"${SRC_DIR}/main.py"
"${SRC_DIR}/application.py"
DESTINATION ${pkgdatadir}/configd/
)
#general
set(CPACK_PACKAGE_NAME "a-config")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "a-config-manager")
set(CPACK_PACKAGE_DESCRIPTION "a-config-manager")
# redhat
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
/etc/amy
)
include(cpack)
Indeed, it confirms that ${PYTHON_EXECUTABLE} == /usr/bin/python3.4 (see 4th line below):
$ make clean ; cmake -DCMAKE_BUILD_TYPE=Release -DSHORT_VERSION=NO -DCUSTOMER=NO .. ; make -j12 ; make package
-- Found PythonInterp: /usr/bin/python3.4 (found suitable version "3.4.5", minimum required is "3.4")
-- Found PythonInterp: /usr/bin/python3.4 (found version "3.4.5")
-- ${PYTHON_EXECUTABLE} == /usr/bin/python3.4
-- Build Type: Release
-- Detected distribution: rhel fedora
-- Detected aConfigd version: 2.3.0-3030-gf7733cf659
-- Detected distribution: rhel fedora
-- Configuring done
-- Generating done
-- Build files have been written to: /local/raid0/git/amy/aConfig/build
Run CPack packaging tool...
CPack: Create package using RPM
CPack: Install projects
CPack: - Run preinstall target for: aConfigd
CPack: - Install project: aConfigd
CPack: Create package
CPackRPM:Warning: CPACK_SET_DESTDIR is set (=ON) while requesting a relocatable package (CPACK_RPM_PACKAGE_RELOCATABLE is set): this is not supported, the package won't be relocatable.
CPackRPM: Will use GENERATED spec file: /local/raid0/git/my/aConfig/build/_CPack_Packages/Linux/RPM/SPECS/a-config.spec
CPack: - package: /local/raid0/git/my/aConfig/build/a-config-2.3.0-3030-gf7733cf659.el7.my.x86_64.rpm generated.
$
However, if I uncomment the "${SRC_DIR}/systemd_client.py" line, I get the error:
Compiling /local/raid0/git/my/aConfig/build/_CPack_Packages/Linux/RPM/a-config-2.3.0-3030-gf7733cf659.el7.my.x86_64/usr/share/configd/configd/systemd_client.py ...
File "/usr/share/configd/configd/systemd_client.py", line 21
def __init__(self, systemd_proxy:Gio.DBusProxy):
^
SyntaxError: invalid syntax
Isn't def __init__(self, systemd_proxy:Gio.DBusProxy): a valid Python 3.4 syntax?
If yes, why does Cmake complains?
The root-cause occurs in the rpmbuild step.
RPM is trying to be extra-helpful, and tries to (byte-code) compile .py files it encounters.
Alas, it wrongly uses the python2 interpreter to create a file's byte-code (even though find_package(PythonInterp 3.4 REQUIRED) is declared in the CMakeLists.txt file).
The fix that worked for me was:
set(CPACK_RPM_BUILDREQUIRES python34-devel)
set(CPACK_RPM_SPEC_MORE_DEFINE "%define __python ${PYTHON_EXECUTABLE}")
When you just run "${SRC_DIR}/systemd_client.py", you're telling it to run that script the same way it would be run by the shell: by looking at the #! line and running it with whatever interpreter is specified there. Which is probably something like #! /usr/bin/python or #! /usr/bin/env python.
If you want to run your script with a particular interpreter, you have to run that interpreter and pass it the script—just as you would at the shell. I'm pretty rusty with CMake, but I'd assume you do that like this:
"${PYTHON_EXECUTABLE}" "${SRC_DIR}/amyconfig_service.py"
Alternatively, since this is your code, maybe you want to use setuptools to programmatically generate scripts for your entry-points, which means it would create a #! line for them that runs whichever Python version was used to run setup.py.
Does anyone know of anything like pylint or pychecker for notepad++? Or perhaps how to use pylint in notepad++.
If you install the Python Script plugin, then you can add a new script with the following lines to get pretty good results:
console.show()
console.clear()
console.run('cmd.exe /c '
+ 'C:\\Python26\\Scripts\\pylint.bat --reports=n -f parseable '
+ '"%s"' % notepad.getCurrentFilename())
The output will include hyperlinks to the lines with the errors/warnings (if the filenames don't have spaces in them...)
The option "-f parseable" is deprecated in the current version of Pylint.
The current equivalent alternative is:
console.run('cmd.exe /c '
+ 'C:\\Python26\\Scripts\\pylint.bat --reports=n '
+ '--msg-template="%s" %s'
% ( '{path}:{line}: {msg_id}({symbol}), {obj} {msg}', notepad.getCurrentFilename()))
Note: python path can be different e.g. C:\\Python27.
Note2: double quotes in --msg-template="..." are important
You could install PyLint using python -m pip install pylint and use it via Notepad++'s Run... command (F5):
cmd /c python -m pylint "$(FULL_CURRENT_PATH)" & pause
To get the output in Notepad++ and link to the code, use NppExec.
None of the other answers worked for me, but this does:
Install PyLint using python -m pip install pylint
Install NppExec via the Plugin Manager, press F6, and save this script as "PyLint":
NPP_SAVE
cd "$(FULL_CURRENT_PATH)"
env_set PYTHONIOENCODING=utf-8
python -u -m pylint "$(FULL_CURRENT_PATH)"
Sample output:
NPP_SAVE: C:\Users\Cees\Documents\http_ear.py
CD: C:\Users\Cees\Documents\http_ear.py
Current directory: C:\Users\Cees\Documents
ENV_SET: PYTHONIOENCODING=utf-8
$(SYS.PYTHONIOENCODING) = utf-8
python -u -m pylint "C:\Users\Cees\Documents\http_ear.py"
Process started (PID=25136) >>>
************* Module http_ear
http_ear.py:16:0: C0301: Line too long (1780/100) (line-too-long)
http_ear.py:17:0: C0301: Line too long (226/100) (line-too-long)
http_ear.py:26:0: C0304: Final newline missing (missing-final-newline)
------------------------------------------------------------------
Your code has been rated at 8.00/10 (previous run: 8.00/10, +0.00)
<<< Process finished (PID=25136). (Exit code 16)
================ READY ================
You can link the bug locations using NppExec's Console Output Filters. Press Shift+F6 and enable this filter with Red set to FF:
%FILE%:%LINE%:%CHAR%
Then double clicking a red line focuses the specified location in the editor.
You should use the Executable instead of the Batch if you want to use Pylint within NotePad++.
Go to the Configuration from Python Script and create a new .py File to run Pylint from that. (i called my file npphelper.py)
(Add that npphelper.py to Menu-items and Toolbar-icons, then you can execute it by pressing a Button.)
This will run Pylint into Notepad++, i splitted the Command into 2 Parts:
pyLint = 'C:\\PROGRA~1\\Python35\\Scripts\\pylint.exe --reports=n'
console.show()
console.clear()
console.run('%s "%s"' % (pyLint, notepad.getCurrentFilename()))
Path to pylint.exe (i used a Shortname instead of Doublequotes)
The File you want to check with Pylint (actualy returns the Path from active Tab)
(You have to change the Paths so that it fits to your Installation...)
All you have to do now is saving this npphelper.py, open the Tab with your Project-File and run the npphelper.py you created for pylint. (e.g. via button)
If you don't want to use the default Configuration then generate a pylintrc Template (save them where you want). I've done it via CMD with the following Command:
pylint.exe --generate-rcfile>>myfilename.pylintrc
Then you need to change some lines into the npphelper.py:
rcfile = 'C:\\PROGRA~1\\Python35\\Scripts\\myrcfile.pylintrc'
pyLint = 'C:\\PROGRA~1\\Python35\\Scripts\\pylint.exe --reports=n --rcfile="%s"' % rcfile
console.show()
console.clear()
console.run('%s "%s"' % (pyLint, notepad.getCurrentFilename()))
I've installed Python Script 1.0.8.0 with all the Extras using the .msi File here.
(Using the PluginManager in Notepad++ gives you version 1.0.6.0 instead of 1.0.8.0)
I use Windows 7 with Notepad++ 6.9.1, Python 3.5.1 and Pylint 1.5.5.
(i installed pylint via CMD -> "pip install pylint" and updated it.)
Some more usefull Links:
How do I create a pylintrc file
PyLint “Unable to import” error - how to set PYTHONPATH?