Skip to content

Commit

Permalink
pep508: Add support for in & not in operators
Browse files Browse the repository at this point in the history
  • Loading branch information
adisbladis committed Oct 25, 2023
1 parent 7dbb3a0 commit 5ae21e7
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 4 deletions.
21 changes: 17 additions & 4 deletions lib/pep508.nix
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{ lib, pep440, pep599, pypa, ... }:

let
inherit (builtins) match elemAt split foldl' substring stringLength typeOf fromJSON isString head mapAttrs elem;
inherit (builtins) match elemAt split foldl' substring stringLength typeOf fromJSON isString head mapAttrs elem length;
inherit (lib) stringToCharacters fix;
inherit (import ./util.nix { inherit lib; }) splitComma;

Expand All @@ -15,6 +15,8 @@ let
and = 5;
or = 10;
not = 1;
"in" = -1;
"not in" = -1;
"" = -1;
};
condGt = l: r: if l == "" then false else condPrio.${l} >= condPrio.${r};
Expand Down Expand Up @@ -93,6 +95,7 @@ let
boolOps = {
"and" = x: y: x && y;
"or" = x: y: x || y;
"in" = x: y: lib.strings.hasInfix x y;
};

isPrimitiveType =
Expand Down Expand Up @@ -172,6 +175,8 @@ fix (self:
if self.openP > 0 || acc.inString then ""
else if substring acc.pos 5 input == " and " then "and"
else if substring acc.pos 4 input == " or " then "or"
else if substring acc.pos 4 input == " in " then "in"
else if substring acc.pos 8 input == " not in " then "not in"
else if substring acc.pos 5 input == " not " then "not"
else "";

Expand All @@ -180,7 +185,8 @@ fix (self:
if cond != "" && condGt cond acc.cond then
(
if (cond == "and" || cond == "not") then 5
else if (cond == "or") then 4
else if (cond == "or" || cond == "in") then 4
else if cond == "not in" then 8
else throw "Unknown cond: ${cond}"
) else -1;

Expand Down Expand Up @@ -226,14 +232,15 @@ fix (self:
(stringToCharacters input);

in
if pos.lhs == -1 then
if pos.lhs == -1 then # No right hand value to extract
(
let
m = split re.operators (unparen input);
mLength = length m;
mAt = elemAt m;
lhs = stripStr (mAt 0);
in
{
if (mLength > 1) then assert mLength == 3; {
type = "compare";
lhs =
if isMarkerVariable lhs then {
Expand All @@ -242,6 +249,12 @@ fix (self:
} else unpackValue lhs;
op = elemAt (mAt 1) 0;
rhs = parseValueVersionDynamic lhs (unpackValue (stripStr (mAt 2)));
} else if isMarkerVariable input then {
type = "variable";
value = input;
} else rec {
value = unpackValue input;
type = typeOf value;
}
) else {
type = "boolOp";
Expand Down
39 changes: 39 additions & 0 deletions lib/test_pep508.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,45 @@ fix (self: {
expected = true;
expr = true;
};

testInOperator = {
expr = pep508.parseMarkers "python_version >= \"3\" and platform_machine in \"x86_64 X86_64 aarch64 AARCH64 ppc64le PPC64LE amd64 AMD64 win32 WIN32\"";
expected = {
lhs = {
lhs = {
type = "variable";
value = "python_version";
};
op = ">=";
rhs = {
type = "version";
value = {
dev = null;
epoch = 0;
local = null;
post = null;
pre = null;
release = [ 3 ];
};
};
type = "compare";
};
op = "and";
rhs = {
lhs = {
type = "variable";
value = "platform_machine";
};
op = "in";
rhs = {
type = "string";
value = "x86_64 X86_64 aarch64 AARCH64 ppc64le PPC64LE amd64 AMD64 win32 WIN32";
};
type = "boolOp";
};
type = "boolOp";
};
};
};

parseString = mapAttrs (_: case: case // { expr = pep508.parseString case.input; }) {
Expand Down

0 comments on commit 5ae21e7

Please sign in to comment.