Skip to content

Commit e97b950

Browse files
fix(poetry): pep503 normalize package name (#242)
# Issue When generating the name of the virtualenv, Poetry honors PEP 503 project name normalization [^1]. In short, the name of the project is lowercased, and all runs of `-_.` are replaced with a single `-`. For example, the normalized name of the following extract of pyproject.toml is `my-project`. ```toml [project] name = "my_project" ``` When a project name is modified like this by Poetry, the virtualenv name generated by this project will not match and the Poetry locator will not pick up any Poetry virtual environments (with the exception of the in-project `.venv`). # PR Description This PR ports the few lines of Python code from poetry-core [^2] that implement the name normalization to the Poetry locator in order to fix this unaligned behavior. [^1]: https://peps.python.org/pep-0503/#normalized-names [^2]: https://github.com/python-poetry/poetry-core/blob/a2c068227358984d835c9684de723b046bdcd67a/src/poetry/core/_vendor/packaging/utils.py#L46-L51 --------- Co-authored-by: Don Jayamanne <don.jayamanne@outlook.com>
1 parent d658378 commit e97b950

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

crates/pet-poetry/src/pyproject_toml.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,14 @@ use std::{
66
path::{Path, PathBuf},
77
};
88

9+
use lazy_static::lazy_static;
910
use log::{error, trace};
11+
use regex::Regex;
12+
13+
lazy_static! {
14+
static ref NORMALIZE_NAME: Regex = Regex::new(r"[-_.]+")
15+
.expect("Error generating RegEx for poetry project name normalization");
16+
}
1017

1118
#[derive(Debug)]
1219
pub struct PyProjectToml {
@@ -15,8 +22,17 @@ pub struct PyProjectToml {
1522

1623
impl PyProjectToml {
1724
fn new(name: String, file: PathBuf) -> Self {
18-
trace!("Poetry project: {:?} with name {:?}", file, name);
19-
PyProjectToml { name }
25+
// Source from https://github.com/python-poetry/poetry-core/blob/a2c068227358984d835c9684de723b046bdcd67a/src/poetry/core/_vendor/packaging/utils.py#L46-L51
26+
// normalized_name = re.sub(r"[-_.]+", "-", name).lower()
27+
let normalized_name = NORMALIZE_NAME
28+
.replace_all(&name.to_lowercase(), "-")
29+
.chars()
30+
.collect::<String>();
31+
32+
trace!("Poetry project: {:?} with name {:?}", file, normalized_name);
33+
PyProjectToml {
34+
name: normalized_name,
35+
}
2036
}
2137
pub fn find(path: &Path) -> Option<Self> {
2238
trace!("Finding poetry file in {:?}", path);
@@ -85,6 +101,32 @@ readme = "README.md"
85101
python = "^3.12"
86102
87103
104+
[build-system]
105+
requires = ["poetry-core"]
106+
build-backend = "poetry.core.masonry.api"
107+
"#;
108+
assert_eq!(
109+
parse_contents(cfg, Path::new("pyproject.toml"))
110+
.unwrap()
111+
.name,
112+
"poetry-demo"
113+
);
114+
}
115+
116+
#[test]
117+
fn extract_normalized_name_from_pyproject_toml() {
118+
let cfg = r#"
119+
[tool.poetry]
120+
name = "poetry_.demo"
121+
version = "0.1.0"
122+
description = ""
123+
authors = ["User Name <bogus.user@some.email.com>"]
124+
readme = "README.md"
125+
126+
[tool.poetry.dependencies]
127+
python = "^3.12"
128+
129+
88130
[build-system]
89131
requires = ["poetry-core"]
90132
build-backend = "poetry.core.masonry.api"

crates/pet-python-utils/src/cache.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ impl CacheImpl {
9191
Entry::Occupied(lock) => lock.get().clone(),
9292
Entry::Vacant(lock) => {
9393
let cache = Box::new(CacheEntryImpl::create(cache_directory.clone(), executable))
94-
as Box<(dyn CacheEntry + 'static)>;
94+
as Box<dyn CacheEntry + 'static>;
9595
lock.insert(Arc::new(Mutex::new(cache))).clone()
9696
}
9797
}

0 commit comments

Comments
 (0)