Skip to content
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

Poetry-built wheels pollute users' site-packages/ directory #12

Closed
Qonfused opened this issue Jul 31, 2023 · 2 comments · Fixed by #13
Closed

Poetry-built wheels pollute users' site-packages/ directory #12

Qonfused opened this issue Jul 31, 2023 · 2 comments · Fixed by #13
Assignees
Labels
project:library type:bug Something isn't working
Milestone

Comments

@Qonfused
Copy link
Owner

Currently blocked by Poetry's include/exclude paths behavior for the build wheel. The current behavior with Poetry's include/exclude paths works as expected including files for the sdist destination, but not for the wheel destination.

Related issues in tracking:

The output paths in the wheel appear to be determined by the relative paths of included directories from the root pyproject.toml file, which if containing files located in the project root will pollute the user's site-packages/ and site-packages/resources directories upon installation!

Additionally, currently suggested workarounds like symlinks aren't compatible between Windows and macOS/Linux environments.

@Qonfused Qonfused added type:bug Something isn't working project:library labels Jul 31, 2023
@Qonfused Qonfused added this to the v1.0.0-dev milestone Jul 31, 2023
@Qonfused Qonfused self-assigned this Jul 31, 2023
@Qonfused
Copy link
Owner Author

Qonfused commented Jul 31, 2023

A possible workaround is to use a packages: field in the pyproject.toml that points to a build staging area where the package structure is amended to be compatible with setuptools. However, this would require rewriting import paths for third_party.* or ocebuild_cli.*, including cross-references with the base ocebuild library.

The current project structure appears as below: (collapsed)
├── pyproject.toml
├── README.md
├── ocebuild
│   ├── __init__.py
│   └── ...
├── ocebuild_cli
│   ├── __init__.py
│   ├── __main__.py
│   └── ...
└── third_party
    ├── __init__.py
    ├── cpython
    │   ├── __init__.py
    │   └── ...
    └── ...
Which would need to be amended to: (collapsed)
├── pyproject.toml
├── README.md
└── ocebuild
    ├── __init__.py
    ├── cli
    │   ├── __init__.py
    │   ├── __main__.py
    │   └── ...
    ├── third_party
    │    ├── __init__.py
    │    ├── cpython
    │    │   ├── __init__.py
    │    │   └── ...
    │    └── ...
    └── ...

The implementation for the wheel would look like this in the pyproject.toml:

[tool.poetry]
packages = [
  # Redirect poetry to staging area for wheel distribution:
  { include = "ocebuild", from = "dist/staging", format = "wheel" }
]

Although it remains unclear whether to handle this sooner in the sdist preparation rather than redirecting for the wheel.

@Qonfused
Copy link
Owner Author

Qonfused commented Jul 31, 2023

An alternate sdist tree can still be built with the use of poetry's undocumented build hooks (i.e. tool.poetry.build.script). This only relies on poetry-core and can still be built by a PEP-517 front-end like PIP.

For example, this hook can point to a ci/hooks/build.py file that is used to create the staging area (and is automatically included in the sdist by poetry):

pyproject.toml
[tool.poetry]
name          = "ocebuild"
version       = "0.0.0-dev"
description   = "Portable OpenCore EFI dependency & build manager."
authors       = [ "Cory Bennett <csquaredbennett@gmail.com>" ]
# ... omitted for brevity
packages      = [
  # Include required modules for the source distribution:
  { include = "ocebuild",     from = ".",             format = "sdist" },
  { include = "ocebuild_cli", from = ".",             format = "sdist" },
  { include = "third_party",  from = ".",             format = "sdist" },
  # Redirect poetry to staging area for the wheel distribution:
  { include = "ocebuild",     from = "dist/staging",  format = "wheel" }
]

[tool.poetry.build]
generate-setup-file = false
script = "ci/hooks/build.py"

[build-system]
requires      = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
ci/hooks/build.py
from functools import partial

from shutil import rmtree, copytree as _copytree

if __name__ == '__main__':
  copytree = partial(_copytree, dirs_exist_ok=True)

  staging_path = 'dist/staging'
  rmtree(staging_path, ignore_errors=True)

  copytree('ocebuild',      f'{staging_path}/ocebuild')
  copytree('ocebuild_cli',  f'{staging_path}/ocebuild/cli')
  copytree('third_party',   f'{staging_path}/ocebuild/third_party')

Although including the previous proposal, this introduces additional complexity as there needs to exist a dist/staging/ocebuild/__init__.py file before the packages: scope is processed (ref: package_include.py#L59-L62).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
project:library type:bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant