python-poetry / poetry

Python packaging and dependency management made easy
https://python-poetry.org
MIT License
30.87k stars 2.25k forks source link

Support generation of poetry manged setup.py file #761

Closed abn closed 3 years ago

abn commented 5 years ago

Issue

As things stand today, poetry packages cannot be installed using pip or any other package managers from a VCS. This is useful when working with unreleased/unpublished versions of dependencies, where dependencies are managed by 'pip' or another tool. This was briefly touched on in #34 for a similar use case.

With this in mind, it could be great if poetry provided a solution, in a limited capacity, similar to what is implemented by poetry-setup. In order to achieve this, poetry could provide a command, eg: poetry setuptools:setupfile, that generates a usable setup.py file using the mechanism used today by SdistBuilder.

In theory, this could be migrated to be a plugin once #693 is implemented.

As an example. this, if implemented, could be used by projects as a pre-commit hook to generate setup.py file on commit. This should allow projects using pip etc. to install unpublished projects developed using poetry (if the maintainer wants it).

In addition to the above use case, this also allows for tools like PyCharm etc., to auto detect requirements and metadata.

Can follow this up with a proposed implementation PR.

Relates-to: #34

webknjaz commented 5 years ago

@abn other way to do it is to actually publish each commit to Test PyPI :)

abn commented 5 years ago

@webknjaz that would definitely work for a subset of use cases. The generation of setup.py and treating it similar to a lock file allows for a broader range of compatibility.

cjw296 commented 5 years ago

Won't pip 19.0 remove the need for this? (as it understands pyproject.toml) - you'll need to add some manual stuff to it though, until https://github.com/sdispater/poetry/issues/744 is resolved.

abn commented 5 years ago

@cjw296 I will see if I can validate that, if pip understands poetry projects, that will most likely cover a large chunk of the use cases. However, without this change, the other tools need to either support PEP-518 or poetry projects explicitly. With that in mind, I do think this is still useful even if pip support is completed.

radek-sprta commented 5 years ago

Snaps require setuptools and setup.py, at least for now, so having way to generate setup.py from poetry would help with that.

aptlin commented 5 years ago

Any updates on that?

stevegore commented 5 years ago

dephell will do this for you:

dephell deps convert --from pyproject.toml --from-format poetry --to setup.py --to-format setuppy

Or you can add this to pyproject.toml and just run dephell deps convert:

[tool.dephell.main]
from = {format = "poetry", path = "pyproject.toml"}
to = {format = "setuppy", path = "setup.py"}
abn commented 5 years ago

I have updated the PR to be a new export format instead of new command.

KelSolaar commented 4 years ago

I would be super glad to have that feature out-of-the-box. I looked quickly at dephell but the fact it added almost 30 dependencies to my project made me uncomfortable.

danielhoherd commented 4 years ago

One great reason to have this feature is that you cannot do pip install -e . unless there is a setup.py file.

ERROR: File "setup.py" not found. Directory cannot be installed in editable mode: /home/username/python-tool
(A "pyproject.toml" file was found, but editable mode currently requires a setup.py based build.)

For now the dephell command up above did what I was looking for, but requried attrs>=19.2.0. Also dephell has 49 dependencies.

orsinium commented 4 years ago

Also dephell has 49 dependencies.

DepHell is intended to be an outside tool like you have no poetry in your dependencies. The recommended way to install dephell is curl -L dephell.org/install | python3 that will put dephell into its own jail.

Also, most of the dependencies are part of dephell's own ecosystem (https://github.com/dephell/). And even after this, there are much fewer dependencies than even in pip (https://github.com/pypa/pip/tree/master/src/pip/_vendor), the only difference is they aren't vendorized for good reasons. Installation of all dependencies from the ground zero takes 17 seconds on TravisCI. So, it's more about decoupling than having a fat dependency tree.

stevegore commented 4 years ago

I feel I should point out that the pyproject.toml addition I've mentioned above doesn't actually required you to add dephell as a dependency of your project. Instead, I've got poetry and dephell both installed as part of the Docker image I use to build our Python projects.

albireox commented 4 years ago

For what it's worth, here is a small script that uses poetry itself to generate the setup.py. It seems to work fine so far.

pawamoy commented 4 years ago

@albireox nice, thank you for the script.

Here are two other versions to find Poetry's lib.

nim65s commented 4 years ago

@pawamoy: thanks, but you have an extra ) after .parent.parent

pawamoy commented 4 years ago

Woops, thanks @nim65s, corrected the snippet :slightly_smiling_face:

I also added support for Windows for the pipx version.

RafalSkolasinski commented 4 years ago

For what it's worth, here is a small script that uses poetry itself to generate the setup.py. It seems to work fine so far.

Is there a reason why we don't add it to poetry itself? Lack of connection to standard package layout with setup.py is what may stop some people from adopting poetry in their projects.

danielhoherd commented 4 years ago

Another reason to generate setup.py is this error from tox:

ERROR: File "setup.py" not found. Directory cannot be installed in editable mode: /home/user/code/foo
(A "pyproject.toml" file was found, but editable mode currently requires a setup.py based build.)

EDIT: as noted in the following comment, this was a problem with my configurations

abn commented 4 years ago

@RafalSkolasinski setup.py is specific to using distutils/setuptools as the build backend. Poetry is a PEP 517 compatible build backend and does not require the setup.py file.

@danielhoherd unsure what is happening here, tox should work file without the setup.py file. You can see poetry's tox.ini as an example. Also see here for more information.

RafalSkolasinski commented 4 years ago

Would it be a good idea to add to documentation why setup.py is not required when using poetry?

Are there any limitations to noy having it? Like, am I able to "pip install -e ." or install directly from Github?

Edit: it seems that missing setup.py does not allow to install package in editable mode

machine42 ➜  poetry-demo pip install -e .
Defaulting to user installation because normal site-packages is not writeable
ERROR: File "setup.py" not found. Directory cannot be installed in editable mode: /home/rskolasinski/private/playground/poetry-demo
(A "pyproject.toml" file was found, but editable mode currently requires a setup.py based build.)

which seems to be quite a limitation for some use cases.

abn commented 4 years ago

Would it be a good idea to add to documentation why setup.py is not required when using poetry?

Personally, I think PEP 517 implications have been already documeted elsewhere. A quick google search lead me to this article, which summarised the implication as of November, 2018. There aslo is a more recently updated article by Brett Cannon here, which I recommend.

It might be good to add some basic information and resources in the introduction section. Happy to accept pull requests.

Are there any limitations to noy having it? Like, am I able to "pip install -e ." or install directly from Github?

PEP 517 has been supported by pip since version 19. The requirement for a setup.py file for an editable install is more a pip concern than poetry. As mentioned in the article above by Brett, you can use a setup.py shim file in your project. This is not something that is required for projects managed by poetry in general. There are no real-world limitations by not having it, the intention is to reduce the number of files required to manage a python project.

If your project requires to be installed in editable mode, I would recommend adding a shim. But this should not be the default behaviour for poetry managed projects.

merwok commented 4 years ago

tox and pip install implement the PEPs to support many build backends.

pip install -e is not compatible yet, but there is ongoing discussion to standardize that and make it work too. In the meantime, each tool can provide a bespoke way to do something like develop/editable mode (for example, flit has flit install -s which gets the same result).

RafalSkolasinski commented 4 years ago

@abn @merwok Thanks guys for the reply and the links, seems I have some readings to do ; - ). Personally I was never a fun of setup.py, found it a bit over complicating things.

I see that pip install . does work properly. I hope it will also work properly when the source is on GitHub using pip install git+...?

I also notice that if activate manually a virtualenvironment (not managed by poetry) then poetry install will give be equivalent of pip install -e . - so that this also makes me happy.

The only thing I seem to be missing is to have equivalent of pip install --user -e . I am working on some scripts that ideally would be installed into ~/.local/bin/... and would like to install them there in editable mode for development.

abn commented 4 years ago

I see that pip install . does work properly. I hope it will also work properly when the source is on GitHub using pip install git+...?

It should, yes. As this is equivalent of cloning a local copy and performing pip install /path/to/clone.

The only thing I seem to be missing is to have equivalent of pip install --user -e . I am working on some scripts that ideally would be installed into ~/.local/bin/... and would like to install them there in editable mode for development.

If your virtual environment is active, any such scripts will be available in your path, as /path/to/venv/bin should be in your PATH.

RafalSkolasinski commented 4 years ago

If your virtual environment is active, any such scripts will be available in your path, as /path/to/venv/bin should be in your PATH.

I meant installation without virtualenvironment that would be equivalent with pip installation with --user flag, as it going into ~/.local/bin and~/.local/lib.

RafalSkolasinski commented 4 years ago

I see there exists https://github.com/python-poetry/poetry/issues/1214 which address my concern. It seems this is the only downside of not having setup.py to me it seems.

Drachenfels commented 4 years ago

There is backward compatibility issue to be taken into account. I am working in an environment that assumes that setup.py is a source of truth. It's either has to be updated and committed or removed altogether. If poetry had this option out of the gate it would make my life easier to convince other people to start using it (simply by making it optional and allowing old-school devs to keep their old ways).

jdeyton commented 4 years ago

@stevegore

dephell will do this for you:

dephell deps convert --from pyproject.toml --from-format poetry --to setup.py --to-format setuppy

Or you can add this to pyproject.toml and just run dephell deps convert:

[tool.dephell.main]
from = {format = "poetry", path = "pyproject.toml"}
to = {format = "setuppy", path = "setup.py"}

The format of the dephell command is --from-path instead of --from and --to-path instead of --to.

i.e.

dephell deps convert --from-path pyproject.toml --from-format poetry --to-path setup.py --to-format setuppy
pawamoy commented 4 years ago

For those having issues with the script from @albireox with newer versions of Poetry, check it out again: https://github.com/sdss/flicamera/blob/master/create_setup.py, it was updated πŸ™‚ Thanks @albireox ❀️ !!

kolypto commented 3 years ago

In fact, poetry generates a setup.py when you build the project, and places it into one of the dist/*.tar.gz files :) Let's extract it:

$ poetry build
$ tar -xvf dist/*.tar.gz --wildcards --no-anchored '*/setup.py' --strip=1

now your poetry project is pip-editable ;)

abn commented 3 years ago

now your poetry project is pip-editable ;)

You can also just use a setup-shim for most cases.

cat "import setuptools; setuptools.setup()" > setup.py

Note that having a setup file can cause some side-effects.

JasonAtallah commented 3 years ago

In fact, poetry generates a setup.py when you build the project, and places it into one of the dist/*.tar.gz files :) Let's extract it:

$ poetry build
$ tar -xvf dist/*.tar.gz --wildcards --no-anchored '*/setup.py' --strip=1

now your poetry project is pip-editable ;)

I was getting errors with --wildcards and --no-anchored.

Running just tar -xvf dist/*.tar.gz '*/setup.py' seems to work for me. I then run cp $(find . -name setup.py) setup.py to copy the setup.py over to the root of the my repo.

Aathish04 commented 3 years ago

Has there been any consensus on whether such a script/tool for keeping the generated setup.py file should be added to poetry itself?

I imagine it would be extremely useful, at least until pypa finally decide what to do when you need an editable install with only a pyproject.toml .

ThatXliner commented 3 years ago

I have a problem with readthedocs.io and I will require a setup.py for the time being (until pip supports installing poetry-based projects via pyproject.toml)

webknjaz commented 3 years ago

Why do you think pip doesn't?

JasonAtallah commented 3 years ago

Created a PR to allow exporting to setup.py

jfaleiro commented 3 years ago

Another implication for not having a setup.py under source control is you can't refer git repository dependencies:

$ poetry add git+https://gitlab.com/jfaleiro/quantlet-streaming.git#XXX

TypeError

  expected string or bytes-like object

  at .venv/lib/python3.8/site-packages/poetry/core/utils/helpers.py:27 in canonicalize_name
       23β”‚ _canonicalize_regex = re.compile(r"[-_]+")
       24β”‚ 
       25β”‚ 
       26β”‚ def canonicalize_name(name):  # type: (str) -> str
    β†’  27β”‚     return _canonicalize_regex.sub("-", name).lower()
       28β”‚ 
       29β”‚ 
       30β”‚ def module_name(name):  # type: (str) -> str
       31β”‚     return canonicalize_name(name).replace(".", "_").replace("-", "_")

The message "expected string or bytes-like object" means poetry could not find a setup.py under source control at https://gitlab.com/jfaleiro/quantlet-streaming.git on tag XXX. It has a pyproject.toml but no setup.py. Hopefully this is helpful to someone else.

finswimmer commented 3 years ago

@jfaleiro there must be another reason for the error you receive. poetry doesn't need a setup.py within the git repo if there is a pyproject.toml and it is a poetry project.

abn commented 3 years ago

Since I am the original author of this issue, I will go ahead and close this. Since 2018, the status quo has changed. This is no longer a useful change or a core feature for poetry. Additionally, my original need is no longer a concern as there is better developer tooling support for poetry now.

For cases where a "legacy" editable mode is desireable you can simply make use of a setup.py shim as originally described in this article.

import setuptools; setuptools.setup()

Note: add name and version if you want sensible metadata that is not UNKNOWN-0.0.0.

Poetry itself now implements an editable install support for projects it manages. That might coer a few use cases. Furhtermore, poetry is in the process of removing the internal supprot for generating setup.py files and hence keeping the export around is added maintanence burden without much return. If such an export is desirable, it can be implemented by the community via the upcoming plug-in system as a plug-in to the export command.

abersheeran commented 3 years ago

I also have this problem. After reviewing the poetry source code, I found a solution and packaged it into a pypi package. https://github.com/abersheeran/poetry2setup

In short, you only need to execute two commands in the project to generate the setup.py file.

pip install poetry2setup

poetry2setup > setup.py
ThatXliner commented 3 years ago

Can't you install from a pyproject.toml now?

ThatXliner commented 3 years ago

@jfaleiro there must be another reason for the error you receive. poetry doesn't need a setup.py within the git repo if there is a pyproject.toml and it is a poetry project.

Like this?

abersheeran commented 3 years ago

@ThatXliner Yes, due to some open secrets (in China). When using pip install . directly to install, the download of poetry-core is a painful burden. I think someone might also have this need, so I posted it under this issue. If it disturbs you, I'm sorry.

Purg commented 2 years ago

For anyway that stumbles into this thread like I have, note that the latest version of poetry-core, version 1.0.8, supports PEP-660 to allow a pip install -e . of your package. I was able to update my pyproject.toml [build-system] section to use this version to do this.

github-actions[bot] commented 5 months ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.