3 A library
Read the tutorial. Build it yourself is the other way to read this part.
just setuptop keeps the most common words of any counts. Another program that counts words could use it too. So it goes
into a library of its own, talib, in the same workspace. A workspace is a set of packages that share one
uv.lock.
The code before this part. The code after it.
3.1 A library, with uv init
uv init --lib makes a library. In a folder of a project, it also makes the library a member of the project's
workspace. --author-from none leaves out the name of the author, which uv would take from your git settings.
This change came from running uv init --lib --author-from none packages/talib.
The folder packages/talib holds a new project, with its own pyproject.toml and a function hello. The
pyproject.toml of tally names it under [tool.uv.workspace].
uv.lock does not name talib yet, so it is out of date until the next move. A uv run would lock it again, so the
check reads the file:
grep -A2 'tool.uv.workspace' pyproject.tomlIt prints the table [tool.uv.workspace], with members = [ and "packages/talib", under it.
What changed
packages/talib/README.md: empty, for the words about the library. New, 0 lines. It comes fromuv init --lib --author-from none packages/talib. The file.packages/talib/pyproject.toml: the project of the library. New, 11 lines. It comes fromuv init --lib --author-from none packages/talib. The file.packages/talib/src/talib/__init__.py: a first function,hello. New, 2 lines. It comes fromuv init --lib --author-from none packages/talib. The file.packages/talib/src/talib/py.typed: empty, to say that the library has types. New, 0 lines. It comes fromuv init --lib --author-from none packages/talib. The file.pyproject.toml: the workspace, with talib as its member. 5 lines added. It comes fromuv init --lib --author-from none packages/talib. The file.- look at
"packages/talib",
- look at
The diff of packages/talib/pyproject.toml
@@ -0,0 +1,11 @@
+[project]
+name = "talib"
+version = "0.1.0"
+description = "Add your description here"
+readme = "README.md"
+requires-python = ">=3.12"
+dependencies = []
+
+[build-system]
+requires = ["uv_build>=0.12.13,<0.13.0"]
+build-backend = "uv_build"The diff of packages/talib/src/talib/__init__.py
@@ -0,0 +1,2 @@
+def hello() -> str:
+ return "Hello from talib!"The diff of pyproject.toml
@@ -28,3 +28,8 @@ line-length = 100
[tool.uv]
default-groups = ["dev", "docs"]
+
+[tool.uv.workspace]
+members = [
+ "packages/talib",
+]3.2 tally depends on talib
tally cannot import talib until it depends on it. uv add finds talib in the workspace, and takes it from there:
This change came from running uv add talib.
pyproject.toml lists talib under dependencies, and a table [tool.uv.sources] says that it comes from the
workspace. uv.lock names both packages.
uv run python -c "import talib; print(talib.hello())"It prints Hello from talib!.
What changed
pyproject.toml: talib, from the workspace. 4 lines added. It comes fromuv add talib. The file.- look at
talib = { workspace = true }
- look at
uv.lock: talib, as a member of the workspace. 16 lines added, 1 removed. It comes fromuv add talib. The file.
The diff of pyproject.toml
@@ -6,6 +6,7 @@ readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"tabulate>=0.9,<0.10",
+ "talib",
]
[project.scripts]
@@ -33,3 +34,6 @@ default-groups = ["dev", "docs"]
members = [
"packages/talib",
]
+
+[tool.uv.sources]
+talib = { workspace = true }3.3 top goes into talib
top is still in tally, and talib has only hello. One patch moves top across, in both packages.
A patch to packages/talib/src/talib/__init__.py.
A patch to src/tally/__init__.py.
top is now in packages/talib/src/talib/__init__.py. src/tally/__init__.py imports it from talib, so the tests
that import top from tally still find it.
uv run python -m unittest discover -s tests -qAll four tests pass.
head -4 packages/talib/src/talib/__init__.py"""talib: small helpers for the counts of words."""
def top(counts: dict[str, int], n: int) -> list[tuple[str, int]]:It prints the docstring of the library, two blank lines, and the first line of top.
What changed
packages/talib/src/talib/__init__.py:top, in place ofhello. 6 lines added, 2 removed. The file.- look at
def top(counts: dict[str, int], n: int) -> list[tuple[str, int]]:
- look at
src/tally/__init__.py:topcomes from talib. 1 line added, 5 removed. The file.- look at
from talib import top
- look at
The diff of packages/talib/src/talib/__init__.py
@@ -1,2 +1,6 @@
-def hello() -> str:
- return "Hello from talib!"
+"""talib: small helpers for the counts of words."""
+
+
+def top(counts: dict[str, int], n: int) -> list[tuple[str, int]]:
+ "The n most common words, most common first."
+ return sorted(counts.items(), key=lambda pair: (-pair[1], pair[0]))[:n]The diff of src/tally/__init__.py
@@ -3,6 +3,7 @@
import sys
from tabulate import tabulate
+from talib import top
def count(text: str) -> dict[str, int]:
@@ -13,11 +14,6 @@ def count(text: str) -> dict[str, int]:
return counts
-def top(counts: dict[str, int], n: int) -> list[tuple[str, int]]:
- "The n most common words, most common first."
- return sorted(counts.items(), key=lambda pair: (-pair[1], pair[0]))[:n]
-
-
def main() -> None:
"Count the words of a file, or of the standard input. Options: --top N, and --table."
args = sys.argv[1:]