Skip to content

Commit 82f3ff1

Browse files
committed
Use importlib.metadata to find and uninstall packages
1 parent e660996 commit 82f3ff1

File tree

4 files changed

+43
-5
lines changed

4 files changed

+43
-5
lines changed

colcon_python_project/metadata.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
# Copyright 2022 Open Source Robotics Foundation, Inc.
22
# Licensed under the Apache License, Version 2.0
33

4-
from email.parser import Parser
54
from pathlib import Path
65
from tempfile import TemporaryDirectory
76

87
from colcon_python_project.hook_caller_decorator \
98
import get_decorated_hook_caller
109

10+
try:
11+
from importlib.metadata import Distribution
12+
except ImportError:
13+
from importlib_metadata import Distribution
14+
1115

1216
async def load_metadata(desc):
1317
"""
@@ -19,10 +23,8 @@ async def load_metadata(desc):
1923
with TemporaryDirectory() as md_dir:
2024
md_name = await hook_caller.prepare_metadata_for_build_wheel(
2125
metadata_directory=md_dir)
22-
md_path = Path(md_dir) / md_name / 'METADATA'
23-
with open(md_path) as f:
24-
metadata = Parser().parse(f)
25-
return metadata
26+
md_path = Path(md_dir) / md_name
27+
return Distribution.at(md_path).metadata
2628

2729

2830
async def load_and_cache_metadata(desc):

colcon_python_project/wheel.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
from colcon_core.python_install_path import get_python_install_path
1717
from distlib.scripts import ScriptMaker
1818

19+
try:
20+
from importlib.metadata import Distribution
21+
except ImportError:
22+
from importlib_metadata import Distribution
23+
1924

2025
def _get_install_path(key, install_base):
2126
return get_python_install_path(key, {'base': str(install_base)})
@@ -41,6 +46,33 @@ def write_and_record(libdir, path, lines):
4146
f'{len(raw)}')
4247

4348

49+
def remove_distributions(name, install_base):
50+
"""
51+
Remove any installed distributions with the given name.
52+
53+
:param name: Name of the distribution.
54+
:param install_base: Path to the base directory to uninstall from.
55+
"""
56+
for search_path in (
57+
_get_install_path('purelib', install_base),
58+
_get_install_path('platlib', install_base),
59+
):
60+
dirs = set()
61+
for dist in Distribution.discover(name=name, path=(search_path,)):
62+
for f in dist.files:
63+
f_abs = f.locate()
64+
if f_abs.is_relative_to(search_path):
65+
f_abs.unlink()
66+
dirs.add(f_abs.parent)
67+
68+
while dirs:
69+
d = dirs.pop()
70+
if d == search_path or any(d.iterdir()):
71+
continue
72+
d.rmdir()
73+
dirs.add(d.parent)
74+
75+
4476
def install_wheel(wheel_path, install_base, script_dir_override=None):
4577
"""
4678
Install a wheel file under the given installation base directory.
@@ -61,6 +93,8 @@ def install_wheel(wheel_path, install_base, script_dir_override=None):
6193
record_file = dist_info_dir + 'RECORD'
6294
entry_points_file = dist_info_dir + 'entry_points.txt'
6395

96+
remove_distributions(distribution, install_base)
97+
6498
with ZipFile(
6599
wheel_path, mode='r', compression=ZIP_DEFLATED, allowZip64=True
66100
) as wf:

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ install_requires =
2828
colcon-core>=0.12.0
2929
colcon-ros
3030
distlib
31+
importlib_metadata;python_version < "3.8"
3132
tomli>=1.0.0;python_version < "3.11"
3233
packages = find:
3334
zip_safe = true

test/spell_check.words

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ toml
6565
tomli
6666
tomllib
6767
traceback
68+
uninstall
6869
unittest
6970
urlsafe
7071
zipfile

0 commit comments

Comments
 (0)