This Q&A cheat sheet gives useful suggestions for developing Python code using VS Code on Mac.
- Use Homebrew to install pyenv
- run install skript
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - add path to .zshrc, create file if not there
touch .zshrc echo 'export PATH=/opt/homebrew/bin:$PATH' >> ~/.zshrc
- make it available
source ~/.zshrc
- run install skript
- Use pyenv to install a (or different) python version incl. pip and make it global, and check it
pyenv install X.Y.Z pyenv global X.Y.Z pyenv version
- Make it work and check python version
echo 'eval "$(pyenv init --path)"' >> ~/.zshrc which python python -V
- For each project create an virutalenv with an specific python version and specifc packages
- Make pyenv init available for interatice shells (for login shells use .zprofile)
'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc 'eval "$(pyenv init -)"' >> ~/.zshrc
How to setup an pyenv that has access to core libraries of python to enhance options of building tools like auto-py-to-exe on mac using Python 3.8
- Uninstall current python version
pyenv uninstall X.X.X
- Use Homebrew to install tcl-tk tools
brew install tcl-tk
- Add path variable
echo 'export PATH="/opt/homebrew/opt/tcl-tk/bin:$PATH"' >> ~/.zshrc
- Reload path file
source .zshrc - Set important variables for correct installation of all core libaries
export LDFLAGS="-L/opt/homebrew/opt/tcl-tk/lib" export CPPFLAGS="-I/opt/homebrew/opt/tcl-tk/include" export PKG_CONFIG_PATH="/opt/homebrew/opt/tcl-tk/lib/pkgconfig" export PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/opt/homebrew/opt/tcl-tk/include' --with-tcltk-libs='-L/opt/homebrew/opt/tcl-tk/lib -ltcl8.6 -ltk8.6' --enable-framework"
- Reinstall Python; only works for version 3.8.13
pyenv install 3.8.13
- Go into repository of code, open cmd and run
python -m venv venv
- This creates the virtual env with the python version the command was executed, only availabe for the code in the local folder
- For Proof run in the local folder in cmd:
source venv/bin/activate which python - Important: It's necessary to have the code in a local folder, not in a synced cloud folder. Otherwise the correct python venv cannot be found or activated.
- To check the installed packages of this virtual env
pip list
- To make the dependencies of packages available for other people
pip freeze > requirements.txt - To install packages of foreign Virtual Env
pip install -r requirements.txt
- Stop using the virutal env in cmd
deactivate
- Make sure that venv is listed in your .gitignore file
- Virtual Enviroments are automatically detected by VS Code
- List all python versions installed by pyenv
pyenv versions
- Location of all python versions installed by pyenv
~/.pyenv/versions/ - System means all other versions not installed by pyenv; either system's version, homebrew directly installed or other way
- python
/usr/bin/python
- python3
/usr/bin/python3
- Just leave them alone; otherwise system wont work
- Change user settings globally (for the user)
~/Library/Application Support/Code/User/settings.json - Change user settings locally (in the workspace)
/.vscode/settings.json
# VSCODE
.vscode
# MAC
.DS_Store
._.DS_Store
**/.DS_Store
**/._.DS_Store
- Install pylint as extension or install it as package
pip install pylint
- Define which of them to use: Default uses extension (useBundle)
"pylint.importStrategy": "useBundle",
"pylint.importStrategy": "fromEnvironment"
- Customize it
"pylint.cwd": "${workspaceFolder}/src", "pylint.args": [ "--max-line-length=200", ],
- Install autopep8 as extension or install it as package
pip install autopep8
- Define which of them to use: Default uses extension (useBundle)
"autopep8.importStrategy": "useBundle",
"autopep8.importStrategy": "fromEnvironment",
- Enable it in workspace settings.json
"[python]": { "editor.defaultFormatter": "ms-python.autopep8", "editor.formatOnSave": true, },
- Customize it
"autopep8.args": [ "--max-line-length","200", "--aggressive", "--aggressive"],
- open locally
.vscode/launch.json
- add configuration in workpspace's .vscode/settings.json (or launch.json)
{ "name": "Debug Python Code", "type": "debugpy", "request": "launch", "program": "${file}", "console": "integratedTerminal", "args": [ "--argName", "argValue" ] } - If you're using older python version 3.8 or 3.9, use
"type": "python"to avoid errors
- run python in a shell
import sys print('\n'.join(sys.path))
pip listpipreqs 'PathToProjectFolder'pip3 freeze > requirements.txtpip3 uninstall -r requirements.txt -ypip3 install -r requirements.txt- github_repo
- venv
- dist
- doc
- concept
- pictures
- src
- package
__init.py__module.py- subfolder
__init.py__submodule.py
- package
- tests
example.py
- .gitignore
- README.md
- LICENSE
- setup.py
- pyproject.toml
- github_repo
- venv
- doc
- concept
- pictures+
- archive
old_script_a.py
- src
mainscript_a.pymainscript_b.pymainscript_c.py- packageA
__init.py__module.py- subfolder
__init.py__submodule.py
- packageB
__init.py__module.py- subfolder
__init.py__submodule.py
- notpackageC
module.py
- tests
test.py
- .gitignore
- README.md
- LICENSE
- VS Code: Add the workspace or the src folder to your PYTHONPATH using the launch.json file from VS Code
"env": { "PYTHONPATH": "${workspaceRoot}:src" }
- Using this method all moduls and subfolders are added to PYTHONPATH and can be seen by each other
- Python Only (favorite): Place the main scripts as top-level file directly after the root
src, so that when pyhton inits the script all folders below are automatically added to PYTHONPATH - Main Difference: If main-scripts are nested in folders, moduls in parallel folders cannot be assessed when using pyhton only, while in VS Code everything can be found by adding the workspace. In case the code is used without the VS Code IDE, it's still can be used, when the scripts are place top-level, the pythonic way.
- Develope them as you wish, but try not to use methods from one package in others, which would cause problems regarding linking to each other when VS Code workspace is not in use
- On the longterm this subpackages can be outsourced to be there own packages
- Install local packages by using the -e parameter to benefit from the most recent changes in this packages without having them distributed in knew releases
python install -e path/to/repo/incl/setuppyfile
- Add a test.py or example.py file for the specific modul in /tests or directly in the specific folder
- Be aware which folder's can be assesed by this file
- Option 0:
- Don't create a init.py file at all, a modul can also be assesed without
- But it's helpful to make
- Option 1:
- One top-level init.py file in the pacakge folder listing all modules
from . import module from .subfolder import submodule
- every subfolder needs to have an empty init.py file
- Option 2 (favorite):
- Every folder and subfolder inside the package contains an init.py file listing all modules of the folder
from . import module
- Define setup.py
- IMPORTANT exclude testfiles
from setuptools import setup setup( name='package', version='0.1.0', description='A example Python package', url='https://github.com/shuds13/pyexample', author='Stephen Hudson', author_email='shudson@anl.gov', license='BSD 2-clause', packages=['pyexample'], install_requires=['mpi4py>=2.0', 'numpy', ], classifiers=[ 'Development Status :: 1 - Planning', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: BSD License', 'Operating System :: POSIX :: Linux', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', ], )
- Define the build system in pyproject.toml
- Start build process after upgrading build package
python -m pip install --upgrade build python -m build
- IMPORTANT
- Result should be on top level folder
- EEG.info in the package folder
- Install the wheel file, stored in the dist folder of the built package
pip install path/to/local/wheelfile.whl
- If you want that changes in the local built immidiately affects your code
pip install -e path/to/local/wheelfile.whl
- Before distributing the package on test pypa, name should be test! pypa python -m twine upload --repository 'package' dist/* user: token password: TOKENKEY pip install -i https://test.pypi.org/simple/ package_test==version
python -m twine upload dist/* user: username passwort: passwort pip install package
source "./venv/bin/activate"
python -u background_script.py- edit .zshrc in a shell
sudo nano .zshrc
- add PYTHONPATH to .zshrc so that python can find it
export PYTHONPATH="Path/To/Local/SrcFolder1":"Path/To/Local/SrcFolder2":$PYTHONPATH
- To avoid error warning in terms of lynting, add in VScode settings.json
"python.linting.pylintArgs": [ "--init-hook", "import sys; sys.path.append('Path/To/Local/SrcFolder1')" ]
- To avoid errors with PyLance add in VScode settings.json
"python.analysis.extraPaths": ["Path/To/Local/SrcFolder1"]
- use tags for different releases, x for major changes like python framework switches, y for features, z for patches
git tag -a vX.Y.Z -m "release message" git push origin vX.Y.Z
The package can made availabe as an editable pacakge by pip install -e ., or just use the local_package (as done before)
- github_repo
- venv
- doc
- concept
- pictures
- packages
- package
__init.py__modul_a.pymodul_b.pymodul_c.py
- package
- scripts
script_a.pyscript_b.py- local_package
__init.py__modul_l1.pymodul_l2.py
- notebooks
notebooks.ipynb
- .gitignore
- pyproject.toml (for managing packages)
- config.toml (for managing script paths)
- README.md
- LICENSE
- data (no changeable datasets)
- meta (addtional variable meta information)
- output (script outputs)
Put the script running part after in if __name__ == "__main__":
