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 yaml formatter #89

Merged
merged 4 commits into from
Mar 6, 2024
Merged
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
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ repos:
- id: isort
files: \.py$
exclude: ^babelizer/data
args: [--force-single-line-imports]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
Expand Down
11 changes: 7 additions & 4 deletions babelizer/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
else: # pragma: no cover (<PY312)
import importlib_resources


from .errors import OutputDirExistsError, ScanError, SetupPyError, ValidationError
from .errors import OutputDirExistsError
from .errors import ScanError
from .errors import SetupPyError
from .errors import ValidationError
from .metadata import BabelMetadata
from .render import render
from .utils import get_setup_py_version, save_files
from .utils import get_setup_py_version
from .utils import save_files

out = partial(click.secho, bold=True, err=True)
err = partial(click.secho, fg="red", err=True)
Expand Down Expand Up @@ -142,7 +145,7 @@ def update(template, quiet, verbose):
metadata_path = None

if not metadata_path:
err("this does not appear to be a babelized folder (missing 'babel.yaml')")
err("this does not appear to be a babelized folder (missing 'babel.toml')")
raise click.Abort()

template = template or str(importlib_resources.files("babelizer") / "data")
Expand Down
96 changes: 15 additions & 81 deletions babelizer/metadata.py
Original file line number Diff line number Diff line change
@@ -1,73 +1,21 @@
"""Library metadata used by the babelizer to wrap libraries."""

import pathlib
import re
import sys
import warnings
from collections import OrderedDict, defaultdict
from collections import defaultdict
from contextlib import suppress

import tomlkit as toml
import tomli_w
import yaml

from .errors import ScanError, ValidationError
if sys.version_info >= (3, 11): # pragma: no cover (PY11+)
import tomllib
else: # pragma: no cover (<PY311)
import tomli as tomllib


def _setup_yaml_with_canonical_dict():
"""Add a pyyaml handler to create canonical dictionaries.

From https://stackoverflow.com/a/8661021
"""
yaml.add_representer(
OrderedDict,
lambda self, data: self.represent_mapping(
"tag:yaml.org,2002:map", data.items()
),
Dumper=yaml.SafeDumper,
)

def repr_ordered_dict(self, data):
return self.represent_mapping("tag:yaml.org,2002:map", data.items())

yaml.add_representer(dict, repr_ordered_dict, Dumper=yaml.SafeDumper)

def repr_dict(self, data):
return self.represent_mapping(
"tag:yaml.org,2002:map", sorted(data.items(), key=lambda t: t[0])
)

yaml.add_representer(dict, repr_dict, Dumper=yaml.SafeDumper)

# https://stackoverflow.com/a/45004464
def repr_str(dumper, data):
if "\n" in data:
return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|")
return dumper.represent_str(data)

yaml.add_representer(str, repr_str, Dumper=yaml.SafeDumper)

def repr_tuple(dumper, data):
return dumper.represent_sequence("tag:yaml.org,2002:seq", list(data))

yaml.add_representer(tuple, repr_tuple, Dumper=yaml.SafeDumper)

# loader = yaml.SafeLoader
yaml.add_implicit_resolver(
"tag:yaml.org,2002:float",
re.compile(
"""^(?:
[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?
|[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)
|\\.[0-9_]+(?:[eE][-+][0-9]+)?
|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*
|[-+]?\\.(?:inf|Inf|INF)
|\\.(?:nan|NaN|NAN))$""",
re.X,
),
list("-+0123456789."),
)


_setup_yaml_with_canonical_dict()
from .errors import ScanError
from .errors import ValidationError


def validate_dict(meta, required=None, optional=None):
Expand Down Expand Up @@ -120,7 +68,7 @@ def _norm_os(name):
class BabelMetadata:
"""Library metadata."""

LOADERS = {"yaml": yaml.safe_load, "toml": toml.parse}
LOADERS = {"yaml": yaml.safe_load, "toml": tomllib.loads}

def __init__(
self, library=None, build=None, package=None, info=None, plugin=None, ci=None
Expand Down Expand Up @@ -163,7 +111,7 @@ def __init__(
self._meta = BabelMetadata.norm(config)

@classmethod
def from_stream(cls, stream, fmt="yaml"):
def from_stream(cls, stream, fmt="toml"):
"""Create an instance of BabelMetadata from a file-like object.

Parameters
Expand All @@ -187,7 +135,7 @@ def from_stream(cls, stream, fmt="yaml"):
meta = loader(stream.read())
except yaml.scanner.ScannerError as error:
raise ScanError(f"unable to scan yaml-formatted metadata file:\n{error}")
except toml.exceptions.ParseError as error:
except tomllib.TOMLDecodeError as error:
raise ScanError(f"unable to scan toml-formatted metadata file:\n{error}")
else:
if not isinstance(meta, dict):
Expand Down Expand Up @@ -390,7 +338,7 @@ def norm(config):
},
}

def dump(self, fp, fmt="yaml"):
def dump(self, fp, fmt="toml"):
"""Write serialized metadata to a file.

Parameters
Expand All @@ -402,7 +350,7 @@ def dump(self, fp, fmt="yaml"):
"""
print(self.format(fmt=fmt), file=fp)

def format(self, fmt="yaml"):
def format(self, fmt="toml"):
"""Serialize metadata to output format.

Parameters
Expand All @@ -417,20 +365,6 @@ def format(self, fmt="yaml"):
"""
return getattr(self, f"format_{fmt}")()

def format_yaml(self):
"""Serialize metadata as YAML.

Returns
-------
str
Serialized metadata as a YAML-formatted string
"""
import io

contents = io.StringIO()
yaml.safe_dump(self._meta, contents, default_flow_style=False)
return contents.getvalue()

def format_toml(self):
"""Serialize metadata as TOML.

Expand All @@ -439,7 +373,7 @@ def format_toml(self):
str
Serialized metadata as a TOML-formatted string
"""
return toml.dumps(self._meta)
return tomli_w.dumps(self._meta, multiline_strings=True)

@staticmethod
def parse_entry_point(specifier):
Expand Down
10 changes: 7 additions & 3 deletions babelizer/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@
import black as blk
import git
import isort
import tomlkit as toml
from cookiecutter.exceptions import OutputDirExistsException
from cookiecutter.main import cookiecutter

if sys.version_info >= (3, 11): # pragma: no cover (PY11+)
import tomllib
else: # pragma: no cover (<PY311)
import tomli as tomllib
if sys.version_info >= (3, 12): # pragma: no cover (PY12+)
import importlib.resources as importlib_resources
else: # pragma: no cover (<PY312)
import importlib_resources

from .errors import OutputDirExistsError, RenderError
from .errors import OutputDirExistsError
from .errors import RenderError


def render(plugin_metadata, output, template=None, clobber=False, version="0.1"):
Expand Down Expand Up @@ -160,7 +164,7 @@ def prettify_python(path_to_repo):
"""
path_to_repo = pathlib.Path(path_to_repo)
with open(path_to_repo / "babel.toml") as fp:
meta = toml.parse(fp.read())
meta = tomllib.loads(fp.read())
module_name = meta["package"]["name"]

files_to_fix = [
Expand Down
3 changes: 2 additions & 1 deletion babelizer/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import pathlib
import subprocess
import sys
from contextlib import contextmanager, suppress
from contextlib import contextmanager
from contextlib import suppress

from .errors import SetupPyError

Expand Down
3 changes: 3 additions & 0 deletions news/89.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

Removed the ability of the *babelizer* to write its config file in
*yaml* format. We switched to using *toml* a while ago.
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ dependencies = [
"gitpython",
"importlib-resources; python_version < '3.12'",
"isort>=5",
"logoizer @ git+https://github.com/mcflugen/logoizer",
"logoizer@ git+https://github.com/mcflugen/logoizer",
"pyyaml",
"tomlkit",
"tomli-w",
"tomli; python_version < '3.11'",
]
dynamic = [
"readme",
Expand Down
Loading