beeware / beeware/briefcase

`sysconfig.get_path("purelib")` returns `site-packages` folder instead of `app_packages`

Open
#2,435 3 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Python
Stars
3.3k
Forks
549
Avg merge
1d 4h
Merged PRs (30d)
40

Description

### Describe the bug

`sysconfig.get_path("purelib")` returns `site-packages` folder instead of `app_packages`

Some libraries access `sysconfig.get_path("purelib")` to get the path of the folder, where the 3rd party libraries are installed. E.g. pydevd ([see here](https://github.com/fabioz/PyDev.Debugger/blob/3030fa9908187513bdd3e3dd93bfa897a95a6ece/pydevd_file_utils.py#L80)) or debugpy ([see here](https://github.com/microsoft/debugpy/blob/b00a8129977494bd127dd0bfed22082597762a08/src/debugpy/_vendored/pydevd/pydevd_file_utils.py#L80))

Currently `sysconfig.get_paths()` returns on Windows
```
{
'stdlib': '...\build\helloworld\windows\app\src\Lib',
'platstdlib': '...\build\helloworld\windows\app\src\Lib',
'purelib': '...\build\helloworld\windows\app\src\Lib\site-packages',
'platlib': '...\build\helloworld\windows\app\src\Lib\site-packages',
'include': '...\build\helloworld\windows\app\src\Include',
'platinclude': '...\build\helloworld\windows\app\src\Include',
'scripts': '...\build\helloworld\windows\app\src\Scripts',
'data': '...\build\helloworld\windows\app\src'
}
```

But `...\build\helloworld\windows\app\src\Lib\site-packages` does not exists, because all libraries are inside `...\build\helloworld\windows\app\src\app_packages`.

### Steps to reproduce

1. Create an example briefcase app
2. Add
```
import sysconfig
print(sysconfig.get_path("purelib"))
```
3. Run `briefcase run`

### Expected behavior

`sysconfig.get_path("purelib")` should return the path to the `app_packages` folder instead of the non existing `site-packages` folder.

### Screenshots

_No response_

### Environment

- Operating System: Windows 11
- Python version: 3.13
- Software versions:
- Briefcase: 0.3.24

### Logs

```

```

### Additional context

There has already been discussion about whether it makes sense to use the standard `site-packages` folder instead of a custom `app_packages` folder, and why it was rejected: https://github.com/beeware/briefcase/issues/2195

I created a working `sysconfig` patch function that can may be used:

```python
def _patch_sysconfig():
import sysconfig

BRIEFCASE_SCHEME = "briefcase"

sysconfig._INSTALL_SCHEMES[BRIEFCASE_SCHEME] = {
"stdlib": "{installed_base}/Lib",
"platstdlib": "{base}/Lib",
"purelib": "{base}/app_packages",
"platlib": "{base}/app_packages",
"include": "{installed_base}/Include",
"platinclude": "{installed_base}/Include",
"scripts": "{base}/Scripts",
"data": "{base}",
}

__orig_get_paths = sysconfig.get_paths
__orig_get_path = sysconfig.get_path

def get_default_scheme():
return BRIEFCASE_SCHEME

def get_paths(*args, **kwargs):
if len(args) >= 1:
new_args = list(args)
if new_args[0] is None:
new_args[0] = BRIEFCASE_SCHEME
args = tuple(new_args)
elif "scheme" not in kwargs or kwargs.get("scheme") is None:
kwargs["scheme"] = BRIEFCASE_SCHEME
return __orig_get_paths(*args, **kwargs)

def get_path(*args, **kwargs):
if len(args) >= 2:
new_args = list(args)
if new_args[1] is None:
new_args[1] = BRIEFCASE_SCHEME
args = tuple(new_args)
elif "scheme" not in kwargs or kwargs.get("scheme") is None:
kwargs["scheme"] = BRIEFCASE_SCHEME
return __orig_get_path(*args, **kwargs)

sysconfig.get_default_scheme = get_default_scheme
sysconfig.get_paths = get_paths
sysconfig.get_path = get_path
```

Contributor guide

Open the contributing guide

Research direction

No implementation file or test is named. Start with the Windows app startup path used by `briefcase run` and the `sysconfig.get_path("purelib")` reproduction, then trace how the app's installation scheme is selected. Done means `purelib` and `platlib` resolve to the existing `app_packages` directory and the behavior is covered for the reported Windows environment.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
build-system
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.