def test_from_pypi_name_response(): repo = NixpkgsData(PYTESTRUNNER_DATA) drvs = repo.from_pypi_name('pytest-runner') assert isinstance(drvs, list) assert isinstance(drvs[0], NixPackage) assert drvs[0].attr == 'pytestrunner' assert drvs[0].version == parse('5.1')
async def _build_version_chooser( load_test_requirements_for: List[str], ignore_test_requirements_for: List[str], load_all_test_requirements: bool) -> VersionChooser: nixpkgs_data = NixpkgsData(await load_nixpkgs_data({})) pypi_cache = PyPICache() pypi_data = PyPIData(pypi_cache) def should_load_tests(package_name): if canonicalize_name(package_name) in [ canonicalize_name(n) for n in ignore_test_requirements_for ]: return False return load_all_test_requirements or canonicalize_name( package_name) in [ canonicalize_name(n) for n in load_test_requirements_for ] version_chooser = VersionChooser( nixpkgs_data, pypi_data, req_evaluate=evaluate_package_requirements, should_load_tests=should_load_tests, ) return version_chooser
async def test_build_sampleproject_expression(fetchPypi): data = await load_nixpkgs_data(PINNED_NIXPKGS_ARGS) nixpkgs = NixpkgsData(data) pypi = PyPIData(PyPICache()) async def f(pkg): return await evaluate_package_requirements(pkg, PINNED_NIXPKGS_ARGS) c = VersionChooser(nixpkgs, pypi, f) await c.require(Requirement('sampleproject==1.3.1')) package: PyPIPackage = c.package_for('sampleproject') # type: ignore sha256 = await get_path_hash(await package.source()) reqs = ChosenPackageRequirements( build_requirements=[], test_requirements=[], runtime_requirements=[c.package_for('peppercorn')] # type: ignore ) meta = await package.metadata() expr = build_nix_expression(package, reqs, meta, sha256, fetchPypi) print(expr) wrapper_expr = f'(import <nixpkgs> {{}}).python3.pkgs.callPackage ({expr}) {{}}' print(wrapper_expr) result = await run_nix_build(wrapper_expr) proc = await asyncio.create_subprocess_shell( f'{result}/bin/sample', stdout=asyncio.subprocess.PIPE) stdout, stderr = await proc.communicate() assert (await proc.wait()) == 0 assert b'Call your main application code here' in stdout
async def test_prefer_nixpkgs_older_version(): nixpkgs = NixpkgsData(NIXPKGS_SAMPLEPROJECT) pypi = PyPIData(DummyCache(sampleproject=SAMPLEPROJECT_DATA)) c = VersionChooser(nixpkgs, pypi, dummy_package_requirements()) await c.require(Requirement('sampleproject')) assert_version(c, 'sampleproject', '1.0') with pytest.raises(NoMatchingVersionFound): await c.require(Requirement('sampleproject>1.0'))
async def test_does_not_user_build_dependencies(): nixpkgs = NixpkgsData(NIXPKGS_JSON) c = VersionChooser( nixpkgs, dummy_pypi, dummy_package_requirements({ "pytz": ([Requirement('setuptools_scm')], [], []), })) await c.require(Requirement('pytz')) assert c.package_for('pytz') assert c.package_for('setuptools_scm') is None
async def test_packages_with_configure(): data = await load_nixpkgs_data(PINNED_NIXPKGS_ARGS) nixpkgs = NixpkgsData(data) pypi = PyPIData(PyPICache()) async def f(pkg): return await evaluate_package_requirements(pkg, PINNED_NIXPKGS_ARGS) c = VersionChooser(nixpkgs, pypi, f) await c.require(Requirement('brotli')) pkg = c.package_for('brotli')
async def test_all_pypi_packages(): nixpkgs = NixpkgsData(NIXPKGS_JSON) pypi = PyPIData(DummyCache(sampleproject=SAMPLEPROJECT_DATA)) c = VersionChooser( nixpkgs, pypi, dummy_package_requirements({ "sampleproject": ([], [], [Requirement('flask')]), })) await c.require(Requirement('sampleproject')) sampleproject = c.package_for('sampleproject') assert c.all_pypi_packages() == [sampleproject]
async def test_uses_runtime_dependencies(): nixpkgs = NixpkgsData(NIXPKGS_JSON) c = VersionChooser( nixpkgs, dummy_pypi, dummy_package_requirements({ "django_2_2": ([], [], [Requirement('pytz')]), })) await c.require(Requirement('django>=2.2')) assert c.package_for('django') assert c.package_for('pytz') assert_version(c, 'pytz', '2019.3')
async def test_test_dependencies(): nixpkgs = NixpkgsData(NIXPKGS_JSON) c = VersionChooser(nixpkgs, dummy_pypi, should_load_tests=lambda _: False, req_evaluate=dummy_package_requirements({ "django_2_2": ([], [Requirement('pytest')], []), })) await c.require(Requirement('django>=2.2')) assert c.package_for('django') assert c.package_for('pytest') is None
async def test_circular_dependencies(): nixpkgs = NixpkgsData(NIXPKGS_JSON) c = VersionChooser( nixpkgs, dummy_pypi, dummy_package_requirements({ 'flask': ([], [], [Requirement("itsdangerous")]), 'itsdangerous': ([], [Requirement('flask')], []), })) await c.require(Requirement('flask')) assert c.package_for('flask') assert c.package_for('itsdangerous')
async def test_parse_single_requirements(): data = await load_nixpkgs_data(PINNED_NIXPKGS_ARGS) nixpkgs = NixpkgsData(data) pypi = PyPIData(PyPICache()) async def f(pkg): return await evaluate_package_requirements(pkg, PINNED_NIXPKGS_ARGS) c = VersionChooser(nixpkgs, pypi, f) await c.require(Requirement('passlib')) assert c.package_for('passlib')
async def test_chosen_package_requirements_fails(): nixpkgs = NixpkgsData(NIXPKGS_JSON) pypi = PyPIData(DummyCache(sampleproject=SAMPLEPROJECT_DATA)) c = VersionChooser(nixpkgs, pypi, dummy_package_requirements()) reqs = PackageRequirements(build_requirements=[], test_requirements=[], runtime_requirements=[Requirement('invalid')]) with pytest.raises(PackageNotFound): ChosenPackageRequirements.from_package_requirements(reqs, c, load_tests=True)
async def test_all(): data = await load_nixpkgs_data(PINNED_NIXPKGS_ARGS) repo = NixpkgsData(data) django = repo.from_requirement(Requirement('django>=2.0'))[0] assert django.version == parse('2.2.14') nix_store_path = await django.source(PINNED_NIXPKGS_ARGS) assert nix_store_path == Path( '/nix/store/1b47170f04xir2vfwxjl2a59mjsrskaq-Django-2.2.14.tar.gz') reqs = await eval_path_requirements(nix_store_path) assert not reqs.build_requirements assert not reqs.test_requirements assert len(reqs.runtime_requirements) == 2 async def f(pkg): return await evaluate_package_requirements(pkg, PINNED_NIXPKGS_ARGS) c = VersionChooser(repo, dummy_pypi, f) await c.require(Requirement('flask')) assert_version(c, 'flask', '1.1.1') assert_version(c, 'itsdangerous', '1.1.0') assert_version(c, 'Werkzeug', '0.16.1')
async def test_nixpkgs_transitive(): nixpkgs = NixpkgsData(NIXPKGS_JSON) c = VersionChooser( nixpkgs, dummy_pypi, dummy_package_requirements({ 'flask': ([], [], [Requirement("itsdangerous")]), 'itsdangerous': ([], [], [Requirement('Werkzeug')]), })) await c.require(Requirement('flask')) assert c.package_for('flask') assert c.package_for('itsdangerous') assert c.package_for('Werkzeug')
async def test_parse_requirements_nixpkgs_with_no_source(): data = await load_nixpkgs_data(PINNED_NIXPKGS_ARGS) nixpkgs = NixpkgsData(data) pypi = PyPIData(PyPICache()) async def f(pkg): return await evaluate_package_requirements(pkg, PINNED_NIXPKGS_ARGS) c = VersionChooser(nixpkgs, pypi, f) await c.require(Requirement('pycrypto')) pkg = c.package_for('pycrypto') assert pkg is not None await pkg.metadata()
async def test_packages_with_markers_in_extras_require(): data = await load_nixpkgs_data(PINNED_NIXPKGS_ARGS) nixpkgs = NixpkgsData(data) pypi = PyPIData(PyPICache()) async def f(pkg): return await evaluate_package_requirements(pkg, PINNED_NIXPKGS_ARGS) c = VersionChooser(nixpkgs, pypi, f) await c.require(Requirement('doit')) assert c.package_for('doit') assert c.package_for('pyinotify') assert c.package_for('macfsevents') is None
async def test_require_local_package(): nixpkgs = NixpkgsData(NIXPKGS_JSON) pypi = PyPIData(DummyCache(sampleproject=SAMPLEPROJECT_DATA)) reqs_f = dummy_package_requirements({ "sampleproject": ([], [], [Requirement('flask')]), }) c = VersionChooser(nixpkgs, pypi, reqs_f) await c.require_local('sampleproject', Path('/src')) sampleproject = c.package_for('sampleproject') assert sampleproject is not None assert isinstance(sampleproject, PyPIPackage) assert c.package_for('flask') src = await sampleproject.source() assert src == Path('/src')
async def test_conflicting_versions(): data = NIXPKGS_JSON.copy() nixpkgs = NixpkgsData(data) pypi = PyPIData(DummyCache(sampleproject=SAMPLEPROJECT_DATA)) c = VersionChooser( nixpkgs, pypi, dummy_package_requirements({ "flask": ([], [], [Requirement('sampleproject==1.0')]), "click": ([], [], [Requirement('sampleproject>1.0')]), })) await c.require(Requirement('click')) assert c.package_for('click') with pytest.raises(NoMatchingVersionFound): await c.require(Requirement('flask'))
async def test_metadata_with_null_version(): data = await load_nixpkgs_data(PINNED_NIXPKGS_ARGS) nixpkgs = NixpkgsData(data) pypi = PyPIData(PyPICache()) async def f(pkg): return await evaluate_package_requirements(pkg, PINNED_NIXPKGS_ARGS) c = VersionChooser(nixpkgs, pypi, f) await c.require(Requirement('daiquiri==2.1.1')) pkg = c.package_for('daiquiri') assert pkg is not None await pkg.metadata() assert pkg.version == Version('2.1.1')
async def test_nixpkgs_dependency_with_unmatched_requirements(): nixpkgs = NixpkgsData(NIXPKGS_JSON) pypi = PyPIData(DummyCache()) c = VersionChooser( nixpkgs, pypi, dummy_package_requirements({ "botocore": ([], [], [Requirement('docutils<0.15')]), })) await c.require(Requirement('botocore')) botocore = c.package_for('botocore') assert botocore is not None assert isinstance(botocore, NixPackage) docutils = c.package_for('docutils') assert docutils is None
async def test_version_chooser_pypi_and_nixpkgs(): data = await load_nixpkgs_data(PINNED_NIXPKGS_ARGS) nixpkgs = NixpkgsData(data) pypi = PyPIData(PyPICache()) async def f(pkg): return await evaluate_package_requirements(pkg, PINNED_NIXPKGS_ARGS) c = VersionChooser(nixpkgs, pypi, f) await c.require(Requirement('faraday-agent-dispatcher==1.0')) assert c.package_for('faraday-agent-dispatcher') assert c.package_for('click') assert c.package_for('websockets') assert c.package_for('syslog_rfc5424_formatter')
async def test_pypi_package(load_tests): nixpkgs = NixpkgsData(NIXPKGS_JSON) pypi = PyPIData(DummyCache(sampleproject=SAMPLEPROJECT_DATA)) c = VersionChooser(nixpkgs, pypi, req_evaluate=dummy_package_requirements({ 'sampleproject': ([], [Requirement('pytest')], []), }), should_load_tests=lambda _: load_tests) await c.require(Requirement('sampleproject')) assert_version(c, 'sampleproject', '1.3.1') if load_tests: assert c.package_for('pytest') is not None else: assert c.package_for('pytest') is None
async def test_chosen_package_requirements_marker(): nixpkgs = NixpkgsData(NIXPKGS_JSON) pypi = PyPIData(DummyCache(sampleproject=SAMPLEPROJECT_DATA)) req = Requirement("notexistent; python_version<'3'") reqs_f = dummy_package_requirements({ "sampleproject": ([req], [], [req]), }) c = VersionChooser(nixpkgs, pypi, reqs_f) await c.require(Requirement('sampleproject')) sampleproject = c.package_for('sampleproject') reqs: PackageRequirements = await reqs_f(sampleproject) chosen: ChosenPackageRequirements chosen = ChosenPackageRequirements.from_package_requirements( reqs, c, load_tests=True) assert len(chosen.runtime_requirements) == 0
async def test_always_ignores_nixpkgs_test_requirements(): nixpkgs = NixpkgsData(NIXPKGS_JSON) pypi = PyPIData(DummyCache(sampleproject=SAMPLEPROJECT_DATA)) reqs_f = dummy_package_requirements({ "sampleproject": ([], [Requirement('pytest')], [Requirement('flask')]), }) def should_load_tests(package_name): # Flask should be a NixPackage. We don't care about its test requirements assert package_name != 'flask' return True c = VersionChooser(nixpkgs, pypi, reqs_f, should_load_tests=should_load_tests) await c.require(Requirement('sampleproject')) assert c.package_for('sampleproject') assert c.package_for('pytest')
async def test_build_sampleproject_nixpkgs(): data = await load_nixpkgs_data(PINNED_NIXPKGS_ARGS) nixpkgs = NixpkgsData(data) pypi = PyPIData(PyPICache()) async def f(pkg): return await evaluate_package_requirements(pkg, PINNED_NIXPKGS_ARGS) c = VersionChooser(nixpkgs, pypi, f) await c.require(Requirement('pytest')) await c.require(Requirement('sampleproject==1.3.1')) package: PyPIPackage = c.package_for('sampleproject') # type: ignore sha256 = await get_path_hash(await package.source()) reqs = ChosenPackageRequirements( build_requirements=[], test_requirements=[c.package_for('pytest')], # type: ignore runtime_requirements=[c.package_for('peppercorn')] # type: ignore ) package.version = Version('1.2.3') meta = await package.metadata() assert package.version == Version('1.3.1') sampleproject_expr = build_nix_expression(package, reqs, meta, sha256) with tempfile.NamedTemporaryFile(suffix='.nix') as fp: fp.write(sampleproject_expr.encode()) fp.flush() nixpkgs_expr = build_overlayed_nixpkgs( {'sampleproject': Path(fp.name)}) print(nixpkgs_expr) wrapper_expr = f"""(({nixpkgs_expr}) {{}}).python3.pkgs.sampleproject""" result = await run_nix_build(wrapper_expr) assert 'default.nix' not in nixpkgs_expr proc = await asyncio.create_subprocess_shell( f'{result}/bin/sample', stdout=asyncio.subprocess.PIPE) stdout, stderr = await proc.communicate() assert (await proc.wait()) == 0 assert b'Call your main application code here' in stdout
async def test_chosen_package_requirements(load_tests, require_pytest): nixpkgs = NixpkgsData(NIXPKGS_JSON) pypi = PyPIData(DummyCache(sampleproject=SAMPLEPROJECT_DATA)) reqs_f = dummy_package_requirements({ "sampleproject": ([], [Requirement('pytest')], [Requirement('flask')]), }) c = VersionChooser(nixpkgs, pypi, reqs_f, should_load_tests=lambda _: load_tests) if require_pytest: await c.require(Requirement('pytest')) await c.require(Requirement('sampleproject')) sampleproject = c.package_for('sampleproject') reqs: PackageRequirements = await reqs_f(sampleproject) chosen: ChosenPackageRequirements chosen = ChosenPackageRequirements.from_package_requirements( reqs, c, load_tests=load_tests) assert len(chosen.runtime_requirements) == 1 assert len(chosen.test_requirements) == int(load_tests) assert chosen.runtime_requirements[0] is c.package_for('flask')
async def test_build_textwrap3_expression(): data = await load_nixpkgs_data(PINNED_NIXPKGS_ARGS) nixpkgs = NixpkgsData(data) pypi = PyPIData(PyPICache()) async def f(pkg): return await evaluate_package_requirements(pkg, PINNED_NIXPKGS_ARGS) c = VersionChooser(nixpkgs, pypi, f) await c.require(Requirement('textwrap3==0.9.1')) package: PyPIPackage = c.package_for('textwrap3') # type: ignore sha256 = await get_path_hash(await package.source()) reqs = ChosenPackageRequirements( build_requirements=[], test_requirements=[], runtime_requirements=[], ) meta = await package.metadata() expr = build_nix_expression(package, reqs, meta, sha256, ('textwrap3', 'zip')) print(expr) wrapper_expr = f'(import <nixpkgs> {{}}).python3.pkgs.callPackage ({expr}) {{}}' print(wrapper_expr) result = await run_nix_build(wrapper_expr)
async def test_multi_nixpkgs_versions(): nixpkgs = NixpkgsData(MULTIVERSION_DATA) c = VersionChooser(nixpkgs, dummy_pypi, dummy_package_requirements()) await c.require(Requirement('a>=2.0.0')) assert_version(c, 'a', '3.0.0')
async def test_python_version_marker(): nixpkgs = NixpkgsData(NIXPKGS_JSON) c = VersionChooser(nixpkgs, dummy_pypi, dummy_package_requirements()) await c.require(Requirement("flask; python_version<'3'")) assert c.package_for('flask') is None
async def test_no_matching_version_with_previous_requirements(): nixpkgs = NixpkgsData(NIXPKGS_JSON) c = VersionChooser(nixpkgs, dummy_pypi, dummy_package_requirements()) await c.require(Requirement('django==2.1.14')) with pytest.raises(NoMatchingVersionFound): await c.require(Requirement('django>=2.2'))