The current answers don't explain how to use setuptools
to install editable
, local dependencies.
The below will install local dependencies as editable for use with setuptools.
setup.py
from pip import main as pip_main
from pip._internal.network.session import PipSession
from pip._internal.models.link import Link
from pip._internal.req import parse_requirements
from pip._internal.req.req_file import ParsedRequirement
from pip._internal.req.constructors import parse_req_from_line
import os
from setuptools import find_packages, setup
def pip_to_setup(requirement: ParsedRequirement, editable=True) -> str:
'''
Convert a pip requirement to a setup.py install_requires
If `editable` then pre-install via `pip install -e ...` and return ''
Else return local path requirement
'''
requirement_parts = parse_req_from_line(
requirement.requirement,
requirement.line_source,
)
if (
isinstance(requirement_parts.link, Link)
and requirement_parts.link.is_existing_dir()
):
package_path = requirement_parts.link.file_path
if editable:
pip_main(['install', '-e', package_path])
return '' # https://medium.com/@ashley.e.shultz/python-mono-repo-with-only-built-in-tooling-7c2d52c2fc66
else:
package_name = os.path.basename(package_path)
return f'{package_name} @ file://{package_path}'
else:
return requirement.requirement
def main():
dir_path = os.path.dirname(__file__)
package_name = os.path.basename(dir_path)
requirements_path = os.path.join(dir_path, 'requirements.txt')
test_requirements_path = os.path.join(dir_path, 'requirements-test.txt')
requirements = parse_requirements(requirements_path, session=PipSession())
install_requires = [pip_to_setup(r) for r in requirements]
test_requires = []
if os.path.isfile(test_requirements_path):
test_requirements = parse_requirements(test_requirements_path, session=PipSession())
test_requires.extend(pip_to_setup(r) for r in test_requirements)
setup(
name=package_name,
setup_requires=['setuptools_scm'],
install_requires=install_requires,
tests_require=test_requires,
extras_require={'test': test_requires},
packages=find_packages(where='src'),
package_dir={'': 'src'},
package_data={'': ['**/*']},
)
if __name__ == '__main__':
main()
(You may have to modify packages
and package_dir
depending on your project structure.
Example requirements.txt
boto3
../your_local_package
file:
URLs independency_links
, which solves my issue. Hopefully it gets merged soon. – Maddening