Skip to content

Commit

Permalink
Can now parse pypi dependencies that don't include parenthesis. conso…
Browse files Browse the repository at this point in the history
…le_script finding no longer whitespace-dependent
  • Loading branch information
David-OConnor committed Sep 21, 2019
1 parent 93ddbdb commit adfabeb
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

## v0.1.1
- Fixed a bug, where spaces could prevent console scripts from being installed
- Fixed parsing pypi requirements that ommit parenthesis
- Now uses `~/.local/share/pyflow` on Linux, `~\AppData\Roaming\pyflow` on Windows, and
`~/Library/Application Support/pyflow` on Mac, instead of `~/.python-installs`

Expand Down
5 changes: 0 additions & 5 deletions src/dep_resolution.rs
Expand Up @@ -310,8 +310,6 @@ fn guess_graph(
}
}

// println!("NON_LOCKED: {:#?}", &non_locked_reqs);
// println!("LOCKED: {:#?}", &locked_reqs);

// Single http call here to pydeps for all this package's reqs, plus version calls for each req.
let mut query_data = match fetch_req_data(&non_locked_reqs, vers_cache) {
Expand Down Expand Up @@ -359,8 +357,6 @@ fn guess_graph(
.filter(|d| util::compare_names(d.name.as_ref().unwrap(), &req.name))
.collect();

// println!("DBG result: {:#?}", &query_result);

let deps: Vec<Dependency> = query_result
.into_iter()
// Our query data should already be compat, but QC here.
Expand Down Expand Up @@ -524,7 +520,6 @@ pub fn resolve(
let mut reqs_searched = Vec::new();

let mut version_cache = HashMap::new();

if guess_graph(
0,
&reqs,
Expand Down
47 changes: 40 additions & 7 deletions src/dep_types.rs
Expand Up @@ -493,7 +493,7 @@ impl Constraint {
major -= 1;
minor = MAX_VER;
patch = MAX_VER;
// ie 2.9.0. Return max of 2.8.999999
// ie 2.9.0. Return max of 2.8.999999
} else if patch == 0 {
minor -= 1;
patch = MAX_VER
Expand Down Expand Up @@ -682,7 +682,7 @@ fn parse_extras(
let ex_re = Regex::new(
r#"(extra|sys_platform|python_version)\s*(\^|~|==|<=|>=|<|>|!=)\s*['"](.*?)['"]"#,
)
.unwrap();
.unwrap();

for caps in ex_re.captures_iter(extras) {
let type_ = caps.get(1).unwrap().as_str();
Expand Down Expand Up @@ -753,14 +753,13 @@ impl Req {
// wildcard, so we don't accidentally match a semicolon here if a
// set of parens appears later. The non-greedy ? in the version-matching
// expression's important as well, in some cases of extras.
Regex::new(r#"^([a-zA-Z\-0-9._]+)\s+\((.*?)\)(?:(?:\s*;\s*)(.*))?$"#).unwrap()
Regex::new(r#"^([a-zA-Z\-0-9._]+)\s+\(?(.*?)\)?(?:(?:\s*;\s*)(.*))?$"#).unwrap()
} else {
// eg saturn = ">=0.3.4", as in pyproject.toml
// todo extras in this format?
Regex::new(r#"^(.*?)\s*=\s*["'](.*)["']$"#).unwrap()
};

// todo: Excessive nesting
if let Some(caps) = re.captures(s) {
let name = caps.get(1).unwrap().as_str().to_owned();
let reqs_m = caps.get(2).unwrap();
Expand All @@ -784,7 +783,6 @@ impl Req {
} else {
// todo extras
Regex::new(r"^([a-zA-Z\-0-9._]+)$").unwrap()
// Regex::new(r"^([a-zA-Z\-0-9._]+)(?:(a|b|rc|dep)(\d+))?$").unwrap()
};

if let Some(caps) = novers_re.captures(s) {
Expand Down Expand Up @@ -1154,7 +1152,7 @@ pub mod tests {
"pathlib2; extra == \"test\" and ( python_version == \"2.7\")",
true,
)
.unwrap();
.unwrap();

let expected2 = Req {
name: "pathlib2".into(),
Expand All @@ -1169,7 +1167,7 @@ pub mod tests {
"win-unicode-console (>=0.5) ; sys_platform == \"win32\" and python_version < \"3.6\"",
true,
)
.unwrap();
.unwrap();

let expected3 = Req {
name: "win-unicode-console".into(),
Expand All @@ -1185,6 +1183,41 @@ pub mod tests {
assert_eq!(actual3, expected3);
}

// Non-standard format I've come across; more like the non-pypi fmt.
#[test]
fn parse_req_pypi_no_parens() {
let actual1 = Req::from_str("pydantic >=0.32.2,<=0.32.2", true).unwrap();
let actual2 = Req::from_str("starlette >=0.11.1,<=0.12.8", true).unwrap();

let expected1 = Req {
name: "pydantic".into(),
constraints: vec![
Constraint::new(Gte, Version::new(0, 32, 2)),
Constraint::new(Lte, Version::new(0, 32, 2)),
],
extra: None,
sys_platform: None,
python_version: None,
install_with_extras: None,
};

let expected2 = Req {
name: "starlette".into(),
constraints: vec![
Constraint::new(Gte, Version::new(0, 11, 1)),
Constraint::new(Lte, Version::new(0, 12, 8)),
],
extra: None,
sys_platform: None,
python_version: None,
install_with_extras: None,
};

assert_eq!(actual1, expected1);
assert_eq!(actual2, expected2);

}

#[test]
fn parse_req_withvers() {
let p = Req::from_str("bolt = \"3.1.4\"", false).unwrap();
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Expand Up @@ -46,6 +46,7 @@ impl FromStr for Os {
"manylinux2010_i686" => Os::Linux32,
"manylinux1_x86_64" => Os::Linux,
"manylinux2010_x86_64" => Os::Linux,
"cygwin" => Os::Linux, // todo is this right?
"linux" => Os::Linux,
"linux2" => Os::Linux,
"windows" => Os::Windows,
Expand Down

0 comments on commit adfabeb

Please sign in to comment.