-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Improve script section: support use of script files #2310
Comments
a question unrelated to my proposal, how would you accomplish to drop the file extension here? [tool.poetry.scripts]
my-script = {path = "bin/my-script.sh"} i'm assuming that you propose to install that file as |
@funkyfuture yes, this is how it will be installed. The name of the installed script in this instance will be "my-script". |
tl;dr
Intro
Entrypoints namespacingin contrast to the PyPA's entrypoints specification other than entrypoints which always point to a member within the package, let's take this setup(
entry_points={
"console_scripts": ["theclitool = a_package.cli:a_function"],
"a_frameworks.serializers": ["a_format = a_package.serializers:a_format_serializer"],
"a_frameworks.data_sources": ["that_catalogue = a_package.data:DataLoader.ingest"],
"a_frameworks.locale_strings": ["it-IT = a_package.locales.it:strings"]
},
scripts=["bin/download-catalogue.sh"]
) @abn's proposal continues to separate out the [tool.poetry.scripts]
"download-catalogue.sh" = {path = "bin/download-catalogue.sh"}
theclitool = {entrypoint = "a_package.cli:a_function"}
[tool.poetry.plugins."a_frameworks.serializers"]
a_format = "a_package.serializers:a_format_serializer"
[tool.poetry.plugins."a_frameworks.data_sources"]
that_catalogue = "a_package.data:DataLoader.ingest"
[tool.poetry.plugins."a_frameworks.locale_strings"]
it-IT = "a_package.locales.it:strings" while both my proposal is to stick with the well-established and versatile namespacing of [tool.poetry.scripts]
paths = ["bin/download-catalogue.sh"]
[tool.poetry.entrypoints.console_scripts]
theclitool = "a_package.cli:a_function"
[tool.poetry.entrypoints."a_frameworks.serializers"]
a_format = "a_package.serializers:a_format_serializer"
[tool.poetry.entrypoints."a_frameworks.data_sources"]
that_catalogue = "a_package.data:DataLoader.ingest"
[tool.poetry.entrypoints."a_frameworks.locale_strings"]
it-IT = "a_package.locales.it:strings" alternatively, [tool.poetry.entrypoints.a_frameworks.serializers]
a_format = "a_package.serializers:a_format_serializer" also, All the extrasanother important, yet completely missing aspect from [tool.poetry.extras]
cliframework = ["cleo"]
https-transport = ["requests"]
xml-parser = ["lxml"]
[tool.poetry.entrypoints.console_scripts]
theclitool = {entrypoint = "a_package.cli:a_function", extras = "cliframework"}
[tool.poetry.entrypoints."a_frameworks.data_sources"]
that_catalogue = {
entrypoint = "a_package.data:DataLoader.ingest",
extras = ["https-transport", "xml-parser"]
} Transitioningsince a new table Furher related issues
(yes, i know poetry doesn't want to be setuptools, but i see no advancement in this regard on its side and effectively it's still a setuptools wrapper, isn't it?) |
@funkyfuture thank you for taking the time to provide feedback. However, this conversation has already been had across the linked related issues. As you have mentioned, poetry is not setuptools. While setuptools uses the The scope of this issue is limited to improve script file support, by allowing poetry users to specify a file to be used. To that effect, we do not wish to replace the "plugin" section or duplicate its functionality in another section. The current proposal has been made with future extensibility in mind. I have updated the title to reflect this clearly. An extension to this could include support for [tool.poetry.scripts]
my-script = {path = "bin/my-script.sh", extras=["foo"]}
my-python-script = {entrypoint = "package.module:function", type="console", extras=["cli"]}
my-python-script = {entrypoint = "package.module.gui:function", type="gui"} |
sorry, but no. in #658 the discussion is mainly @brycedrennan explaining what scripts in the scope of packaging are not. in #1023 it's @grabear, @tedmiston and me expressing concerns about the confusing design. in #1504 @peterdeme is proposing to keep none of my points of critique regarding ambiguity, clear distinction, consistency and adequate naming of configuration keys i tried to elaborate above is discussed there in a way that deserves to be called that way (including posts by me).
what would be the three use-cases? my argument is, that there is only one general use-case, to group and to name entrypoints, in order to facilitate infinite concrete use-cases.
could you please elaborate on the potential confusion of entrypoints?
i did not argue that it should be repeated b/c it's already done, but b/c it's done well and simple. i do not see an improvement with the current state, your proposal, or any argument in your rationale that would explain why it would be.
that i see, but i could hardly leave the broader picture out of the scope, because, as you write, the console_scripts end up in the same metadata fields as "plugins" with the same properties, and imo should hence be configured by the user equally to avoid confusion from the start and down the road. one thing i forgot to mention in my previous response; i would expect users to ask for the use of |
Hey guys @funkyfuture and @abn ! Just want to preface with, I love to use poetry! And I'm assuming you guys do too, especially since you're both willing to put so much time into the development process. I'm out of the loop on this and haven't developed with poetry in about 4-5 months. But I will say this.. The current implementation can be confusing it doesn't document the different script strategies used throughout the python universe (including poetry). My suggestion would be to encapsulate any previously existing strategies using the same syntax to avoid confusion #1023 (comment):
And then if you want to create a new poetry specific strategies for deploying scripts, then make sure it's well documented and distinguished from the alternatives (setuptools entrypoint, setuptools console_scirpts, setuptools scripts) If you think that the old setuptools strategies for accomplishing this are dumb, then don't include them. The reason that there are so many issues regarding this is that: Anyways, I hope this helps! |
I agree with @funkyfuture, certain concept are imporant and not discussed. People (like me) are trying for a while to move from setuptools to something else. Poetry is a more valid tool which is really promising, but lacks features. @funkyfuture gave a very well presentation on what's needed To be honest, I want to see a tool that is extendible and powerful. Does poetry as a project have a statement on what it wants to achieve? But, as.I hope, the objetive is to built a powerful extensible tool, then please, listen also to what @funkyfuture says (I would have written something similar, but they did a great work articulating the issues) It's also ok to have a plan which is big, and implementing part of it, step by step. |
Hello,
I suggest to open a new issue about the the things you find confusing, so that we can keep the focus of the discussion here to the suggestions made by @abn . I guess most of the confusing are due to the behavior one knows from other tools and expects to find the same behavior in poetry, which isn't necessarily the case.
The extensibility is near. With poetry 1.1 there will be a plugin system (#1856) fin swimmer |
To be clear, the project team does not consider the setuptools configuration layout for handling this is in anyway shape or form incorrect or "dumb". We simply feel that it does not fit well as is for poetry.
In order to use the same configuration syntax/layout as setuptools temporarily, it would mean implementing new configuration mechanisms within poetry. This is not something that the project team would like to do, we prefer to avoid creating multiple ways to do the same thing. Additionally, this also pollutes the configuration namespace unnecessarily, especially since we know we do not want to keep the setuptools layout for this configuration. A lot has changed since the original implementation for script/plugin support was added to poetry. The documentation, as it stands today, has gaps when detailing the concepts and how they map to entry points/plugins as described by setuptools. At the end of the day, the objective is to enable a poetry user to specify the installation of a script when their package is installed. In our opinion, there is no real advantage in following the exact syntax/layout used by setuptools here. Poetry has to cater to users having varied levels of understanding about Python's packaging. As part of this implementation however, I would expect the documentation to be updated and also provide examples for users that are more familiar with setuptools. I have, based on the above discussions, updated the description to include additional details as well as use new properties to better map to the PyPA specification data model. |
@abn I haven't checked the repo to read any updates. So I'm not sure what you guys have done to the documentation with respect to this issue.. But when you implement the new docs could you explicitly compare poetry's strategies vs setuptools? That way it is clear to the veteran, and novice users. |
@grabear in the issue description under "Comparison with setuptools" I have added configuration comparisons for now, which should get incorporated in the documentation when this is implemented. If you are talking about the documentation in the broader context, I would suggest opening a new issue specifying what areas (outside of console scripts) require these comparisions. Also, feel free to contribute any such changes. Happy to review. |
Implemented file scripts python-poetry/poetry-core#40 |
I assume once python-poetry/poetry-core#40, this will need to be applied to the In that case, it'd be great if we could leverage |
@TBBle we should be able to reuse the logic if done right; for editable installs. As for the use of The |
Certainly the parsing logic in python-poetry/poetry-core#40 should be reusable in If However, with |
Hello, I'm a new poetry user trying to transition from a project using setuptools. It seems python-poetry/poetry-core#40 is implemented but, from the master docs here, this change is not being implemented in v1.2? Please may you advise if and when this feature will be implemented? |
Also curious about this! |
Any updates on this? |
Any updates? Seems like a pretty bad move to override setuptools |
This is mostly implemented in core, but |
I have a question for the current specification. Why to have different field for each type? Since we have the discriminator My point is, why not to call everything For instance: [tool.poetry.scripts]
console-script = {source = "package.module:function", type = "console"}
gui-script = {source = "package.module:function", type = "gui"}
file-script = {source = "bin/script.sh", type= "file"} By the way, if you stick to |
As far as I can tell, this doesn't work as described. There also appears to be no documentation about what the intended behavior is, if it is something different than the original proposal. I filed #7925 asking whether this feature was actually implemented, and if so, how it is intended to be used, but I was told that that question should be asked in this thread instead. So, the question: is there any working example of this feature? I have been unable to construct one - see #7925 (comment) for an unsuccessful attempt - and was eventually forced to remove Poetry from my project. What I expect is that I can install an executable script as part of my Python package, so that it will be added to |
Repeating what I said in the other: that poetry-core MR does not do what you think it does (I don't know what part of the discussion has misled you). There is an open issue - this one! - wishing for the job to be finished. |
The linked example should work if a distribution is generated (i.e. an sdist or wheel is output) and installed using As a workaround, you could use something like https://github.com/nat-n/poethepoet to make those scripts easily running in a
One possible piece of confusion is that the original description of that PR included Unless I'm confused, and that is working? |
Ah, I see. Thank for you the explanation. It never would have occurred to me that this only worked specifically when installing the package with Pip and not with Poetry directly. Indeed, with the following [tool.poetry]
name = "poetry-repro"
version = "0.1.0"
description = "https://github.com/python-poetry/poetry/issues/7925"
authors = ["Radon Rosborough <radon@intuitiveexplanations.com>"]
packages = [{ include = "poetry_repro"}]
[tool.poetry.dependencies]
python = "^3.10"
[tool.poetry.scripts]
foo = {reference = "foo.bash", type = "file"}
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api" And an executable script |
Thanks for sharing, Poe — this looks like what I wanted Poetry scripts to do this whole time. I'll be sure to try that one on my next project. |
Still have trouble understanding how this currently works ^^ the docs say: [tool.poetry.scripts]
devtest = { reference = "mypackage:test.run_tests", extras = ["test"], type = "console" } but to me it seems like this works: [tool.poetry.scripts]
devtest = { callable= "mypackage:test.run_tests", extras = ["test"] } or am I misunderstanding something? |
@zeratax yeah the docs don't even mention where all those fields come from or how they are used |
The docs are correct, but do not yet describe the new "type" added to support this feature (i.e. this ticket), so they only list the already-existing This appears to be all you're after, @zeratax, based on your example. @arielnmz if you think the docs need more details on those fields, I'd suggest opening a new ticket for that, as this ticket is about a new feature, not the existing documented feature, and it'll get lost in the noise here. The JSON schema documents the fields with more detail, but that includes the field values used by this ticket's new feature. The feature from this ticket (PyPA wheel-packaged executable scripts) is not yet documented. This is probably because until |
so, I just tried |
Yes, maybe, or not. But definitely not before this issue is closed, which it is not. |
My mistake, I thought the issue was to support the syntax, including the various types.
Since the syntax is now supported, it seems that the issue is at least half-completed. |
As-of-today, poetry-core only supports two type values, If |
I want to say +1 for this and share you one additional use case. There is https://xon.sh shell (Python package) that is based on Python. Xonsh syntax is based on Python and allows to distribute apps using PyPi. But to run xonsh script it's needed to run script using xonsh. Real life examples you can find in xonsh-awesome-cli-app. This all means this use case:
#!/usr/bin/env xonsh
echo Hello from @("Xonsh")
file-script = {source = "bin/myapp", type= "file"} Then I want to just do: pip install myapp
# After this: xonsh dependency installed, myapp now in ~/.local/bin.
myapp hello
# Because of myapp has xonsh shebang it was executed under xonsh.
# Everything is working out of the box. So I'm +1 for ability to put raw script files into the package. |
poetry already has the ability to put raw script files into the package, the state of this issue is per #2310 (comment) (thumbs up on your own comments don't count!) |
I'm pretty confused.. This doesn't work:
But if I move the file, this works: [tool.poetry.scripts]
start-web = { reference = "start-web-app.sh", type = "file" } but the expected Is this a bug? I would expect the key ( |
Yeah, that does look like a bug. A quick glance at the code shows that the script entry-name is lost, and only the filename is used. That might be deliberate (but is definitely not what I would have expected) but either way it should have found it by relative path compared to the pyproject.toml, looking at the same code. (There's a test-case that covers this code and includes checking relative paths but the failure may be happening in code later than the test-case covers.) I'd suggest opening a new bug for those issues. |
How we can distribute bash script (or other scripts)I would like to add details about the behavior of poetry when installing a script file. In fact, the following lines seem to work:
But, to run 'samplescript', you must use: not This works like that because the reference script is just moved into the bin folder of the target environment. The script is not renamed. For me, this aspect was not really clear, this is why I wanted to clarify it here. A gentle suggestionI would like to propose two things. The first one is to give the possibility to rename the script with a particular option, e.g. target_filename, keeping the current behavior as default one if the option is not given. Here an example:
This way, we can run the script with the command "my_script.sh". We can imagine using only "my_script" or whatever we want. My second suggestion is to document the script feature. For now, poetry documentation just explains how to configure a python script, giving a package path and a function to run. It could be great to have more details to avoid people to search for solutions. Also, it would be great to precise that, as the scripts are copied into the bin, you'll need to use 'pip install .' again each time you modify the script and you want to run it. |
Improve script support
Rationale & Background
Python packaging supports the distribution and installation of executable scripts by specifying one or more of the following.
console_scripts
gui_scripts
The PyPA Entry points specification details the implementation requirement for handling (1) and (2). As for (3), refer to PEP 427.
Poetry, today, allows for the handling of console_scripts as documented here. Non-script entry points (plugins) are also already supported by Poetry as documented here and is considered a separate feature within the context of Poetry.
As part of the requested enhancement, we want to expand the current support distributing scripts with Poetry managed projects to include both entry point scripts as well as file sourced scripts.
Configuration Specification
In order to achieve this, we need to expand the capabilities offered by the scripts section of the poetry configuration. Today, we expect
console_scripts
to be configured as follows.This should be extended to support various configurations as shown here.
Entry point script configuration
importable.module
,importable.module:object.attr
console
. Allowed values for reference sourced scripts areconsole
andgui
.File sourced script configuration
file
for file sourced scripts.While it is possible to detect if a given value is a method or script, the team feels that using an in-line table here will allow for future enhancements to this feature. And furthermore, it allows us to be explicit rather than implicit with respect to the intention.
An implementation of this feature should ensure the following.
console_scripts
andgui_scripts
sections of theentry_point.txt
file as described by PyPA specifications.pyproject.toml
files.Support for extras
Use of
extras
for an entry point will not be supported by poetry. As per PyPA specifications, these are discouraged for new publishers is discouraged and will not be supported by poetry at this time.If in the future, this recommendation changes, adding support for this would be as trivial as adding an additional property
extras
in the script configuration.Backwards compatibility
To ensure older configuration will still work, string values must also be accepted as a script value. This will default to treating it as an entry point console script. The following will be equivalent.
Comparison with setuptools
While these concepts are familiar for users that have used
setuptools
, the intention here is not copy the configuration interface one-to-one, but rather provide an intuitive and objective driven configuration interface within the context of a Poetry managed project.To understand better the differences based on the above specification, here are
setuptools
configurations compared with Poetry configuration achieving the same objective.Entry point script (console)
setup.py
:pyproject.toml
:Entry point script (gui)
setup.py
:pyproject.toml
:File sourced script
setup.py
:pyproject.toml
:Related Issues
scripts
#241The text was updated successfully, but these errors were encountered: