Skip to content

Commit

Permalink
introduce tool.poetry.self.plugins section to define Poetry plugins…
Browse files Browse the repository at this point in the history
… that are required for the project (python-poetry#9547)

* when running `poetry install` and required plugins are not available in Poetry's own environment they are installed only for the project into .poetry/plugins inside the project folder
* when creating the application .poetry/plugins is added to the front of sys.path

Co-authored-by: Arun Babu Neelicattu <[email protected]>
  • Loading branch information
radoering and abn committed Jul 14, 2024
1 parent d32d667 commit 37416f5
Show file tree
Hide file tree
Showing 27 changed files with 1,305 additions and 115 deletions.
22 changes: 22 additions & 0 deletions docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,28 @@ You can also list all currently installed plugins by running:
poetry self show plugins
```

### Project plugins

You can also specify that a plugin is required for your project
in the `tool.poetry.self` section of the pyproject.toml file:

```toml
[tool.poetry.self.plugins]
my-application-plugin = ">1.0"
```

If the plugin is not installed in Poetry's own environment when running `poetry install`,
it will be installed only for the current project under `.poetry/plugins`
in the project's directory.

The syntax to specify `plugins` is the same as for [dependencies]({{< relref "managing-dependencies" >}}).

{{% warning %}}
You can even overwrite a plugin in Poetry's own environment with another version.
However, if a plugin's dependencies are not compatible with packages in Poetry's own
environment, installation will fail.
{{% /warning %}}


## Maintaining a plugin

Expand Down
15 changes: 15 additions & 0 deletions docs/pyproject.md
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,21 @@ any custom url in the `urls` section.

If you publish your package on PyPI, they will appear in the `Project Links` section.

## `self`

In this section, you can specify requirements for Poetry itself.

You can also specify that a plugin is required for your project:
You can specify that certain plugins are required for your project:

```toml
[tool.poetry.self.plugins]
my-application-plugin = ">=1.0"
my-plugin = ">=1.0,<2.0"
```

See [Project plugins]({{< relref "plugins#project-plugins" >}}) for more information.

## Poetry and PEP-517

[PEP-517](https://www.python.org/dev/peps/pep-0517/) introduces a standard way
Expand Down
18 changes: 10 additions & 8 deletions src/poetry/console/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import re

from contextlib import suppress
from functools import cached_property
from importlib import import_module
from pathlib import Path
from typing import TYPE_CHECKING
from typing import cast

Expand Down Expand Up @@ -111,20 +113,13 @@ def __init__(self) -> None:

@property
def poetry(self) -> Poetry:
from pathlib import Path

from poetry.factory import Factory

if self._poetry is not None:
return self._poetry

project_path = Path.cwd()

if self._io and self._io.input.option("directory"):
project_path = Path(self._io.input.option("directory")).absolute()

self._poetry = Factory().create_poetry(
cwd=project_path,
cwd=self._directory,
io=self._io,
disable_plugins=self._disable_plugins,
disable_cache=self._disable_cache,
Expand Down Expand Up @@ -340,6 +335,7 @@ def _load_plugins(self, io: IO | None = None) -> None:
from poetry.plugins.application_plugin import ApplicationPlugin
from poetry.plugins.plugin_manager import PluginManager

PluginManager.add_project_plugin_path(self._directory)
manager = PluginManager(ApplicationPlugin.group)
manager.load_plugins()
manager.activate(self)
Expand Down Expand Up @@ -382,6 +378,12 @@ def _default_definition(self) -> Definition:

return definition

@cached_property
def _directory(self) -> Path:
if self._io and self._io.input.option("directory"):
return Path(self._io.input.option("directory")).absolute()
return Path.cwd()


def main() -> int:
exit_code: int = Application().run()
Expand Down
3 changes: 3 additions & 0 deletions src/poetry/console/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from cleo.helpers import option

from poetry.console.commands.installer_command import InstallerCommand
from poetry.plugins.plugin_manager import PluginManager


if TYPE_CHECKING:
Expand Down Expand Up @@ -106,6 +107,8 @@ def handle(self) -> int:

from poetry.masonry.builders.editable import EditableBuilder

PluginManager.ensure_project_plugins(self.poetry, self.io)

if self.option("extras") and self.option("all-extras"):
self.line_error(
"<error>You cannot specify explicit"
Expand Down
4 changes: 1 addition & 3 deletions src/poetry/console/commands/self/show/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@ def _system_project_handle(self) -> int:
}

for group in [ApplicationPlugin.group, Plugin.group]:
for entry_point in PluginManager(group).get_plugin_entry_points(
env=system_env
):
for entry_point in PluginManager(group).get_plugin_entry_points():
assert entry_point.dist is not None

package = packages_by_name[canonicalize_name(entry_point.dist.name)]
Expand Down
Loading

0 comments on commit 37416f5

Please sign in to comment.