Skip to content

    Chapter 8, Environment

    Which tool to choose, editor and project structure

    Five tools do similar things. I compare them with objective criteria and say what I would choose in each situation.

    Code for this chapter: ambiente/cap08_estrutura_projeto.py

    Comparison

    Criterionpip and venvpyenvpipxPoetryuv
    Installs Python versionsNoYes (compiles)NoNoYes (pre-built binaries)
    Creates virtual environmentYes (venv)NoOne per toolYesYes
    Resolves indirect dependenciesBasicNoNoYesYes
    Generates lockfileNoNoNoYesYes
    Installs CLI toolsNoNoYesNoYes (uv tool)
    Publishes packagesNoNoNoYesYes (uv publish)
    Learning curveLowAverageLowAverageLow

    My recommendation

    I would choose uv for new projects because it covers the entire cycle with a single tool. I would choose Poetry if the team is already using it and the poetry.lock is in production: switching managers for trendiness is a cost without return. I would choose pip and venv to learn and for restricted environments where only the system's Python is available: what you learn there applies to everything else. I would choose pyenv if I needed a specific build of Python. I would choose pipx for global tools on machines where uv is not available.

    Editor

    VS Code with the Microsoft Python extension solves most cases. After opening the project folder, choose the interpreter with the command Python: Select Interpreter (the command palette opens with Ctrl+Shift+P, or Cmd+Shift+P on macOS) and point to the .venv of the project. PyCharm is a complete alternative if you prefer an IDE.

    Be careful with the Code Runner extension

    By default, Code Runner executes the file in the Output panel of VS Code, which does not accept input. Examples with input() get stuck or fail there. Run in the integrated terminal (python3 arquivo.py) or use the Run Python File button from the official extension.

    The minimum structure of a project

    Estrutura recomendada
    meu-projeto/
      pyproject.toml
      README.md
      .python-version
      .gitignore
      src/
        meu_projeto/
          __init__.py
          __main__.py
      tests/
        test_basico.py
    

    Every entry point should be importable without executing anything. The default is a main() protected:

    ambiente/cap08_estrutura_projeto.pylinhas 10 a 15
    def main() -> None:
        print("projeto funcionando")
    
    
    if __name__ == "__main__":
        main()
    
    Output
    projeto funcionando
    

    I explain the reason for this protection in the modules chapter.

    Exercise 1

    Set up your working environment

    Create a folder meu-primeiro-projeto, fix Python 3.13, create the environment, install requests and confirm within Python that the environment is active.