Visual Studio Code: run Python file with arguments - python

Is there an easy way to run a Python file inside Visual Studio Code with arguments?
I know I can add a custom configuration in the launch.json file with the args keyword. However, it is annoying to modify the launch.json file every time just because I want to use different arguments.

Visual Studio Code only supports one launch.json file. However, it supports two or more configurations, and they appear in the left-hand menu/pane's drop down list (instead of "No Configurations").
In the DEBUG pane, either click the Config button circled in red above or click the blue link "create launch.json file":
Click it and it creates a launch.json file with debugging configurations. Edit this file and add the args in this key-pair format AND add multiple for different args including Variable Substitution!
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File with my args",
"type": "python",
"request": "launch",
"program": "${file}",
"args": [
"--username", "Jeremy",
"--account", "Stackoverflow"
],
"console": "integratedTerminal"
},
{
"name": "Python: Current File with UserName arg",
"type": "python",
"request": "launch",
"program": "${file}",
"args": ["${env:USERNAME}"],
"console": "integratedTerminal"
}
]
}
Put a breakpoint in your Python script, for example on the first line under def main(...) and then press F5 or click Run Menu > Start Debugging.

A workaround is to have your script ask for the command-line arguments (in the internal Visual Studio Code console).
This can be made much more usable by leaning on readline, which allows you to do things like press the Up arrow key to cycle through previous commands (command history), and more. An example:
import argparse, readline
def main():
# Ask for additional command line arguments if needed (for VSCode)
parser = argparse.ArgumentParser()
parser.add_argument('--interactive', action='store_true', default=False)
(args, rest) = parser.parse_known_args()
if args.interactive:
try: readline.read_history_file()
except: pass
rest += input("Arguments: ").split(" ") # Get input args
try: readline.write_history_file()
except: pass
# Your other script arguments go here
parser.add_argument("-output-dir", default="/out")
# ...
args = parser.parse_args(rest)
print(args)
if __name__ == "__main__":
main()
Then just set up Visual Studio Code to always pass in the --interactive argument, and your script will always ask for arguments (with history!) even as you set breakpoints.

You can add a custom task to do this. This deals with the tasks.json. You can add a default tasks.json file for you project (project folder). Follow these steps. Keyboard press Ctrl + Shift + B. It will prompt the following popup
Click on the Configure Build Task If there is already a custom tasks.json file created in the following location .vscode/tasks.json editor will open it. If not, it will give a drop down of suggestions of already existing task runners.
Our intention is to create a custom tasks.json file for our project, so to create one we need to select the Others option from the drop down. Check the screenshot below.
Once you select the Others option, you could see a default tasks.json file will get created from the root directory of the project to the location .vscode/tasks.json. Below is an example of tasks.json.
Now edit the tasks.json file to support Python.
Change the Command property from "echo" to "Python"
Keep showOutput as "Always"
Change args (arguments) from ["Hello World"] to ["${file}"] (filename)
Delete the last property problemMatcher
Keep isShellCommand and version properties as unchanged
Save the changes made
You can now open your .py file and run it nicely with the shortcut Ctrl + Shift + B.

If you don’t have a task.json file in your project you can create a new one with press Ctrl + Shift + B. Then choose the first option showing to you then replace all of them with the below:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Run Python with argument",
"type": "shell",
"command": "python PROGRAM_NAME.py ARG1 ARG2 ...",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Otherwise add the above configuration in your existed tasks.json file.
Replace PROGRAM_NAME in the above configuration with your program name and ARG1 ARG2 ... indicate your specific arguments.
After all, you can execute your created task with Ctrl + Shift + B and choose the new "Run Python with argument" task.

Another option is you can run your python program from the commandline via
python3 -m debugpy --wait-for-client --listen localhost:5678 myprogram.py
Then you can use a Python: Remote Attach launch.json configuration to connect to the program. It means an extra step every time to you turn on your program: run the program on the CLI then attach debugger, but it does make specifying the arguments more fluid.
To make things even simpler, you could put the above in a bash script and pass through args from CLI to python:
start.sh "my arg that changes all the time"
Then attach via "Remote Attach".

I have looked for a solution to the issue described here but don't think any of the answers are sufficient so I have created a debugpy-run utility to solve it.
If you have the VS Code Python extension installed then the full debugpy debugger is already bundled with it. The utility finds the path where debugpy is installed and then runs it for program and arguments you specify, in listen mode. Connect to it from within VS Code using the Python "Remote Attach" debug configuration (using the default host and port settings). You can just control+c and then re-run the command with changed arguments using your shell history and command line editing facilities, for each debug run.

In addition, to xdhmoore's answers, for those not too familiar with creating configurations in launch.json, it should look as follows:
"configurations": [
...,
{
"name": "Python: Remote Attach",
"type": "python",
"request": "attach",
"host": "127.0.0.1",
"port": 5678
}
]
To start debugging, first issue the command line command in the terminal and then launch the (newly created) launch configuration Python: Remote Attach from the debug launch menu in VS Code.

I had a similar problem in VS 2019. I wanted to start python file with arguments in environment generated by VS. I wasn't able to find good simple solution, so basically I went to ENV\Scripts folder, opened terminal there and run
python "FullPath\MyFile.py" -some arguments
It works OK, but VS needs to be closed.

If you are using a virtual environment, be sure to use the full path to the environment's Python interpreter.

Maybe this will do what you want: create a python.bat file in your %PATH% that points to python.exe:
C:\Users\joecoder\AppData\Local\Programs\Python\Python37\python.exe %*
Then use a Visual Studio Code terminal window (you can open a new one from the Terminal tab at the top of Visual Studio Code) to change directory to where your .py file resides, and run as normal:
PS C:\Users\joecoder> cd vscode\python
PS C:\Users\joecoder\vscode\python> python test.py 1 2 3
Of course this runs outside of Visual Studio Code, so be sure to write out changes after edits and you'll have to use print() style debugging.

Related

Cannot launch debugger for azure function app in vs code

I am trying to debug an azure function app in VSCode using Python in a Windows10 environment. Whenever I launch the debugger it hangs for a long period of time and then opens a message box that says
ECONNREFUSED 127.0.0.1:9091
There are a bunch of posts about this but none seem helpful/can solve the problem. Here is what I've tried:
uninstalling and re-installing different versions of
azure-function-core-tools using windows installer, npm and chocolatey
uninstalling and re-installing Azure Functions extension in VS Code
changing the extension bundle
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[3.3.0, 4.0.0)"
}
modifying local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "python"
}
}
deleting C:\Users\admin.azure-functions-core-tools\Functions\ExtensionBundles
creating a function app from command line using "func init" and lauching debugger by running "func host start" in active venv
I am using Python38 and really have no idea what else to try. Any suggestions are welcome.
Thanks!
Cannot launch debugger for azure function app in VScode-
ECONNREFUSED 127.0.0.1:9091
This type of generic error may occur for a variety of reasons.
Need to check and modify:
First and foremost, check whether the versions of Azure functions core tools and Pip are upgraded to the current version:
To upgrade pip:
python -m pip install --upgrade pip
To install and upgrade azure-functions:
pip install azure-functions
Go to the below path,
view -> Command palette -> User Settings
Python functions, task runFunctionsHost windows command only work with powershell:
Set the integrated > default profile: Windows to PowerShell as PowerShell runtime host is functional with Python functions. It was previously set to "null".
The debug configuration is specified in your tasks.json and launch.json files in the .vscode folder.
As stated here , the default listening port in launch.json is set to 9091. Here, I updated it to "port: 7071" which is open for traffic on my function project, launched the files, and then executed the "Attach to Python Functions" debug task once again.
Under .VScode folder -> launch.json file, this configuration changes works for me.
launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "python_modules./.bin/func",
"console": "integratedTerminal"
},
{
"name": "Attach to Python Functions",
"type": "python",
"request": "attach",
"port": 7071,
"preLaunchTask": "func: host start"
}
]
}
Added multiple debug points, debugged and triggered successfully as shown below:
Also Check here for more approaches given by #Hari Krishna
found the solution at:
https://github.com/Azure/azure-functions-core-tools/issues/3160#issuecomment-1266273749
I ran command func start in verbose mode
func start --verbose
from there it was clear that the process timed out when trying to download a new extension bundle. Most likely due to slow internet. I manually installed the new extension bundle:
https://functionscdn.azureedge.net/public/ExtensionBundles/Microsoft.Azure.Functions.ExtensionBundle/3.15.0/Microsoft.Azure.Functions.ExtensionBundle.3.15.0_any-any.zip
(the full path should be in the --verbose output) and extracted to
C:\Users[user name].azure-functions-core-tools\Functions\ExtensionBundles\Microsoft.Azure.Functions.ExtensionBundle\3.15.0
It now works. Thanks everyone for input.

Difference between Python on VSCode vs PyChamp or Console Python

A little bit of context...I'm new to python so, Since I am new to the language I've started by googling the best IDE to use with python, many sites recommended Pycharm so I started using it, But since I use VSCode at work I decided to try it but I've experienced some issues with it, and for that reason I not able to use it at the moment. Let me explain maybe someone knows the reason of a possible solution.
I'm currently running Python 3.10.2
In one of my script I use argparse to receive serval execution parameters, in particular a parameter called "FILTER" so in argparse I have defined this parameter as follows:
parser.add_argument('-f', '-filter', '-F', '--FILTER', dest='filter', action='append',
help='Apply column filters according to the operator en value provided')
Basically the idea is to receive a, NAME, OPERATOR and VALUE to filter. ie.
-f TERM_LN!=PLUSS (this works fine in both IDE and python console)
-f CRNCY_CDE=032 (this works fine in both IDE and python console)
-f AMOUNT>=0,02 (this only works on PyCharm and console BUT not in VSCode)
By debugging the script I've noticed that argparse.parse_args() function returns the AMOUNT filter as follows... filter:[' AMOUNT,02'] in VSCode (Incorrect) whereas on the Python console or PyCharm I see it like [' AMOUNT>=0,02'] (Correct)
Just as a side note, when I invoke the script form the console I pass the argument like this...
(venv) C:\dev\PythonProjects\PyAuthomation\venv\Scripts>python ../../generator.py "-f AMOUNT>=0,02" ../../Info.xls --VERBOSE (Verbose is only for getting diagnostics info of the running script)
From Pycharm I've configured the parameters for the script from the option Run -> Edit Configurations... in the parameter option I introduced
"-f AMOUNT>=0,02" Info.xls --VERBOSE
From VSCode from what I've found on the internet the way to provided the parameter for the execution of the python script is by creating the file "Launch.json".
This is my actual configuration...
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"args": [
"-f AMOUNT>=0,02",
"INFO.xls",
"--VERBOSE"
]
}
]
}
I've also noticed that Console or Pycharm only returns the actual parameter value whereas VSCode also return SPACE character between the -f and the Name of the filter as if the space char was part of the actual parameter name, even though I was not expecting that it's easy to solve.
On the other hand, the issue with the ">=" it's not. I have no idea what's the correct way to configure VSCode to accept such types of parameters as plain text just like the PyCharm or the Python console does, It seems that some kind of parsing is causing the issue, but I have no idea Why or any possible workaround for it.
One additional note if I change the ">=" for "=" everything works as expected.
Thanks in advance
Regards
Your problems aren't with argparse, but with how the various inputs are "split" by the shell or ide.
I have a simple script that echos the sys.argv list that argparse works with:
0012:~/mypy$ cat echo.py
import sys
print(sys.argv)
Just using a linux terminal window (console)
0012:~/mypy$ python3 echo.py -f TERM_LN!=PLUSS
['echo.py', '-f', 'TERM_LN!=PLUSS']
0014:~/mypy$ python3 echo.py -f CRNCY_CDE=032
['echo.py', '-f', 'CRNCY_CDE=032']
0014:~/mypy$ python3 echo.py -f AMOUNT>=0,02
0015:~/mypy$ ls =*
'=0,02'
0015:~/mypy$ cat =0,02
['echo.py', '-f', 'AMOUNT']
The last redirected the output to a file1 because of how the shell interpreted the '>'
quoting to block the redirect. This is often needed in shell to block special character handling:
0018:~/mypy$ python3 echo.py -f "AMOUNT>=0,02"
['echo.py', '-f', 'AMOUNT>=0,02']
Notice in all of these the '-f' is a separate string. So your json probably should be:
"args": [
"-f",
"AMOUNT>=0,02",
"INFO.xls",
"--VERBOSE"
]
edit
I'm not quite sure what you mean by 'python console', but since I usually use ipython to test and demonstrate code, I can run a script with it's %run magic.
0845:~/mypy$ ipython3
Python 3.8.10 (default, Nov 26 2021, 20:14:08)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.0.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: %run echo.py -f AMOUNT>=0,02
['echo.py', '-f', 'AMOUNT>=0,02']
That is not using the bash shell, so doesn't redirect.
Using its shell magic I need the quotes:
In [4]: !python3 echo.py -f "AMOUNT>=0,02"
['echo.py', '-f', 'AMOUNT>=0,02']
I use ipython "straight", but judging from other SO questions, people use in other IDEs, such as spyder. I haven't paid attention to those details. I use Geany as my main script editor. You'll also see a lot of Jupyter use, which includes ipython, and browser based notebooks.
Since you are (apparently) using Windows, your shell interactions may be different.
The problem with arguments containing < and > is cmd.
The Python extension passes a command to cmd in a string
cd <somedir> && cmd /C "bit debug command with parameters"
cmd somehow removes the < and > and makes it file redirections for stdin and stdout. I have not found a way to escape the > to prevent cmd from removing it when passed with /C.
The solution is to use a task to start the debugger and attach VSC to this debugger. In the task you can add " to prevent the shell cmd to process the > as a file redirect.
What to do is explained in: How do I redirect input and output in VSC python code to find the text needed for the <path> part in task.json, and you might need to change the extension name ms-python.python-2021.12.1559732655
For your case I use the following
task.json
{
"version": "2.0.0",
"tasks": [
{
"label": "Script for filter",
"type": "shell",
"command": "${command:python.interpreterPath} <path>\\.vscode\\extensions\\ms-python.python-2021.12.1559732655\\pythonFiles\\lib\\python\\debugpy --listen 5678 --wait-for-client ${file} -f \"AMOUNT>=0,02\""
"problemMatcher": []
}
]
}
Watch the passing of the argument -f \"AMOUNT>=0,02\". You have to add " to prevent the terminal shell/cmd to create a file redirect. You have to escape the " inside a JSON string.
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Attach to Process port 5678",
"type": "python",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
}
},
{
"name": "Python: Start Process port 5678",
"type": "python",
"request": "launch",
"code": "print()",
"preLaunchTask": "Script for filter"
}
],
"compounds": [
{
"name": "Debug filter",
"configurations": [
"Python: Start Process port 5678",
"Python: Attach to Process port 5678"
]
}
]
}
Select Debug filter in the debug bar and start the debug session.
Edit
Just found out that if you use Powershell as your integrated terminal the command arguments all get surrounded with '
You only have to split the -f AMOUNT>=0,02 in 2 elements of the args array to make sure they are passed as 2 separate arguments.
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"args": [
"-f",
"AMOUNT>=0,02",
"INFO.xls",
"--VERBOSE"
]
}
]
}

Breakpoints in callbacks are not hit in Python in VS Code

I am new to Python and doing some development on Windows using Python 3.7 + Anaconda + VS Code. Now when I debug my Python program by hitting F5 with a debug configuraiton like this :
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode":false,
"env": {
"PYTHONPATH": "PATH\\TO\\PYTHON"}
}
I discovered that the breakpoints I placed in the callback functions are not hit, while the "normal" breakpoints are. The callbacks are definitely called because I can see the output from the terminal. It should be noted that only callbacks from external packages are not paused by the breakpoints. The callback functions that I created myself do not have this kind of problem. The function can be paused if I place a line breakpoint() but obviously it makes the debug routine very clumsy.
I have searched the web but didn't have too many references of this problem. Anyone happenes to see this before?
UPDATE:
Here I have attached some code and steps I used when launching and debugging. The code looks like this:
class MyDerivedClass(BaseClassOfExternalPackage):
def __init__(self, settings : ExternalPackageSetting):
if settings:
super(MyDerivedClass, self).__init__(settings)
def onConnect(self, msg):
# breakpoint()
self.write_log("Connect success. " + msg)
And the function onConnect is a callback defined in the BaseClassOfExternalPackage from external package. So the breakpoint I put in the self.write_log line, never gets hit although the log is written successfully. And if I uncomment the breakpoint line, the program is paused successfully.
How I debug the program: I click the side-bar of VS-code to select the python executable that I set for this conda env. And the configuration part "env": {"PYTHONPATH": "PATH\\TO\\PYTHON"}, PATH\\TO\\PYTHON is no conda env path, but the root folder of my program (if I don't set it like this it won't import the modules I write)

How to configure VS Code pytest extension to show test results in the integrated terminal (instead of the integrated output)?

When I run tests with the VS Code pytest extension, it prints the results to the integrated output, but I'd rather have them in in the integrated terminal.
I found this, but unfortunately the settings code snippet which might exposes what I am looking for, has dead links on the images and does not show up (couldn't find it in the corresponding github repo neither) :(
Does anyone has a clue how to change this (probably in settings.json)? Is it even possible to print the results in the integrated terminal?
Thanks in advance!
There isn't a way to have test runs triggered via the extension print out to the terminal. You will need to run your tests manually in the terminal to get the output there.
at settings.json add
"python.testing.pytestArgs": [
"-s"
],
if already there is an arg, just add
,"-s"
Try again with the latest update (on 1.61.0 as of writing this) — at this point in time, I am getting the output in the integrated terminal, too.
I tried to add -s to pytest.ini or setting.json and none of them worked. The only way I was able to make something decent was by creating a vscode task:
Just create a simple json Task and use this simple script to either run all the tests in a file or select the function name and run the other task to run a single pytest:
{
"version": "2.0.0",
"tasks": [
{
"label": "pytest-file",
"type": "shell",
"command": "pytest ${file} -s"
},
{
"label": "pytest-test",
"type": "shell",
"command": "pytest ${file} -k ${selectedText} -s"
},
]
}

How to run Run only a Single test in Visual Studio Code and Python with output

Does anyone know how to run only one python test with Test Explorer in Visual Studio Code?
I have installed https://marketplace.visualstudio.com/items?itemName=LittleFoxTeam.vscode-python-test-adapter.
I am using pytest.
In the picture below:
If I press "Run Test" then only one test runs, but I do not see any log / output.
To see the output I have to press "Run", but this runs all my tests. This is incredibly frustrating.
I would like to be able to run only the one test with the Visual Studio Code interface and see the log for this run.
I did not find one elegant way to just run one test and then see the correct sampled/collected output from that test, but I found a way to run only the test I was working on by tagging it with:
#pytest.mark.run_this_test
and hit F5 anywhere in VSCode to just run this test over and over again. The PyTest debug config looks like this:
{
"name": "PyTest",
"type": "python",
"request": "launch",
"console": "integratedTerminal",
"module": "pytest",
"args": [
"-s", "-m run_this_test"
],
"justMyCode": false,
"pythonPath": "${config:python.pythonPath}",
"env": {
"PYTHONPATH": "${workspaceRoot}"
}
This 'tagging' does not scale in a team obviously, but it works for me alone.
I created a repo containing my solution: https://bitbucket.org/geircode/vscode-testsetup-python
To test it:
run the script "requirements.install.bat"
open vscode in the root folder
select "PyTest" in the "debug and run" tab
Hit F5 to start debugging and see the correct output from the test
Check the Output Panel for output (look under the View menu if you're unfamiliar with it). There's probably a channel there where test output is sent (e.g. for the Python extension for VS Code it creates a "Python Test Log" channel for all test output).
From VS Code test explorer it's possible. Hope this helps.

Categories

Resources