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

refactor: ruamel #1964

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
45 changes: 23 additions & 22 deletions conda_smithy/configure_feedstock.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import copy
import glob
import hashlib
import io
import logging
import os
import re
Expand All @@ -18,6 +19,8 @@
from os import fspath
from pathlib import Path, PurePath
import requests
from ruamel.yaml import YAML as ruamel_yaml
from collections import OrderedDict

try:
from builtins import ExceptionGroup
Expand Down Expand Up @@ -676,14 +679,6 @@ def _collapse_subpackage_variants(
)


def _yaml_represent_ordereddict(yaml_representer, data):
# represent_dict processes dict-likes with a .sort() method or plain iterables of key-value
# pairs. Only for the latter it never sorts and retains the order of the OrderedDict.
return yaml.representer.SafeRepresenter.represent_dict(
yaml_representer, data.items()
)


def _santize_remote_ci_setup(remote_ci_setup):
remote_ci_setup_ = conda_build.utils.ensure_list(remote_ci_setup)
remote_ci_setup = []
Expand Down Expand Up @@ -717,6 +712,10 @@ def finalize_config(config, platform, arch, forge_config):
return config


def represent_ordereddict(dumper, data):
return dumper.represent_mapping("tag:yaml.org,2002:map", data)


def dump_subspace_config_files(
metas, root_path, platform, arch, upload, forge_config
):
Expand All @@ -739,12 +738,9 @@ def dump_subspace_config_files(
"collapsed subspace config files: {}".format(pprint.pformat(configs))
)

# get rid of the special object notation in the yaml file for objects that we dump
yaml.add_representer(set, yaml.representer.SafeRepresenter.represent_list)
yaml.add_representer(
tuple, yaml.representer.SafeRepresenter.represent_list
)
yaml.add_representer(OrderedDict, _yaml_represent_ordereddict)
ruamel = ruamel_yaml(typ="safe")
ruamel.default_flow_style = False
ruamel.Representer.add_representer(OrderedDict, represent_ordereddict)

platform_arch = "{}-{}".format(platform, arch)

Expand Down Expand Up @@ -773,7 +769,7 @@ def dump_subspace_config_files(
)

with write_file(out_path) as f:
yaml.dump(config, f, default_flow_style=False)
ruamel.dump(config, f)

target_platform = config.get("target_platform", [platform_arch])[0]
result.append(
Expand Down Expand Up @@ -1836,7 +1832,9 @@ def _azure_specific_setup(jinja_env, forge_config, forge_dir, platform):
azure_settings["strategy"]["matrix"][data["config_name"]] = config_rendered
# fmt: on

forge_config["azure_yaml"] = yaml.dump(azure_settings)
buffer = io.StringIO()
ruamel_yaml(typ="safe").dump(azure_settings, buffer)
forge_config["azure_yaml"] = buffer.getvalue()
_render_template_exe_files(
forge_config=forge_config,
jinja_env=jinja_env,
Expand Down Expand Up @@ -2041,7 +2039,7 @@ def render_README(jinja_env, forge_config, forge_dir, render_info=None):
variant_name, _ = os.path.splitext(filename)
variants.append(variant_name)
with open(os.path.join(ci_support_path, filename)) as fh:
data = yaml.safe_load(fh)
data = ruamel_yaml(typ="safe").load(fh)
channel_targets.append(
data.get("channel_targets", ["conda-forge main"])[0]
)
Expand Down Expand Up @@ -2098,7 +2096,9 @@ def render_README(jinja_env, forge_config, forge_dir, render_info=None):
azure_build_id_from_token(forge_config)

logger.debug("README")
logger.debug(yaml.dump(forge_config))
buffer = io.StringIO()
ruamel_yaml(typ="safe").dump(forge_config, buffer)
logger.debug(buffer.getvalue())

with write_file(target_fname) as fh:
fh.write(template.render(**forge_config))
Expand Down Expand Up @@ -2160,7 +2160,7 @@ def _update_dict_within_dict(items, config):
def _read_forge_config(forge_dir, forge_yml=None):
# Load default values from the conda-forge.yml file
with open(CONDA_FORGE_YAML_DEFAULTS_FILE, "r") as fh:
default_config = yaml.safe_load(fh.read())
default_config = ruamel_yaml(typ="safe").load(fh.read())

if forge_yml is None:
forge_yml = os.path.join(forge_dir, "conda-forge.yml")
Expand All @@ -2175,7 +2175,7 @@ def _read_forge_config(forge_dir, forge_yml=None):
)

with open(forge_yml, "r") as fh:
documents = list(yaml.safe_load_all(fh))
documents = list(ruamel_yaml(typ="safe").load_all(fh))
file_config = (documents or [None])[0] or {}

# Validate loaded configuration against a JSON schema.
Expand Down Expand Up @@ -2326,9 +2326,10 @@ def _load_forge_config(forge_dir, exclusive_config_file, forge_yml=None):
# Set some more azure defaults
config["azure"].setdefault("user_or_org", config["github"]["user_or_org"])

log = yaml.safe_dump(config)
logger.debug("## CONFIGURATION USED\n")
logger.debug(log)
buffer = io.StringIO()
ruamel_yaml().dump(config, buffer)
logger.debug(buffer.getvalue())
logger.debug("## END CONFIGURATION\n")

if config["provider"]["linux_aarch64"] == "default":
Expand Down
7 changes: 4 additions & 3 deletions conda_smithy/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from inspect import cleandoc
from typing import Any, Dict, List, Literal, Optional, Union

import yaml
from ruamel.yaml import YAML
from pydantic import BaseModel, Field, create_model, ConfigDict

from conda.base.constants import KNOWN_SUBDIRS
Expand Down Expand Up @@ -1257,7 +1257,8 @@ class ConfigModel(BaseModel):
if __name__ == "__main__":
# This is used to generate the model dump for conda-smithy internal use
# and for documentation purposes.

yaml = YAML()
yaml.indent(mapping=2, sequence=4, offset=2)
model = ConfigModel()

with CONDA_FORGE_YAML_SCHEMA_FILE.open(mode="w+") as f:
Expand All @@ -1266,4 +1267,4 @@ class ConfigModel(BaseModel):
f.write("\n")

with CONDA_FORGE_YAML_DEFAULTS_FILE.open(mode="w+") as f:
f.write(yaml.dump(model.model_dump(), indent=2))
f.write(yaml.dump(model.model_dump()))
23 changes: 23 additions & 0 deletions news/ruamel-refactor.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
**Added:**

* <news item>

**Changed:**

* Use ruamel library and remove usage of yaml almost everywhere - except at conda-smithy/variant_algebra.py

**Deprecated:**

* <news item>

**Removed:**

* <news item>

**Fixed:**

* <news item>

**Security:**

* <news item>
12 changes: 7 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from textwrap import dedent

import pytest
import yaml
from ruamel.yaml import YAML

from jinja2 import FileSystemLoader
from jinja2.sandbox import SandboxedEnvironment
Expand Down Expand Up @@ -55,6 +55,8 @@ def recipe_dirname():

@pytest.fixture(scope="function")
def config_yaml(testing_workdir, recipe_dirname):
yaml = YAML()
yaml.default_flow_style = False
config = {"python": ["2.7", "3.5"], "r_base": ["3.3.2", "3.4.2"]}
os.makedirs(os.path.join(testing_workdir, recipe_dirname))
with open(os.path.join(testing_workdir, "config.yaml"), "w") as f:
Expand All @@ -65,7 +67,7 @@ def config_yaml(testing_workdir, recipe_dirname):
os.path.join(testing_workdir, recipe_dirname, "default_config.yaml"),
"w",
) as f:
yaml.dump(config, f, default_flow_style=False)
yaml.dump(config, f)
# need selectors, so write these more manually
f.write(
dedent(
Expand Down Expand Up @@ -94,18 +96,18 @@ def config_yaml(testing_workdir, recipe_dirname):
os.path.join(testing_workdir, recipe_dirname, "short_config.yaml"), "w"
) as f:
config = {"python": ["2.7"]}
yaml.dump(config, f, default_flow_style=False)
yaml.dump(config, f)
with open(
os.path.join(testing_workdir, recipe_dirname, "long_config.yaml"), "w"
) as f:
config = {"python": ["2.7", "3.5", "3.6"]}
yaml.dump(config, f, default_flow_style=False)
yaml.dump(config, f)
with open(os.path.join(testing_workdir, "conda-forge.yml"), "w") as f:
config = {
"upload_on_branch": "foo-branch",
"recipe_dir": recipe_dirname,
}
yaml.dump(config, f, default_flow_style=False)
yaml.dump(config, f)
return testing_workdir


Expand Down
14 changes: 8 additions & 6 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
import subprocess
from textwrap import dedent

import yaml
from ruamel.yaml import YAML
import pytest
import shutil

from conda_smithy import cli

_thisdir = os.path.abspath(os.path.dirname(__file__))

yaml = YAML(typ="safe")

InitArgs = collections.namedtuple(
"ArgsObject",
("recipe_directory", "feedstock_directory", "temporary_directory"),
Expand Down Expand Up @@ -79,7 +81,7 @@ def test_init_with_custom_config(py_recipe):
init_obj(args)
destination = os.path.join(recipe, "py-test-feedstock")
assert os.path.isdir(destination)
data = yaml.safe_load(
data = yaml.load(
open(os.path.join(destination, "conda-forge.yml"), "r").read()
)
assert data.get("bot") != None
Expand Down Expand Up @@ -125,7 +127,7 @@ def test_init_multiple_output_matrix(testing_workdir):
)
assert os.path.isfile(linux_libpng16)
with open(linux_libpng16) as f:
config = yaml.safe_load(f)
config = yaml.load(f)
assert config["libpng"] == ["1.6"]
assert config["libpq"] == ["9.5"]
# this is a zipped key, but it's not used, so it shouldn't show up
Expand Down Expand Up @@ -240,7 +242,7 @@ def test_init_cuda_docker_images(testing_workdir):
)
assert os.path.isfile(fn)
with open(fn) as fh:
config = yaml.safe_load(fh)
config = yaml.load(fh)
assert config["cuda_compiler"] == ["nvcc"]
assert config["cuda_compiler_version"] == [f"{v}"]
if v is None:
Expand Down Expand Up @@ -291,7 +293,7 @@ def test_init_multiple_docker_images(testing_workdir):
fn = os.path.join(matrix_dir, "linux_64_.yaml")
assert os.path.isfile(fn)
with open(fn) as fh:
config = yaml.safe_load(fh)
config = yaml.load(fh)
assert config["docker_image"] == ["pickme_a"]
assert config["cdt_name"] == ["pickme_1"]

Expand Down Expand Up @@ -368,5 +370,5 @@ def test_render_variant_mismatches(testing_workdir):
continue
cfg = os.path.join(matrix_dir, _cfg)
with open(cfg, "r") as f:
data = yaml.safe_load(f)
data = yaml.load(f)
assert data["a"] == data["b"]
1 change: 0 additions & 1 deletion tests/test_condaforge_config_schema.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import pytest
from pydantic import ValidationError
import yaml
from conda_smithy.schema import ConfigModel


Expand Down
Loading