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

Improve script section: support use of script files #2310

Open
abn opened this issue Apr 14, 2020 · 37 comments
Open

Improve script section: support use of script files #2310

abn opened this issue Apr 14, 2020 · 37 comments
Labels
kind/feature Feature requests/implementations status/triage This issue needs to be triaged

Comments

@abn
Copy link
Member

abn commented Apr 14, 2020

Improve script support

Rationale & Background

Python packaging supports the distribution and installation of executable scripts by specifying one or more of the following.

  1. Entry points console_scripts
  2. Entry points gui_scripts
  3. Script files

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.

[tool.poetry.scripts]
poetry = 'poetry.console:run'

This should be extended to support various configurations as shown here.

[tool.poetry.scripts]
console-script = {reference = "package.module:function", type = "console"}
gui-script = {reference = "package.module:function", type = "gui"}
file-script = {source = "bin/script.sh", type= "file"}

Entry point script configuration

Name Description
reference Required value corresponding to object reference for the the entry point. Eg: importable.module, importable.module:object.attr
type Optional value indicating the type of script. Defaults to console. Allowed values for reference sourced scripts are console and gui.

File sourced script configuration

Name Description
source Required value corresponding to the source file for the script to be included.
type Optional value indicating the type of script. Defaults to 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.

  1. Project distribution must correctly populate console_scripts and gui_scripts sections of the entry_point.txt file as described by PyPA specifications.
  2. Configuration is backwards compatible with existing 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.

Using extras for an entry point is no longer recommended. Consumers should support parsing them from existing distributions, but may then ignore them. New publishing tools need not support specifying extras. The functionality of handling extras was tied to setuptools’ model of managing ‘egg’ packages, but newer tools such as pip and virtualenv use a different model.

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.

[tool.poetry.scripts]
poetry = 'poetry.console:run'
[tool.poetry.scripts]
poetry = {reference = "poetry.console:run", type = "console"}

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:

setup(
    ...
    entry_points = {
        'console_scripts': ['funniest-joke=funniest.command_line:main'],
    }
    ...
)

pyproject.toml:

[tool.poetry.scripts]
funniest-joke = {reference = "funniest.command_line:main", type = "console"}

Entry point script (gui)

setup.py:

setup(
    ...
    entry_points = {
        'gui_scripts': ['funniest-joke=funniest.gui:main'],
    }
    ...
)

pyproject.toml:

[tool.poetry.scripts]
funniest-joke = {reference = "funniest.gui:main", type = "gui"}

File sourced script

setup.py:

setup(
    ...
    scripts=['bin/funniest-joke'],
    ...
)

pyproject.toml:

[tool.poetry.scripts]
funniest-joke = {source = "bin/funniest-joke", type = "file"}

Related Issues

@abn abn added kind/feature Feature requests/implementations status/triage This issue needs to be triaged labels Apr 14, 2020
@funkyfuture
Copy link
Contributor

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 my-script.

@abn
Copy link
Member Author

abn commented Apr 21, 2020

@funkyfuture yes, this is how it will be installed. The name of the installed script in this instance will be "my-script".

@funkyfuture
Copy link
Contributor

funkyfuture commented Apr 21, 2020

tl;dr

poetry shouldn't establish concepts that blur distinct, existing ones. it should treat equal concepts equally. setuptools entrypoints can be used versatile and poetry shouldn't insinuate assumptions on their use by using specific usage-related terms. a generalized approach on entrypoints allows to canonically handle their optionality that stems from required extras. that lack is a show-stopper for adopting poetry by projects that rely on this feature.

Intro

poetry, today, allows for the handling of console_script and other entrypoints which are defined in two different namespaces within the tool.poetry namespace of a pyproject.toml (plugins & scripts). setuptools' pkg_resources module offers interfaces to canonically query entrypoints, regardless their function.

Entrypoints namespacing

in contrast to the PyPA's entrypoints specification poetry's expects console_scripts - for which beside gui_scripts an extended, afaik non-standardized handling exists - in another namespace than all other entrypoint groups. at the same time all other entrypoint grouposs are lumped together under the term plugins.

other than entrypoints which always point to a member within the package, scripts (as defined by this keyword to setuptools.setup) can point to any file within the distributed package source, but it doesn't necessarily need to be Python code or depend on the package itself. if it was a Python code file, the shebang could point to any Python interpreter and there's no way to control that it would point the one that is used for the package installation. in some cases it is used to install further (non-Python) dependencies or data that is required to make use of the package. another difference between console_scripts entrypoints and scripts is that the former can lead to installations of various executables that execute callables within the same module.

let's take this setuptools setup as an example:

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 console_scripts entrypoints from others and specifies different notation of entrypoints as tables and inline tables:

[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 plugins and scripts are no hard terms, the underlying mechanics actually allow uses that don't fit them. in the example that would be the locale example, which wouldn't match the connotation of a functional enhancement that one may have with plugins. the console_scripts entrypoints could be a standalone server or a complex tool like poetry which most wouldn't recognize as scripts. hence, actually, the term commands might be better suited than console_scripts. while it might an option to use that better term by translating it to setuptools.setup, that would make that name unusable as group name and could hinder the adoption of poetry by projects that may use it.

my proposal is to stick with the well-established and versatile namespacing of setuptools:

[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, poetry may allow nested tables to define entrypoint groups and flatten these:

[tool.poetry.entrypoints.a_frameworks.serializers]
a_format = "a_package.serializers:a_format_serializer"

also, src may be clearer as keyword in the tools.poetry.scripts instead of paths.

All the extras

another important, yet completely missing aspect from poetry that unifies all entrypoints and sets them apart from setuptools scripts is their optionality that depends on the specification of extras. with the above clear distinction and (re-)unification in place, any tools.poetry.entrypoints table's entry could alternatively take an inline table as value to define dependencies on one or more extras. The extras value could either be a string or a list of such that need to point to keys that are defined in the tools.poetry.extras table:

[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"]
}

Transitioning

since a new table entrypoints is used, it should be easy to convert definitions from the plugins table while this is still supported as deprecated feature. the intended use of specifications from the scripts table seems to be distinguishable by heuristics, but i haven't thought deeply about that yet, there might be edge cases.

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?)

@abn abn changed the title Improve script support Improve script section: support use of script files Apr 21, 2020
@abn
Copy link
Member Author

abn commented Apr 21, 2020

@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 entry_points argument to configure all three use cases, this can, in the end, be one of the more confusing aspects of the setup.py file. And this is not something that we should repeat just because it is what is already done. PyPA's interoperability specification exists "to allow build tools other than setuptools to publish pkg_resources compatible entry point metadata, and runtime libraries other than pkg_resources to portably read published entry point metadata (potentially with different caching and conflict resolution strategies)" [1]. It does not dictate or recommend how build tools expose these features to end users in their respective configurations. Any build artifacts produced by Poetry will be interoperable as per the recommended specification.

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 extras and also for distinguishing between console and gui quite easily. For example;

[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"}

@funkyfuture
Copy link
Contributor

However, this conversation has already been had across the linked related issues.

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 scripts distinct from console_scripts. which is then again followed by people talking about task runners.

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).

While setuptools uses the entry_points argument to configure all three use cases

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.

this can, in the end, be one of the more confusing aspects of the setup.py

could you please elaborate on the potential confusion of entrypoints?

And this is not something that we should repeat just because it is what is already done.

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.

The scope of this issue is limited to improve script file support

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 extras in conjunction of executable files with the schema you propose.

@grabear
Copy link

grabear commented May 22, 2020

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):

It's also not super clear in the documentation what the difference is between 'plugins' and 'scripts'.
Based on the original comment:

  • poetry's scripts == setuptools' entrypoint/console_script
  • setuptools' scripts keyword != poetry (is not represented by poetry)

And new information:

By changing the link in the 'plugins' documentation to the one supplied above, I think that would also help clear things up:

From this (main page of setuptools) to this (the actual article).

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:
A) Setuptools is confusing
B) Poetry is confusing
C) Poetry has made itself and Setuptools more confusing

Anyways, I hope this helps!

@kalfa
Copy link

kalfa commented May 30, 2020

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.
In addition, some feature are really confusing and seem to have been not well-though.
This is a a show-stopper for many of us.

@funkyfuture gave a very well presentation on what's needed

To be honest, I want to see a tool that is extendible and powerful.
All the talking I see in many places for this project are about to implement a very limited set of narrowed-down features with a limited use.

Does poetry as a project have a statement on what it wants to achieve?
It's ok if it's "help simple projects to be built". But it means it's not many people who needs advanced tools. Too bad for those people, they'll stay longer with setuptools.

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.
I do not mean to insult anyone, but it feels silly not to take advantege of the great potentiality of this project and design things properly.

@finswimmer
Copy link
Member

Hello,

In addition, some feature are really confusing and seem to have been not well-though.

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.

To be honest, I want to see a tool that is extendible and powerful.

The extensibility is near. With poetry 1.1 there will be a plugin system (#1856)

fin swimmer

@abn
Copy link
Member Author

abn commented Jun 1, 2020

If you think that the old setuptools strategies for accomplishing this are dumb, then don't include them.

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.

My suggestion would be to encapsulate any previously existing strategies using the same syntax to avoid confusion

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.

@grabear
Copy link

grabear commented Jun 8, 2020

@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.

@abn
Copy link
Member Author

abn commented Jun 9, 2020

@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.

@peterdeme
Copy link

Implemented file scripts python-poetry/poetry-core#40
Please review it. Thanks.

@TBBle
Copy link
Contributor

TBBle commented Jan 4, 2021

I assume once python-poetry/poetry-core#40, this will need to be applied to the EditableBuilder here too.

In that case, it'd be great if we could leverage distlib.scripts because that can also create Windows executables for console_scripts-style launchers, rather than the current batch-file generation, which can lead to issues like #2030 (although #2030 itself is a problem in get-poetry.py)

@abn
Copy link
Member Author

abn commented Jan 4, 2021

@TBBle we should be able to reuse the logic if done right; for editable installs.

As for the use of distlib, I need to check what the latest in the packaging community is regarding this. Last I checked there were some differences of opinions in what is "official" and what is not. :(

The get-poetry issues need to be revisited seperately. We need to revisit how poetry itself is distributed. We might end up doing something more standardised later on.

@TBBle
Copy link
Contributor

TBBle commented Jan 5, 2021

Certainly the parsing logic in python-poetry/poetry-core#40 should be reusable in EditableBuilder, but as far as I understand, the Builders in poetry-core will never be responsible for creating the (current) batch or (future) executable for the console_scripts, they just bundle the relevant python file into the sdist/wheel package, and the install-time handler is the one that performs that logic in those cases, because it's install-platform specific.

If distlib itself is a concern, setuptools also exposes a mechanism for configuring exe-runners for console_scripts and gui_scripts. I personally prefer the bundled-exe approach (distlib) to the stock-exe-that-uses-argv[0] (setuptools), but it's only a preference. (pip install -e actually uses the latter, because it delegates such installs entirely to setuptools, but I assume we don't want that).

However, with setuptools, you need to make the determination yourself of whether it's a console_script/gui_script, or (copied) script, in which case implementing the current feature is agnostic to fixing #2030-style issues by replacing the .cmd/.bat wrappers for console_scripts.

@jamesowers-ch
Copy link

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?

@ottomata
Copy link

It seems python-poetry/poetry-core#40 is implemented but, from the master docs here, this change is not being implemented in v1.2?

Also curious about this!

@elitejake
Copy link

Any updates on this?

@arielnmz
Copy link

Any updates? Seems like a pretty bad move to override setuptools scripts but actually implement entry points instead

@neersighted
Copy link
Member

This is mostly implemented in core, but poetry run is currently broken with this variant of scripts, and it is undocumented. PRs documenting it are welcome!

@wagnerluis1982
Copy link
Contributor

wagnerluis1982 commented Feb 20, 2023

I have a question for the current specification.

Why to have different field for each type? Since we have the discriminator type, I don't see a very good reasons to write source and reference depends on the type.

My point is, why not to call everything source or everything reference?

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 reference, any chance to shorten to ref? 🙂

@raxod502
Copy link

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 $PATH like native Python entry points. This does not seem possible with Poetry, although the discussion in this issue and numerous linked issues suggests that it should be. Have I missed something?

@dimbleby
Copy link
Contributor

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.

@TBBle
Copy link
Contributor

TBBle commented May 24, 2023

The linked example should work if a distribution is generated (i.e. an sdist or wheel is output) and installed using pip or other installation tool. The missing thing is just that poetry install specifically doesn't yet know how to handle such scripts, which is why this ticket is still open.

As a workaround, you could use something like https://github.com/nat-n/poethepoet to make those scripts easily running in a poetry install-created environment if you need them during development as well as for end-users.

I don't know what part of the discussion has misled you

One possible piece of confusion is that the original description of that PR included poetry run scriptname as an example, which I don't believe works currently, because that relies on the scripts being installed into the Poetry-managed venv's bin/ folder.

Unless I'm confused, and that is working?

@raxod502
Copy link

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 pyproject.toml:

[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 foo.bash and an empty file called poetry_repro/__init__.py, running pip3 install . finally creates a file foo.bash in the bin subdirectory of the virtualenv. I read this thread and numerous linked discussions but was unable to determine that this was the right combination of parameters to get things working.

@tedmiston
Copy link

As a workaround, you could use something like https://github.com/nat-n/poethepoet

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.

@zeratax
Copy link

zeratax commented Nov 6, 2023

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?

@arielnmz
Copy link

arielnmz commented Nov 7, 2023

@zeratax yeah the docs don't even mention where all those fields come from or how they are used

@TBBle
Copy link
Contributor

TBBle commented Nov 9, 2023

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 type = "console" for PyPA console_scripts entry points scripts. If console_scripts is all you want, then the docs are fine. The callable= syntax is the old syntax, so it works, but is not documented as it has been replaced by the currently-documented syntax for a few years now.

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 poetry install understands this feature (i.e. when this ticket is resolved), then it's likely been shown to lead to confusion from users if they use it, because it works for pip install but not yet for poetry install.

@kristjanvalur
Copy link

so, I just tried type="gui" and it doesn't allow it. Wasn't this supposed to be supported? I just want the script to be launched using pythonw.exe on windows.

@bersbersbers
Copy link
Contributor

Wasn't this supposed to be supported?

Yes, maybe, or not. But definitely not before this issue is closed, which it is not.

@kristjanvalur
Copy link

Wasn't this supposed to be supported?

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.

console-script = {reference = "package.module:function", type = "console"}

Since the syntax is now supported, it seems that the issue is at least half-completed.

@TBBle
Copy link
Contributor

TBBle commented Feb 8, 2024

As-of-today, poetry-core only supports two type values, file and console.

If gui support is added, it won't cause this issue to be closed, as this issue is tracking not just the underlying support in poetry-core, but also integration with poetry, e.g., poetry install, which does not support script types other than console. Adding the new type (or types) to the documentation is probably also required to close this ticket, which of course comes after the code actually works.

@anki-code
Copy link

anki-code commented Mar 1, 2024

file-script = {source = "bin/script.sh", type= "file"}

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:

  1. For example I have script file 'myapp':
#!/usr/bin/env xonsh
echo Hello from @("Xonsh")
  1. I have package with pyproject.toml that includes: xonsh dependency, myapp xonsh script.
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.

@dimbleby
Copy link
Contributor

dimbleby commented Mar 1, 2024

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!)

@xaviergmail
Copy link

I'm pretty confused..

This doesn't work:

[tool.poetry.scripts]
start-web = { reference = "scripts/start-web-app.sh", type = "file" }

But if I move the file, this works:

[tool.poetry.scripts]
start-web = { reference = "start-web-app.sh", type = "file" }

but the expected start-web executable instead uses the reference and it can only be executed by running start-web-app.sh, that's the only script that appears in bin/ after installing with pip (or in the poetry venv).

Is this a bug? I would expect the key (start-web) to be the name of the executable that ends up in bin/ and for references inside subdirectories to work.

@TBBle
Copy link
Contributor

TBBle commented Apr 13, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Feature requests/implementations status/triage This issue needs to be triaged
Projects
None yet
Development

No branches or pull requests