Skip to content

Commit 6e1b253

Browse files
authored
Merge pull request #87 from kurtmckee/fix-find_distributions-lacking-a-name
Find all available distributions when no name is given
2 parents 67e2110 + 83de1d3 commit 6e1b253

File tree

4 files changed

+69
-11
lines changed

4 files changed

+69
-11
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Fixed
2+
-----
3+
4+
* Find all available distributions when no name is given.
5+
6+
This allows tools like flake8 to auto-detect installed plugins.

src/sqliteimport/accessor.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,35 @@ def get_file(
268268

269269
return decompress(contents)
270270

271+
def find_distributions(self, name: str | None) -> typing.Generator[str]:
272+
if name is not None:
273+
path_pattern = f"{name}-%.dist-info/METADATA"
274+
else:
275+
path_pattern = "%.dist-info/METADATA"
276+
277+
sql = """
278+
SELECT
279+
path
280+
FROM code
281+
WHERE
282+
path LIKE $path_pattern
283+
;
284+
"""
285+
286+
cursor = self.connection.execute(
287+
sql,
288+
{"path_pattern": path_pattern},
289+
)
290+
rows = cursor.fetchall()
291+
if rows is None:
292+
return
293+
294+
path: str
295+
for (path,) in rows:
296+
module, _, _ = path.partition("-")
297+
if module.isidentifier():
298+
yield module
299+
271300
def list_directory(self, path_like: str) -> list[str]:
272301
"""List the contents of a directory."""
273302

src/sqliteimport/importer.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
)
2525

2626

27-
class SqliteFinder(importlib.abc.MetaPathFinder):
27+
class SqliteFinder(importlib.metadata.DistributionFinder):
2828
def __init__(self, database: pathlib.Path | sqlite3.Connection) -> None:
2929
if isinstance(database, pathlib.Path):
3030
self.database = database
@@ -69,17 +69,9 @@ def find_distributions(
6969
) -> typing.Generator[SqliteDistribution]:
7070
if context is None:
7171
context = importlib.metadata.DistributionFinder.Context()
72-
if context.name is None:
73-
return
7472

75-
# Determine if the distribution exists.
76-
# This try/except block is an inelegant conditional.
77-
try:
78-
self.accessor.get_file(path=f"{context.name}-%.dist-info/METADATA")
79-
except FileNotFoundError:
80-
return
81-
82-
yield SqliteDistribution(context.name, self.connection)
73+
for module in self.accessor.find_distributions(context.name):
74+
yield SqliteDistribution(module, self.connection)
8375

8476

8577
@accommodate_python_39_from_package_behavior
@@ -114,6 +106,12 @@ def __init__(self, name: str, connection: sqlite3.Connection) -> None:
114106
self.__connection = connection
115107
self.__accessor = Accessor(connection)
116108

109+
if sys.version_info < (3, 10):
110+
# The `.name` property doesn't exist in Python 3.9.
111+
@property
112+
def name(self) -> str:
113+
return self.metadata["Name"]
114+
117115
def locate_file(self, path: typing.Any) -> pathlib.Path:
118116
raise NotImplementedError()
119117

tests/test_importing.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import importlib.machinery
22
import importlib.metadata
33
import importlib.resources
4+
import importlib.util
45
import sys
56
import types
67
import uuid
@@ -220,3 +221,27 @@ def test_distribution_finding(database):
220221
name = f"p{uuid.uuid4().hex}"
221222
discovered = list(sqliteimport.importer.SqliteDistribution.discover(name=name))
222223
assert discovered == []
224+
225+
226+
def test_find_distributions_finds_nothing(database):
227+
name = f"p{uuid.uuid4().hex}"
228+
distributions = list(importlib.metadata.distributions(name=name))
229+
assert distributions == []
230+
231+
232+
@pytest.mark.parametrize("name", ("package_filesystem", "package_sqlite"))
233+
def test_find_distributions_one_name(database, name, ignore_tempermental_deprecations):
234+
distributions = list(importlib.metadata.distributions(name=name))
235+
assert len(distributions) == 1
236+
assert distributions[0].metadata["Name"] == name.replace("_", "-")
237+
238+
239+
def test_find_distributions_finds_everything(database):
240+
distributions = list(importlib.metadata.distributions())
241+
distribution_names = {d.metadata["Name"] for d in distributions}
242+
expected_names = {
243+
"module-sqlite",
244+
"namespace-sqlite-plugin",
245+
"package-sqlite",
246+
}
247+
assert distribution_names & expected_names == expected_names

0 commit comments

Comments
 (0)