Skip to content

Commit

Permalink
Replace pkg_resources by importlib.resources (#496)
Browse files Browse the repository at this point in the history
  • Loading branch information
hynek committed Apr 24, 2023
1 parent 29163bc commit 5642c8e
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 31 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ requires-python = ">=3.7"
dependencies = [
"click",
"click-default-group",
"importlib-resources>1.3; python_version<'3.9'",
"incremental",
"jinja2",
"setuptools",
"tomli; python_version<'3.11'",
]

Expand Down
25 changes: 20 additions & 5 deletions src/towncrier/_settings/load.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@

from __future__ import annotations

import atexit
import os
import sys

from collections import OrderedDict
from contextlib import ExitStack
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Mapping

import pkg_resources

from .._settings import fragment_types as ft


Expand All @@ -23,6 +23,12 @@
else:
from typing import Literal

if sys.version_info < (3, 9):
import importlib_resources as resources
else:
from importlib import resources


if sys.version_info < (3, 11):
import tomli as tomllib
else:
Expand Down Expand Up @@ -106,6 +112,11 @@ def load_config_from_file(directory: str, config_file: str) -> Config:
return parse_toml(directory, config)


# Clean up possible temporary files on exit.
_file_manager = ExitStack()
atexit.register(_file_manager.close)


def parse_toml(base_path: str, config: Mapping[str, Any]) -> Config:
if "tool" not in config:
raise ConfigError("No [tool.towncrier] section.", failing_option="all")
Expand Down Expand Up @@ -146,14 +157,18 @@ def parse_toml(base_path: str, config: Mapping[str, Any]) -> Config:

template = config.get("template", _template_fname)
if template.startswith("towncrier:"):
resource_name = "templates/" + template.split("towncrier:", 1)[1] + ".rst"
if not pkg_resources.resource_exists("towncrier", resource_name):
resource_name = f"templates/{template.split('towncrier:', 1)[1]}.rst"
resource_path = _file_manager.enter_context(
resources.as_file(resources.files("towncrier") / resource_name)
)

if not resource_path.is_file():
raise ConfigError(
"Towncrier does not have a template named '%s'."
% (template.split("towncrier:", 1)[1],)
)

template = pkg_resources.resource_filename("towncrier", resource_name)
template = str(resource_path)
else:
template = os.path.join(base_path, template)

Expand Down
1 change: 1 addition & 0 deletions src/towncrier/newsfragments/496.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Towncrier no longer depends on setuptools & uses importlib.resources (or its backport) instead.
15 changes: 15 additions & 0 deletions src/towncrier/test/helpers.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
from __future__ import annotations

import sys

from functools import wraps
from pathlib import Path
from typing import Any, Callable

from click.testing import CliRunner


if sys.version_info < (3, 9):
import importlib_resources as resources
else:
from importlib import resources


def read(filename: str | Path) -> str:
return Path(filename).read_text()

Expand All @@ -20,6 +28,13 @@ def write(path: str | Path, contents: str) -> None:
p.write_text(contents)


def read_pkg_resource(path: str) -> str:
"""
Read *path* from the towncrier package.
"""
return (resources.files("towncrier") / path).read_text("utf8")


def with_isolated_runner(fn: Callable[..., Any]) -> Callable[..., Any]:
"""
Run *fn* within an isolated filesystem and add the kwarg *runner* to its
Expand Down
19 changes: 5 additions & 14 deletions src/towncrier/test/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@

from collections import OrderedDict

import pkg_resources

from twisted.trial.unittest import TestCase

from .._builder import render_fragments, split_fragments
from .helpers import read_pkg_resource


class FormatterTests(TestCase):
Expand Down Expand Up @@ -119,9 +118,7 @@ def test_basic(self):
- Web fixed. (#3)
"""

template = pkg_resources.resource_string(
"towncrier", "templates/default.rst"
).decode("utf8")
template = read_pkg_resource("templates/default.rst")

fragments = split_fragments(fragments, definitions)
output = render_fragments(
Expand Down Expand Up @@ -208,9 +205,7 @@ def test_issue_format(self):
- xxbar, xx1, xx9, xx142
"""

template = pkg_resources.resource_string(
"towncrier", "templates/default.rst"
).decode("utf8")
template = read_pkg_resource("templates/default.rst")

fragments = split_fragments(fragments, definitions)
output = render_fragments(
Expand Down Expand Up @@ -266,9 +261,7 @@ def test_line_wrapping(self):
a a (#3)
"""

template = pkg_resources.resource_string(
"towncrier", "templates/default.rst"
).decode("utf8")
template = read_pkg_resource("templates/default.rst")

fragments = split_fragments(fragments, definitions)
output = render_fragments(
Expand Down Expand Up @@ -317,9 +310,7 @@ def test_line_wrapping_disabled(self):
- a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a (#3)
""" # NOQA

template = pkg_resources.resource_string(
"towncrier", "templates/default.rst"
).decode("utf8")
template = read_pkg_resource("templates/default.rst")

fragments = split_fragments(fragments, definitions)
output = render_fragments(
Expand Down
15 changes: 4 additions & 11 deletions src/towncrier/test/test_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
from pathlib import Path
from textwrap import dedent

import pkg_resources

from click.testing import CliRunner
from twisted.trial.unittest import TestCase

from .._builder import render_fragments, split_fragments
from .._writer import append_to_newsfile
from ..build import _main
from .helpers import read_pkg_resource


class WritingTests(TestCase):
Expand Down Expand Up @@ -92,9 +91,7 @@ def test_append_at_top(self):

fragments = split_fragments(fragments, definitions)

template = pkg_resources.resource_string(
"towncrier", "templates/default.rst"
).decode("utf8")
template = read_pkg_resource("templates/default.rst")

append_to_newsfile(
tempdir,
Expand Down Expand Up @@ -205,9 +202,7 @@ def test_append_at_top_with_hint(self):

fragments = split_fragments(fragments, definitions)

template = pkg_resources.resource_string(
"towncrier", "templates/default.rst"
).decode("utf8")
template = read_pkg_resource("templates/default.rst")

append_to_newsfile(
tempdir,
Expand Down Expand Up @@ -242,9 +237,7 @@ def test_multiple_file_no_start_string(self):
definitions = {}
fragments = split_fragments(fragments={}, definitions=definitions)

template = pkg_resources.resource_string(
"towncrier", "templates/default.rst"
).decode("utf8")
template = read_pkg_resource("templates/default.rst")

content = render_fragments(
template=template,
Expand Down

3 comments on commit 5642c8e

@kloczek
Copy link

Choose a reason for hiding this comment

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

Is it possible to release new version because that commit? 🤔

@kloczek
Copy link

Choose a reason for hiding this comment

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

Looks like since last release already in git repo is +140 commits.
It would be good to release new version .. please.

@kloczek
Copy link

Choose a reason for hiding this comment

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

correction .. 20 commits 😋

Please sign in to comment.