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

Remove optional From Dependency Info in Internal Code #389

Merged
merged 5 commits into from
May 20, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ repos:
args: ["--profile", "black", "--filter-files"]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.0.1
rev: v1.1.1
hooks:
- id: mypy
additional_dependencies: [types-filelock, types-requests, types-toml, types-PyYAML, types-freezegun, types-setuptools, pydantic]
Expand Down
2 changes: 1 addition & 1 deletion conda_lock/conda_lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ def render_lockfile_for_platform( # noqa: C901
lockfile.toposort_inplace()

for p in lockfile.package:
if p.platform == platform and ((not p.optional) or (p.category in categories)):
if p.platform == platform and p.category in categories:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: not p.optionalp.category == "main".
Since "main" in categories, this is redundant and can be deleted.

Therefore, this is logically sound.

if p.manager == "pip":
pip_deps.append(p)
elif p.manager == "conda":
Expand Down
4 changes: 2 additions & 2 deletions conda_lock/conda_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
conda_pkgs_dir,
is_micromamba,
)
from conda_lock.lockfile import HashModel, LockedDependency, _apply_categories
from conda_lock.lockfile import HashModel, LockedDependency, apply_categories
from conda_lock.models.channel import Channel
from conda_lock.models.lock_spec import Dependency, VersionedDependency

Expand Down Expand Up @@ -195,7 +195,7 @@ def normalize_url(url: str) -> str:
}

# propagate categories from explicit to transitive dependencies
_apply_categories(
apply_categories(
requested={k: v for k, v in specs.items() if v.manager == "conda"},
planned=planned,
)
Expand Down
41 changes: 25 additions & 16 deletions conda_lock/lockfile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from collections import defaultdict
from textwrap import dedent
from typing import Collection, Dict, List, Optional, Sequence, Set
from typing import Any, Collection, Dict, List, Optional, Sequence, Set

import yaml

Expand All @@ -21,7 +21,7 @@
from .models import UpdateSpecification as UpdateSpecification


def _apply_categories(
def apply_categories(
requested: Dict[str, Dependency],
planned: Dict[str, LockedDependency],
categories: Sequence[str] = ("main", "dev"),
Expand Down Expand Up @@ -81,12 +81,9 @@ def seperator_munge_get(
# try a conda target first
target = seperator_munge_get(planned, dep)
target.category = source.category
target.optional = source.optional


def parse_conda_lock_file(
path: pathlib.Path,
) -> Lockfile:
def parse_conda_lock_file(path: pathlib.Path) -> Lockfile:
if not path.exists():
raise FileNotFoundError(f"{path} not found")

Expand All @@ -96,6 +93,9 @@ def parse_conda_lock_file(
if not (isinstance(version, int) and version <= Lockfile.version):
raise ValueError(f"{path} has unknown version {version}")

for p in content["package"]:
del p["optional"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: we need to delete the optional key in order to parse this as a StrictModel.


return Lockfile.parse_obj(content)


Expand Down Expand Up @@ -159,13 +159,22 @@ def write_section(text: str) -> None:
"""
)

yaml.dump(
{
"version": Lockfile.version,
**json.loads(
content.json(by_alias=True, exclude_unset=True, exclude_none=True)
),
},
stream=f,
sort_keys=False,
)
output: Dict[str, Any] = {
"version": Lockfile.version,
"metadata": json.loads(
content.metadata.json(
Comment on lines +212 to +213
Copy link
Contributor

@maresb maresb May 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just noticed that in #390 you have here instead "metadata": content.metadata.dict( which seems more elegant. Is this an accident, or does this cover some edge case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there was an issue when encoding content.metadata as a dict due to a special class / container that was used in the metadata (was it a frozenset?). Let me check for certain.

by_alias=True, exclude_unset=True, exclude_none=True
)
),
"package": [
{
**package.dict(
by_alias=True, exclude_unset=True, exclude_none=True
),
"optional": (package.category != "main"),
}
for package in content.package
],
}

yaml.dump(output, stream=f, sort_keys=False)
1 change: 0 additions & 1 deletion conda_lock/lockfile/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ class LockedDependency(StrictModel):
dependencies: Dict[str, str] = {}
url: str
hash: HashModel
optional: bool = False
category: str = "main"
source: Optional[DependencySource] = None
build: Optional[str] = None
Expand Down
1 change: 0 additions & 1 deletion conda_lock/models/lock_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
class _BaseDependency(StrictModel):
name: str
manager: Literal["conda", "pip"] = "conda"
optional: bool = False
category: str = "main"
extras: List[str] = []

Expand Down
2 changes: 1 addition & 1 deletion conda_lock/pypi_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def solve_pypi(
continue
planned[pypi_name] = locked_dep

lockfile._apply_categories(requested=pip_specs, planned=planned)
lockfile.apply_categories(requested=pip_specs, planned=planned)

return {dep.name: dep for dep in requirements}

Expand Down
1 change: 0 additions & 1 deletion conda_lock/src_parser/conda_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ def conda_spec_to_versioned_dep(spec: str, category: str) -> VersionedDependency
name=ms.name,
version=ms.get("version", ""),
manager="conda",
optional=category != "main",
category=category,
extras=[],
build=ms.get("build"),
Expand Down
1 change: 0 additions & 1 deletion conda_lock/src_parser/environment_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ def _parse_environment_file_for_platform(
parse_python_requirement(
spec,
manager="pip",
optional=category != "main",
category=category,
normalize_name=False,
)
Expand Down
15 changes: 2 additions & 13 deletions conda_lock/src_parser/pyproject_toml.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ def parse_poetry_pyproject_toml(
["tool", "poetry", *section], contents, {}
).items():
category: str = dep_to_extra.get(depname) or default_category
optional: bool = category != "main"
manager: Literal["conda", "pip"] = "conda"
url = None
extras = []
Expand Down Expand Up @@ -244,7 +243,6 @@ def parse_poetry_pyproject_toml(
url=url,
hashes=[hashes],
manager=manager,
optional=optional,
category=category,
extras=extras,
)
Expand All @@ -255,7 +253,6 @@ def parse_poetry_pyproject_toml(
name=name,
version=version,
manager=manager,
optional=optional,
category=category,
extras=extras,
)
Expand All @@ -281,7 +278,6 @@ def specification_with_dependencies(
name=depname,
version=conda_version,
manager="conda",
optional=False,
category="main",
extras=[],
)
Expand Down Expand Up @@ -318,7 +314,6 @@ def to_match_spec(conda_dep_name: str, conda_version: Optional[str]) -> str:
def parse_python_requirement(
requirement: str,
manager: Literal["conda", "pip"] = "conda",
optional: bool = False,
category: str = "main",
normalize_name: bool = True,
) -> Dependency:
Expand All @@ -345,7 +340,6 @@ def parse_python_requirement(
return URLDependency(
name=conda_dep_name,
manager=manager,
optional=optional,
category=category,
extras=extras,
url=url,
Expand All @@ -356,7 +350,6 @@ def parse_python_requirement(
name=conda_dep_name,
version=conda_version or "*",
manager=manager,
optional=optional,
category=category,
extras=extras,
)
Expand Down Expand Up @@ -387,9 +380,7 @@ def parse_requirements_pyproject_toml(
for path, category in sections.items():
for dep in get_in(list(path), contents, []):
dependencies.append(
parse_python_requirement(
dep, manager="conda", category=category, optional=category != "main"
)
parse_python_requirement(dep, manager="conda", category=category)
)

return specification_with_dependencies(
Expand Down Expand Up @@ -420,9 +411,7 @@ def parse_pdm_pyproject_toml(
for section, deps in get_in(["tool", "pdm", "dev-dependencies"], contents).items():
dev_reqs.extend(
[
parse_python_requirement(
dep, manager="conda", category="dev", optional=True
)
parse_python_requirement(dep, manager="conda", category="dev")
for dep in deps
]
)
Expand Down
9 changes: 0 additions & 9 deletions tests/test_conda_lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,6 @@ def test_parse_environment_file_with_pip(pip_environment: Path):
VersionedDependency(
name="requests-toolbelt",
manager="pip",
optional=False,
category="main",
extras=[],
version="=0.9.1",
Expand Down Expand Up @@ -485,7 +484,6 @@ def test_choose_wheel() -> None:
"fastavro": VersionedDependency(
name="fastavro",
manager="pip",
optional=False,
category="main",
extras=[],
version="1.4.7",
Expand Down Expand Up @@ -602,7 +600,6 @@ def test_parse_meta_yaml_file(meta_yaml_environment: Path):
# Ensure that this platform specific dep is included
assert "zlib" in specs
assert specs["pytest"].category == "dev"
assert specs["pytest"].optional is True


def test_parse_poetry(poetry_pyproject_toml: Path):
Expand All @@ -618,10 +615,8 @@ def test_parse_poetry(poetry_pyproject_toml: Path):
assert specs["sqlite"].version == "<3.34"
assert specs["certifi"].version == ">=2019.11.28"
assert specs["pytest"].version == ">=5.1.0,<5.2.0"
assert specs["pytest"].optional is True
assert specs["pytest"].category == "dev"
assert specs["tomlkit"].version == ">=0.7.0,<1.0.0"
assert specs["tomlkit"].optional is True
assert specs["tomlkit"].category == "tomlkit"

assert res.channels == [Channel.from_string("defaults")]
Expand Down Expand Up @@ -718,7 +713,6 @@ def test_parse_flit(flit_pyproject_toml: Path):
assert specs["sqlite"].version == "<3.34"
assert specs["certifi"].version == ">=2019.11.28"
assert specs["pytest"].version == ">=5.1.0"
assert specs["pytest"].optional is True
assert specs["pytest"].category == "dev"

assert specs["toml"].manager == "pip"
Expand All @@ -742,11 +736,9 @@ def test_parse_pdm(pdm_pyproject_toml: Path):
assert specs["certifi"].version == ">=2019.11.28"
# PEP 621 optional dependencies (show up in package metadata)
assert specs["click"].version == ">=7.0"
assert specs["click"].optional is True
assert specs["click"].category == "cli"
# PDM dev extras
assert specs["pytest"].version == ">=5.1.0"
assert specs["pytest"].optional is True
assert specs["pytest"].category == "dev"
# Conda channels
assert res.channels == [Channel.from_string("defaults")]
Expand Down Expand Up @@ -1204,7 +1196,6 @@ def test_poetry_version_parsing_constraints(
name=package,
version=poetry_version_to_conda_version(version) or "",
manager="conda",
optional=False,
category="main",
extras=[],
),
Expand Down