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

convert_deps_to_pip function is not available #5040

Closed
paulcqtruong opened this issue Apr 11, 2022 · 6 comments
Closed

convert_deps_to_pip function is not available #5040

paulcqtruong opened this issue Apr 11, 2022 · 6 comments
Labels
Status: Awaiting Update ⏳ This issue requires more information before assistance can be provided.

Comments

@paulcqtruong
Copy link

Be sure to check the existing issues (both open and closed!), and make sure you are running the latest version of Pipenv.

Check the diagnose documentation for common issues before posting! We may close your issue if it is very similar to one of them. Please be considerate, or be on your way.

Make sure to mention your debugging experience if the documented solution failed.

Issue description

The method pipenv.utils.convert_deps_to_pip has disappeared in the latest release 2022.4.8

Expected result

I can't find any announcement of retiring the function above or proposal of an alternative to convert_deps_to_pip

Actual result

The exception logs as below

 AttributeError: module 'pipenv.utils' has no attribute 'convert_deps_to_pip'

Steps to replicate

If you're on macOS, run the following:

$ pipenv shell
$ python -c "import pipenv.utils; help(pipenv.utils.convert_deps_to_pip)"
@matteius
Copy link
Member

@paulcqtruong That is an internal method to Pipenv, can you explain what you use it for? There is a new requirements command in 2022.4.8 that might be useful to you.

Otherwise though, that method still exists. Its pipenv.utils.dependencies.convert_deps_to_pip. It was mentioned in the release notes:

Internal to pipenv, the utils.py was split into a utils module with unused code removed. #4992

@matteius matteius added the Status: Awaiting Update ⏳ This issue requires more information before assistance can be provided. label Apr 12, 2022
@matteius
Copy link
Member

Closing this as there isn't much pipenv can do -- the utils namespacing is a big improvement to working on the code and has lead to some bug fixing and issue squashing along the way.

@DSamuylov
Copy link

@matteius, I may have an example of a use case:

  • package_a has a Pipenv file and setup.py
  • package_b has a Pipenv file and depends on package_a.
  • When developing package_b, I would like to install package_a in editable mode with pipenv install -e ../package_a

The last step should also install all dependencies of package_a to the environment of package_b. From my understanding, this requires me to specify the list of dependencies in setup.py of package_a using install_requires. From the example that I found here, this can be achieved with:

from setuptools import setup, find_packages

from pipenv.project import Project
from pipenv.utils import convert_deps_to_pip

pfile = Project(chdir=False).parsed_pipfile
requirements = convert_deps_to_pip(pfile["packages"], r=False)

setup(
    name="cloudsense-logging",
    version="0.1.0",
    packages=find_packages(),
    install_requires=requirements,
)

Is there a better approach that does not make me rely on utils that seems to be internal to Pipenv?

@matteius
Copy link
Member

matteius commented Sep 28, 2022

@DSamuylov A few thoughts -- Including code that has to be evaluated, even an interpolated sting, is problematic for the setup.py AST parsers of requirementslib, and unlike pip--it will not evaluate code in the setup.py, so I think you would still have issues with a package setup.py like this if pre-built wheels were not available and a user were to pipenv install cloudsense-logging or certain locking scenarios. See #5167 for additional context on that. As such, whatever you put into install_requirements should already be the fully evaluated string (no f-strings or interpolation) for best compatibility.

From the sound of your example case, you are developing package_b and managing its dependencies with pipenv Pipfile/lock file and package_a is being developed similar. There is no good way to dynamically and safely evaluate the install_requires at runtime this way, so I recommend not doing this. Also it would be better if the project dependencies were defined in a pyproject.toml instead of the old style setup.py install_requires. https://setuptools.pypa.io/en/latest/userguide/dependency_management.html In both cases though, to use properly would require updating the requires value to be an already evaluated string or in the case of pyproject.toml, list of strings. You could write a utility you invoke after changing top level requirements to try an automate making this update. It would have to be done ahead of install time, as that should ensure an already evaluated string.

As far as using the utils from pipenv. you are welcome to do so but they are subject to change and improvements. The utils file was broken into separate files in a utils module to be more organized, that method is still in that module at pipenv.utils.dependencies. We have a similar thing where we use pip resolver internally to pipenv and when we upgarde internal pip versions sometimes that "API" contract breaks down and we have to fix the integration before we can use the new version of pip.

I took your example and modified it to generate the requirements for pipenv, but there should still be a step of sanitizing it (as ['-e .[dev,tests]' is a editable install of itself and would not be compatible, and the fully evaluated list should be in the pyproject.toml

>>> from pipenv.project import Project
>>> from pipenv.utils.dependencies import convert_deps_to_pip
>>> pfile = Project(chdir=False).parsed_pipfile
>>> requirements = convert_deps_to_pip(pfile["dev-packages"])
>>> requirements
['-e .[dev,tests]', 'sphinx==4.*', 'sphinx-click==4.*', 'sphinxcontrib-spelling==7.*', 'click==8.0.3', '-e ./tests/pytest-pypi', 'pypiserver==1.*', "
stdeb ; sys_platform == 'linux'", "zipp==3.6.0 ; python_version < '3.10'", 'pre-commit==2.*', "atomicwrites ; sys_platform == 'win32'", 'pytest-cov==
3.*', 'typing-extensions==4.*', "waitress ; sys_platform == 'win32'", "gunicorn ; sys_platform == 'linux'"]

@DSamuylov
Copy link

@matteius, Thank you a lot for your prompt response, I highly appreciate it! Just before I saw your reply, I was about to write that this approach does not work. I am not sure if it linked to your argument, but from my understanding with such approach there is also a circular requirement to install the dependency: from project_b you install dependencies from project_a, and in the setup.py of project_a there is a list of dependencies that is read out from the pipenv file in project_a which contains the requirement to install the project_a and so on... I resolved for now with providing a list of already evaluated strings.

I had setup.py that I reused for years, and it worked for me without any problems until recently. I knew about the PEP regarding pyproject.toml, but I am still trying to figure out how it works exactly. I read in some sources the recommendation to have 2 lines toml that defines setuptools, but the rest still define in setup.py. But I am not sure if it is correct, and trying to understand it requires a lot of reading... but I am making progress :) If you have any more useful links on this topic, I would highly appreciate if you could share.

@matteius
Copy link
Member

Sorry @DSamuylov I think I misspoke this morning about pipenv using pyproject.toml for it install_requires, which is currently a list in setup.py. Requirementslib which pipenv relies on has a pyproject.toml as well, also not defining the required packages, but requirementslib puts them into the setup.cfg https://github.com/sarugaku/requirementslib/blob/main/setup.cfg#L42
but that being said, pyproject.toml does appear to support putting the depdendencies list under the project section. https://setuptools.pypa.io/en/latest/userguide/dependency_management.html#declaring-required-dependency

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting Update ⏳ This issue requires more information before assistance can be provided.
Projects
None yet
Development

No branches or pull requests

3 participants