Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ probe export --help
- `probe_py/probe_py`: Main package to be imported or run.
- `probe_py/pyproject.toml`: Definition of main package and dependencies.
- `probe_py/tests`: Python unittests, i.e., `from probe_py import foobar; test_foobar()`; Run `just test-py`.
- `probe_py/mypy_stubs`: "Stub" files that tell Mypy how to check untyped library code. Should be added to `$MYPYPATH` by `nix develop`.
- `tests`: End-to-end opaque-box tests. They will be run with Pytest, but they will not test Python directly; they should always `subprocess.run(["probe", ...])`. Additionally, some tests have to be manually invoked.
- `docs`: Documentation and papers.
- `benchmark`: Programs and infrastructure for benchmarking.
Expand Down
55 changes: 34 additions & 21 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@
old-stdenv = pkgs.overrideCC pkgs.stdenv new-clang-old-glibc;
in rec {
packages = rec {
types-networkx = python.pkgs.buildPythonPackage rec {
pname = "types-networkx";
version = "3.5.0.20251104";
src = pkgs.fetchPypi {
pname = "types_networkx";
inherit version;
sha256 = "0ae55ff562126dcb7dc6bf0b716a2333b69d5ff6fbcb7f768916eb8bd09fc0c9";
};
pyproject = true;
nativeBuildInputs = [python.pkgs.setuptools];
propagatedBuildInputs = [python.pkgs.numpy];
};
inherit (cli-wrapper-pkgs) cargoArtifacts probe-cli;
libprobe = old-stdenv.mkDerivation rec {
pname = "libprobe";
Expand Down Expand Up @@ -151,28 +163,29 @@
};
propagatedBuildInputs = [
python.pkgs.networkx
python.pkgs.pygraphviz
python.pkgs.numpy
python.pkgs.pydot
python.pkgs.rich
python.pkgs.typer
python.pkgs.xdg-base-dirs
python.pkgs.sqlalchemy
python.pkgs.pyyaml
python.pkgs.numpy
python.pkgs.tqdm
python.pkgs.typer
python.pkgs.xdg-base-dirs
];
nativeCheckInputs = [
python.pkgs.mypy
python.pkgs.types-pyyaml
python.pkgs.pytest
python.pkgs.pytest-asyncio
python.pkgs.pytest-timeout
python.pkgs.types-tqdm
types-networkx
pkgs.ruff
];
checkPhase = ''
runHook preCheck
#ruff format --check probe_src # TODO: uncomment
ruff check .
python -c 'import probe_py'
MYPYPATH=$src/mypy_stubs:$MYPYPATH mypy --strict --package probe_py
mypy --strict --package probe_py
runHook postCheck
'';
};
Expand All @@ -190,11 +203,11 @@
checks = {
inherit
(cli-wrapper.checks."${system}")
probe-workspace-audit
probe-workspace-clippy
probe-workspace-deny
probe-workspace-doc
probe-workspace-fmt
probe-workspace-audit
probe-workspace-deny
probe-workspace-nextest
;
fmt-nix = pkgs.stdenv.mkDerivation {
Expand All @@ -213,6 +226,7 @@
packages.probe
(python.withPackages (ps:
with ps; [
packages.probe-py
pytest
pytest-timeout
pytest-asyncio
Expand Down Expand Up @@ -244,23 +258,22 @@
probe-python = python.withPackages (pypkgs: [
# probe_py.manual runtime requirements
pypkgs.networkx
pypkgs.numpy
pypkgs.pydot
pypkgs.rich
pypkgs.typer
pypkgs.sqlalchemy
pypkgs.xdg-base-dirs
pypkgs.pyyaml
pypkgs.numpy
pypkgs.tqdm
pypkgs.typer
pypkgs.xdg-base-dirs

# probe_py.manual "dev time" requirements
pypkgs.types-tqdm
pypkgs.types-pyyaml
pypkgs.pytest
pypkgs.pytest-timeout
pypkgs.mypy
pypkgs.ipython
pypkgs.mypy
pypkgs.pytest
pypkgs.pytest-asyncio
pypkgs.pytest-timeout
pypkgs.types-tqdm
packages.types-networkx

# libprobe build time requirement
pypkgs.pycparser
Expand All @@ -276,10 +289,10 @@
shellPackages =
[
# Rust tools
pkgs.cargo-deny
pkgs.cargo-audit
pkgs.cargo-machete
pkgs.cargo-deny
pkgs.cargo-hakari
pkgs.cargo-machete

# Replay tools
pkgs.buildah
Expand All @@ -298,8 +311,8 @@
old-pkgs.criterion # unit testing framework

# Programs for testing
pkgs.nix
pkgs.coreutils
pkgs.nix

# For other lints
pkgs.alejandra
Expand Down
122 changes: 0 additions & 122 deletions probe_py/mypy_stubs/networkx/__init__.pyi

This file was deleted.

1 change: 0 additions & 1 deletion probe_py/mypy_stubs/networkx/drawing/__init__.pyi

This file was deleted.

9 changes: 0 additions & 9 deletions probe_py/mypy_stubs/networkx/drawing/nx_pydot.pyi

This file was deleted.

1 change: 0 additions & 1 deletion probe_py/mypy_stubs/scipy/__init__.pyi

This file was deleted.

1 change: 0 additions & 1 deletion probe_py/mypy_stubs/scipy/cluster/__init__.pyi

This file was deleted.

10 changes: 0 additions & 10 deletions probe_py/mypy_stubs/scipy/cluster/hierarchy.pyi

This file was deleted.

2 changes: 1 addition & 1 deletion probe_py/probe_py/dataflow_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,4 +301,4 @@ def shorten_path(input: pathlib.Path) -> str:
data["shape"] = "rectangle"
data["id"] = str(hash(node))
for a, b in cycle:
dataflow_graph.edges[a, b]["color"] = "red" # type: ignore
dataflow_graph.edges[a, b]["color"] = "red"
26 changes: 13 additions & 13 deletions probe_py/probe_py/graph_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,11 @@
_Node = typing.TypeVar("_Node")


_CoNode = typing.TypeVar("_CoNode", covariant=True)


@dataclasses.dataclass(frozen=True)
class Segment(typing.Generic[_CoNode]):
dag_tc: ReachabilityOracle[_CoNode]
upper_bound: frozenset[_CoNode]
lower_bound: frozenset[_CoNode]
class Segment(typing.Generic[_Node]):
dag_tc: ReachabilityOracle[_Node]
upper_bound: frozenset[_Node]
lower_bound: frozenset[_Node]

def __post_init__(self) -> None:
assert self.upper_bound
Expand All @@ -38,15 +35,15 @@ def __post_init__(self) -> None:
assert not unbounded, \
f"{unbounded} in self.lower_bound is not a descendant of any in {self.upper_bound=}"

def nodes(self) -> collections.abc.Iterable[_CoNode]:
def nodes(self) -> collections.abc.Iterable[_Node]:
return self.dag_tc.nodes_between(self.upper_bound, self.lower_bound)

def overlaps(self, other: Segment[_CoNode]) -> bool:
def overlaps(self, other: Segment[_Node]) -> bool:
assert self.dag_tc is other.dag_tc
return bool(frozenset(self.nodes()) & frozenset(other.nodes()))

@staticmethod
def union(segments: typing.Sequence[Segment[_CoNode]]) -> Segment[_CoNode]:
def union(segments: typing.Sequence[Segment[_Node]]) -> Segment[_Node]:
assert segments
dag_tc = segments[0].dag_tc
assert all(segment.dag_tc is dag_tc for segment in segments)
Expand Down Expand Up @@ -86,7 +83,8 @@ def map_nodes(
) -> networkx.DiGraph[_Node2]:
dct = {node: function(node) for node in graph.nodes()}
assert util.all_unique(dct.values()), util.duplicates(dct.values())
return networkx.relabel_nodes(graph, dct)
ret = typing.cast("networkx.DiGraph[_Node2]", networkx.relabel_nodes(graph, dct))
return ret


def serialize_graph(
Expand Down Expand Up @@ -233,7 +231,7 @@ def create(dag: networkx.DiGraph[_Node]) -> ReachabilityOracle[_Node]:

@abc.abstractmethod
def is_reachable(self, u: _Node, v: _Node) -> bool:
pass
...

@abc.abstractmethod
def nodes_between(
Expand Down Expand Up @@ -321,6 +319,7 @@ def non_ancestors(
candidates: collections.abc.Iterable[_Node],
lower_bounds: collections.abc.Iterable[_Node],
) -> collections.abc.Iterable[_Node]:
"Return all candidates that are not ancestors of any element in lower_bounds."
return frozenset({
candidate
for candidate in candidates
Expand All @@ -335,6 +334,7 @@ def non_descendants(
candidates: collections.abc.Iterable[_Node],
upper_bounds: collections.abc.Iterable[_Node],
) -> collections.abc.Iterable[_Node]:
"Return all candidates that are not descendent of any element in upper_bounds."
return frozenset({
candidate
for candidate in candidates
Expand Down Expand Up @@ -376,7 +376,7 @@ def add_edge(self, source: _Node, target: _Node) -> None:


def get_faces(
planar_graph: networkx.PlanarEmbedding[_Node], # type: ignore
planar_graph: networkx.PlanarEmbedding[_Node],
) -> frozenset[tuple[_Node, ...]]:
faces = set()
covered_half_edges = set()
Expand Down
Loading