Skip to content

Document how to debug a Briefcase app with popular IDEs #1393

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
freakboy3742 opened this issue Jul 30, 2023 · 6 comments
Open

Document how to debug a Briefcase app with popular IDEs #1393

freakboy3742 opened this issue Jul 30, 2023 · 6 comments
Labels
documentation An improvement required in the project's documentation. enhancement New features, or improvements to existing features. good first issue Is this your first time contributing? This could be a good place to start!

Comments

@freakboy3742
Copy link
Member

What is the problem or limitation you are having?

briefcase dev is the documented way to run a Briefcase app; however, the only way to debug an app with briefcase dev is to set a breakpoint() and use pdb. This is less than ideal, as modern IDEs provide built-in debuggers and test runners.

Describe the solution you'd like

Add documentation how to configure VSCode, PyCharm, and other common IDEs so that their native "run" and "test" mechanisms reproduce what briefcase dev does.

The tl;dr is that you need to:

  1. Add every directory mentioned in sources to the PYTHONPATH
  2. Set the working directory to the user's home directory
  3. Remove the project directory (the directory that contains pyproject.tomlfrom the PYTHONPATH (it's usually the first entry insys.path`)
  4. Run the app name as a module (i.e., the equivalent of python -m myapp)

To run in test mode, you also need to add all the directories mentioned in test_sources, plus change the runtime module to tests.myapp.

Specifics can be found by reverse engineering src/briefcase/commands/dev.py.

We should document the specific instructions for configuring common IDEs (at present, I'd say that means VSCode and PyCharm); but we should also document the generic requirements so that any other IDE user knows what is needed.

Describe alternatives you've considered

Continue to encourage briefcase dev and breakpoint().

Additional context

Documenting manual configuration is a stop-gap measure. Longer term, it would be desirable to capture these instructions as a Briefcase plugin for VSCode and PyCharm.

@freakboy3742 freakboy3742 added enhancement New features, or improvements to existing features. documentation An improvement required in the project's documentation. labels Jul 30, 2023
@freakboy3742 freakboy3742 added the good first issue Is this your first time contributing? This could be a good place to start! label Jul 31, 2023
@pathunstrom
Copy link

Notes on PyCharm:

PyCharm has built in options for adding the content root (the "project" directory. . . usually) and the sources root to the path as part of its run function. Oddly, I cannot seem to disable the content root if I'm using the sources root. This might be a bug in pycharm.

The setting the working directory to the user's home is simple there's a field for it.

image

This also runs in the debugger without issue.

Testing configuration:

This was actually easier, I started with the default test runner configuration for pytest, and filled in the relevant fields. Here, the content root and sources root are actually separate check boxes and seem to work more reliably.

image

@merhovon
Copy link

Anleitung für das Debugging einer BeeWare-Anwendung in Visual Studio Code:

  1. Vorbereitung des Projekts:

    • Stelle sicher, dass du das neueste BeeWare Briefcase und Visual Studio Code installiert hast.
    • Öffne dein BeeWare-Projekt in VS Code.
  2. Konfiguration der Debugging-Einstellungen:

    • Gehe zu der Debug-Ansicht in VS Code (das Symbol, das wie ein Käfer aussieht, in der Sidebar).
    • Erstelle eine neue launch.json-Datei oder bearbeite die vorhandene mit der folgenden Konfiguration:
      {
          "version": "0.2.0",
          "configurations": [
              {
                  "name": "Python Debugger: Attach using Process Id",
                  "type": "python",
                  "request": "attach",
                  "processId": "${command:pickProcess}",
                  "justMyCode": true
              }
          ]
      }
  3. Start des Debuggings:

    • Gebe im integrierten Terminal von VS Code den Befehl briefcase dev ein, um deine BeeWare-Anwendung zu starten.
    • Sobald deine Anwendung läuft, drücke F5 oder klicke auf den grünen "Start Debugging"-Button in der Debug-Ansicht. Du wirst aufgefordert, den Prozess auszuwählen, den du debuggen möchtest – wähle deine BeeWare-Anwendung.
  4. Debugging:

    • Nutze die Debugging-Werkzeuge von VS Code, wie Breakpoints, Schritt-für-Schritt-Execution, Variableninspektion etc., um deine Anwendung zu debuggen.
  5. Beenden des Debuggings:

    • Drücke Shift + F5 oder klicke auf den roten "Stop Debugging"-Button in der Debug-Ansicht, um den Debugging-Prozess zu beenden und zurück zur Entwicklungsumgebung zu gelangen.

@eltoro0815
Copy link

Hi:)

I tried to use the solution for debugging briefcase dev in Visual Code on a Windows 10 System.

My briefcase version is: 0.3.18

Visual Studio Code version is: 1.89.1

I tried to use this launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python Debugger: Attach using Process Id",
            "type": "python",
            "request": "attach",
            "processId": "${command:pickProcess}",
            "justMyCode": true
        }
    ]
}

I run briefcase dev in the integrated Terminal.
I run the Debugger with the name Python Debugger: Attach using Process Id
I am asked to select the process. The briefcase.exe is shown as expected.
After selecting it there are shown three items under CALL STACK:

  • MainThread
  • daciaspringstatus output streamer
  • Dummy-2

The problem is:

- None of my breakpoints is working

Can anybody validate if this solution actually works and give feedback?

@freakboy3742
Copy link
Member Author

@eltoro0815 If you're on Windows, the issue is almost certainly the threading approach used by Windows apps. A Toga windows app immediately starts a subthread which is where the app actually runs. I have no idea if VSCode needs special handling to catch breakpoints in that subthread, but given that we're using the Windows threading API to start that thread, not the Python API, it wouldn't surprise me if VSCode isn't able to "see" the child thread.

@timrid
Copy link

timrid commented Feb 5, 2025

Here's what I found out about debugging briefcases with VSCode:

My Setup:

  • Host system: Windows 11
  • VSCode: v1.96.4
  • VSCode Extension ms-python.python: v2024.22.2
  • VSCode Extension ms-python.debugpy: v2024.14.0
  • Python 3.13.0
  • briefcase: v0.3.21

Debugging briefcase dev

Debugging briefcase dev is very easy with VSCode. You just have to add this configuration in launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Briefcase: Dev",
            "type": "debugpy",
            "request": "launch",
            "module": "briefcase",
            "args": [
                "dev",
            ],
            "justMyCode": false  // this is optional, only if you want to debug into other library (eg. into toga).
        }
    ]
}

Now you just have to execute "Start Debugging" (F5) and it will execute python -m briefcase dev with active debugger in your currently activated (virtual) python environment :)

Debugging briefcase run <platform>

With the briefcase dev approach, however, only code running on the host system can be debugged. To be able to debug Android apps as well, you have to work with a packaged version of the application code using briefcase run android. However, it can also make sense to be able to debug a packaged version on Windows with briefcase run windows, as these work slightly differently to the developer version.

To debug an application in general with briefcase run <platform> the following is required:

  1. Add debugpy as dependency to the project
  2. Call debugpy.listen(5678, in_process_debug_adapter=True) at the beginning of the program.
  3. Add the following configuration to launch.json:
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Briefcase: Attach",
            "type": "debugpy",
            "request": "attach",
            "connect": {
                "host": "localhost",
                "port": 5678
            },
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}/src",
                    "remoteRoot": "<THIS IS PLATFORM DEPENDENT>"
                },
            ],
            "justMyCode": false  // this is optional, only if you want to debug into other library (eg. into toga).
        },
    ]
}
  1. Start the application (briefcase run <platform>)
  2. Attach VSCode debugger
  3. Use VSCode debugger (eg. breakpoints, debug console, ...)

However, this is only the general process. Depending on the platform (Windows, Android), I noticed a few special aspects. As I only have a Windows host PC, I was only able to test these two platforms. In principle, however, this should be transferable to all platforms. (Only the web platform should not work, because debugpy creates an socket server and web browsers only support websocket clients)

Debugging briefcase run android

The following is required to debug an Android application.

  1. Add debugpy as dependency to the project.

Eg. pyproject.toml:

# ...
[tool.briefcase.app.helloworld]
# ...
requires = [
    "debugpy"
]
# ...
  1. Ensure that the .py files are copied to the .apk.

Normally, when creating the Android app, only the compiled .pyc files are transferred to the .apk and not the original .py files. As a result, I was able to insert a breakpoint in the source code via debugpy.breakpoint(), but when I tried to dynamically add a new breakpoint via VSCode, the error "Breakpoint in file that does not exist" always appeared. This is because the .py files are not present in the .apk.

To get the .py files into the .apk, you also have to declare them as test_sources. But this feels more like a workaround. And it is also not possible to set breakpoints in the requirements (e.g. in toga), as only the .pyc files are still available here.

Add this to pyproject.toml

# ...
[tool.briefcase.app.helloworld]
# ...
sources = [
    "src/helloworld",
]
test_sources = [
    "tests",
    "src/helloworld"  # <-- add this
]
# ...
  1. Call debugpy.listen(5678, in_process_debug_adapter=True) at the beginning of the program.
import debugpy

...

def main():
    debugpy.listen(5678, in_process_debug_adapter=True)
    return HelloWorld()
  1. Add the following configuration to launch.json:
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Briefcase: Attach Android",
            "type": "debugpy",
            "request": "attach",
            "connect": {
                "host": "localhost",
                "port": 5678
            },
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}/src",
                    "remoteRoot": "/data/data/com.example.helloworld/files/chaquopy/AssetFinder/app"
                },
                {
                    "localRoot": "${workspaceFolder}/build/helloworld/android/gradle/app/build/python/pip/debug/common",
                    "remoteRoot": "/data/data/com.example.helloworld/files/chaquopy/AssetFinder/requirements"
                },
            ],
            "justMyCode": false
        },
    ]
}
  1. Start the application: briefcase run android

  2. Forward Port 5678 from Emulator/Phone to Local PC via ADB.

adb.exe -s <device-id> forward tcp:5678 tcp:5678

(<device-id> is shown in console while starting. Eg. [helloworld] Starting app on @beePhone (running emulator) (device ID emulator-5554) or can be retrived by adb.exe devices)
(adb.exe is available under %USERPROFILE%\AppData\Local\BeeWare\briefcase\Cache\tools\android_sdk\platform-tools\adb.exe)

  1. Open VSCode and switch to "Run and Debug" (Ctrl+Shift+D), select the configuration "Briefcase: Attach Android" and click "Start Debugging" (F5).

  2. Use VSCode debugger (eg. breakpoints, debug console, ...)

Debugging briefcase run windows

The following is required to debug an Windows packaged application.

  1. Add debugpy as dependency to the project.

Eg. pyproject.toml:

# ...
[tool.briefcase.app.helloworld]
# ...
requires = [
    "debugpy"
]
# ...
  1. Call debugpy.listen(5678, in_process_debug_adapter=True) at the beginning of the program.

Unfortunately, since Python 3.11 this gives an exception AttributeError: module 'os' has no attribute '__file__'

Full traceback
Traceback (most recent call last):
  File "\app\helloworld\__main__.py", line 4, in <module>
    main().main_loop()
    ^^^^^^
  File "\app\helloworld\app.py", line 150, in main
    start_debugpy()
  File "\app\helloworld\app.py", line 86, in start_debugpy
    debugpy.listen(5678, in_process_debug_adapter=True)
  File "\app_packages\debugpy\public_api.py", line 28, in wrapper
    from debugpy.server import api
  File "\app_packages\debugpy\server\__init__.py", line 7, in <module>
    import debugpy._vendored.force_pydevd  # noqa
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "\app_packages\debugpy\_vendored\force_pydevd.py", line 44, in <module>
    preimport('pydevd', [
  File "\app_packages\debugpy\_vendored\__init__.py", line 126, in preimport
    import_module(name)
  File "importlib\__init__.py", line 126, in import_module
  File "\app_packages\debugpy\_vendored\pydevd\pydevd.py", line 39, in <module>
    import pydevd_file_utils
  File "\app_packages\debugpy\_vendored\pydevd\pydevd_file_utils.py", line 98, in <module>
    _library_dir = _get_library_dir()
                   ^^^^^^^^^^^^^^^^^^
  File "\app_packages\debugpy\_vendored\pydevd\pydevd_file_utils.py", line 91, in _get_library_dir
    library_dir = os.path.dirname(os.__file__)
                                  ^^^^^^^^^^^
AttributeError: module 'os' has no attribute '__file__'

I guess that is has something to do with the new frozen imports since Python 3.11. Because of this, os is now a frozen module. And I found a commit in CPython, that added __file__ to frozen stdlib modules. Maybe this is not reflected in the Stub of briefcase-windows-VisualStuido-template? However, I'm not deep enough into the CPython implementation to fully understand the problem.

But as a workaround you can simply set os.__file__ = "".

import debugpy
import os

...

def main():
    if not hasattr(os, "__file__"):
        os.__file__ = ""
    debugpy.listen(5678, in_process_debug_adapter=True)
    return HelloWorld()
  1. Add the following configuration to launch.json:
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Briefcase: Attach Windows",
            "type": "debugpy",
            "request": "attach",
            "connect": {
                "host": "localhost",
                "port": 5678
            },
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}/src",
                    "remoteRoot": "${workspaceFolder}/build/helloworld/windows/app/src/app"
                },
            ],
            "justMyCode": false
        },
    ]
}
  1. Start the application: briefcase run windows

  2. Open VSCode and switch to "Run and Debug" (Ctrl+Shift+D), select the configuration "Briefcase: Attach Windows" and click "Start Debugging" (F5).

  3. Use VSCode debugger (eg. breakpoints, debug console, ...)

@mhsmith
Copy link
Member

mhsmith commented Feb 6, 2025

I haven't tried it for years, but I made some notes about debugging Python code on Android with PyCharm here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation An improvement required in the project's documentation. enhancement New features, or improvements to existing features. good first issue Is this your first time contributing? This could be a good place to start!
Projects
None yet
Development

No branches or pull requests

6 participants