spyder-ide / spyder

Official repository for Spyder - The Scientific Python Development Environment
https://www.spyder-ide.org
MIT License
8.22k stars 1.59k forks source link

Request: command line option to specify interpreter #18805

Open jeremymatt opened 2 years ago

jeremymatt commented 2 years ago

I'm exploring the recommended method of having a single spyder install and then selecting different conda environments from the interpreter list as necessary. However, I find the current workflow to be somewhat clunky (i.e., run spyder, click preferences, click Python Interpreter, select "use the following...", select the interpreter, close preferences, start a new console).

Is it possible to pass the path of a conda environment (i.e., the output of python -c "import sys; print(sys.executable)") when calling spyder from the anaconda command prompt? My use-case is that I would like to be able to write a batch script that takes the name of a conda environment as an argument, builds the interpreter path, and then calls spyder with that interpreter path.

I realize that this is both a relatively minor issue and may be niche functionality, but it'd be nice to have added if it's not too much trouble.

PS: I did some searching around and checked spyder -h and didn't find any obvious solutions. Sorry if I missed something

ccordoba12 commented 2 years ago

Hey @jeremymatt, thanks for your suggestion. Unfortunately, there's no such option but it shouldn't be hard to add. Please take a look at PR's #16518 and #17657 to see how this is done for different plugins.

In your case, you need to read the new command line option you want to add (let's say -i for interpreter) in the MainInterpreter plugin and set the executable option (see PR #17788) on it.

jeremymatt commented 2 years ago

Thanks for the tips, I'll play around with it and see if I can get it working.

nobubblegums commented 1 year ago

Hi @jeremymatt , were you able to do this? I switch environments a lot yet still install spyder on each one, changing interpreters on standalone spyder feels clunky indeed.

ccordoba12 commented 1 year ago

@nobubblegums, I think your use case will be covered once we merge the functionality developed in pull request #20421.

afkrause commented 1 year ago

I was about to request the same: a command line option to specify the python interpreter path. I hope that functionality will be implemented soon. That would be awesome!

raffaem commented 8 months ago

In the meantime I made a script that start spyder using the Python interpreter of the currently active pyenv virtual environment, and set working dirrectory to the current working directory to:

#!/usr/bin/env bash

SPYDERENV=spyder-env

# Get binary to activate spyder virtual environment
SPYDERACT="$HOME/.pyenv/versions/$SPYDERENV/bin/activate"
if [ ! -f "$SPYDERACT" ]; then
    printf "Activate binary for spyder environment not found: \"%s\"\n" "$SPYDERACT"
    exit 1
else
    printf "Found spyder activate binary: \"%s\"\n" "$SPYDERACT"
fi

# Get foreign virtual environment
ENV=$(pyenv version | awk '{print $1}')
printf "Using pyenv foreign virtual environment \"%s\"\n" "$ENV"

# Spyder doesn't like symbolink links in transient.ini/executable
ENVPATH=$(readlink -fn $HOME/.pyenv/versions/$ENV)
# printf "ENVPATH=%s\n" "$ENVPATH"
if [ ! -d "$ENVPATH" ]; then
    printf "ENVPATH is not a directory"
    exit
fi

# Get path of the Python interpreter of the foreign environment
ENVINT="$ENVPATH/bin/python"
if [ ! -f "$ENVINT" ]; then
    printf "Interpreter \"%s\" does not exist\n" "$ENVINT"
    exit 3
else
    printf "Found interpreter: \"%s\"\n" "$ENVINT"
fi

# Check if `spyder-kernels` python package is installed in foreign environment
# and install it if it isn't
ENVPYVER=$(ls "$ENVPATH/lib" | tr -d "\n")
# printf "ENVPYVER=%s\n" "$ENVPYVER"
ENVPKG="$ENVPATH/lib/$ENVPYVER/site-packages/spyder_kernels"
# printf "ENVPKG=%s\n" "$ENVPKG"
if [ ! -d "$ENVPKG" ]; then
    printf "Installing python package \"spyder-kernels\" in virtual environment\n"
    ENVPIP="$ENVPATH/bin/pip"
    if [ ! -f "$ENVPIP" ]; then
        printf "ERROR: Cannot find pip in environment: \"%s\"\n" "$ENVPIP"
        exit 3
    fi
    "$ENVPIP" install --upgrade spyder-kernels >/dev/null 2>&1
else
    printf "Python package \"spyder-kernels\" is already installed in virtual environment\n"
fi

printf "Starting spyder\n"

# Change spyder.ini
SPYDERINI="$HOME/.config/spyder-py3/config/spyder.ini"
if [ ! -f "$SPYDERINI" ]; then
    printf "ERROR: Cannot find spyder.ini in \"%s\"\n" "$SPYDERINI"
    exit 1
fi
sed -E -i.bak \
    -e '/^\[main_interpreter\]$/,/^\[/ s/^(default\s?=\s?).*/\1False/' \
    -e '/^\[main_interpreter\]$/,/^\[/ s/^(custom\s?=\s?).*/\1True/' \
    -e '/^\[workingdir\]$/,/^\[/ s/^(console\/use_project_or_home_directory\s?=\s?).*/\1False/' \
    -e '/^\[workingdir\]$/,/^\[/ s/^(console\/use_cwd\s?=\s?).*/\1False/' \
    -e '/^\[workingdir\]$/,/^\[/ s/^(console\/use_fixed_directory\s?=\s?).*/\1True/' \
    -e '/^\[workingdir\]$/,/^\[/ s/^(startup\/use_project_or_home_directory\s?=\s?).*/\1False/' \
    -e '/^\[workingdir\]$/,/^\[/ s/^(startup\/use_fixed_directory\s?=\s?).*/\1True/' \
    "$SPYDERINI"
# DEBUG
# printf "\n# spyder.ini -> [main_interpreter]\n"
# printf "%s\n" "------"
# sed -n '/^\[main_interpreter\]$/,/^$/ {/^$/!p}' "$SPYDERINI"
# printf "%s\n" "------"

# Change transient.ini
PWD=$(pwd)
# printf "PWD=%s\n" "$PWD"
PWDESC=${PWD//\//\\/}
# printf "PWDESC=%s\n" "$PWDESC"
TRANSIENTINI="$HOME/.config/spyder-py3/config/transient.ini"
if [ ! -f "$TRANSIENTINI" ]; then
    printf "ERROR: Cannot find transient.ini in \"%s\"\n" "$TRANSIENTINI"
    exit 1
fi
sed -E -i.bak \
    -e "/^\[workingdir\]$/,/^\[/ s/^(startup\/fixed_directory\s?=\s?).*/\1${PWDESC}/" \
    -e "/^\[workingdir\]$/,/^\[/ s/^(console\/fixed_directory\s?=\s?).*/\1${PWDESC}/" \
    -e "/^\[run\]$/,/^\[/ s/^(default\/wdir\/fixed_directory\s?=\s?).*/\1${PWDESC}/" \
    -e "/^\[main_interpreter\]$/,/^\[/ s/^(custom_interpreters_list\s?=\s?).*/\1\[\]/" \
    -e "/^\[main_interpreter\]$/,/^\[/ s/^(custom_interpreter\s?=\s?).*/\1${ENVINT//\//\\/}/" \
    -e "/^\[main_interpreter\]$/,/^\[/ s/^(executable\s?=\s?).*/\1${ENVINT//\//\\/}/" \
    "$TRANSIENTINI"
# DEBUG
# printf "\n# trainsient.ini -> [workingdir]\n"
# printf "%s\n" "------"
# sed -n '/^\[workingdir\]$/,/^$/ {/^$/!p}' "$TRANSIENTINI"
# printf "%s\n" "------"
# printf "\n# transient.ini -> [run]\n"
# printf "%s\n" "------"
# sed -n '/^\[run\]$/,/^$/ {/^$/!p}' "$TRANSIENTINI"
# printf "%s\n" "------"
# printf "\n# transient.init -> [main_interpreter]\n"
# printf "%s\n" "------"
# sed -n '/^\[main_interpreter\]$/,/^$/ {/^$/!p}' "$TRANSIENTINI"
# printf "%s\n" "------"
# printf "\n"

. "$SPYDERACT"
spyder
printf "Script ended\n"

Using it like this:

  1. Install Spyder in its own virtual environment:
    pyenv virtualenv 3.12 spyder-env
    . $HOME/.pyenv/versions/spyder-env/bin/activate
    pip install --upgrade spyder numpy scipy pandas matplotlib sympy cython spyder-line-profiler spyder-notebook spyder-terminal
  2. Activate the environment under which your script is supposed to run (different from the environment in which Spyder is installed)
  3. Call the script
raffaem commented 8 months ago

Anyway looks like Spyder 6 will have a plugin for that: https://github.com/spyder-ide/spyder-env-manager

ccordoba12 commented 8 months ago

Unfortunately, that plugin is in alpha state yet and we need more funding to take it to the next level.