From 4a8e6e7c5d0f21b58dc1b74dffbf133d7798faf7 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Mon, 8 Aug 2022 13:01:11 -0400 Subject: [PATCH 01/23] Adding cpdag class --- pywhy_graphs/__init__.py | 1 + pywhy_graphs/admg.py | 55 +------------- pywhy_graphs/base.py | 55 ++++++++++++++ pywhy_graphs/cpdag.py | 157 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 214 insertions(+), 54 deletions(-) create mode 100644 pywhy_graphs/base.py diff --git a/pywhy_graphs/__init__.py b/pywhy_graphs/__init__.py index 14807d9a4..38f274be3 100644 --- a/pywhy_graphs/__init__.py +++ b/pywhy_graphs/__init__.py @@ -1,4 +1,5 @@ from .admg import ADMG +from .cpdag import CPDAG __version__ = 'v0.1dev0' \ No newline at end of file diff --git a/pywhy_graphs/admg.py b/pywhy_graphs/admg.py index 867ccd3a7..477f11766 100644 --- a/pywhy_graphs/admg.py +++ b/pywhy_graphs/admg.py @@ -1,59 +1,6 @@ -from typing import List, Set, Iterator - import networkx as nx from graphs import MixedEdgeGraph - - -class AncestralMixin: - def ancestors(self, source) -> Set: - """Ancestors of 'source' node with directed path.""" - return nx.ancestors(self.sub_directed_graph, source) - - def descendants(self, source) -> Set: - """Descendants of 'source' node with directed path.""" - return nx.descendants(self.sub_directed_graph, source) - - def children(self, n) -> Iterator: - """Return an iterator over children of node n. - - Children of node 'n' are nodes with a directed - edge from 'n' to that node. For example, - 'n' -> 'x', 'n' -> 'y'. Nodes only connected - via a bidirected edge are not considered children: - 'n' <-> 'y'. - - Parameters - ---------- - n : node - A node in the causal DAG. - - Returns - ------- - children : Iterator - An iterator of the children of node 'n'. - """ - return self.sub_directed_graph.successors(n) - - def parents(self, n) -> Iterator: - """Return an iterator over parents of node n. - - Parents of node 'n' are nodes with a directed - edge from 'n' to that node. For example, - 'n' <- 'x', 'n' <- 'y'. Nodes only connected - via a bidirected edge are not considered parents: - 'n' <-> 'y'. - - Parameters - ---------- - n : node - A node in the causal DAG. - - Returns - ------- - parents : Iterator - An iterator of the parents of node 'n'. - """ - return self.sub_directed_graph.predecessors(n) +from .base import AncestralMixin class ADMG(MixedEdgeGraph, AncestralMixin): diff --git a/pywhy_graphs/base.py b/pywhy_graphs/base.py new file mode 100644 index 000000000..135f148fa --- /dev/null +++ b/pywhy_graphs/base.py @@ -0,0 +1,55 @@ +from typing import Set, Iterator + +import networkx as nx + + +class AncestralMixin: + def ancestors(self, source) -> Set: + """Ancestors of 'source' node with directed path.""" + return nx.ancestors(self.sub_directed_graph, source) + + def descendants(self, source) -> Set: + """Descendants of 'source' node with directed path.""" + return nx.descendants(self.sub_directed_graph, source) + + def children(self, n) -> Iterator: + """Return an iterator over children of node n. + + Children of node 'n' are nodes with a directed + edge from 'n' to that node. For example, + 'n' -> 'x', 'n' -> 'y'. Nodes only connected + via a bidirected edge are not considered children: + 'n' <-> 'y'. + + Parameters + ---------- + n : node + A node in the causal DAG. + + Returns + ------- + children : Iterator + An iterator of the children of node 'n'. + """ + return self.sub_directed_graph.successors(n) + + def parents(self, n) -> Iterator: + """Return an iterator over parents of node n. + + Parents of node 'n' are nodes with a directed + edge from 'n' to that node. For example, + 'n' <- 'x', 'n' <- 'y'. Nodes only connected + via a bidirected edge are not considered parents: + 'n' <-> 'y'. + + Parameters + ---------- + n : node + A node in the causal DAG. + + Returns + ------- + parents : Iterator + An iterator of the parents of node 'n'. + """ + return self.sub_directed_graph.predecessors(n) diff --git a/pywhy_graphs/cpdag.py b/pywhy_graphs/cpdag.py index e69de29bb..eac7fddc2 100644 --- a/pywhy_graphs/cpdag.py +++ b/pywhy_graphs/cpdag.py @@ -0,0 +1,157 @@ +from typing import FrozenSet, Dict, Iterator + +from collections import defaultdict +import networkx as nx +from graphs import MixedEdgeGraph +from .base import AncestralMixin + + +class CPDAG(MixedEdgeGraph, AncestralMixin): + """Completed partially directed acyclic graphs (CPDAG). + + CPDAGs generalize causal DAGs by allowing undirected edges. + Undirected edges imply uncertainty in the orientation of the causal + relationship. For example, ``A - B``, can be ``A -> B`` or ``A <- B``, + allowing for a Markov equivalence class of DAGs for each CPDAG. + This means that the number of DAGs represented by a CPDAG is $2^n$, where + ``n`` is the number of undirected edges present in the CPDAG. + + Parameters + ---------- + incoming_directed_edges : input directed edges (optional, default: None) + Data to initialize directed edges. All arguments that are accepted + by `networkx.DiGraph` are accepted. + incoming_undirected_edges : input undirected edges (optional, default: None) + Data to initialize undirected edges. All arguments that are accepted + by `networkx.Graph` are accepted. + directed_edge_name : str + The name for the directed edges. By default 'directed'. + undirected_edge_name : str + The name for the directed edges. By default 'undirected'. + attr : keyword arguments, optional (default= no attributes) + Attributes to add to graph as key=value pairs. + + See Also + -------- + networkx.DiGraph + networkx.Graph + ADMG + + Notes + ----- + CPDAGs are Markov equivalence class of causal DAGs. The implicit assumption in + these causal graphs are the Structural Causal Model (or SCM) is Markovian, inducing + causal sufficiency, where there is no unobserved latent confounder. This allows CPDAGs + to be learned from score-based (such as the GES algorithm) and constraint-based + (such as the PC algorithm) approaches for causal structure learning. + + One should not use CPDAGs if they suspect their data has unobserved latent confounders. + """ + + def __init__(self, + incoming_directed_edges=None, + incoming_undirected_edges=None, + directed_edge_name='directed', + undirected_edge_name='undirected', + **attr): + super().__init__(**attr) + self.add_edge_type(nx.DiGraph(incoming_directed_edges), directed_edge_name) + self.add_edge_type(nx.Graph(incoming_undirected_edges), undirected_edge_name) + + self._directed_name = directed_edge_name + self._undirected_name = undirected_edge_name + + if not nx.is_directed_acyclic_graph(self.sub_directed_graph()): + raise RuntimeError(f"{self} is not a DAG, which it should be.") + + def undirected_edges(self): + return self.get_graphs(self._undirected_name).edges + + def directed_edges(self): + return self.get_graphs(self._directed_name).edges + + def sub_directed_graph(self): + return self._get_internal_graph(self._directed_name) + + def sub_undirected_graph(self): + return self._get_internal_graph(self._undirected_name) + + def orient_undirected_edge(self, u, v): + """Orient undirected edge into an arrowhead. + + If there is an undirected edge u - v, then the arrowhead + will orient u -> v. If the correct order is v <- u, then + simply pass the arguments in different order. + + Parameters + ---------- + u : node + The parent node + v : node + The node that 'u' points to in the graph. + """ + if not self.has_undirected_edge(u, v): + raise RuntimeError(f"There is no undirected edge between {u} and {v}.") + + self.remove_undirected_edge(v, u) + self.add_edge(u, v) + + def possible_children(self, n) -> Iterator: + """Return an iterator over children of node n. + + Children of node 'n' are nodes with a directed + edge from 'n' to that node. For example, + 'n' -> 'x', 'n' -> 'y'. Nodes only connected + via a bidirected edge are not considered children: + 'n' <-> 'y'. + + Parameters + ---------- + n : node + A node in the causal DAG. + + Returns + ------- + children : Iterator + An iterator of the children of node 'n'. + """ + return self.sub_undirected_graph.neighbors(n) + + def possible_parents(self, n) -> Iterator: + """Return an iterator over parents of node n. + + Parents of node 'n' are nodes with a directed + edge from 'n' to that node. For example, + 'n' <- 'x', 'n' <- 'y'. Nodes only connected + via a bidirected edge are not considered parents: + 'n' <-> 'y'. + + Parameters + ---------- + n : node + A node in the causal DAG. + + Returns + ------- + parents : Iterator + An iterator of the parents of node 'n'. + """ + return self.sub_undirected_graph.neighbors(n) + + + +class ExtendedPattern(CPDAG): + def __init__(self, incoming_directed_edges=None, incoming_undirected_edges=None, directed_edge_name='directed', undirected_edge_name='undirected', **attr): + super().__init__(incoming_directed_edges, incoming_undirected_edges, directed_edge_name, undirected_edge_name, **attr) + + # extended patterns store unfaithful triples + self._unfaithful_triples = dict() + + def mark_unfaithful_triple(self, v_i, u, v_j): + if any(node not in self.nodes for node in [v_i, u, v_j]): + raise RuntimeError(f"The triple {v_i}, {u}, {v_j} is not in the graph.") + + self._unfaithful_triples[frozenset(v_i, u, v_j)] = None + + def unfaithful_triples(self) -> Dict: + return self._unfaithful_triples From 62025ad126a4c536d21b5e25d2c5263b49e72b03 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Mon, 8 Aug 2022 15:13:31 -0400 Subject: [PATCH 02/23] Adding CPDAG and working unit tests --- .github/workflows/main.yml | 2 +- docs/api.rst | 45 ------ junit-results.xml | 1 + pywhy_graphs/__init__.py | 3 +- pywhy_graphs/admg.py | 37 +++-- pywhy_graphs/base.py | 12 +- pywhy_graphs/cpdag.py | 61 ++++---- pywhy_graphs/function.py | 13 ++ pywhy_graphs/tests/test_admg.py | 238 ++++++++++++++++++-------------- 9 files changed, 213 insertions(+), 199 deletions(-) create mode 100644 junit-results.xml create mode 100644 pywhy_graphs/function.py diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a7b986294..740e77ae3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -59,7 +59,7 @@ jobs: fail-fast: false matrix: os: [ubuntu, macos, windows] - python-version: [3.7, 3.8, 3.9, "3.10"] + python-version: [3.8, 3.9, "3.10"] name: build ${{ matrix.os }} - py${{ matrix.python-version }} runs-on: ${{ matrix.os }}-latest defaults: diff --git a/docs/api.rst b/docs/api.rst index 125edff6c..77806da58 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -23,39 +23,8 @@ graphs encountered in the literature. .. autosummary:: :toctree: generated/ - StructuralCausalModel CPDAG ADMG - PAG - -To see a breakdown of different inner graph functionalities, -see the :ref:`Graph API ` page. See - -.. toctree:: - :maxdepth: 0 - - graph_api - - -IO for reading/writing causal graphs -==================================== -We advocate for using our implemented causal graph classes whenever -utilizing various packages. However, we also support transformations -to and from popular storage classes, such as ``numpy arrays``, -``pandas dataframes``, ``pgmpy``, ``DOT`` and ``dagitty``. Note that -not all these are supported for all types of graphs because of -inherent limitations in supporting mixed-edge graphs in other formats. - -.. currentmodule:: pywhy_graphs.io - -.. autosummary:: - :toctree: generated/ - - load_from_networkx - load_from_numpy - load_from_pgmpy - to_networkx - to_numpy Converting Graphs ================= @@ -65,17 +34,3 @@ Converting Graphs :toctree: generated/ dag2cpdag - admg2pag - -Utility Algorithms for Causal Graphs -==================================== -.. currentmodule:: pywhy_graphs.algorithms - -.. autosummary:: - :toctree: generated/ - - discriminating_path - possibly_d_sep_sets - uncovered_pd_path - is_markov_equivalent - compute_v_structures \ No newline at end of file diff --git a/junit-results.xml b/junit-results.xml new file mode 100644 index 000000000..a12af5745 --- /dev/null +++ b/junit-results.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pywhy_graphs/__init__.py b/pywhy_graphs/__init__.py index 38f274be3..9eb6b6f09 100644 --- a/pywhy_graphs/__init__.py +++ b/pywhy_graphs/__init__.py @@ -1,5 +1,4 @@ - from .admg import ADMG from .cpdag import CPDAG -__version__ = 'v0.1dev0' \ No newline at end of file +__version__ = "v0.1dev0" diff --git a/pywhy_graphs/admg.py b/pywhy_graphs/admg.py index 477f11766..024e21aa4 100644 --- a/pywhy_graphs/admg.py +++ b/pywhy_graphs/admg.py @@ -1,5 +1,6 @@ import networkx as nx from graphs import MixedEdgeGraph + from .base import AncestralMixin @@ -44,20 +45,22 @@ class ADMG(MixedEdgeGraph, AncestralMixin): edges and directed edges. Non-directed edges in an ADMG can be present as bidirected edges standing for latent confounders, or undirected edges standing for selection bias. - + - Normal directed edges (<-, ->, indicating causal relationship) = `networkx.DiGraph` - Bidirected edges (<->, indicating latent confounder) = `networkx.Graph` - Undirected edges (--, indicating selection bias) = `networkx.Graph` """ - def __init__(self, + def __init__( + self, incoming_directed_edges=None, incoming_bidirected_edges=None, incoming_undirected_edges=None, - directed_edge_name='directed', - bidirected_edge_name='bidirected', - undirected_edge_name='undirected', - **attr): + directed_edge_name="directed", + bidirected_edge_name="bidirected", + undirected_edge_name="undirected", + **attr, + ): super().__init__(**attr) self.add_edge_type(nx.DiGraph(incoming_directed_edges), directed_edge_name) self.add_edge_type(nx.Graph(incoming_bidirected_edges), bidirected_edge_name) @@ -66,7 +69,7 @@ def __init__(self, self._directed_name = directed_edge_name self._bidirected_name = bidirected_edge_name self._undirected_name = undirected_edge_name - + if not nx.is_directed_acyclic_graph(self.sub_directed_graph()): raise RuntimeError(f"{self} is not a DAG, which it should be.") @@ -78,23 +81,29 @@ def c_components(self): comp : iterator of sets The c-components. """ - return nx.connected_components(self.sub_bidirected_graph) + return nx.connected_components(self.sub_bidirected_graph()) # return [comp for comp in c_comps if len(comp) > 1] - def bidirected_edges(self): + def bidirected_edges(self) -> nx.reportviews.EdgeView: + """`EdgeView` of the bidirected edges.""" return self.get_graphs(self._bidirected_name).edges - def undirected_edges(self): + def undirected_edges(self) -> nx.reportviews.EdgeView: + """`EdgeView` of the undirected edges.""" return self.get_graphs(self._undirected_name).edges - def directed_edges(self): + def directed_edges(self) -> nx.reportviews.EdgeView: + """`EdgeView` of the directed edges.""" return self.get_graphs(self._directed_name).edges - def sub_directed_graph(self): + def sub_directed_graph(self) -> nx.DiGraph: + """Sub-graph of just the directed edges.""" return self._get_internal_graph(self._directed_name) - def sub_bidirected_graph(self): + def sub_bidirected_graph(self) -> nx.Graph: + """Sub-graph of just the bidirected edges.""" return self._get_internal_graph(self._bidirected_name) - def sub_undirected_graph(self): + def sub_undirected_graph(self) -> nx.Graph: + """Sub-graph of just the undirected edges.""" return self._get_internal_graph(self._undirected_name) diff --git a/pywhy_graphs/base.py b/pywhy_graphs/base.py index 135f148fa..6d374d436 100644 --- a/pywhy_graphs/base.py +++ b/pywhy_graphs/base.py @@ -1,16 +1,18 @@ -from typing import Set, Iterator +from typing import Iterator, Set import networkx as nx class AncestralMixin: + """Mixin for graphs with ancestral functions.""" + def ancestors(self, source) -> Set: """Ancestors of 'source' node with directed path.""" - return nx.ancestors(self.sub_directed_graph, source) + return nx.ancestors(self.sub_directed_graph(), source) # type: ignore def descendants(self, source) -> Set: """Descendants of 'source' node with directed path.""" - return nx.descendants(self.sub_directed_graph, source) + return nx.descendants(self.sub_directed_graph(), source) # type: ignore def children(self, n) -> Iterator: """Return an iterator over children of node n. @@ -31,7 +33,7 @@ def children(self, n) -> Iterator: children : Iterator An iterator of the children of node 'n'. """ - return self.sub_directed_graph.successors(n) + return self.sub_directed_graph().successors(n) # type: ignore def parents(self, n) -> Iterator: """Return an iterator over parents of node n. @@ -52,4 +54,4 @@ def parents(self, n) -> Iterator: parents : Iterator An iterator of the parents of node 'n'. """ - return self.sub_directed_graph.predecessors(n) + return self.sub_directed_graph().predecessors(n) # type: ignore diff --git a/pywhy_graphs/cpdag.py b/pywhy_graphs/cpdag.py index eac7fddc2..541756959 100644 --- a/pywhy_graphs/cpdag.py +++ b/pywhy_graphs/cpdag.py @@ -1,8 +1,8 @@ -from typing import FrozenSet, Dict, Iterator +from typing import Dict, Iterator -from collections import defaultdict import networkx as nx from graphs import MixedEdgeGraph + from .base import AncestralMixin @@ -13,8 +13,6 @@ class CPDAG(MixedEdgeGraph, AncestralMixin): Undirected edges imply uncertainty in the orientation of the causal relationship. For example, ``A - B``, can be ``A -> B`` or ``A <- B``, allowing for a Markov equivalence class of DAGs for each CPDAG. - This means that the number of DAGs represented by a CPDAG is $2^n$, where - ``n`` is the number of undirected edges present in the CPDAG. Parameters ---------- @@ -48,32 +46,42 @@ class CPDAG(MixedEdgeGraph, AncestralMixin): One should not use CPDAGs if they suspect their data has unobserved latent confounders. """ - def __init__(self, + def __init__( + self, incoming_directed_edges=None, incoming_undirected_edges=None, - directed_edge_name='directed', - undirected_edge_name='undirected', - **attr): + directed_edge_name="directed", + undirected_edge_name="undirected", + **attr, + ): super().__init__(**attr) self.add_edge_type(nx.DiGraph(incoming_directed_edges), directed_edge_name) self.add_edge_type(nx.Graph(incoming_undirected_edges), undirected_edge_name) self._directed_name = directed_edge_name self._undirected_name = undirected_edge_name - + if not nx.is_directed_acyclic_graph(self.sub_directed_graph()): raise RuntimeError(f"{self} is not a DAG, which it should be.") - def undirected_edges(self): + # extended patterns store unfaithful triples + # these can be used for conservative structure learning algorithm + self._unfaithful_triples = dict() + + def undirected_edges(self) -> nx.reportviews.EdgeView: + """`EdgeView` of the undirected edges.""" return self.get_graphs(self._undirected_name).edges - def directed_edges(self): + def directed_edges(self) -> nx.reportviews.EdgeView: + """`EdgeView` of the directed edges.""" return self.get_graphs(self._directed_name).edges - def sub_directed_graph(self): + def sub_directed_graph(self) -> nx.DiGraph: + """Sub-graph of just the directed edges.""" return self._get_internal_graph(self._directed_name) - def sub_undirected_graph(self): + def sub_undirected_graph(self) -> nx.Graph: + """Sub-graph of just the undirected edges.""" return self._get_internal_graph(self._undirected_name) def orient_undirected_edge(self, u, v): @@ -115,7 +123,7 @@ def possible_children(self, n) -> Iterator: children : Iterator An iterator of the children of node 'n'. """ - return self.sub_undirected_graph.neighbors(n) + return self.sub_undirected_graph().neighbors(n) def possible_parents(self, n) -> Iterator: """Return an iterator over parents of node n. @@ -136,22 +144,25 @@ def possible_parents(self, n) -> Iterator: parents : Iterator An iterator of the parents of node 'n'. """ - return self.sub_undirected_graph.neighbors(n) - - + return self.sub_undirected_graph().neighbors(n) -class ExtendedPattern(CPDAG): - def __init__(self, incoming_directed_edges=None, incoming_undirected_edges=None, directed_edge_name='directed', undirected_edge_name='undirected', **attr): - super().__init__(incoming_directed_edges, incoming_undirected_edges, directed_edge_name, undirected_edge_name, **attr) + def mark_unfaithful_triple(self, v_i, u, v_j) -> None: + """Mark an unfaithful triple. - # extended patterns store unfaithful triples - self._unfaithful_triples = dict() - - def mark_unfaithful_triple(self, v_i, u, v_j): + Parameters + ---------- + v_i : node + The first node in a triple. + u : node + The second node in a triple. + v_j : node + The third node in a triple. + """ if any(node not in self.nodes for node in [v_i, u, v_j]): raise RuntimeError(f"The triple {v_i}, {u}, {v_j} is not in the graph.") - self._unfaithful_triples[frozenset(v_i, u, v_j)] = None + self._unfaithful_triples[frozenset(v_i, u, v_j)] = None # type: ignore def unfaithful_triples(self) -> Dict: + """Unfaithful triples.""" return self._unfaithful_triples diff --git a/pywhy_graphs/function.py b/pywhy_graphs/function.py new file mode 100644 index 000000000..4326fe8ee --- /dev/null +++ b/pywhy_graphs/function.py @@ -0,0 +1,13 @@ +def orient_undirected_edge(G, u, v): + """Orient undirected edge into a directed edge. + + Parameters + ---------- + G : _type_ + _description_ + u : _type_ + _description_ + v : _type_ + _description_ + """ + pass diff --git a/pywhy_graphs/tests/test_admg.py b/pywhy_graphs/tests/test_admg.py index ff012730e..8f3d197f8 100644 --- a/pywhy_graphs/tests/test_admg.py +++ b/pywhy_graphs/tests/test_admg.py @@ -1,108 +1,9 @@ -from pywhy_graphs import ADMG +import pytest +from pywhy_graphs import ADMG, CPDAG -class TestADMG(TestDAG, TestExportGraph): - """Test relevant causal graph properties.""" - def setup_method(self): - # start every graph with the confounded graph - # 0 -> 1, 0 -> 2 with 1 <--> 0 - self.Graph = ADMG - incoming_latent_data = [(0, 1)] - - # build dict-of-dict-of-dict K3 - ed1, ed2 = ({}, {}) - incoming_graph_data = {0: {1: ed1, 2: ed2}} - self.G = self.Graph(incoming_graph_data, incoming_latent_data) - - def test_hash(self): - """Test hashing a causal graph.""" - G = self.G - current_hash = hash(G) - assert G._current_hash is None - - G.add_bidirected_edge("1", "2") - new_hash = hash(G) - assert current_hash != new_hash - - G.remove_bidirected_edge("1", "2") - assert current_hash == hash(G) - - def test_full_graph(self): - """Test computing a full graph from causal graph.""" - G = self.G - # the current hash should match after computing full graphs - current_hash = hash(G) - G.compute_full_graph() - assert current_hash == G._current_hash - G.compute_full_graph() - assert current_hash == G._current_hash - - # after adding a new edge, the hash should change and - # be different - G.add_bidirected_edge("1", "2") - new_hash = hash(G) - assert new_hash != G._current_hash - - # once the hash is computed, it should be the same again - G.compute_full_graph() - assert new_hash == G._current_hash - - # removing the bidirected edge should result in the same - # hash again - G.remove_bidirected_edge("1", "2") - assert current_hash != G._current_hash - G.compute_full_graph() - assert current_hash == G._current_hash - - # different orders of edges shouldn't matter - G_copy = G.copy() - G.add_bidirected_edge("1", "2") - G.add_bidirected_edge("2", "3") - G_hash = hash(G) - G_copy.add_bidirected_edge("2", "3") - G_copy.add_bidirected_edge("1", "2") - copy_hash = hash(G_copy) - assert G_hash == copy_hash - - def test_bidirected_edge(self): - """Test bidirected edge functions.""" - # add bidirected edge to an isolated node - G = self.G - G.add_bidirected_edge(1, 5) - assert G.has_bidirected_edge(1, 5) - assert G.has_bidirected_edge(5, 1) - G.remove_bidirected_edge(1, 5, remove_isolate=False) - assert 5 in G - assert nx.is_isolate(G, 5) - assert not G.has_bidirected_edge(1, 5) - assert not G.has_bidirected_edge(5, 1) - - G.add_bidirected_edge(1, 5) - G.remove_bidirected_edge(1, 5) - print(G.nodes) - assert 5 not in G - - def test_m_separation(self): - G = self.G.copy() - # add collider on 0 - G.add_edge(3, 0) - - # normal d-separation statements should hold - assert not d_separated(G, 1, 2, set()) - assert not d_separated(G, 1, 2) - assert d_separated(G, 1, 2, 0) - - # when we add an edge from 0 -> 1 - # there is no d-separation statement - assert not d_separated(G, 3, 1, set()) - assert not d_separated(G, 3, 1, 0) - - # test collider works on bidirected edge - # 1 <-> 0 - G.remove_edge(0, 1) - assert d_separated(G, 3, 1, set()) - assert not d_separated(G, 3, 1, 0) +class BaseGraph: def test_children_and_parents(self): """Test working with children and parents.""" # 0 -> 1, 0 -> 2 with 1 <--> 0 @@ -115,7 +16,7 @@ def test_children_and_parents(self): assert [0] == list(G.parents(1)) # a lone bidirected edge is not a child or a parent - G.add_bidirected_edge(2, 3) + G.add_edge(2, 3, "undirected") assert [] == list(G.parents(3)) assert [] == list(G.children(3)) @@ -123,10 +24,133 @@ def test_size(self): G = self.G # size stores all edges - assert G.size() == 3 - assert G.number_of_edges() == 2 - assert G.number_of_bidirected_edges() == 1 + assert G.number_of_edges() == 3 + assert G.number_of_edges(edge_type="directed") == 2 + # TODO: size() does not work yet due to degree + # assert G.size() == 3 + + +class TestCPDAG(BaseGraph): + def setup_method(self): + # start every graph with the confounded graph + # 0 -> 1, 0 -> 2 with 1 <--> 0 + self.Graph = CPDAG + incoming_uncertain_data = [(0, 1)] + + # build dict-of-dict-of-dict K3 + ed1, ed2 = ({}, {}) + incoming_graph_data = {0: {1: ed1, 2: ed2}} + self.G = self.Graph(incoming_graph_data, incoming_uncertain_data) + + +class TestADMG(BaseGraph): + """Test relevant causal graph properties.""" + + def setup_method(self): + # start every graph with the confounded graph + # 0 -> 1, 0 -> 2 with 1 <--> 0 + self.Graph = ADMG + incoming_latent_data = [(0, 1)] + + # build dict-of-dict-of-dict K3 + ed1, ed2 = ({}, {}) + incoming_graph_data = {0: {1: ed1, 2: ed2}} + self.G = self.Graph(incoming_graph_data, incoming_latent_data) + + def test_bidirected_edge(self): + """Test bidirected edge functions.""" + # add bidirected edge to an isolated node + G = self.G + + # error if edge types are not specified correctly + # in adherence with networkx API + with pytest.raises(ValueError, match="Edge type bi-directed not"): + G.add_edge(1, 5, edge_type="bi-directed") + + # 'bidirected' is a default edge type name in ADMG + G.add_edge(1, 5, "bidirected") + assert G.has_edge(1, 5, "bidirected") + assert G.has_edge(5, 1, "bidirected") + G.remove_edge(1, 5, "bidirected") + assert 5 in G + assert not G.has_edge(1, 5, "bidirected") + assert not G.has_edge(5, 1, "bidirected") + # TODO: make work once degree works as expected + # assert nx.is_isolate(G, 5) def test_c_components(self): """Test working with c-components in causal graph.""" - pass \ No newline at end of file + G = self.G + + assert list(G.c_components()) == [{0, 1}, {2}] + + # def test_hash(self): + # """Test hashing a causal graph.""" + # G = self.G + # current_hash = hash(G) + # assert G._current_hash is None + + # G.add_bidirected_edge("1", "2") + # new_hash = hash(G) + # assert current_hash != new_hash + + # G.remove_bidirected_edge("1", "2") + # assert current_hash == hash(G) + + # def test_full_graph(self): + # """Test computing a full graph from causal graph.""" + # G = self.G + # # the current hash should match after computing full graphs + # current_hash = hash(G) + # G.compute_full_graph() + # assert current_hash == G._current_hash + # G.compute_full_graph() + # assert current_hash == G._current_hash + + # # after adding a new edge, the hash should change and + # # be different + # G.add_bidirected_edge("1", "2") + # new_hash = hash(G) + # assert new_hash != G._current_hash + + # # once the hash is computed, it should be the same again + # G.compute_full_graph() + # assert new_hash == G._current_hash + + # # removing the bidirected edge should result in the same + # # hash again + # G.remove_bidirected_edge("1", "2") + # assert current_hash != G._current_hash + # G.compute_full_graph() + # assert current_hash == G._current_hash + + # # different orders of edges shouldn't matter + # G_copy = G.copy() + # G.add_bidirected_edge("1", "2") + # G.add_bidirected_edge("2", "3") + # G_hash = hash(G) + # G_copy.add_bidirected_edge("2", "3") + # G_copy.add_bidirected_edge("1", "2") + # copy_hash = hash(G_copy) + # assert G_hash == copy_hash + + # def test_m_separation(self): + # G = self.G.copy() + # # add collider on 0 + # G.add_edge(3, 0) + + # # normal d-separation statements should hold + # assert not d_separated(G, 1, 2, set()) + # assert not d_separated(G, 1, 2) + # assert d_separated(G, 1, 2, 0) + + # # when we add an edge from 0 -> 1 + # # there is no d-separation statement + # assert not d_separated(G, 3, 1, set()) + # assert not d_separated(G, 3, 1, 0) + + # # test collider works on bidirected edge + # # 1 <-> 0 + # G.remove_edge(0, 1) + # assert d_separated(G, 3, 1, set()) + # assert not d_separated(G, 3, 1, 0) From 1ecc2d8c54c07e1683f88f12cfddf00753374fa6 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Tue, 9 Aug 2022 12:22:56 -0400 Subject: [PATCH 03/23] Remove --- .github/workflows/main.yml | 1 + docs/tutorials/cgm.ipynb | 254 ------------------------------------- docs/whats_new/v0.1.rst | 14 +- 3 files changed, 2 insertions(+), 267 deletions(-) delete mode 100644 docs/tutorials/cgm.ipynb diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 740e77ae3..07fba3135 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -75,6 +75,7 @@ jobs: architecture: 'x64' - name: Install dependencies run: | + python -m pip install --progress-bar off git+https://github.com/py-why/graphs python -m pip install --progress-bar off --upgrade pip setuptools wheel python -m pip install --progress-bar off .[build] - name: Test package install diff --git a/docs/tutorials/cgm.ipynb b/docs/tutorials/cgm.ipynb deleted file mode 100644 index 2ca6d0097..000000000 --- a/docs/tutorials/cgm.ipynb +++ /dev/null @@ -1,254 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Causal Graphical Models\n", - "\n", - "In this section, we explore what are known as causal graphical models (CGM), which are essentially Bayesian networks where edges imply causal influence rather then just probabilistic dependence.\n", - "\n", - "CGMs are assumed to be acyclic, meaning they do not have cycles among their variables." - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "import networkx as nx\n", - "from pywhy_graphs import ADMG\n", - "\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Causally Sufficient Models\n", - "\n", - "Here, we don't have any latent variables. We demonstrate how a CGM works in code and what we can do with it.\n", - "\n", - "We also demonstrate Clustered DAGs (CDAGs), which form from a cluster of variables, which is represented underneath the hood with two graphs. One consisting of all the variables denoting the cluster ID in the metadata, and another consisting of the graph between clusters. The first graph may be incompletely specified, since we do not require the edges within a cluster be fully specified.\n", - "\n", - "Based on knowledge of CDAGs, we know that d-separation is complete." - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [], - "source": [ - "dag = nx.MultiDiGraph()" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'direct'" - ] - }, - "execution_count": 63, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dag.add_edge('A', 'B', key='direct')\n", - "dag.add_edge('A', 'B', key='bidirected')\n", - "dag.add_edge('B', 'A', key='bidirected')\n", - "dag.add_edge('C', 'B', key='direct')" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[('A', 'B', 'direct'), ('A', 'B', 'bidirected'), ('B', 'A', 'bidirected'), ('C', 'B', 'direct')]\n" - ] - } - ], - "source": [ - "print(dag.edges)" - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "MultiDiGraph with 3 nodes and 4 edges\n", - "[]\n" - ] - }, - { - "ename": "NetworkXError", - "evalue": "graph should be directed acyclic", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNetworkXError\u001b[0m Traceback (most recent call last)", - "Input \u001b[0;32mIn [68]\u001b[0m, in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 52\u001b[0m \u001b[38;5;28mprint\u001b[39m(edges)\n\u001b[1;32m 53\u001b[0m \u001b[38;5;66;03m# set alpha value for each edge\u001b[39;00m\n\u001b[1;32m 54\u001b[0m \u001b[38;5;66;03m# for i in range(M):\u001b[39;00m\n\u001b[1;32m 55\u001b[0m \u001b[38;5;66;03m# edges[i].set_alpha(edge_alphas[i])\u001b[39;00m\n\u001b[0;32m---> 57\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mnx\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43md_separated\u001b[49m\u001b[43m(\u001b[49m\u001b[43mG\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mC\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mA\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[43m}\u001b[49m\u001b[43m)\u001b[49m)\n", - "File \u001b[0;32m compilation 8:4\u001b[0m, in \u001b[0;36margmap_d_separated_5\u001b[0;34m(G, x, y, z)\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mos\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mpath\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m splitext\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mcontextlib\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m contextmanager\n\u001b[0;32m----> 4\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mpathlib\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Path\n\u001b[1;32m 6\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mnetworkx\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mnx\u001b[39;00m\n\u001b[1;32m 7\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mnetworkx\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mutils\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m create_random_state, create_py_random_state\n", - "File \u001b[0;32m~/miniforge3/envs/causal3.8m1/lib/python3.8/site-packages/networkx/algorithms/d_separation.py:106\u001b[0m, in \u001b[0;36md_separated\u001b[0;34m(G, x, y, z)\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 71\u001b[0m \u001b[38;5;124;03mReturn whether node sets ``x`` and ``y`` are d-separated by ``z``.\u001b[39;00m\n\u001b[1;32m 72\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 102\u001b[0m \n\u001b[1;32m 103\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 105\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m nx\u001b[38;5;241m.\u001b[39mis_directed_acyclic_graph(G):\n\u001b[0;32m--> 106\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m nx\u001b[38;5;241m.\u001b[39mNetworkXError(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mgraph should be directed acyclic\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 108\u001b[0m union_xyz \u001b[38;5;241m=\u001b[39m x\u001b[38;5;241m.\u001b[39munion(y)\u001b[38;5;241m.\u001b[39munion(z)\n\u001b[1;32m 110\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28many\u001b[39m(n \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m G\u001b[38;5;241m.\u001b[39mnodes \u001b[38;5;28;01mfor\u001b[39;00m n \u001b[38;5;129;01min\u001b[39;00m union_xyz):\n", - "\u001b[0;31mNetworkXError\u001b[0m: graph should be directed acyclic" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAV0AAADnCAYAAAC9roUQAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAd6klEQVR4nO3deVxU9f4G8GdgANkUcDc1N1xLUUnJq8aSN80XKYsKEpq4XDXcuvLCzEzNyuW6ZFlZmt40RBDGa6ZdF5QQM1myFDVvYqIpIhJbLA4z5/dHP+fKVVBw5nzPDM/7PzvDOY9pz+vbdz7nHJUkSSAiInlYiQ5ARNSQsHSJiGTE0iUikhFLl4hIRixdIiIZqWs72KxZM6lDhw4yRSEisgwZGRn5kiQ1f9CxWku3Q4cOSE9PN00qIiILpVKprtR0jNsLREQyYukSEcmIpUtEJCOWLhGRjFi6REQyYukSEcmIpUtEJCOWLhGRjFi6REQyYukSEcmIpUtEJCOWLhGRjFi6REQyYukSEcmIpUtEJCOWLhGZtcrKSkiS9MBjpYUVKCuplDlR7Vi6RGS29uzZg0aNGsHKygohISG4evUqdDod0tLSsHjuSoS1WI2JT6xHXk6R6KgGtb45gohIya5c+e8LGnbt2oXr16+juLgYP/74I55AbzyNUVBZWSH30u9o0b6JwKT/xdIlIrP1r3/9q9qvU1JSAAAtWrTA9byzcERTzJs9G097Pyki3gNxe4GIzMKRI0cwaNAg2Nvbo1evXgCAzMzM+z43ZswYlJSUQIIekRsCMH3VaKhUKrnj1ogrXSJSpBs3bmDr1q0YPHgwhg4diuHDh6OqqgoAkJeXBwDIzs7G1atXcezYMaSlpcHLywvr1q1DeXk5wsPDERkZKfK38EAsXSJSFEmS4OHhgZ9++gkA0LhxYxQWFmLMmDG4cOECxo4dayhTNzc3uLm5oU+fPtDr9fD390d2djY8PDywadMmRa1w72LpEpFQ165dwxtvvIH9+/fjxRdfxCeffIIzZ84AABwcHDBv3jyoVCrExMTUep5ly5Zh//79cHNzg0ajgb29vRzx64ylS0TCVFVVoXPnzrhz5w4A4Ntvv4W9vT0uXLiAO3fu4Kmnnnqk83z11VdYunQprKysEBsbiw4dOpgw9ePhF2lEJJvTp0/Dz88PdnZ2ePbZZ6HX6+Hs7AwnJyeEh4fj+++/BwB07dr1kQv34sWLePnllwEA77zzDoYNG2ay/MbAlS4RmVRZWRnUajVsbGwwYMAAaLVaAMDt27dha2uL/Pz8ep+7tLQUAQEBKC4uRlBQEKKjo40V22S40iUikzh58iT69esHJycnuLu7AwB69eqFdu3a4a233sLp06cf6/ySJGHSpEk4d+4cevToga1btyryi7P/xZUuEZmEr68vysvLAQBOTk5QqVT44YcfjHb+f/zjH9i9ezcaN24MjUYDZ2dno53blLjSJaLHVlVVhXXr1qFFixZ44oknoNfr8dxzz6FLly747LPPDONfxnL48GEsWLAAAPDFF1+gW7duRj2/KXGlS0SPbcSIETh8+DAAQK1WQ5IkHDhwwCTXunLlCkJCQqDX67Fo0SKMGjXKJNcxFa50iajOioqK8Oqrr8LPzw+FhYXQ6/UAAC8vL2RkZMDa2tok1y0vL0dgYCBu376NESNGYMmSJSa5jilxpUtEdbJv3z6MHj0aOp0OAHDixAn8+9//RmVlJRwdHU12XUmSMGPGDGRmZqJTp0748ssvTVbupsSVLhE9lE6nw/fffw+tVovY2FjodDqo1WpMnjwZI0aMgFqtNmnhAsDHH3+Mf/7zn7C3t4dGo4Grq6tJr2cqXOkSUa0OHTqEl19+GXl5eQgPD8emTZvg7++PkSNHwsnJSZYMqampmDNnDgBgy5Yt6N27tyzXNQWWLhHVKC8vDy+88ILhdTgeHh5wdHTEuHHjZMtw48YNBAcHo6qqCvPmzUNoaKhs1zYFli4RVVNeXo7FixfD1dUVkZGRcHFxQePGjbFt2zZ4e3vLmuXOnTsIDg5Gbm4uvL29sWrVKlmvbwosXSIy+OqrrxASEoKysjJYW1tj4cKFKCgoEJZn3rx5OHHiBNq2bYtdu3ZBrTb/yuIXaURkMHv2bJSVlUGlUiEqKkpolm3btuGjjz6Cra0tEhIS0KJFC6F5jIWlS9SASZKENWvWoHPnzjh69CjWr1+P0NBQXLlyBe+9956wXBkZGZg+fToAYOPGjRgwYICwLMZm/mt1IqoXSZLw3HPPGV7muHv3bmzcuFH4HV75+fkIDAxEZWUlpk2bhilTpgjNY2xc6RI1UNeuXTMUbv/+/bFy5UrBif58hkNISAhycnIwcOBAbNiwQXQko+NKl6gBqaysxNSpU/Hrr7/i0KFDiI6Ohru7OyIiIhTxWMQ33ngDR44cQYsWLbB7927Y2dmJjmR0LF2iBiInJwd9+/Y1TCPcvn0bK1asEJzqv+Lj47Fq1SpYW1sjPj4ebdu2FR3JJFi6RA3E4sWLUVBQYJhMaNOmjehIBmfPnsWkSZMAAGvWrMHQoUMFJzIdli6RBdNqtYiKikL37t3x1ltvobKyEvPnz0f//v1FRzMoLCxEYGAg/vjjD4SFhWH27NmiI5mU6u7tfQ/i6ekppaenyxiHiIylqKgI/fr1Q3Z2NhwdHVFaWio60n30ej1GjRqFffv2oU+fPjhx4gQcHBxEx3psKpUqQ5Ikzwcd4/QCkYUKDQ1FdnY2gD/v7FKi5cuXY9++fXB1dUViYqJFFO7DsHSJLExhYSHKysrg4+MDV1dXbNmyBW+//bboWPf5+uuvsWTJEqhUKsTExKBTp06iI8mCpUtkQdasWYOmTZuiZ8+eiIqKQkFBASIiIkTHus8vv/yCsLAwSJKE5cuXY/jw4aIjyYalS2Qh3n77bcyfPx96vR4uLi6i49SotLQUAQEBKCoqQkBAAF5//XXRkWTF0iWyEPv37wcA9OvXDydPnhSc5sEkScLkyZNx9uxZdO/eHdu2bVPETRly4sgYkRnT6/WIjIxEx44dceDAAWRmZsLHx0exRbZ27VrExcXB2dkZGo0GjRs3Fh1JdhwZIzJTkiRhyJAhSE1Nhb29PcrKykRHqlVSUhKGDRsGvV6PxMREBAQEiI5kMhwZI7JAS5cuRWpqKgAgMjJScJra5eTkYNy4cdDr9Vi4cKFFF+7DcHuByEy1a9cONjY2mDFjhqJfY1NRUYGgoCDk5+fjhRdewLJly0RHEoqlS2RmZsyYgaSkJJw8eVIxTweriSRJmDlzJtLT09GxY0fExMTA2tpadCyhWLpEZiQsLAwxMTEAgMuXL6Nfv36CE9Vu06ZN2Lp1K+zt7aHRaODm5iY6knDc0yUyExcvXjQUbnBwsOIL97vvvjM8vOazzz5Dnz59BCdSBq50iczEE088gb59++KZZ57Bpk2bRMepVW5uLoKCgqDVajFnzhyEhYWJjqQYLF0ihdu/fz/CwsIwa9YsZGZmio7zUHfu3MGYMWNw48YNDB06FKtXrxYdSVFYukQKlpOTg9GjR0Or1RrGw5Ru/vz5OH78ONq0aYO4uDjY2NiIjqQo3NMlUrCIiAhotVo0atQIO3fuFB3nobZv344PPvgANjY2SEhIQMuWLUVHUhyWLpGCjRs3Dh07dsShQ4fQokUL0XFqlZmZiWnTpgEAPvzwQ3h5eQlOpEwsXSIF+vjjj/HUU0/h+eefR3Z2NgYPHiw6Uq1u376NwMBAVFRUYMqUKYbypfuxdIkU5sCBA5g5cyaysrJw8OBB0XEeSqfTITQ0FFeuXMEzzzyDDz74QHQkRWPpEilMaGgogD9HxKZMmSI4zcMtWrQIhw4dQvPmzZGQkIBGjRqJjqRonF4gUhBJktCpUyfk5uYiLS1N8bfMJiQkYMWKFbC2tkZcXBzatWsnOpLisXSJFOLAgQNITU1FRkaGop+ncNe5c+fwyiuvAABWr14Nb29voXnMBUuXSAHOnz+PkSNHQpIkhIWFoUePHqIj1eruq3ZKS0sREhKCuXPnio5kNrinS6QA/v7+kCQJbm5u6N69u+g4tdLr9ZgwYQIuXryI3r17Y/PmzWaxMlcKli6RYJIk4bfffoNKpcLu3bsVX2Dvvvsu9u7dCxcXFyQmJsLR0VF0JLPC7QUiwXQ6Hc6cOYOqqirFr3IPHDiAxYsXQ6VSISYmBp07dxYdyexwpUsk0NChQ2Fra4vc3FzFF+6lS5cwfvx4SJKEZcuWYcSIEaIjmSWudIkEWbduHVJSUgAAtra2gtPU7o8//kBAQAAKCwvx0ksvYeHChaIjmS2udIkEWb58OQBgyJAhGDBggOA0NZMkCVOmTMGZM2fQtWtXfPHFF7CyYnXUF//NEQkybdo0DB48GF9//bXoKLVav349YmNj4eTkBI1GgyZNmoiOZNZYukQyKygowOTJkxEREYGUlBQ4OzuLjlSjo0ePIioqCgCwbds29OzZU3Ai88c9XSKZDR06FFlZWbh16xb27t0rOk6Nrl69inHjxkGn02HBggUICgoSHckicKVLJKPjx48jKysLADBp0iTBaWpWUVGBoKAg3Lp1C8OGDTPsP9PjY+kSySg5ORkA0KVLFwQEBAhOU7NZs2YhLS0NTz75JHbu3Kn4B++YE24vEMkoKioKbdu2RXBwsOgoNfr000+xefNmNGrUCBqNBk2bNhUdyaKwdIlkIEkSgoKCcOnSJRw/flyxt86ePHkSkZGRAP4s3759+wpOZHlYukQyiImJgUajAfDnE7qUOLFw8+ZNBAUFQavVIjIyEuHh4aIjWSTu6RLJIDo6GgDw9NNPo23btoLT3E+r1WLMmDG4fv06Bg8ejLVr14qOZLFYukQycHR0hJ2dHXbs2CE6ygNFRUUhJSUFrVu3Rnx8PGxsbERHsljcXiAyMUmScOHCBUiSpMjbZ3fs2IH3338fNjY2SEhIQKtWrURHsmjK+xtAZEFOnz4NOzs7DBgwQJGFe/r0acPr0jds2IBnn31WcCLLp7y/BUQWJDIyElqtFvn5+aKj3KegoACBgYEoLy/HpEmT8Le//U10pAaBpUtkIlVVVfjuu+8AwDCGpRQ6nQ6hoaG4fPkyPD098dFHHyn+jRWWgnu6RCaiUqkMD4iZNWuW4DTVLV68GAcPHkSzZs2QkJCARo0aiY7UYLB0iUykoqICp06dgr29vego1Wg0Grz77ruwsrLCrl270L59e9GRGhRuLxCZwPHjx9G4cWP07t1bdJRqLly4gAkTJgAAVq1aBV9fX8GJGh6WLpEJzJ07F3q9HjqdTnQUg+LiYowePRqlpaUYN24cXnvtNdGRGiSWLpGRVVRUIDMzEwAwb948wWn+pNfrMXHiRPz888946qmnsGXLFn5xJgj3dImMzMbGBt7e3tDr9Zg+fbroOACAFStWYM+ePWjSpAk0Go1iH7jTELB0iYysqKgIcXFxaNasmegoAIBvvvkGixYtAgB8+eWX6NKli+BEDRu3F4iM6NKlS2jevDnc3d1FRwEAZGdnY/z48ZAkCUuWLMHIkSNFR2rwWLpERrRy5Uro9XpIkiQ6CsrKyhAYGIjff/8d/v7+ePPNN0VHIrB0iYzqyJEjAABvb2+hOSRJwtSpU/Hjjz/C3d0d27dvV+SzHxoi/ikQGVFoaCg6duyI999/X2iODRs2ICYmBo6OjtBoNGjSpInQPPRfqtr+N8jT01NKT0+XMQ6R+ZIkCcXFxcILLjk5GX5+ftDpdIiLi8OYMWOE5mmIVCpVhiRJng86xpUukZEMHz4cLi4uiI2NFZbh2rVrGDt2LHQ6HaKioli4CsTSJTKCkpISHDp0CABQWloqJENlZSWCg4ORl5cHPz8/vPvuu0JyUO1YukRGcOTIEUiSBJVKJez16rNnz8b333+P9u3bIzY2Fmo1x/CViH8qREbQs2dPtGzZEi+99BJcXFxkv/7mzZvx6aefws7ODomJiYq5MYPux9IlMgJ3d3dcv35dyFjWqVOn8OqrrwIANm3ahP79+8uegR4dtxeIHtPVq1fh4OCAXr16yX7tvLw8BAUF4c6dO5g5cyYmTpwoewaqG5Yu0WPasGEDKioqcOPGDVmvq9VqMXbsWFy7dg2DBg3CunXrZL0+1Q9Ll+gxpaSkAIDh1TxyiY6ORnJyMlq1aoX4+HjY2trKen2qH5Yu0WMaMGAAbGxsEB0dLds1Y2JisG7dOqjVauzevRtt2rSR7dr0eHhHGpGZ+emnn+Dl5YXy8nJ8+OGHhi/RSDl4RxqRifznP/9Bq1atMGfOHFmuV1BQgICAAJSXl2PixImYOXOmLNcl42HpEj2GN998Ezdv3sTevXtNfi2dToewsDBkZ2ejX79++Pjjj/nKHTPE0iV6DKdOnQIAWd76u2TJEnzzzTdo2rQpEhMTFfdqd3o0LF2ix+Ds7AwAmDFjhkmvs2fPHixfvhxWVlaIjY3Fk08+adLrkenwjjSix/Ddd9+hrKzMpLfd/vzzz5gwYQIA4L333sPzzz9vsmuR6XGlS1RPFy9ehI+PD1JTU012jZKSEgQEBKCkpATBwcGIiooy2bVIHixdonqaOXMmTp06hRUrVpjk/JIk4ZVXXsH58+fRs2dPfP755/zizAKwdInq6eeffwYAk735d+XKlUhMTETjxo2h0WgM+8dk3li6RPWk0+kAwCTPzz148CDeeOMNAMCOHTvQtWtXo1+DxOAXaUT1dOzYMWRmZuKll14y6nkvX76M0NBQ6PV6LF68GP7+/kY9P4nFlS5RPe3duxft2rUz6jnLysoQGBiIgoICvPjii3jrrbeMen4SjytdonpISEhAVFQUmjZtivz8fKOcU5IkTJ8+HadPn0bnzp2xY8cOIQ9FJ9PinyhRPdx9CaUxH6f44YcfYvv27XBwcIBGo4Grq6vRzk3KwdIlqofc3FwAQKdOnYxyvpSUFLz22msAgC1btuDpp582ynlJebi9QFQPS5cuRVlZGTZs2PDY5/rtt98wZswYVFVV4e9//ztCQkKMkJCUiqVLVA+dO3fGli1bHvuLtMrKSgQHB+PmzZvw8fEx2Y0WpBwsXaI6qqqqQqtWrVBWVob8/Hy4ubnV+1xz587FyZMn0a5dO+zatQtqNf+TtHT8Eyaqo0uXLuGPP/4A8GcB19fnn3+OTz75BHZ2dkhMTETz5s2NFZEUjF+kEdXR3dt/ra2t612UaWlphrc+fPTRR/D0fOCbXcgCcaVLVEcDBw5E69at8cILL9TrATR5eXkICgpCZWUlpk+fjoiICBOkJKVi6RLVUcuWLXH9+vV6/WxVVRVCQkJw9epVeHl5Yf369cYNR4rH7QWiOoqLi4ODgwM2btxY559dsGABjh49ipYtWyIhIQF2dnYmSEhKxtIlqqONGzeivLwccXFxdfq52NhYrFmzBmq1GvHx8WjTpo2JEpKSsXSJ6qiwsBAA4OLi8sg/c+bMGUyePBkAsHbtWgwZMsQEycgcsHSJ6qh79+4AgJEjRz7S53///XcEBASgrKwM4eHhiIyMNGU8UjiVJEk1HvT09JTS09NljEOkfJIkIS8vDy1btnzoZ/V6Pfz9/bF//354eHggNTUVDg4OMqQkkVQqVYYkSQ+cA+RKl6iONm7ciKlTp0Kr1T70s0uXLsX+/fvh5uaGxMREFi5xZIyorqKiolBRUYGUlBT4+vrW+Lm9e/di2bJlsLKyws6dO9GxY0cZU5JScaVLVEeVlZUAUOuLIi9evIjw8HAAwDvvvIO//vWvsmQj5WPpEtWBXq833IVW01uAS0pKEBAQgOLiYgQFBSE6OlrOiKRw3F4gqgMrKyvs2rULWq32gSNjkiQhIiIC586dQ48ePbB169Z63SpMloulS1RHDg4O6NChwwOPrV69Grt374azszM0Gk2tWxDUMHF7gagOsrKyMHLkSPTv3x/vv/8+bt++bTh2+PBhvP766wCA7du3o1u3bqJikoKxdIkeUXFxMWbMmAEAqKiowNy5c9G+fXuMHTsWv/zyC0JCQqDX67Fo0SKMGjVKcFpSKm4vED2i8+fP4/jx49X+mU6nQ3x8PM6fP4/bt29j+PDhWLJkiZiAZBa40iV6RFlZWbj3Dk43NzdUVlbC3t4eZ8+eRfv27TFnzhxYW1sLTElKx9IlekTjxo1Ds2bNAADBwcGGUbDy8nJYW1vj+vXrGDFiBH744QeRMUnhWLpEj8jR0RFvv/02rKys4ODggHufS6LT6aDX6xEeHo4ePXoITElKxz1dojro1asX9Ho9srOzkZ2dDeDPd6VNnToV8+fPR+fOnQUnJKVj6RLVwZXTBeiFkWh03Q1rVs9CgiYea9euRbt27URHIzPB0iW6h16vR05ODlq3bn3fq3QunLyGxOhz6ICBsLoKnPtCi/hv4gUlJXPF0iW6x9atWzFlyhTY2NjAw8MDnp6eaN26NSZMmIDUhIu4U14FANBrgR8OZqNKq4PahtMK9OhYukT36NOnD9zd3fHLL78gLS0NaWlpAIAPPvgAW5fsh6292lC8Tq72sFbzu2iqG5YuNXjZ2dk4cuQIjhw5gqSkJNy6deu+z/j7+2P4tH44k/wrTiRcgLObPRbtGcuH2VCdsXSpwcnNzUVSUpKhZH/99ddqx9u0aQO1Wo2cnBzY2Nhg27ZtGD9+PABgwa5gSJLEsqV6Y+mSxSsqKsKxY8cMRZuVlVXtuKurK3x8fODn5wc/Pz8cPnwYkZGRaNKkCfbs2QNvb+9qn2fh0uNg6ZLFKS8vx4kTJwxbBunp6dDr9YbjDg4OGDJkiKFk+/TpU+3WXbVajcjISMyYMQM9e/YU8VsgC8a3AZPZq6qqQnp6uqFkT5w4YXilDvBniXp5eRlKduDAgbC1tRWYmCxdbW8D5kqXzI4kSTh79qyhZJOTk1FSUmI4rlKp0LdvX0PJDh48GE5OTgITE/0XS5fMwsMmDLp27Qo/Pz/4+vrCx8cHTZs2FZSUqHYsXVKkuxMGd7/8etCEwd2VrK+vL2/DJbPB0iVFqOuEQdeuXTlFQGaJpUtC1GXCwNfXFx4eHnw4OFkEli7J4lEmDAYNGgRfX1/4+fnBy8uLEwZkkVi6ZBIPmzAAAA8PD8N2wZAhQzhhQA0CS5eM5u6Ewd0vwPLy8qodd3d3N5Sst7e34dU3RA0JS5fqjRMGRHXH0qVHVlRUhOTkZMOWQU0TBnf3Zbt168YJA6L/wdKlGj1swsDe3r7aMww4YUD0cCxdMniUCYNnn3222jMM/veVNkRUO5ZuA3bvhEFSUhKSk5NRXFxc7TP3ThgMHjwYzs7OgtISWQaWbgPzKBMGd/dkfXx8OGFAZGQsXQt38+ZNw3TBgyYMWrduXW3CoH379mKCEjUQLF0L87AJAxcXl2rPMOCEAZG8WLpmri4TBr6+vujbty8nDIgEYumamXsnDJKSkpCamlrjhIGvry+8vLw4YUCkICxdhZMkCVlZWdWeYfCgCYO7X34NGTKEEwZECsbSVaDLly9Xe0vC/04YdOnSxbAnywkDIvPC0lWAeycMkpKScPny5WrHOWFAZDlYugLcO2GQlJSEs2fPVjt+74SBr68vunfvzgkDIgvB0pVBRUUFUlNTDavZtLQ0ThgQNVAsXROoqqpCRkaGYV+2pgmDe9+SwAkDooaBpWsEjzJh0KdPn2pvSeCEAVHDxNKtJ04YEFF9sHQf0d0Jg7v7spwwIKL6YOnWoKioCN9++61hNcsJAyIyBpbu/6uoqLjvGQY6nc5wnBMGRGQMDbZ0H2XC4C9/+QsnDIjIqBpM6d47YZCUlIRjx45xwoCIZGfRpXv58uVqt9fevHmz2nFOGBCR3CyqdG/evImjR48atgw4YUBESmPWpVtcXFztLQmcMCAipTOr0r13wiApKQlpaWkPnDC4++UXJwyISGkUU7rHYs5g82uHUF5yBz0GtUXUzkA4utgiIyPDsC+bmpqKiooKw8+o1WoMGjTIsGXACQMiUjpFlO7pw9nYMGUf7pRXAQDOHLuCl92X41vdRhSXcMKAiCyHIko3afsZQ+ECgK5KD12hGpXQc8KAiCyKIkrXxu7+fVcbtS0y0zLQ06OrgERERKZhJToAAIyY3h92DjaGX9s2UqPfsE4sXCKyOIoo3S79WmPZv8ej28An0MbdDcMme2Bh4ljRsYiIjE4R2wsA0Gtwe6w5GSE6BhGRSSlipUtE1FCwdImIZMTSJSKSEUuXiEhGLF0iIhmxdImIZMTSJSKSEUuXiEhGLF0iIhmxdImIZMTSJSKSEUuXiEhGLF0iIhmxdImIZMTSJSKSkUqSpJoPqlS3AFyRLw4RkUV4UpKk5g86UGvpEhGRcXF7gYhIRixdIiIZsXSJiGTE0iUikhFLl4hIRv8H3gzY3/lb4lUAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "print(dag)\n", - "G = dag\n", - "pos = nx.random_layout(dag)\n", - "node_sizes = [3 + 10 * i for i in range(len(G))]\n", - "M = G.number_of_edges()\n", - "edge_colors = range(2, M + 2)\n", - "edge_alphas = [(5 + i) / (M + 4) for i in range(M)]\n", - "cmap = plt.cm.viridis\n", - "\n", - "# nx.draw_networkx(dag, pos=pos)\n", - "nodes = nx.draw_networkx_nodes(G, pos, node_size=node_sizes, node_color=\"indigo\")\n", - "directed_edges = nx.draw_networkx_edges(\n", - " G,\n", - " pos,\n", - " edgelist=[('A', 'B', 'direct'), ('C', 'B', 'direct')],\n", - " node_size=node_sizes,\n", - " arrowstyle=\"->\",\n", - " arrowsize=10,\n", - " # edge_color=edge_colors,\n", - " edge_cmap=cmap,\n", - " width=2,\n", - " # connectionstyle=\"arc3,rad=0.1\"\n", - ")\n", - "bd_edges = nx.draw_networkx_edges(\n", - " G,\n", - " pos,\n", - " edgelist=[('A', 'B', 'bidirected')],\n", - " node_size=node_sizes,\n", - " style='dotted',\n", - " # arrowstyle=\"->\",\n", - " arrowsize=10,\n", - " # edge_color=edge_colors,\n", - " edge_cmap=cmap,\n", - " width=2,\n", - " connectionstyle=\"arc3,rad=0.4\"\n", - ")\n", - "\n", - "bd_edges = nx.draw_networkx_edges(\n", - " G,\n", - " pos,\n", - " edgelist=[('B', 'A', 'bidirected')],\n", - " node_size=node_sizes,\n", - " style='dotted',\n", - " # arrowstyle=\"->\",\n", - " arrowsize=10,\n", - " # edge_color=edge_colors,\n", - " edge_cmap=cmap,\n", - " width=2,\n", - " connectionstyle=\"arc3,rad=-0.4\"\n", - ")\n", - "\n", - "# set alpha value for each edge\n", - "# for i in range(M):\n", - " # edges[i].set_alpha(edge_alphas[i])\n", - "\n", - "print(nx.d_separated(G, 'C', 'A', {}))" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'ADMGicalModel' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m/Users/pywhy/Documents/causalscm/examples/cgm.ipynb Cell 2'\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m nodes \u001b[39m=\u001b[39m [\n\u001b[1;32m 2\u001b[0m \u001b[39m'\u001b[39m\u001b[39ma\u001b[39m\u001b[39m'\u001b[39m, \u001b[39m'\u001b[39m\u001b[39mb\u001b[39m\u001b[39m'\u001b[39m, \u001b[39m'\u001b[39m\u001b[39mc\u001b[39m\u001b[39m'\u001b[39m, \u001b[39m'\u001b[39m\u001b[39md\u001b[39m\u001b[39m'\u001b[39m, \u001b[39m'\u001b[39m\u001b[39me\u001b[39m\u001b[39m'\u001b[39m\n\u001b[1;32m 3\u001b[0m ]\n\u001b[0;32m----> 4\u001b[0m cgm \u001b[39m=\u001b[39m ADMGicalModel(ebunch\u001b[39m=\u001b[39mnodes)\n", - "\u001b[0;31mNameError\u001b[0m: name 'ADMGicalModel' is not defined" - ] - } - ], - "source": [ - "nodes = [\n", - " 'a', 'b', 'c', 'd', 'e'\n", - "]\n", - "cgm = ADMG(ebunch=nodes)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "interpreter": { - "hash": "553a3a3baccf4e9d9e89b766458dc3beb76edeb53bd5cd6bfe933226e6c48e71" - }, - "kernelspec": { - "display_name": "causalm1", - "language": "python", - "name": "causalm1" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/docs/whats_new/v0.1.rst b/docs/whats_new/v0.1.rst index 726462f33..b0869d1a4 100644 --- a/docs/whats_new/v0.1.rst +++ b/docs/whats_new/v0.1.rst @@ -26,19 +26,7 @@ Version 0.1 Changelog --------- -- |Feature| Implement and test the :class:`pywhy_graphs.discovery.FCI` algorithm, by `Adam Li`_ (:gh:`1`) -- |Feature| Implement :class:`pywhy_graphs.ci.KernelCITest` for kernel-based conditional independence testing, by `Adam Li`_ (:gh:`14`) -- |Feature| Implement and test the :class:`pywhy_graphs.DAG` for fully observed causal DAGs, by `Adam Li`_ (:gh:`15`) -- |Feature| Implement and test the :class:`pywhy_graphs.CPDAG` for CPDAGs, by `Adam Li`_ (:gh:`16`) -- |Feature| Implement and test the ``pywhy_graphs.discovery.learn_skeleton_graph_with_order`` for learning skeleton graph and keeping track of dependencies, by `Adam Li`_ (:gh:`17`) -- |Feature| Implement and test the :class:`pywhy_graphs.discovery.RobustPC` for learning PC algorithm robustly with MCI condition, by `Adam Li`_ (:gh:`17`) -- |Feature| Implement and test the :class:`pywhy_graphs.ci.ParentChildOracle` for running CI-discovery algorithms with the known parents, by `Adam Li`_ (:gh:`17`) -- |Feature| Add ability to export/load causal graphs to networkx, by `Adam Li`_ (:gh:`17`) -- |Feature| Add ability to export/load causal graphs to numpy and pgmpy, by `Adam Li`_ (:gh:`26`) -- |Feature| Add ability to compare causal graphs, (i.e. CPDAGs and PAGs) for evaluation of structure learning, by `Adam Li`_ (:gh:`26`) -- |API| All CI tests now have an abstract class representation for the ``test`` function, by `Adam Li`_ (:gh:`26`) -- |API| Refactor the skeleton learning phase of the constraint-based causal discovery into a class of its own, by `Adam Li`_ (:gh:``) -- |Feature| Adding the conservative PC algorithm :class:`pywhy_graphs.discovery.ConservativePC` for applying conservative rules to the orientations, by `Adam Li`_ (:gh:`29`) +- |Feature| Implement and test the :class:`pywhy_graphs.CPDAG` for CPDAGs, by `Adam Li`_ (:gh:`6`) Code and Documentation Contributors ----------------------------------- From c4c7b65786ad732e32dbf16065f729e0cff59dbf Mon Sep 17 00:00:00 2001 From: Adam Li Date: Tue, 9 Aug 2022 12:27:36 -0400 Subject: [PATCH 04/23] Fix ci Signed-off-by: Adam Li --- .circleci/config.yml | 16 ++-------------- .github/workflows/main.yml | 1 - junit-results.xml | 2 +- pywhy_graphs/cpdag.py | 6 +++--- 4 files changed, 6 insertions(+), 19 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 65d8af854..326442b08 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -45,9 +45,6 @@ jobs: name: Set BASH_ENV command: | set -e - curl https://raw.githubusercontent.com/mne-tools/mne-python/main/tools/setup_xvfb.sh -o setup_xvfb.sh - chmod +x setup_xvfb.sh - ./setup_xvfb.sh sudo apt install -qq graphviz optipng python3.8-venv python3-venv libxft2 python3.8 -m venv ~/python_env echo "set -e" >> $BASH_ENV @@ -77,9 +74,7 @@ jobs: python -m pip install --progress-bar off --upgrade pip setuptools wheel python -m pip install --progress-bar off . python -m pip install --progress-bar off .[doc,gui] - python -m pip uninstall -yq mne mne-qt-browser - python -m pip install --progress-bar off git+https://github.com/py-why/mne-python - python -m pip install --progress-bar off git+https://github.com/py-why/mne-qt-browser + python -m pip install --progress-bar off git+https://github.com/py-why/pywhy-graphs - save_cache: name: Save pip cache key: pip-cache @@ -94,9 +89,6 @@ jobs: - run: name: Check pip package versions command: pip freeze - - run: - name: Display MNE infos - command: QT_DEBUG_PLUGINS=1 mne sys_info -pd - run: name: Check installation command: | @@ -166,10 +158,6 @@ jobs: command: | python -m pip install --progress-bar off --upgrade pip setuptools wheel python -m pip install --progress-bar off .[doc] - - run: - name: Check installation - command: | - mne sys_info -pd - run: name: make linkcheck command: | @@ -210,7 +198,7 @@ jobs: # see: https://github.com/tschaub/gh-pages/issues/354 command: | npm install gh-pages@3.0 - git config --global user.email "circle@mne.com" + git config --global user.email "circle@pywhy.com" git config --global user.name "Circle Ci" - add_ssh_keys: fingerprints: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 07fba3135..602c5c711 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -141,7 +141,6 @@ jobs: run: | python -m pip uninstall -yq networkx - name: Run pytest # headless via Xvfb on linux - uses: GabrielBB/xvfb-action@v1.6 with: run: pytest main/pywhy_graphs --cov=main/pywhy_graphs --cov-report=xml --cov-config=main/pyproject.toml - name: Upload coverage stats to codecov diff --git a/junit-results.xml b/junit-results.xml index a12af5745..519e0b389 100644 --- a/junit-results.xml +++ b/junit-results.xml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/pywhy_graphs/cpdag.py b/pywhy_graphs/cpdag.py index 541756959..5662c068e 100644 --- a/pywhy_graphs/cpdag.py +++ b/pywhy_graphs/cpdag.py @@ -98,11 +98,11 @@ def orient_undirected_edge(self, u, v): v : node The node that 'u' points to in the graph. """ - if not self.has_undirected_edge(u, v): + if not self.has_edge(u, v, self._undirected_name): raise RuntimeError(f"There is no undirected edge between {u} and {v}.") - self.remove_undirected_edge(v, u) - self.add_edge(u, v) + self.remove_edge(v, u, self._undirected_name) + self.add_edge(u, v, self._directed_name) def possible_children(self, n) -> Iterator: """Return an iterator over children of node n. From 228646db21404cacf69ceca59a51e552c1604d72 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Tue, 9 Aug 2022 12:31:14 -0400 Subject: [PATCH 05/23] Fix workflow --- .github/workflows/main.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 602c5c711..0f26d720b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -141,8 +141,7 @@ jobs: run: | python -m pip uninstall -yq networkx - name: Run pytest # headless via Xvfb on linux - with: - run: pytest main/pywhy_graphs --cov=main/pywhy_graphs --cov-report=xml --cov-config=main/pyproject.toml + run: pytest main/pywhy_graphs --cov=main/pywhy_graphs --cov-report=xml --cov-config=main/pyproject.toml - name: Upload coverage stats to codecov if: ${{ matrix.os == 'ubuntu' && matrix.python-version == '3.10' && matrix.networkx == 'stable' }} uses: codecov/codecov-action@v3 From ce5b77cc103fbe7aacab25fe7f998e41d7834a17 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Thu, 11 Aug 2022 12:29:22 -0400 Subject: [PATCH 06/23] Adding CPDAG --- .DS_Store | Bin 0 -> 6148 bytes .github/.DS_Store | Bin 0 -> 6148 bytes docs/conf.py | 4 +- docs/sphinxext/gh_substitutions.py | 33 ----- pyproject.toml | 2 +- pywhy_graphs/__init__.py | 1 + pywhy_graphs/admg.py | 15 +++ pywhy_graphs/base.py | 4 +- pywhy_graphs/cpdag.py | 17 ++- pywhy_graphs/export.py | 125 +++++++++++++++++ pywhy_graphs/scm.py | 208 +++++++++++++++++++++++++++++ pywhy_graphs/viz/__init__.py | 1 + pywhy_graphs/viz/draw.py | 46 +++++++ 13 files changed, 414 insertions(+), 42 deletions(-) create mode 100644 .DS_Store create mode 100644 .github/.DS_Store delete mode 100644 docs/sphinxext/gh_substitutions.py create mode 100644 pywhy_graphs/export.py create mode 100644 pywhy_graphs/scm.py create mode 100644 pywhy_graphs/viz/__init__.py create mode 100644 pywhy_graphs/viz/draw.py diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1cb2b079784c590f10e09458f0a3156eb1d603ac GIT binary patch literal 6148 zcmeHKu};G<5IvVjw1S}{V-PDsR7@~HsKSb%T^LJSnj$4i1$56RurRPO@gGQx9rz4B zf`NBF6B5!&NJt2wJL&u!`_6uOR$`loOnW+P5jBaZ4ri=2P|PvzXRlbzwX6b-9b-T- zUC@9oW85d{XW&+FL7lGdmjcH2#I4VYTUaJvBUONY~r}I&rMv`pIc=RGH5M^YLg% zDYUvSGkIGt_7ypt-QK4o;gIJRXMemK?aodt$GpEZ@5h(Mv#Y5Bs(>o+a|N(xv(;Aw zwNwRE0aYMZfd3CZoH1~i3EE!=3VSdCdT6$WI^QKY$9EVw%mmQ`Gm;9FRO7A~M$*yl zySTt%CMfA-+>yw*nT@-l7&|-0_iZ?tKu}9nKouw}uq2O7-v5sl-~Y==`lJe|0{=<@ z*E4$$DkHcJ^Ql zdkpC}^aFbCr614_=qcaR8A&EF-Ztb?OwkzW%}O)U=m|+40AP(_SOX{n0LMb;Jiw|z zsGrJ=ESMJZV`_{R_;3gTS<2I%ZQhF9R>?=7C(>+|~>cIYg}CpGVr z?Dllv4=-=C@5*K~h-H9w-1%17{DDL~jT0qE6uNgH~I^)HUU@2lM?7_Td@_u%iA z)6BaRXTf;qUO$Ota)P~+m64^D`C-893tyg}kZdHD0n5OgFhKW%z(VL6%r&a311psR zAUfEr1a- 1] + @property def bidirected_edges(self) -> nx.reportviews.EdgeView: """`EdgeView` of the bidirected edges.""" return self.get_graphs(self._bidirected_name).edges + @property def undirected_edges(self) -> nx.reportviews.EdgeView: """`EdgeView` of the undirected edges.""" return self.get_graphs(self._undirected_name).edges + @property def directed_edges(self) -> nx.reportviews.EdgeView: """`EdgeView` of the directed edges.""" return self.get_graphs(self._directed_name).edges diff --git a/pywhy_graphs/base.py b/pywhy_graphs/base.py index 6d374d436..27685836d 100644 --- a/pywhy_graphs/base.py +++ b/pywhy_graphs/base.py @@ -6,11 +6,11 @@ class AncestralMixin: """Mixin for graphs with ancestral functions.""" - def ancestors(self, source) -> Set: + def predecessors(self, source) -> Set: """Ancestors of 'source' node with directed path.""" return nx.ancestors(self.sub_directed_graph(), source) # type: ignore - def descendants(self, source) -> Set: + def successors(self, source) -> Set: """Descendants of 'source' node with directed path.""" return nx.descendants(self.sub_directed_graph(), source) # type: ignore diff --git a/pywhy_graphs/cpdag.py b/pywhy_graphs/cpdag.py index 5662c068e..512c60505 100644 --- a/pywhy_graphs/cpdag.py +++ b/pywhy_graphs/cpdag.py @@ -1,4 +1,4 @@ -from typing import Dict, Iterator +from typing import Dict, FrozenSet, Iterator import networkx as nx from graphs import MixedEdgeGraph @@ -68,10 +68,20 @@ def __init__( # these can be used for conservative structure learning algorithm self._unfaithful_triples = dict() + @property + def undirected_edge_name(self): + return self._undirected_name + + @property + def directed_edge_name(self): + return self._directed_name + + @property def undirected_edges(self) -> nx.reportviews.EdgeView: """`EdgeView` of the undirected edges.""" return self.get_graphs(self._undirected_name).edges + @property def directed_edges(self) -> nx.reportviews.EdgeView: """`EdgeView` of the directed edges.""" return self.get_graphs(self._directed_name).edges @@ -84,7 +94,7 @@ def sub_undirected_graph(self) -> nx.Graph: """Sub-graph of just the undirected edges.""" return self._get_internal_graph(self._undirected_name) - def orient_undirected_edge(self, u, v): + def orient_uncertain_edge(self, u, v): """Orient undirected edge into an arrowhead. If there is an undirected edge u - v, then the arrowhead @@ -163,6 +173,7 @@ def mark_unfaithful_triple(self, v_i, u, v_j) -> None: self._unfaithful_triples[frozenset(v_i, u, v_j)] = None # type: ignore - def unfaithful_triples(self) -> Dict: + @property + def excluded_triples(self) -> Dict[FrozenSet, None]: """Unfaithful triples.""" return self._unfaithful_triples diff --git a/pywhy_graphs/export.py b/pywhy_graphs/export.py new file mode 100644 index 000000000..64f372050 --- /dev/null +++ b/pywhy_graphs/export.py @@ -0,0 +1,125 @@ +from copy import deepcopy + +import networkx as nx +import numpy as np +from graphs import MixedEdgeGraph + +from pywhy_graphs import ADMG + +EDGE_TO_VALUE_MAPPING = { + None: 0, + "directed": 1, + "undirected": 2, + "bidirected": 3, + "circle": 4, +} + + +def to_digraph(graph: MixedEdgeGraph): + """Convert causal graph to a uni-edge networkx directed graph. + + Parameters + ---------- + graph : MixedEdgeGraph + A causal mixed-edge graph. + + Returns + ------- + G : nx.DiGraph | nx.MultiDiGraph + The networkx directed graph with multiple edges with edge + attributes indicating via the keyword "type", which type of + causal edge it is. + """ + if len(graph.get_graphs()) == 1: + G = nx.DiGraph() + else: + G = nx.MultiDiGraph() + + # preserve the name + G.graph.update(deepcopy(graph.graph)) + graph_type = type(graph).__name__ # GRAPH_TYPE[type(causal_graph)] + G.graph["graph_type"] = graph_type + + G.add_nodes_from((n, deepcopy(d)) for n, d in graph.nodes.items()) + + # add all the edges + for edge_type, edge_adj in graph.adj.items(): + # replace edge marks with their appropriate string representation + attr = {"type": edge_type} + G.add_edges_from( + (u, v, deepcopy(d), attr.items()) + for u, nbrs in edge_adj.items() + for v, d in nbrs.items() + ) + return G + + +def to_numpy(causal_graph): + """Convert causal graph to a numpy adjacency array. + + Parameters + ---------- + causal_graph : instance of DAG + The causal graph. + + Returns + ------- + numpy_graph : np.ndarray of shape (n_nodes, n_nodes) + The numpy array that represents the graph. The values representing edges + are mapped according to a pre-defined set of values. See Notes. + + Notes + ----- + The adjacency matrix is defined where the ijth entry of ``numpy_graph`` has a + non-zero entry if there is an edge from i to j. The ijth entry is symmetric with the + jith entry if the edge is 'undirected', or 'bidirected'. Then specific edges are + mapped to the following values: + + - directed edge (->): 1 + - undirected edge (--): 2 + - bidirected edge (<->): 3 + - circle endpoint (-o): 4 + + Circle endpoints can be symmetric, but they can also contain a tail, or a directed + edge at the other end. + """ + if isinstance(causal_graph, ADMG): + raise RuntimeError("Converting ADMG to numpy format is not supported.") + + # master list of nodes is in the internal dag + node_list = causal_graph.nodes + n_nodes = len(node_list) + + numpy_graph = np.zeros((n_nodes, n_nodes)) + bidirected_graph_arr = None + graph_map = dict() + for edge_type, graph in causal_graph.get_graphs(): + # handle bidirected edge separately + if edge_type == "bidirected": + bidirected_graph_arr = nx.to_numpy_array(graph, nodelist=node_list) + continue + + # convert internal graph to a numpy array + graph_arr = nx.to_numpy_array(graph, nodelist=node_list) + graph_map[edge_type] = graph_arr + + # ADMGs can have two edges between any 2 nodes + if type(causal_graph).__name__ == "ADMG": + # we handle this case separately from the other graphs + assert len(graph_map) == 1 + + # set all bidirected edges with value 10 + bidirected_graph_arr[bidirected_graph_arr != 0] = 10 + numpy_graph += bidirected_graph_arr + numpy_graph += graph_arr + else: + # map each edge to an edge value + for name, graph_arr in graph_map.items(): + graph_arr[graph_arr != 0] = EDGE_TO_VALUE_MAPPING[name] + numpy_graph += graph_arr + + # bidirected case is handled separately + if bidirected_graph_arr is not None: + numpy_graph += bidirected_graph_arr + + return numpy_graph diff --git a/pywhy_graphs/scm.py b/pywhy_graphs/scm.py new file mode 100644 index 000000000..3f82a31d2 --- /dev/null +++ b/pywhy_graphs/scm.py @@ -0,0 +1,208 @@ +import inspect +from collections import defaultdict +from typing import Callable, Dict + +import pandas as pd + +from pywhy_graphs import ADMG + + +class StructuralCausalModel: + """Structural Causal Model (SCM) class. + + Assumes that all exogenous variables are independent of + each other. That is no exogenous variable is a function + of other exogenous variables passed in. + + This assumes the causal independence mechanism, where all + exogenous variables are independent of each other. + + Parameters + ---------- + exogenous : Dict of functions + The exogenous variables and their functional form + passed in as values. This forms a symbolic mapping + from exogenous variable names to their distribution. + The exogenous variable functions should not have + any parameters. + endogenous : Dict of lambda functions + The endogenous variable functions may have parameters. + + Attributes + ---------- + causal_dependencies : dict + A mapping of each variable and its causal dependencies based + on the SCM functions. + var_list : list + The list of variable names in the SCM. + _symbolic_runtime : dict + The mapping from each variable in the SCM to the sampled + value of that variable. Used when sampling from the SCM. + + Examples + -------- + >>> import numpy as np + >>> rng = np.random.RandomState() + >>> func_uxy = rng.uniform + >>> func_uz = rng.uniform + >>> func_x = lambda u_xy: 2 * u_xy + >>> func_y = lambda x, u_xy: x + >>> func_z = lambda u_z: u_z**2 + >>> scm = StructuralCausalModel( + exogenous={ + "u_xy": func_uxy, + }, + endogenous={"x": func_x, "y": func_y}, + ) + + """ + + _symbolic_runtime: Dict[str, float] + + def __init__(self, exogenous: Dict[str, Callable], endogenous: Dict[str, Callable]) -> None: + self._symbolic_runtime = dict() + + # construct symbolic table of all variables + self.exogenous = exogenous + self.endogenous = endogenous + + # keep track of all variables for error checking + endog_var_list = list(endogenous.keys()) + exog_var_list = list(self.exogenous.keys()) + var_list = [] + var_list.extend(endog_var_list) + var_list.extend(exog_var_list) + self.var_list = var_list + + self.causal_dependencies = {} + + input_warn_list = [] + for endog_var, endog_func in endogenous.items(): + # get all variable names from endogenous function + endog_input_vars = inspect.getfullargspec(endog_func).args + + # check for input arguments for functions that are not + # defined within the SCM + if any(name not in var_list for name in endog_input_vars): + input_warn_list.extend(endog_input_vars) + + self.causal_dependencies[endog_var] = endog_input_vars + + # All variables should be defined if they have a functional form + if input_warn_list: + raise ValueError( + f"Endogenous functions define a list of variables not " + f"within the set of passed variables: {input_warn_list}" + ) + + def __str__(self): + """For printing.""" + return ( + f"Structural Causal Model:\n" + f"endogenous: {list(self.endogenous.keys())}\n" + f"exogenous: {list(self.exogenous.keys())}\n" + ) + + def sample(self, n: int = 1000, include_latents: bool = True) -> pd.DataFrame: + """Sample from the SCM. + + Parameters + ---------- + n : int, optional + Number of samples to generate, by default 1000. + include_latents : bool, optional + Whether to include latent variables in the returned + dataset, by default True. + + Returns + ------- + result_df : pd.DataFrame + The sampled dataset. + """ + df_values = [] + + # construct truth-table based on the SCM + for _ in range(n): + self._symbolic_runtime = dict() + + # sample all latent variables, which are independent + for exog, exog_func in self.exogenous.items(): + self._symbolic_runtime[exog] = exog_func() + + # sample now all observed variables + for endog, endog_func in self.endogenous.items(): + endog_value = self._sample_function(endog_func, self._symbolic_runtime) + + if endog not in self._symbolic_runtime: + self._symbolic_runtime[endog] = endog_value + + # add each sample to + df_values.append(self._symbolic_runtime) + + # now convert the final sample to a dataframe + result_df = pd.DataFrame(df_values) + + if not include_latents: + # remove latent variable columns + result_df.drop(self.exogenous.keys(), axis=1, inplace=True) + else: + # make sure to order the columns with latents first + def key(x): + return x not in self.exogenous.keys() + + result_df = result_df[sorted(result_df, key=key)] + return result_df + + def _sample_function(self, func: Callable, result_table: Dict[str, float]): + # get all input variables for the function + input_vars = inspect.getfullargspec(func).args + + # recursive tree stopping condition + if all(name in result_table for name in input_vars): + return func(*[result_table[name] for name in input_vars]) + + # get all variable names that we still need to sample + # then recursively call function to sample all variables + to_sample_vars = [name for name in input_vars if name not in result_table] + + for name in to_sample_vars: + result_table[name] = self._sample_function(self.endogenous[name], result_table) + return func(*[result_table[name] for name in input_vars]) + + def get_causal_graph(self) -> ADMG: + """Compute the induced causal diagram. + + Returns + ------- + G : instance of ADMG + The causal graphical model corresponding to + the SCM. + + """ + edge_list = [] + latent_edge_dict = defaultdict(set) + + # form the edge lists + for end_var, end_input_vars in self.causal_dependencies.items(): + # for every input variable, form either an edge, or a latent edge + for input_var in end_input_vars: + if input_var in self.endogenous: + edge_list.append((input_var, end_var)) + elif input_var in self.exogenous: + latent_edge_dict[input_var].add(end_var) + + # add latent edges + latent_edge_list = [] + for _, pc_comps in latent_edge_dict.items(): + if len(pc_comps) == 2: + latent_edge_list.append(pc_comps) + + G = ADMG( + incoming_directed_edges=edge_list, + incoming_bidirected_edges=latent_edge_list, + name="Induced Causal Graph from SCM", + ) + for node in self.endogenous.keys(): + G.add_node(node) + + return G diff --git a/pywhy_graphs/viz/__init__.py b/pywhy_graphs/viz/__init__.py new file mode 100644 index 000000000..9ed91b181 --- /dev/null +++ b/pywhy_graphs/viz/__init__.py @@ -0,0 +1 @@ +from .draw import draw diff --git a/pywhy_graphs/viz/draw.py b/pywhy_graphs/viz/draw.py new file mode 100644 index 000000000..0314c9236 --- /dev/null +++ b/pywhy_graphs/viz/draw.py @@ -0,0 +1,46 @@ +from graphs import MixedEdgeGraph + + +def draw(G: MixedEdgeGraph, direction=None): + """ + Visualize the graph. + + :return : dot language representation of the graph. + """ + from graphviz import Digraph + + dot = Digraph() + + # set direction from left to right if that's preferred + if direction == "LR": + dot.graph_attr["rankdir"] = direction + + shape = "square" # 'plaintext' + for v in G.nodes: + child = str(v) + + dot.node(child, shape=shape, height=".5", width=".5") + + for parent in G.predecessors(v): + parent = str(parent) + if parent == v: + dot.edge(parent, child, style="invis") + else: + dot.edge(parent, child, color="blue") + + if hasattr(G, "undirected_edges"): + for neb1, neb2 in G.undirected_edges: + neb1, neb2 = str(neb1), str(neb2) + dot.edge(neb1, neb2, dir="none", color="brown") + + if hasattr(G, "bidirected_edges"): + for sib1, sib2 in G.bidirected_edges: + sib1, sib2 = str(sib1), str(sib2) + dot.edge(sib1, sib2, dir="both", color="red") + + if hasattr(G, "circle_edges"): + for sib1, sib2 in G.circle_edges: + sib1, sib2 = str(sib1), str(sib2) + dot.edge(sib1, sib2, arrowhead="circle", color="green") + + return dot From 022ccd07067264d093e31a10f9814f3c2d197208 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Thu, 11 Aug 2022 12:29:41 -0400 Subject: [PATCH 07/23] Remove dsstore --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 1cb2b079784c590f10e09458f0a3156eb1d603ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKu};G<5IvVjw1S}{V-PDsR7@~HsKSb%T^LJSnj$4i1$56RurRPO@gGQx9rz4B zf`NBF6B5!&NJt2wJL&u!`_6uOR$`loOnW+P5jBaZ4ri=2P|PvzXRlbzwX6b-9b-T- zUC@9oW85d{XW&+FL7lGdmjcH2#I4VYTUaJvBUONY~r}I&rMv`pIc=RGH5M^YLg% zDYUvSGkIGt_7ypt-QK4o;gIJRXMemK?aodt$GpEZ@5h(Mv#Y5Bs(>o+a|N(xv(;Aw zwNwRE0aYMZfd3CZoH1~i3EE!=3VSdCdT6$WI^QKY$9EVw%mmQ`Gm;9FRO7A~M$*yl zySTt%CMfA-+>yw*nT@-l7&|-0_iZ?tKu}9nKouw}uq2O7-v5sl-~Y==`lJe|0{=<@ z Date: Thu, 11 Aug 2022 12:30:08 -0400 Subject: [PATCH 08/23] Also fix CI --- .github/workflows/main.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0f26d720b..055a55f3f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,4 @@ -name: unit-tests +name: gh-ci-checks concurrency: group: ${{ github.workflow }}-${{ github.event.number }}-${{ github.event.type }} cancel-in-progress: true @@ -10,6 +10,8 @@ on: branches: [main] paths: - '**.py' + tags: + - 'v*.*.*' workflow_dispatch: jobs: From 4adc7aa66d88728dbfc37282ffe7f0e879044eff Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 00:17:48 -0400 Subject: [PATCH 09/23] Adding poetry lock and updated CI --- .github/workflows/main.yml | 55 +- .gitignore | 1 + junit-results.xml | 1 - poetry.lock | 3231 ++++++++++++++++++++++++++++++++++++ pyproject.toml | 217 +-- 5 files changed, 3380 insertions(+), 125 deletions(-) delete mode 100644 junit-results.xml create mode 100644 poetry.lock diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 055a55f3f..9b9a7efc3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,6 +18,9 @@ jobs: style: timeout-minutes: 10 runs-on: ubuntu-latest + strategy: + matrix: + poetry-version: [1.1.14] steps: - name: Checkout repository uses: actions/checkout@v3 @@ -26,10 +29,14 @@ jobs: with: python-version: '3.9' architecture: 'x64' + - name: Install Poetry ${{ matrix.poetry-version }} + uses: abatilo/actions-poetry@v2.0.0 + with: + poetry-version: ${{ matrix.poetry-version }} + - name: Install Poetry Dynamic Versioning Plugin + run: pip install poetry-dynamic-versioning - name: Install dependencies - run: | - python -m pip install --progress-bar off --upgrade pip setuptools wheel - python -m pip install --progress-bar off .[style] + run: poetry install - name: Run flake8 uses: py-actions/flake8@v2 with: @@ -62,6 +69,7 @@ jobs: matrix: os: [ubuntu, macos, windows] python-version: [3.8, 3.9, "3.10"] + poetry-version: [1.1.14] name: build ${{ matrix.os }} - py${{ matrix.python-version }} runs-on: ${{ matrix.os }}-latest defaults: @@ -75,18 +83,25 @@ jobs: with: python-version: ${{ matrix.python-version }} architecture: 'x64' - - name: Install dependencies + - name: Install Poetry ${{ matrix.poetry-version }} + uses: abatilo/actions-poetry@v2.0.0 + with: + poetry-version: ${{ matrix.poetry-version }} + - name: Install Poetry Dynamic Versioning Plugin + run: pip install poetry-dynamic-versioning + - name: Install from source run: | - python -m pip install --progress-bar off git+https://github.com/py-why/graphs - python -m pip install --progress-bar off --upgrade pip setuptools wheel - python -m pip install --progress-bar off .[build] + python -m pip install -e . - name: Test package install run: python -c "import pywhy_graphs; print(pywhy_graphs.__version__)" - name: Remove package install run: python -m pip uninstall -yq pywhy_graphs + - name: Check poetry lock file + run: poetry update --dry-run - name: Build package - run: python -m build + run: poetry build - name: Upload package distribution files + if: ${{ matrix.os == 'ubuntu' && matrix.python-version == '3.10' }} uses: actions/upload-artifact@v3 with: name: package @@ -111,6 +126,7 @@ jobs: matrix: os: [ubuntu, macos, windows] python-version: [3.8, "3.10"] # oldest and newest supported versions + poetry-version: [1.1.14] networkx: [stable, main] name: pytest ${{ matrix.os }} - py${{ matrix.python-version }} - Networkx ${{ matrix.networkx }} runs-on: ${{ matrix.os }}-latest @@ -127,23 +143,22 @@ jobs: with: python-version: ${{ matrix.python-version }} architecture: 'x64' - - name: Install Qt dependencies - if: "matrix.os == 'ubuntu'" - run: | - sudo apt update - sudo apt install qt5-default - - name: Install package + - name: Install Poetry ${{ matrix.poetry-version }} + uses: abatilo/actions-poetry@v2.0.0 + with: + poetry-version: ${{ matrix.poetry-version }} + - name: Install Poetry Dynamic Versioning Plugin + run: pip install poetry-dynamic-versioning + - name: Install packages via poetry run: | - python -m pip install --progress-bar off --upgrade pip setuptools wheel - python -m pip install --progress-bar off main/.[test] - # TODO: remove this eventually - python -m pip install --progress-bar off git+https://github.com/py-why/graphs + python -m poetry install - name: Install Networkx (main) if: "matrix.networkx == 'main'" run: | python -m pip uninstall -yq networkx + python -m pip install --progress-bar off git+https://github.com/networkx/networkx - name: Run pytest # headless via Xvfb on linux - run: pytest main/pywhy_graphs --cov=main/pywhy_graphs --cov-report=xml --cov-config=main/pyproject.toml + run: poetry run poe unit_test - name: Upload coverage stats to codecov if: ${{ matrix.os == 'ubuntu' && matrix.python-version == '3.10' && matrix.networkx == 'stable' }} uses: codecov/codecov-action@v3 @@ -169,7 +184,7 @@ jobs: - name: Install dependencies run: | python -m pip install --progress-bar off --upgrade pip setuptools wheel - python -m pip install --progress-bar off .[build] + python -m pip install --progress-bar off build twine - name: Prepare environment run: | echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV diff --git a/.gitignore b/.gitignore index 4e9b4b71a..9d123cf40 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ __pycache__/ *$py.class .vscode +junit-results.xml # C extensions *.so diff --git a/junit-results.xml b/junit-results.xml deleted file mode 100644 index 519e0b389..000000000 --- a/junit-results.xml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 000000000..61f6367f0 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,3231 @@ +[[package]] +name = "alabaster" +version = "0.7.12" +description = "A configurable sidebar-enabled Sphinx theme" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "appnope" +version = "0.1.3" +description = "Disable App Nap on macOS >= 10.9" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "atomicwrites" +version = "1.4.1" +description = "Atomic file writes." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "attrs" +version = "22.1.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +tests_no_zope = ["cloudpickle", "pytest-mypy-plugins", "mypy (>=0.900,!=0.940)", "pytest (>=4.3.0)", "pympler", "hypothesis", "coverage[toml] (>=5.0.2)"] +tests = ["cloudpickle", "zope.interface", "pytest-mypy-plugins", "mypy (>=0.900,!=0.940)", "pytest (>=4.3.0)", "pympler", "hypothesis", "coverage[toml] (>=5.0.2)"] +docs = ["sphinx-notfound-page", "zope.interface", "sphinx", "furo"] +dev = ["cloudpickle", "pre-commit", "sphinx-notfound-page", "sphinx", "furo", "zope.interface", "pytest-mypy-plugins", "mypy (>=0.900,!=0.940)", "pytest (>=4.3.0)", "pympler", "hypothesis", "coverage[toml] (>=5.0.2)"] + +[[package]] +name = "babel" +version = "2.10.3" +description = "Internationalization utilities" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pytz = ">=2015.7" + +[[package]] +name = "backcall" +version = "0.2.0" +description = "Specifications for callback functions passed in to an API" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "bandit" +version = "1.7.4" +description = "Security oriented static analyser for python code." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} +GitPython = ">=1.0.1" +PyYAML = ">=5.3.1" +stevedore = ">=1.20.0" + +[package.extras] +yaml = ["pyyaml"] +toml = ["toml"] +test = ["pylint (==1.9.4)", "beautifulsoup4 (>=4.8.0)", "toml", "testtools (>=2.3.0)", "testscenarios (>=0.5.0)", "stestr (>=2.5.0)", "flake8 (>=4.0.0)", "fixtures (>=3.0.0)", "coverage (>=4.5.4)"] + +[[package]] +name = "beartype" +version = "0.10.4" +description = "Unbearably fast runtime type checking in pure Python." +category = "main" +optional = false +python-versions = ">=3.6.0" + +[package.extras] +test-tox = ["numpy", "typing-extensions", "mypy (>=0.800)", "pytest (>=4.0.0)", "sphinx"] +test-tox-coverage = ["coverage (>=5.5)"] +doc-rtd = ["sphinx-rtd-theme (==0.5.1)", "sphinx (==4.1.0)"] +dev = ["numpy", "typing-extensions", "mypy (>=0.800)", "sphinx (>=4.1.0)", "tox (>=3.20.1)", "pytest (>=4.0.0)", "sphinx", "coverage (>=5.5)"] +all = ["typing-extensions (>=3.10.0.0)"] + +[[package]] +name = "beautifulsoup4" +version = "4.11.1" +description = "Screen-scraping library" +category = "dev" +optional = false +python-versions = ">=3.6.0" + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +lxml = ["lxml"] +html5lib = ["html5lib"] + +[[package]] +name = "black" +version = "22.6.0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} +typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} + +[package.extras] +uvloop = ["uvloop (>=0.15.2)"] +jupyter = ["tokenize-rt (>=3.2.0)", "ipython (>=7.8.0)"] +d = ["aiohttp (>=3.7.4)"] +colorama = ["colorama (>=0.4.3)"] + +[[package]] +name = "bleach" +version = "5.0.1" +description = "An easy safelist-based HTML-sanitizing tool." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +six = ">=1.9.0" +webencodings = "*" + +[package.extras] +css = ["tinycss2 (>=1.1.0,<1.2)"] +dev = ["build (==0.8.0)", "flake8 (==4.0.1)", "hashin (==0.17.0)", "pip-tools (==6.6.2)", "pytest (==7.1.2)", "Sphinx (==4.3.2)", "tox (==3.25.0)", "twine (==4.0.1)", "wheel (==0.37.1)", "black (==22.3.0)", "mypy (==0.961)"] + +[[package]] +name = "certifi" +version = "2022.6.15" +description = "Python package for providing Mozilla's CA Bundle." +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "cffi" +version = "1.15.1" +description = "Foreign Function Interface for Python calling C code." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "charset-normalizer" +version = "2.1.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "dev" +optional = false +python-versions = ">=3.6.0" + +[package.extras] +unicode_backport = ["unicodedata2"] + +[[package]] +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "codespell" +version = "2.1.0" +description = "Codespell" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +hard-encoding-detection = ["chardet"] +dev = ["pytest-dependency", "pytest-cov", "pytest", "flake8", "check-manifest"] + +[[package]] +name = "colorama" +version = "0.4.5" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "coverage" +version = "6.4.4" +description = "Code coverage measurement for Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "cycler" +version = "0.11.0" +description = "Composable style cycles" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "docstring-parser" +version = "0.7.3" +description = "" +category = "dev" +optional = false +python-versions = "~=3.5" + +[[package]] +name = "docutils" +version = "0.17.1" +description = "Docutils -- Python Documentation Utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "dowhy" +version = "0.8" +description = "DoWhy is a Python library for causal inference that supports explicit modeling and testing of causal assumptions." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +networkx = ">=2.0" +numpy = ">=1.15" +pandas = ">=0.24" +pydot = ">=1.4" +scikit-learn = "*" +scipy = "*" +statsmodels = "*" +sympy = ">=1.4" + +[package.extras] +plotting = ["matplotlib"] + +[[package]] +name = "entrypoints" +version = "0.4" +description = "Discover and load entry points from installed packages." +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "falcon" +version = "2.0.0" +description = "An unladen web framework for building APIs and app backends." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "fastjsonschema" +version = "2.16.1" +description = "Fastest Python implementation of JSON schema" +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +devel = ["colorama", "jsonschema", "json-spec", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] + +[[package]] +name = "flake8" +version = "5.0.4" +description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" +optional = false +python-versions = ">=3.6.1" + +[package.dependencies] +mccabe = ">=0.7.0,<0.8.0" +pycodestyle = ">=2.9.0,<2.10.0" +pyflakes = ">=2.5.0,<2.6.0" + +[[package]] +name = "fonttools" +version = "4.35.0" +description = "Tools to manipulate font files" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] +unicode = ["unicodedata2 (>=14.0.0)"] +ufo = ["fs (>=2.2.0,<3)"] +type1 = ["xattr"] +symfont = ["sympy"] +repacker = ["uharfbuzz (>=0.23.0)"] +plot = ["matplotlib"] +pathops = ["skia-pathops (>=0.5.0)"] +lxml = ["lxml (>=4.0,<5)"] +interpolatable = ["munkres", "scipy"] +graphite = ["lz4 (>=1.7.4.2)"] +all = ["xattr", "unicodedata2 (>=14.0.0)", "munkres", "brotli (>=1.0.1)", "scipy", "brotlicffi (>=0.8.0)", "uharfbuzz (>=0.23.0)", "skia-pathops (>=0.5.0)", "sympy", "matplotlib", "lz4 (>=1.7.4.2)", "zopfli (>=0.1.4)", "lxml (>=4.0,<5)", "fs (>=2.2.0,<3)"] + +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["wheel", "flake8", "markdown", "twine"] + +[[package]] +name = "gitdb" +version = "4.0.9" +description = "Git Object Database" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +smmap = ">=3.0.1,<6" + +[[package]] +name = "gitpython" +version = "3.1.27" +description = "GitPython is a python library used to interact with Git repositories" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +gitdb = ">=4.0.1,<5" + +[[package]] +name = "graphs" +version = "0.1.dev0" +description = "graphs: Mixed edge graphs for networkx." +category = "main" +optional = false +python-versions = "~=3.8" +develop = false + +[package.dependencies] +importlib-resources = {version = "*", markers = "python_version < \"3.9\""} +networkx = ">=2.8.3" +numpy = ">=1.16.0" +scipy = ">=1.2.0" + +[package.extras] +all = ["graphs", "graphs", "graphs", "graphs"] +build = ["build", "twine"] +doc = ["memory-profiler", "numpydoc", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-bibtex", "sphinx-issues", "sphinx-copybutton", "sphinx-gallery", "sphinx-rtd-theme", "typing-extensions", "pydot", "pandas", "matplotlib", "graphviz", "dowhy"] +full = ["graphs"] +style = ["black", "codespell", "isort", "flake8", "mypy", "pydocstyle"] +test = ["pandas", "pytest", "pytest-cov"] + +[package.source] +type = "git" +url = "https://github.com/py-why/graphs.git" +reference = 'main' +resolved_reference = "81b718186deaf698a0eb7fd7fd2b2c7fe449a5b4" + +[[package]] +name = "graphviz" +version = "0.20.1" +description = "Simple Python interface for Graphviz" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +test = ["coverage", "pytest-cov", "mock (>=4)", "pytest-mock (>=3)", "pytest (>=7)"] +docs = ["sphinx-rtd-theme", "sphinx-autodoc-typehints", "sphinx (>=5)"] +dev = ["twine", "wheel", "pep8-naming", "flake8", "tox (>=3)"] + +[[package]] +name = "hug" +version = "2.6.1" +description = "A Python framework that makes developing APIs as simple as possible, but no simpler." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +falcon = "2.0.0" +requests = "*" + +[[package]] +name = "idna" +version = "3.3" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "imagesize" +version = "1.4.1" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "importlib-metadata" +version = "4.12.0" +description = "Read metadata from Python packages" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +testing = ["importlib-resources (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-black (>=0.3.7)", "pytest-perf (>=0.9.2)", "flufl.flake8", "pyfakefs", "packaging", "pytest-enabler (>=1.3)", "pytest-cov", "pytest-flake8", "pytest-checkdocs (>=2.4)", "pytest (>=6)"] +perf = ["ipython"] +docs = ["rst.linker (>=1.9)", "jaraco.packaging (>=9)", "sphinx"] + +[[package]] +name = "importlib-resources" +version = "5.9.0" +description = "Read resources from Python packages" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +testing = ["pytest-mypy (>=0.9.1)", "pytest-black (>=0.3.7)", "pytest-enabler (>=1.3)", "pytest-cov", "pytest-flake8", "pytest-checkdocs (>=2.4)", "pytest (>=6)"] +docs = ["jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "jaraco.packaging (>=9)", "sphinx"] + +[[package]] +name = "iniconfig" +version = "1.1.1" +description = "iniconfig: brain-dead simple config-ini parsing" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "ipython" +version = "7.34.0" +description = "IPython: Productive Interactive Computing" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +appnope = {version = "*", markers = "sys_platform == \"darwin\""} +backcall = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +pickleshare = "*" +prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" +pygments = "*" +traitlets = ">=4.2" + +[package.extras] +all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.17)", "pygments", "qtconsole", "requests", "testpath"] +doc = ["Sphinx (>=1.3)"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["notebook", "ipywidgets"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"] + +[[package]] +name = "isort" +version = "5.10.1" +description = "A Python utility / library to sort Python imports." +category = "dev" +optional = false +python-versions = ">=3.6.1,<4.0" + +[package.extras] +plugins = ["setuptools"] +colors = ["colorama (>=0.4.3,<0.5.0)"] +requirements_deprecated_finder = ["pip-api", "pipreqs"] +pipfile_deprecated_finder = ["requirementslib", "pipreqs"] + +[[package]] +name = "jedi" +version = "0.18.1" +description = "An autocompletion tool for Python that can be used for text editors." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +parso = ">=0.8.0,<0.9.0" + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"] + +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "joblib" +version = "1.1.0" +description = "Lightweight pipelining with Python functions" +category = "main" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "jsonschema" +version = "4.10.0" +description = "An implementation of JSON Schema validation for Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +attrs = ">=17.4.0" +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "jupyter-client" +version = "7.3.4" +description = "Jupyter protocol implementation and client libraries" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +entrypoints = "*" +jupyter-core = ">=4.9.2" +nest-asyncio = ">=1.5.4" +python-dateutil = ">=2.8.2" +pyzmq = ">=23.0" +tornado = ">=6.0" +traitlets = "*" + +[package.extras] +doc = ["ipykernel", "myst-parser", "sphinx-rtd-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt"] +test = ["codecov", "coverage", "ipykernel (>=6.5)", "ipython", "mypy", "pre-commit", "pytest", "pytest-asyncio (>=0.18)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "jupyter-core" +version = "4.11.1" +description = "Jupyter core package. A base package on which Jupyter projects rely." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +pywin32 = {version = ">=1.0", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} +traitlets = "*" + +[package.extras] +test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "jupyterlab-pygments" +version = "0.2.2" +description = "Pygments theme using JupyterLab CSS variables" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "kiwisolver" +version = "1.4.4" +description = "A fast implementation of the Cassowary constraint solver" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "latexcodec" +version = "2.0.1" +description = "A lexer and codec to work with LaTeX code in Python." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +six = ">=1.4.1" + +[[package]] +name = "livereload" +version = "2.6.3" +description = "Python LiveReload is an awesome tool for web developers" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +six = "*" +tornado = {version = "*", markers = "python_version > \"2.7\""} + +[[package]] +name = "lxml" +version = "4.9.1" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" + +[package.extras] +cssselect = ["cssselect (>=0.7)"] +html5 = ["html5lib"] +htmlsoup = ["beautifulsoup4"] +source = ["Cython (>=0.29.7)"] + +[[package]] +name = "mako" +version = "1.2.1" +description = "A super-fast templating language that borrows the best ideas from the existing templating languages." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +MarkupSafe = ">=0.9.2" + +[package.extras] +babel = ["babel"] +lingua = ["lingua"] +testing = ["pytest"] + +[[package]] +name = "markdown" +version = "3.4.1" +description = "Python implementation of Markdown." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} + +[package.extras] +testing = ["pyyaml", "coverage"] + +[[package]] +name = "markupsafe" +version = "2.1.1" +description = "Safely add untrusted strings to HTML/XML markup." +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "matplotlib" +version = "3.5.3" +description = "Python plotting package" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.0.1" +numpy = ">=1.17" +packaging = ">=20.0" +pillow = ">=6.2.0" +pyparsing = ">=2.2.1" +python-dateutil = ">=2.7" +setuptools_scm = ">=4,<7" + +[[package]] +name = "matplotlib-inline" +version = "0.1.5" +description = "Inline Matplotlib backend for Jupyter" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +traitlets = "*" + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "memory-profiler" +version = "0.60.0" +description = "A module for monitoring memory usage of a python program" +category = "dev" +optional = false +python-versions = ">=3.4" + +[package.dependencies] +psutil = "*" + +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "mistune" +version = "0.8.4" +description = "The fastest markdown parser in pure Python" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "mkdocs" +version = "1.2.4" +description = "Project documentation with Markdown." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +click = ">=3.3" +ghp-import = ">=1.0" +importlib-metadata = ">=3.10" +Jinja2 = ">=2.10.1" +Markdown = ">=3.2.1" +mergedeep = ">=1.3.4" +packaging = ">=20.5" +PyYAML = ">=3.10" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] + +[[package]] +name = "mkdocs-material" +version = "7.3.0" +description = "A Material Design theme for MkDocs" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +markdown = ">=3.2" +mkdocs = ">=1.2.2" +mkdocs-material-extensions = ">=1.0" +Pygments = ">=2.4" +pymdown-extensions = ">=7.0" + +[[package]] +name = "mkdocs-material-extensions" +version = "1.0.3" +description = "Extension pack for Python Markdown." +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "mpmath" +version = "1.2.1" +description = "Python library for arbitrary-precision floating-point arithmetic" +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +tests = ["pytest (>=4.6)"] +develop = ["wheel", "codecov", "pytest-cov", "pycodestyle", "pytest (>=4.6)"] + +[[package]] +name = "mypy" +version = "0.971" +description = "Optional static typing for Python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +mypy-extensions = ">=0.4.3" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = ">=3.10" + +[package.extras] +reports = ["lxml"] +python2 = ["typed-ast (>=1.4.0,<2)"] +dmypy = ["psutil (>=4.0)"] + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "nbclient" +version = "0.6.6" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +category = "dev" +optional = false +python-versions = ">=3.7.0" + +[package.dependencies] +jupyter-client = ">=6.1.5" +nbformat = ">=5.0" +nest-asyncio = "*" +traitlets = ">=5.2.2" + +[package.extras] +sphinx = ["autodoc-traits", "mock", "moto", "myst-parser", "Sphinx (>=1.7)", "sphinx-book-theme"] +test = ["black", "check-manifest", "flake8", "ipykernel", "ipython (<8.0.0)", "ipywidgets (<8.0.0)", "mypy", "pip (>=18.1)", "pre-commit", "pytest (>=4.1)", "pytest-asyncio", "pytest-cov (>=2.6.1)", "setuptools (>=60.0)", "testpath", "twine (>=1.11.0)", "xmltodict"] + +[[package]] +name = "nbconvert" +version = "6.5.3" +description = "Converting Jupyter Notebooks" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +beautifulsoup4 = "*" +bleach = "*" +defusedxml = "*" +entrypoints = ">=0.2.2" +jinja2 = ">=3.0" +jupyter-core = ">=4.7" +jupyterlab-pygments = "*" +lxml = "*" +MarkupSafe = ">=2.0" +mistune = ">=0.8.1,<2" +nbclient = ">=0.5.0" +nbformat = ">=5.1" +packaging = "*" +pandocfilters = ">=1.4.1" +pygments = ">=2.4.1" +tinycss2 = "*" +traitlets = ">=5.0" + +[package.extras] +all = ["pytest", "pytest-cov", "pytest-dependency", "ipykernel", "ipywidgets (>=7)", "pre-commit", "pyppeteer (>=1,<1.1)", "tornado (>=6.1)", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "nbsphinx (>=0.2.12)", "ipython"] +docs = ["sphinx (>=1.5.1)", "sphinx-rtd-theme", "nbsphinx (>=0.2.12)", "ipython"] +serve = ["tornado (>=6.1)"] +test = ["pytest", "pytest-cov", "pytest-dependency", "ipykernel", "ipywidgets (>=7)", "pre-commit", "pyppeteer (>=1,<1.1)"] +webpdf = ["pyppeteer (>=1,<1.1)"] + +[[package]] +name = "nbformat" +version = "5.4.0" +description = "The Jupyter Notebook format" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +fastjsonschema = "*" +jsonschema = ">=2.6" +jupyter-core = "*" +traitlets = ">=5.1" + +[package.extras] +test = ["check-manifest", "testpath", "pytest", "pre-commit"] + +[[package]] +name = "nbsphinx" +version = "0.8.9" +description = "Jupyter Notebook Tools for Sphinx" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +docutils = "*" +jinja2 = "*" +nbconvert = "!=5.4" +nbformat = "*" +sphinx = ">=1.8" +traitlets = ">=5" + +[[package]] +name = "nest-asyncio" +version = "1.5.5" +description = "Patch asyncio to allow nested event loops" +category = "dev" +optional = false +python-versions = ">=3.5" + +[[package]] +name = "networkx" +version = "2.8.5" +description = "Python package for creating and manipulating graphs and networks" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.extras] +default = ["numpy (>=1.19)", "scipy (>=1.8)", "matplotlib (>=3.4)", "pandas (>=1.3)"] +developer = ["pre-commit (>=2.19)", "mypy (>=0.960)"] +doc = ["sphinx (>=5)", "pydata-sphinx-theme (>=0.9)", "sphinx-gallery (>=0.10)", "numpydoc (>=1.4)", "pillow (>=9.1)", "nb2plots (>=0.6)", "texext (>=0.6.6)"] +extra = ["lxml (>=4.6)", "pygraphviz (>=1.9)", "pydot (>=1.4.2)", "sympy (>=1.10)"] +test = ["pytest (>=7.1)", "pytest-cov (>=3.0)", "codecov (>=2.1)"] + +[[package]] +name = "numpy" +version = "1.23.2" +description = "NumPy is the fundamental package for array computing with Python." +category = "main" +optional = false +python-versions = ">=3.8" + +[[package]] +name = "numpydoc" +version = "1.4.0" +description = "Sphinx extension to support docstrings in Numpy format" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +Jinja2 = ">=2.10" +sphinx = ">=3.0" + +[package.extras] +testing = ["matplotlib", "pytest-cov", "pytest"] + +[[package]] +name = "packaging" +version = "21.3" +description = "Core utilities for Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" + +[[package]] +name = "pandas" +version = "1.4.3" +description = "Powerful data structures for data analysis, time series, and statistics" +category = "dev" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +numpy = [ + {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, + {version = ">=1.20.0", markers = "platform_machine == \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.19.2", markers = "platform_machine == \"aarch64\" and python_version < \"3.10\""}, + {version = ">=1.18.5", markers = "platform_machine != \"aarch64\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, +] +python-dateutil = ">=2.8.1" +pytz = ">=2020.1" + +[package.extras] +test = ["pytest-xdist (>=1.31)", "pytest (>=6.0)", "hypothesis (>=5.5.3)"] + +[[package]] +name = "pandocfilters" +version = "1.5.0" +description = "Utilities for writing pandoc filters in python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "parso" +version = "0.8.3" +description = "A Python Parser" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + +[[package]] +name = "pastel" +version = "0.2.1" +description = "Bring colors to your terminal." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pathspec" +version = "0.9.0" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[[package]] +name = "patsy" +version = "0.5.2" +description = "A Python package for describing statistical models and for building design matrices." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +numpy = ">=1.4" +six = "*" + +[package.extras] +test = ["scipy", "pytest-cov", "pytest"] + +[[package]] +name = "pbr" +version = "5.10.0" +description = "Python Build Reasonableness" +category = "dev" +optional = false +python-versions = ">=2.6" + +[[package]] +name = "pdocs" +version = "1.1.1" +description = "A simple program and library to auto generate API documentation for Python modules." +category = "dev" +optional = false +python-versions = ">=3.6,<4.0" + +[package.dependencies] +docstring_parser = ">=0.7.2,<0.8.0" +hug = ">=2.6,<3.0" +Mako = ">=1.1,<2.0" +Markdown = ">=3.0.0,<4.0.0" + +[[package]] +name = "pexpect" +version = "4.8.0" +description = "Pexpect allows easy control of interactive console applications." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pickleshare" +version = "0.7.5" +description = "Tiny 'shelve'-like database with concurrency support" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "pillow" +version = "9.2.0" +description = "Python Imaging Library (Fork)" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +tests = ["pytest-timeout", "pytest-cov", "pytest", "pyroma", "packaging", "olefile", "markdown2", "defusedxml", "coverage", "check-manifest"] +docs = ["sphinxext-opengraph", "sphinx-removed-in", "sphinx-issues (>=3.0.1)", "sphinx-copybutton", "sphinx (>=2.4)", "olefile", "furo"] + +[[package]] +name = "pkgutil-resolve-name" +version = "1.3.10" +description = "Resolve a name to an object." +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "platformdirs" +version = "2.5.2" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +test = ["pytest (>=6)", "pytest-mock (>=3.6)", "pytest-cov (>=2.7)", "appdirs (==1.4.4)"] +docs = ["sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)", "proselint (>=0.10.2)", "furo (>=2021.7.5b38)"] + +[[package]] +name = "pluggy" +version = "1.0.0" +description = "plugin and hook calling mechanisms for python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +testing = ["pytest-benchmark", "pytest"] +dev = ["tox", "pre-commit"] + +[[package]] +name = "poethepoet" +version = "0.16.0" +description = "A task runner that works well with poetry." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +pastel = ">=0.2.1,<0.3.0" +tomli = ">=1.2.2" + +[package.extras] +poetry_plugin = ["poetry (>=1.0,<2.0)"] + +[[package]] +name = "portray" +version = "1.7.0" +description = "Your Project with Great Documentation" +category = "dev" +optional = false +python-versions = ">=3.6,<4.0" + +[package.dependencies] +GitPython = ">=3.0,<4.0" +hug = ">=2.6,<3.0" +livereload = ">=2.6.3,<3.0.0" +mkdocs = ">=1.2,<1.3" +mkdocs-material = ">=7.0,<8.0" +pdocs = ">=1.1.1,<2.0.0" +pymdown-extensions = ">=7.0,<8.0" +toml = ">=0.10.0,<0.11.0" +yaspin = ">=0.15.0,<0.16.0" + +[[package]] +name = "prompt-toolkit" +version = "3.0.30" +description = "Library for building powerful interactive command lines in Python" +category = "dev" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "psutil" +version = "5.9.1" +description = "Cross-platform lib for process and system monitoring in Python." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +test = ["wmi", "pywin32", "enum34", "mock", "ipaddress"] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "pybtex" +version = "0.24.0" +description = "A BibTeX-compatible bibliography processor in Python" +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" + +[package.dependencies] +latexcodec = ">=1.0.4" +PyYAML = ">=3.01" +six = "*" + +[package.extras] +test = ["pytest"] + +[[package]] +name = "pybtex-docutils" +version = "1.0.2" +description = "A docutils backend for pybtex." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +docutils = ">=0.8" +pybtex = ">=0.16" + +[[package]] +name = "pycodestyle" +version = "2.9.1" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pydata-sphinx-theme" +version = "0.9.0" +description = "Bootstrap-based Sphinx theme from the PyData community" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +beautifulsoup4 = "*" +docutils = "!=0.17.0" +packaging = "*" +sphinx = ">=4.0.2" + +[package.extras] +dev = ["pydata-sphinx-theme", "nox", "pre-commit", "pyyaml"] +coverage = ["pydata-sphinx-theme", "codecov", "pytest-cov"] +test = ["pydata-sphinx-theme", "pytest"] +doc = ["sphinx-design", "xarray", "numpy", "plotly", "jupyter-sphinx", "sphinx-sitemap", "sphinxext-rediraffe", "pytest-regressions", "pytest", "pandas", "myst-parser", "numpydoc"] + +[[package]] +name = "pydocstyle" +version = "6.1.1" +description = "Python docstring style checker" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +snowballstemmer = "*" + +[package.extras] +toml = ["toml"] + +[[package]] +name = "pydot" +version = "1.4.2" +description = "Python interface to Graphviz's Dot" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +pyparsing = ">=2.1.4" + +[[package]] +name = "pyflakes" +version = "2.5.0" +description = "passive checker of Python programs" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "pygments" +version = "2.13.0" +description = "Pygments is a syntax highlighting package written in Python." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +plugins = ["importlib-metadata"] + +[[package]] +name = "pymdown-extensions" +version = "7.1" +description = "Extension pack for Python Markdown." +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" + +[package.dependencies] +Markdown = ">=3.2" + +[[package]] +name = "pyparsing" +version = "3.0.9" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +category = "dev" +optional = false +python-versions = ">=3.6.8" + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pyrsistent" +version = "0.18.1" +description = "Persistent/Functional/Immutable data structures" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "pytest" +version = "7.1.2" +description = "pytest: simple powerful testing with Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +py = ">=1.8.2" +tomli = ">=1.0.0" + +[package.extras] +testing = ["xmlschema", "requests", "pygments (>=2.7.2)", "nose", "mock", "hypothesis (>=3.56)", "argcomplete"] + +[[package]] +name = "pytest-cov" +version = "3.0.0" +description = "Pytest plugin for measuring coverage." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["virtualenv", "pytest-xdist", "six", "process-tests", "hunter", "fields"] + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2022.2.1" +description = "World timezone definitions, modern and historical" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "pywin32" +version = "304" +description = "Python for Window Extensions" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "pyyaml" +version = "6.0" +description = "YAML parser and emitter for Python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyyaml = "*" + +[[package]] +name = "pyzmq" +version = "23.2.1" +description = "Python bindings for 0MQ" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +cffi = {version = "*", markers = "implementation_name == \"pypy\""} +py = {version = "*", markers = "implementation_name == \"pypy\""} + +[[package]] +name = "requests" +version = "2.28.1" +description = "Python HTTP for Humans." +category = "dev" +optional = false +python-versions = ">=3.7, <4" + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<3" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] + +[[package]] +name = "scikit-learn" +version = "1.1.2" +description = "A set of python modules for machine learning and data mining" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +joblib = ">=1.0.0" +numpy = ">=1.17.3" +scipy = ">=1.3.2" +threadpoolctl = ">=2.0.0" + +[package.extras] +tests = ["numpydoc (>=1.2.0)", "pyamg (>=4.0.0)", "mypy (>=0.961)", "black (>=22.3.0)", "flake8 (>=3.8.2)", "pytest-cov (>=2.9.0)", "pytest (>=5.0.1)", "pandas (>=1.0.5)", "scikit-image (>=0.16.2)", "matplotlib (>=3.1.2)"] +examples = ["seaborn (>=0.9.0)", "pandas (>=1.0.5)", "scikit-image (>=0.16.2)", "matplotlib (>=3.1.2)"] +docs = ["sphinxext-opengraph (>=0.4.2)", "sphinx-prompt (>=1.3.0)", "Pillow (>=7.1.2)", "numpydoc (>=1.2.0)", "sphinx-gallery (>=0.7.0)", "sphinx (>=4.0.1)", "memory-profiler (>=0.57.0)", "seaborn (>=0.9.0)", "pandas (>=1.0.5)", "scikit-image (>=0.16.2)", "matplotlib (>=3.1.2)"] +benchmark = ["memory-profiler (>=0.57.0)", "pandas (>=1.0.5)", "matplotlib (>=3.1.2)"] + +[[package]] +name = "scipy" +version = "1.9.0" +description = "SciPy: Scientific Library for Python" +category = "main" +optional = false +python-versions = ">=3.8,<3.12" + +[package.dependencies] +numpy = ">=1.18.5,<1.25.0" + +[[package]] +name = "semversioner" +version = "1.1.0" +description = "Manage properly semver in your repository" +category = "dev" +optional = false +python-versions = ">=3.7.0" + +[package.dependencies] +click = ">=8.0.0" +jinja2 = ">=3.0.0" + +[[package]] +name = "setuptools-scm" +version = "6.4.2" +description = "the blessed package to manage your versions by scm tags" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +packaging = ">=20.0" +tomli = ">=1.0.0" + +[package.extras] +toml = ["setuptools (>=42)"] +test = ["virtualenv (>20)", "pytest (>=6.2)"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "smmap" +version = "5.0.0" +description = "A pure Python implementation of a sliding window memory map manager" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "soupsieve" +version = "2.3.2.post1" +description = "A modern CSS selector implementation for Beautiful Soup." +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "sphinx" +version = "5.1.1" +description = "Python documentation generator" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=1.3" +colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.14,<0.20" +imagesize = "*" +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} +Jinja2 = ">=2.3" +packaging = "*" +Pygments = ">=2.0" +requests = ">=2.5.0" +snowballstemmer = ">=1.1" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = ">=2.0.0" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = ">=1.1.5" + +[package.extras] +test = ["typed-ast", "cython", "html5lib", "pytest (>=4.6)"] +lint = ["types-requests", "types-typed-ast", "docutils-stubs", "sphinx-lint", "mypy (>=0.971)", "isort", "flake8-bugbear", "flake8-comprehensions", "flake8 (>=3.5.0)"] +docs = ["sphinxcontrib-websupport"] + +[[package]] +name = "sphinx-copybutton" +version = "0.5.0" +description = "Add a copy button to each of your code cells." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +sphinx = ">=1.8" + +[package.extras] +rtd = ["sphinx-book-theme", "myst-nb", "ipython", "sphinx"] +code_style = ["pre-commit (==2.12.1)"] + +[[package]] +name = "sphinx-gallery" +version = "0.11.0" +description = "A Sphinx extension that builds an HTML version of any Python script and puts it into an examples gallery." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +sphinx = ">=1.8.3" + +[[package]] +name = "sphinx-issues" +version = "3.0.1" +description = "A Sphinx extension for linking to your project's issue tracker" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +sphinx = "*" + +[package.extras] +tests = ["pytest (>=6.2.0)"] +lint = ["pre-commit (>=2.7,<3.0)", "flake8-bugbear (==20.11.1)", "flake8 (==3.9.2)"] +dev = ["tox", "pre-commit (>=2.7,<3.0)", "flake8-bugbear (==20.11.1)", "flake8 (==3.9.2)", "pytest (>=6.2.0)"] + +[[package]] +name = "sphinx-rtd-theme" +version = "1.0.0" +description = "Read the Docs theme for Sphinx" +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" + +[package.dependencies] +docutils = "<0.18" +sphinx = ">=1.6" + +[package.extras] +dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client"] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.2" +description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +test = ["pytest"] +lint = ["docutils-stubs", "mypy", "flake8"] + +[[package]] +name = "sphinxcontrib-bibtex" +version = "2.4.2" +description = "Sphinx extension for BibTeX style citations." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +docutils = ">=0.8" +pybtex = ">=0.24" +pybtex-docutils = ">=1.0.0" +Sphinx = ">=2.1" + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.2" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +test = ["pytest"] +lint = ["docutils-stubs", "mypy", "flake8"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.0.0" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +test = ["html5lib", "pytest"] +lint = ["docutils-stubs", "mypy", "flake8"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +test = ["mypy", "flake8", "pytest"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.3" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +test = ["pytest"] +lint = ["docutils-stubs", "mypy", "flake8"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.5" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +test = ["pytest"] +lint = ["docutils-stubs", "mypy", "flake8"] + +[[package]] +name = "statsmodels" +version = "0.13.2" +description = "Statistical computations and models for Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +numpy = ">=1.17" +packaging = ">=21.3" +pandas = ">=0.25" +patsy = ">=0.5.2" +scipy = ">=1.3" + +[package.extras] +build = ["cython (>=0.29.26)"] +develop = ["cython (>=0.29.26)"] +docs = ["sphinx", "nbconvert", "jupyter-client", "ipykernel", "matplotlib", "nbformat", "numpydoc", "pandas-datareader"] + +[[package]] +name = "stevedore" +version = "4.0.0" +description = "Manage dynamic plugins for Python applications" +category = "dev" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + +[[package]] +name = "sympy" +version = "1.10.1" +description = "Computer algebra system (CAS) in Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +mpmath = ">=0.19" + +[[package]] +name = "threadpoolctl" +version = "3.1.0" +description = "threadpoolctl" +category = "main" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "tinycss2" +version = "1.1.1" +description = "A tiny CSS parser" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +webencodings = ">=0.4" + +[package.extras] +test = ["coverage", "pytest-isort", "pytest-flake8", "pytest-cov", "pytest"] +doc = ["sphinx-rtd-theme", "sphinx"] + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "tornado" +version = "6.2" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +category = "dev" +optional = false +python-versions = ">= 3.7" + +[[package]] +name = "traitlets" +version = "5.3.0" +description = "" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +test = ["pre-commit", "pytest"] + +[[package]] +name = "typing-extensions" +version = "4.3.0" +description = "Backported and Experimental Type Hints for Python 3.7+" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "urllib3" +version = "1.26.11" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +secure = ["ipaddress", "certifi", "idna (>=2.0.0)", "cryptography (>=1.3.4)", "pyOpenSSL (>=0.14)"] +brotli = ["brotlipy (>=0.6.0)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] + +[[package]] +name = "watchdog" +version = "2.1.9" +description = "Filesystem events monitoring" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + +[[package]] +name = "wcwidth" +version = "0.2.5" +description = "Measures the displayed width of unicode strings in a terminal" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "yaspin" +version = "0.15.0" +description = "Yet Another Terminal Spinner" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "zipp" +version = "3.8.1" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +testing = ["pytest-mypy (>=0.9.1)", "pytest-black (>=0.3.7)", "func-timeout", "jaraco.itertools", "pytest-enabler (>=1.3)", "pytest-cov", "pytest-flake8", "pytest-checkdocs (>=2.4)", "pytest (>=6)"] +docs = ["jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "jaraco.packaging (>=9)", "sphinx"] + +[metadata] +lock-version = "1.1" +python-versions = ">=3.8,<3.11" +content-hash = "3600e2273eef36be216a9e82d272fd67cf8b52889f6969883628d7c65ab115ab" + +[metadata.files] +alabaster = [ + {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, + {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, +] +appnope = [ + {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, + {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, +] +atomicwrites = [ + {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, +] +attrs = [ + {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, + {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, +] +babel = [ + {file = "Babel-2.10.3-py3-none-any.whl", hash = "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb"}, + {file = "Babel-2.10.3.tar.gz", hash = "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51"}, +] +backcall = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, +] +bandit = [ + {file = "bandit-1.7.4-py3-none-any.whl", hash = "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a"}, + {file = "bandit-1.7.4.tar.gz", hash = "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2"}, +] +beartype = [ + {file = "beartype-0.10.4-py3-none-any.whl", hash = "sha256:1a65453bc25b39979bf5ad65fe5e73350551282956456d828fb5783468649e3e"}, + {file = "beartype-0.10.4.tar.gz", hash = "sha256:24ec69f6a7f4e6e97af403d08de270def3248518060327095d23b1c4df64bf2a"}, +] +beautifulsoup4 = [ + {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"}, + {file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"}, +] +black = [ + {file = "black-22.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69"}, + {file = "black-22.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807"}, + {file = "black-22.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6797f58943fceb1c461fb572edbe828d811e719c24e03375fd25170ada53825e"}, + {file = "black-22.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c85928b9d5f83b23cee7d0efcb310172412fbf7cb9d9ce963bd67fd141781def"}, + {file = "black-22.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:f6fe02afde060bbeef044af7996f335fbe90b039ccf3f5eb8f16df8b20f77666"}, + {file = "black-22.6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cfaf3895a9634e882bf9d2363fed5af8888802d670f58b279b0bece00e9a872d"}, + {file = "black-22.6.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94783f636bca89f11eb5d50437e8e17fbc6a929a628d82304c80fa9cd945f256"}, + {file = "black-22.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2ea29072e954a4d55a2ff58971b83365eba5d3d357352a07a7a4df0d95f51c78"}, + {file = "black-22.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e439798f819d49ba1c0bd9664427a05aab79bfba777a6db94fd4e56fae0cb849"}, + {file = "black-22.6.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:187d96c5e713f441a5829e77120c269b6514418f4513a390b0499b0987f2ff1c"}, + {file = "black-22.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:074458dc2f6e0d3dab7928d4417bb6957bb834434516f21514138437accdbe90"}, + {file = "black-22.6.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a218d7e5856f91d20f04e931b6f16d15356db1c846ee55f01bac297a705ca24f"}, + {file = "black-22.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:568ac3c465b1c8b34b61cd7a4e349e93f91abf0f9371eda1cf87194663ab684e"}, + {file = "black-22.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6c1734ab264b8f7929cef8ae5f900b85d579e6cbfde09d7387da8f04771b51c6"}, + {file = "black-22.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9a3ac16efe9ec7d7381ddebcc022119794872abce99475345c5a61aa18c45ad"}, + {file = "black-22.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:b9fd45787ba8aa3f5e0a0a98920c1012c884622c6c920dbe98dbd05bc7c70fbf"}, + {file = "black-22.6.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7ba9be198ecca5031cd78745780d65a3f75a34b2ff9be5837045dce55db83d1c"}, + {file = "black-22.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a3db5b6409b96d9bd543323b23ef32a1a2b06416d525d27e0f67e74f1446c8f2"}, + {file = "black-22.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:560558527e52ce8afba936fcce93a7411ab40c7d5fe8c2463e279e843c0328ee"}, + {file = "black-22.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b154e6bbde1e79ea3260c4b40c0b7b3109ffcdf7bc4ebf8859169a6af72cd70b"}, + {file = "black-22.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:4af5bc0e1f96be5ae9bd7aaec219c901a94d6caa2484c21983d043371c733fc4"}, + {file = "black-22.6.0-py3-none-any.whl", hash = "sha256:ac609cf8ef5e7115ddd07d85d988d074ed00e10fbc3445aee393e70164a2219c"}, + {file = "black-22.6.0.tar.gz", hash = "sha256:6c6d39e28aed379aec40da1c65434c77d75e65bb59a1e1c283de545fb4e7c6c9"}, +] +bleach = [ + {file = "bleach-5.0.1-py3-none-any.whl", hash = "sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a"}, + {file = "bleach-5.0.1.tar.gz", hash = "sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c"}, +] +certifi = [ + {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, + {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"}, +] +cffi = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] +charset-normalizer = [ + {file = "charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"}, + {file = "charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"}, +] +click = [ + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, +] +codespell = [ + {file = "codespell-2.1.0-py3-none-any.whl", hash = "sha256:b864c7d917316316ac24272ee992d7937c3519be4569209c5b60035ac5d569b5"}, + {file = "codespell-2.1.0.tar.gz", hash = "sha256:19d3fe5644fef3425777e66f225a8c82d39059dcfe9edb3349a8a2cf48383ee5"}, +] +colorama = [ + {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, + {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, +] +coverage = [ + {file = "coverage-6.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7b4da9bafad21ea45a714d3ea6f3e1679099e420c8741c74905b92ee9bfa7cc"}, + {file = "coverage-6.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fde17bc42e0716c94bf19d92e4c9f5a00c5feb401f5bc01101fdf2a8b7cacf60"}, + {file = "coverage-6.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdbb0d89923c80dbd435b9cf8bba0ff55585a3cdb28cbec65f376c041472c60d"}, + {file = "coverage-6.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:67f9346aeebea54e845d29b487eb38ec95f2ecf3558a3cffb26ee3f0dcc3e760"}, + {file = "coverage-6.4.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42c499c14efd858b98c4e03595bf914089b98400d30789511577aa44607a1b74"}, + {file = "coverage-6.4.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c35cca192ba700979d20ac43024a82b9b32a60da2f983bec6c0f5b84aead635c"}, + {file = "coverage-6.4.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9cc4f107009bca5a81caef2fca843dbec4215c05e917a59dec0c8db5cff1d2aa"}, + {file = "coverage-6.4.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f444627b3664b80d078c05fe6a850dd711beeb90d26731f11d492dcbadb6973"}, + {file = "coverage-6.4.4-cp310-cp310-win32.whl", hash = "sha256:66e6df3ac4659a435677d8cd40e8eb1ac7219345d27c41145991ee9bf4b806a0"}, + {file = "coverage-6.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:35ef1f8d8a7a275aa7410d2f2c60fa6443f4a64fae9be671ec0696a68525b875"}, + {file = "coverage-6.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c1328d0c2f194ffda30a45f11058c02410e679456276bfa0bbe0b0ee87225fac"}, + {file = "coverage-6.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61b993f3998ee384935ee423c3d40894e93277f12482f6e777642a0141f55782"}, + {file = "coverage-6.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d5dd4b8e9cd0deb60e6fcc7b0647cbc1da6c33b9e786f9c79721fd303994832f"}, + {file = "coverage-6.4.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7026f5afe0d1a933685d8f2169d7c2d2e624f6255fb584ca99ccca8c0e966fd7"}, + {file = "coverage-6.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9c7b9b498eb0c0d48b4c2abc0e10c2d78912203f972e0e63e3c9dc21f15abdaa"}, + {file = "coverage-6.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ee2b2fb6eb4ace35805f434e0f6409444e1466a47f620d1d5763a22600f0f892"}, + {file = "coverage-6.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ab066f5ab67059d1f1000b5e1aa8bbd75b6ed1fc0014559aea41a9eb66fc2ce0"}, + {file = "coverage-6.4.4-cp311-cp311-win32.whl", hash = "sha256:9d6e1f3185cbfd3d91ac77ea065d85d5215d3dfa45b191d14ddfcd952fa53796"}, + {file = "coverage-6.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e3d3c4cc38b2882f9a15bafd30aec079582b819bec1b8afdbde8f7797008108a"}, + {file = "coverage-6.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a095aa0a996ea08b10580908e88fbaf81ecf798e923bbe64fb98d1807db3d68a"}, + {file = "coverage-6.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef6f44409ab02e202b31a05dd6666797f9de2aa2b4b3534e9d450e42dea5e817"}, + {file = "coverage-6.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b7101938584d67e6f45f0015b60e24a95bf8dea19836b1709a80342e01b472f"}, + {file = "coverage-6.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14a32ec68d721c3d714d9b105c7acf8e0f8a4f4734c811eda75ff3718570b5e3"}, + {file = "coverage-6.4.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6a864733b22d3081749450466ac80698fe39c91cb6849b2ef8752fd7482011f3"}, + {file = "coverage-6.4.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:08002f9251f51afdcc5e3adf5d5d66bb490ae893d9e21359b085f0e03390a820"}, + {file = "coverage-6.4.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a3b2752de32c455f2521a51bd3ffb53c5b3ae92736afde67ce83477f5c1dd928"}, + {file = "coverage-6.4.4-cp37-cp37m-win32.whl", hash = "sha256:f855b39e4f75abd0dfbcf74a82e84ae3fc260d523fcb3532786bcbbcb158322c"}, + {file = "coverage-6.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ee6ae6bbcac0786807295e9687169fba80cb0617852b2fa118a99667e8e6815d"}, + {file = "coverage-6.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:564cd0f5b5470094df06fab676c6d77547abfdcb09b6c29c8a97c41ad03b103c"}, + {file = "coverage-6.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cbbb0e4cd8ddcd5ef47641cfac97d8473ab6b132dd9a46bacb18872828031685"}, + {file = "coverage-6.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6113e4df2fa73b80f77663445be6d567913fb3b82a86ceb64e44ae0e4b695de1"}, + {file = "coverage-6.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d032bfc562a52318ae05047a6eb801ff31ccee172dc0d2504614e911d8fa83e"}, + {file = "coverage-6.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e431e305a1f3126477abe9a184624a85308da8edf8486a863601d58419d26ffa"}, + {file = "coverage-6.4.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cf2afe83a53f77aec067033199797832617890e15bed42f4a1a93ea24794ae3e"}, + {file = "coverage-6.4.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:783bc7c4ee524039ca13b6d9b4186a67f8e63d91342c713e88c1865a38d0892a"}, + {file = "coverage-6.4.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ff934ced84054b9018665ca3967fc48e1ac99e811f6cc99ea65978e1d384454b"}, + {file = "coverage-6.4.4-cp38-cp38-win32.whl", hash = "sha256:e1fabd473566fce2cf18ea41171d92814e4ef1495e04471786cbc943b89a3781"}, + {file = "coverage-6.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:4179502f210ebed3ccfe2f78bf8e2d59e50b297b598b100d6c6e3341053066a2"}, + {file = "coverage-6.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:98c0b9e9b572893cdb0a00e66cf961a238f8d870d4e1dc8e679eb8bdc2eb1b86"}, + {file = "coverage-6.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc600f6ec19b273da1d85817eda339fb46ce9eef3e89f220055d8696e0a06908"}, + {file = "coverage-6.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a98d6bf6d4ca5c07a600c7b4e0c5350cd483c85c736c522b786be90ea5bac4f"}, + {file = "coverage-6.4.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01778769097dbd705a24e221f42be885c544bb91251747a8a3efdec6eb4788f2"}, + {file = "coverage-6.4.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfa0b97eb904255e2ab24166071b27408f1f69c8fbda58e9c0972804851e0558"}, + {file = "coverage-6.4.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fcbe3d9a53e013f8ab88734d7e517eb2cd06b7e689bedf22c0eb68db5e4a0a19"}, + {file = "coverage-6.4.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:15e38d853ee224e92ccc9a851457fb1e1f12d7a5df5ae44544ce7863691c7a0d"}, + {file = "coverage-6.4.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6913dddee2deff8ab2512639c5168c3e80b3ebb0f818fed22048ee46f735351a"}, + {file = "coverage-6.4.4-cp39-cp39-win32.whl", hash = "sha256:354df19fefd03b9a13132fa6643527ef7905712109d9c1c1903f2133d3a4e145"}, + {file = "coverage-6.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:1238b08f3576201ebf41f7c20bf59baa0d05da941b123c6656e42cdb668e9827"}, + {file = "coverage-6.4.4-pp36.pp37.pp38-none-any.whl", hash = "sha256:f67cf9f406cf0d2f08a3515ce2db5b82625a7257f88aad87904674def6ddaec1"}, + {file = "coverage-6.4.4.tar.gz", hash = "sha256:e16c45b726acb780e1e6f88b286d3c10b3914ab03438f32117c4aa52d7f30d58"}, +] +cycler = [ + {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, + {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, +] +decorator = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] +defusedxml = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] +docstring-parser = [ + {file = "docstring_parser-0.7.3.tar.gz", hash = "sha256:cde5fbf8b846433dfbde1e0f96b7f909336a634d5df34a38cb75050c7346734a"}, +] +docutils = [ + {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, + {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, +] +dowhy = [ + {file = "dowhy-0.8-py3-none-any.whl", hash = "sha256:5b5ff9b0f6c4740073bba83b9a7c209b557b23639f34436c5b2cce706ca8e986"}, + {file = "dowhy-0.8.tar.gz", hash = "sha256:0711489d44de3891bbf853019f60a36a50ff37e33f4173b8e85e93392f37c5f7"}, +] +entrypoints = [ + {file = "entrypoints-0.4-py3-none-any.whl", hash = "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f"}, + {file = "entrypoints-0.4.tar.gz", hash = "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4"}, +] +falcon = [ + {file = "falcon-2.0.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:733033ec80c896e30a43ab3e776856096836787197a44eb21022320a61311983"}, + {file = "falcon-2.0.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f93351459f110b4c1ee28556aef9a791832df6f910bea7b3f616109d534df06b"}, + {file = "falcon-2.0.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:e9efa0791b5d9f9dd9689015ea6bce0a27fcd5ecbcd30e6d940bffa4f7f03389"}, + {file = "falcon-2.0.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:59d1e8c993b9a37ea06df9d72cf907a46cc8063b30717cdac2f34d1658b6f936"}, + {file = "falcon-2.0.0-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:a5ebb22a04c9cc65081938ee7651b4e3b4d2a28522ea8ec04c7bdd2b3e9e8cd8"}, + {file = "falcon-2.0.0-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:95bf6ce986c1119aef12c9b348f4dee9c6dcc58391bdd0bc2b0bf353c2b15986"}, + {file = "falcon-2.0.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:aa184895d1ad4573fbfaaf803563d02f019ebdf4790e41cc568a330607eae439"}, + {file = "falcon-2.0.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:74cf1d18207381c665b9e6292d65100ce146d958707793174b03869dc6e614f4"}, + {file = "falcon-2.0.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24adcd2b29a8ffa9d552dc79638cd21736a3fb04eda7d102c6cebafdaadb88ad"}, + {file = "falcon-2.0.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:18157af2a4fc3feedf2b5dcc6196f448639acf01c68bc33d4d5a04c3ef87f494"}, + {file = "falcon-2.0.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e3782b7b92fefd46a6ad1fd8fe63fe6c6f1b7740a95ca56957f48d1aee34b357"}, + {file = "falcon-2.0.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:9712975adcf8c6e12876239085ad757b8fdeba223d46d23daef82b47658f83a9"}, + {file = "falcon-2.0.0-py2.py3-none-any.whl", hash = "sha256:54f2cb4b687035b2a03206dbfc538055cc48b59a953187b0458aa1b574d47b53"}, + {file = "falcon-2.0.0.tar.gz", hash = "sha256:eea593cf466b9c126ce667f6d30503624ef24459f118c75594a69353b6c3d5fc"}, +] +fastjsonschema = [ + {file = "fastjsonschema-2.16.1-py3-none-any.whl", hash = "sha256:2f7158c4de792555753d6c2277d6a2af2d406dfd97aeca21d17173561ede4fe6"}, + {file = "fastjsonschema-2.16.1.tar.gz", hash = "sha256:d6fa3ffbe719768d70e298b9fb847484e2bdfdb7241ed052b8d57a9294a8c334"}, +] +flake8 = [ + {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, + {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, +] +fonttools = [ + {file = "fonttools-4.35.0-py3-none-any.whl", hash = "sha256:0292e391c1b46f2308bda20ea2a2dd5253725e7e2d3a1928b631338eb318eb22"}, + {file = "fonttools-4.35.0.zip", hash = "sha256:1cfb335c0abdeb6231191dc4f9d7ce1173e2ac94b335c617e045b96f9c974aea"}, +] +ghp-import = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] +gitdb = [ + {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, + {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, +] +gitpython = [ + {file = "GitPython-3.1.27-py3-none-any.whl", hash = "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d"}, + {file = "GitPython-3.1.27.tar.gz", hash = "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704"}, +] +graphs = [] +graphviz = [ + {file = "graphviz-0.20.1-py3-none-any.whl", hash = "sha256:587c58a223b51611c0cf461132da386edd896a029524ca61a1462b880bf97977"}, + {file = "graphviz-0.20.1.zip", hash = "sha256:8c58f14adaa3b947daf26c19bc1e98c4e0702cdc31cf99153e6f06904d492bf8"}, +] +hug = [ + {file = "hug-2.6.1-py2.py3-none-any.whl", hash = "sha256:31c8fc284f81377278629a4b94cbb619ae9ce829cdc2da9564ccc66a121046b4"}, + {file = "hug-2.6.1.tar.gz", hash = "sha256:b0edace2acb618873779c9ce6ecf9165db54fef95c22262f5700fcdd9febaec9"}, +] +idna = [ + {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, + {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, +] +imagesize = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] +importlib-metadata = [ + {file = "importlib_metadata-4.12.0-py3-none-any.whl", hash = "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23"}, + {file = "importlib_metadata-4.12.0.tar.gz", hash = "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670"}, +] +importlib-resources = [ + {file = "importlib_resources-5.9.0-py3-none-any.whl", hash = "sha256:f78a8df21a79bcc30cfd400bdc38f314333de7c0fb619763f6b9dabab8268bb7"}, + {file = "importlib_resources-5.9.0.tar.gz", hash = "sha256:5481e97fb45af8dcf2f798952625591c58fe599d0735d86b10f54de086a61681"}, +] +iniconfig = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] +ipython = [ + {file = "ipython-7.34.0-py3-none-any.whl", hash = "sha256:c175d2440a1caff76116eb719d40538fbb316e214eda85c5515c303aacbfb23e"}, + {file = "ipython-7.34.0.tar.gz", hash = "sha256:af3bdb46aa292bce5615b1b2ebc76c2080c5f77f54bda2ec72461317273e7cd6"}, +] +isort = [ + {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, + {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, +] +jedi = [ + {file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"}, + {file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"}, +] +jinja2 = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] +joblib = [ + {file = "joblib-1.1.0-py2.py3-none-any.whl", hash = "sha256:f21f109b3c7ff9d95f8387f752d0d9c34a02aa2f7060c2135f465da0e5160ff6"}, + {file = "joblib-1.1.0.tar.gz", hash = "sha256:4158fcecd13733f8be669be0683b96ebdbbd38d23559f54dca7205aea1bf1e35"}, +] +jsonschema = [ + {file = "jsonschema-4.10.0-py3-none-any.whl", hash = "sha256:92128509e5b700bf0f1fd08a7d018252b16a1454465dfa6b899558eeae584241"}, + {file = "jsonschema-4.10.0.tar.gz", hash = "sha256:8ff7b44c6a99c6bfd55ca9ac45261c649cefd40aaba1124c29aaef1bcb378d84"}, +] +jupyter-client = [ + {file = "jupyter_client-7.3.4-py3-none-any.whl", hash = "sha256:17d74b0d0a7b24f1c8c527b24fcf4607c56bee542ffe8e3418e50b21e514b621"}, + {file = "jupyter_client-7.3.4.tar.gz", hash = "sha256:aa9a6c32054b290374f95f73bb0cae91455c58dfb84f65c8591912b8f65e6d56"}, +] +jupyter-core = [ + {file = "jupyter_core-4.11.1-py3-none-any.whl", hash = "sha256:715e22bb6cc7db3718fddfac1f69f1c7e899ca00e42bdfd4bf3705452b9fd84a"}, + {file = "jupyter_core-4.11.1.tar.gz", hash = "sha256:2e5f244d44894c4154d06aeae3419dd7f1b0ef4494dc5584929b398c61cfd314"}, +] +jupyterlab-pygments = [ + {file = "jupyterlab_pygments-0.2.2-py2.py3-none-any.whl", hash = "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f"}, + {file = "jupyterlab_pygments-0.2.2.tar.gz", hash = "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"}, +] +kiwisolver = [ + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"}, + {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"}, + {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"}, + {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"}, + {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"}, + {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"}, + {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"}, + {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"}, + {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"}, + {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"}, + {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"}, + {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, +] +latexcodec = [ + {file = "latexcodec-2.0.1-py2.py3-none-any.whl", hash = "sha256:c277a193638dc7683c4c30f6684e3db728a06efb0dc9cf346db8bd0aa6c5d271"}, + {file = "latexcodec-2.0.1.tar.gz", hash = "sha256:2aa2551c373261cefe2ad3a8953a6d6533e68238d180eb4bb91d7964adb3fe9a"}, +] +livereload = [ + {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, +] +lxml = [ + {file = "lxml-4.9.1-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:98cafc618614d72b02185ac583c6f7796202062c41d2eeecdf07820bad3295ed"}, + {file = "lxml-4.9.1-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c62e8dd9754b7debda0c5ba59d34509c4688f853588d75b53c3791983faa96fc"}, + {file = "lxml-4.9.1-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:21fb3d24ab430fc538a96e9fbb9b150029914805d551deeac7d7822f64631dfc"}, + {file = "lxml-4.9.1-cp27-cp27m-win32.whl", hash = "sha256:86e92728ef3fc842c50a5cb1d5ba2bc66db7da08a7af53fb3da79e202d1b2cd3"}, + {file = "lxml-4.9.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4cfbe42c686f33944e12f45a27d25a492cc0e43e1dc1da5d6a87cbcaf2e95627"}, + {file = "lxml-4.9.1-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dad7b164905d3e534883281c050180afcf1e230c3d4a54e8038aa5cfcf312b84"}, + {file = "lxml-4.9.1-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a614e4afed58c14254e67862456d212c4dcceebab2eaa44d627c2ca04bf86837"}, + {file = "lxml-4.9.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f9ced82717c7ec65a67667bb05865ffe38af0e835cdd78728f1209c8fffe0cad"}, + {file = "lxml-4.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:d9fc0bf3ff86c17348dfc5d322f627d78273eba545db865c3cd14b3f19e57fa5"}, + {file = "lxml-4.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e5f66bdf0976ec667fc4594d2812a00b07ed14d1b44259d19a41ae3fff99f2b8"}, + {file = "lxml-4.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fe17d10b97fdf58155f858606bddb4e037b805a60ae023c009f760d8361a4eb8"}, + {file = "lxml-4.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8caf4d16b31961e964c62194ea3e26a0e9561cdf72eecb1781458b67ec83423d"}, + {file = "lxml-4.9.1-cp310-cp310-win32.whl", hash = "sha256:4780677767dd52b99f0af1f123bc2c22873d30b474aa0e2fc3fe5e02217687c7"}, + {file = "lxml-4.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:b122a188cd292c4d2fcd78d04f863b789ef43aa129b233d7c9004de08693728b"}, + {file = "lxml-4.9.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:be9eb06489bc975c38706902cbc6888f39e946b81383abc2838d186f0e8b6a9d"}, + {file = "lxml-4.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:f1be258c4d3dc609e654a1dc59d37b17d7fef05df912c01fc2e15eb43a9735f3"}, + {file = "lxml-4.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:927a9dd016d6033bc12e0bf5dee1dde140235fc8d0d51099353c76081c03dc29"}, + {file = "lxml-4.9.1-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9232b09f5efee6a495a99ae6824881940d6447debe272ea400c02e3b68aad85d"}, + {file = "lxml-4.9.1-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:04da965dfebb5dac2619cb90fcf93efdb35b3c6994fea58a157a834f2f94b318"}, + {file = "lxml-4.9.1-cp35-cp35m-win32.whl", hash = "sha256:4d5bae0a37af799207140652a700f21a85946f107a199bcb06720b13a4f1f0b7"}, + {file = "lxml-4.9.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4878e667ebabe9b65e785ac8da4d48886fe81193a84bbe49f12acff8f7a383a4"}, + {file = "lxml-4.9.1-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:1355755b62c28950f9ce123c7a41460ed9743c699905cbe664a5bcc5c9c7c7fb"}, + {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:bcaa1c495ce623966d9fc8a187da80082334236a2a1c7e141763ffaf7a405067"}, + {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6eafc048ea3f1b3c136c71a86db393be36b5b3d9c87b1c25204e7d397cee9536"}, + {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:13c90064b224e10c14dcdf8086688d3f0e612db53766e7478d7754703295c7c8"}, + {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206a51077773c6c5d2ce1991327cda719063a47adc02bd703c56a662cdb6c58b"}, + {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e8f0c9d65da595cfe91713bc1222af9ecabd37971762cb830dea2fc3b3bb2acf"}, + {file = "lxml-4.9.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8f0a4d179c9a941eb80c3a63cdb495e539e064f8054230844dcf2fcb812b71d3"}, + {file = "lxml-4.9.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:830c88747dce8a3e7525defa68afd742b4580df6aa2fdd6f0855481e3994d391"}, + {file = "lxml-4.9.1-cp36-cp36m-win32.whl", hash = "sha256:1e1cf47774373777936c5aabad489fef7b1c087dcd1f426b621fda9dcc12994e"}, + {file = "lxml-4.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:5974895115737a74a00b321e339b9c3f45c20275d226398ae79ac008d908bff7"}, + {file = "lxml-4.9.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:1423631e3d51008871299525b541413c9b6c6423593e89f9c4cfbe8460afc0a2"}, + {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:2aaf6a0a6465d39b5ca69688fce82d20088c1838534982996ec46633dc7ad6cc"}, + {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:9f36de4cd0c262dd9927886cc2305aa3f2210db437aa4fed3fb4940b8bf4592c"}, + {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae06c1e4bc60ee076292e582a7512f304abdf6c70db59b56745cca1684f875a4"}, + {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:57e4d637258703d14171b54203fd6822fda218c6c2658a7d30816b10995f29f3"}, + {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6d279033bf614953c3fc4a0aa9ac33a21e8044ca72d4fa8b9273fe75359d5cca"}, + {file = "lxml-4.9.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a60f90bba4c37962cbf210f0188ecca87daafdf60271f4c6948606e4dabf8785"}, + {file = "lxml-4.9.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6ca2264f341dd81e41f3fffecec6e446aa2121e0b8d026fb5130e02de1402785"}, + {file = "lxml-4.9.1-cp37-cp37m-win32.whl", hash = "sha256:27e590352c76156f50f538dbcebd1925317a0f70540f7dc8c97d2931c595783a"}, + {file = "lxml-4.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:eea5d6443b093e1545ad0210e6cf27f920482bfcf5c77cdc8596aec73523bb7e"}, + {file = "lxml-4.9.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f05251bbc2145349b8d0b77c0d4e5f3b228418807b1ee27cefb11f69ed3d233b"}, + {file = "lxml-4.9.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:487c8e61d7acc50b8be82bda8c8d21d20e133c3cbf41bd8ad7eb1aaeb3f07c97"}, + {file = "lxml-4.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d1a92d8e90b286d491e5626af53afef2ba04da33e82e30744795c71880eaa21"}, + {file = "lxml-4.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:b570da8cd0012f4af9fa76a5635cd31f707473e65a5a335b186069d5c7121ff2"}, + {file = "lxml-4.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ef87fca280fb15342726bd5f980f6faf8b84a5287fcc2d4962ea8af88b35130"}, + {file = "lxml-4.9.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:93e414e3206779ef41e5ff2448067213febf260ba747fc65389a3ddaa3fb8715"}, + {file = "lxml-4.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6653071f4f9bac46fbc30f3c7838b0e9063ee335908c5d61fb7a4a86c8fd2036"}, + {file = "lxml-4.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:32a73c53783becdb7eaf75a2a1525ea8e49379fb7248c3eeefb9412123536387"}, + {file = "lxml-4.9.1-cp38-cp38-win32.whl", hash = "sha256:1a7c59c6ffd6ef5db362b798f350e24ab2cfa5700d53ac6681918f314a4d3b94"}, + {file = "lxml-4.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:1436cf0063bba7888e43f1ba8d58824f085410ea2025befe81150aceb123e345"}, + {file = "lxml-4.9.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:4beea0f31491bc086991b97517b9683e5cfb369205dac0148ef685ac12a20a67"}, + {file = "lxml-4.9.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:41fb58868b816c202e8881fd0f179a4644ce6e7cbbb248ef0283a34b73ec73bb"}, + {file = "lxml-4.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:bd34f6d1810d9354dc7e35158aa6cc33456be7706df4420819af6ed966e85448"}, + {file = "lxml-4.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:edffbe3c510d8f4bf8640e02ca019e48a9b72357318383ca60e3330c23aaffc7"}, + {file = "lxml-4.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6d949f53ad4fc7cf02c44d6678e7ff05ec5f5552b235b9e136bd52e9bf730b91"}, + {file = "lxml-4.9.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:079b68f197c796e42aa80b1f739f058dcee796dc725cc9a1be0cdb08fc45b000"}, + {file = "lxml-4.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9c3a88d20e4fe4a2a4a84bf439a5ac9c9aba400b85244c63a1ab7088f85d9d25"}, + {file = "lxml-4.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4e285b5f2bf321fc0857b491b5028c5f276ec0c873b985d58d7748ece1d770dd"}, + {file = "lxml-4.9.1-cp39-cp39-win32.whl", hash = "sha256:ef72013e20dd5ba86a8ae1aed7f56f31d3374189aa8b433e7b12ad182c0d2dfb"}, + {file = "lxml-4.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:10d2017f9150248563bb579cd0d07c61c58da85c922b780060dcc9a3aa9f432d"}, + {file = "lxml-4.9.1-pp37-pypy37_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0538747a9d7827ce3e16a8fdd201a99e661c7dee3c96c885d8ecba3c35d1032c"}, + {file = "lxml-4.9.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0645e934e940107e2fdbe7c5b6fb8ec6232444260752598bc4d09511bd056c0b"}, + {file = "lxml-4.9.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6daa662aba22ef3258934105be2dd9afa5bb45748f4f702a3b39a5bf53a1f4dc"}, + {file = "lxml-4.9.1-pp38-pypy38_pp73-macosx_10_15_x86_64.whl", hash = "sha256:603a464c2e67d8a546ddaa206d98e3246e5db05594b97db844c2f0a1af37cf5b"}, + {file = "lxml-4.9.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c4b2e0559b68455c085fb0f6178e9752c4be3bba104d6e881eb5573b399d1eb2"}, + {file = "lxml-4.9.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0f3f0059891d3254c7b5fb935330d6db38d6519ecd238ca4fce93c234b4a0f73"}, + {file = "lxml-4.9.1-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c852b1530083a620cb0de5f3cd6826f19862bafeaf77586f1aef326e49d95f0c"}, + {file = "lxml-4.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:287605bede6bd36e930577c5925fcea17cb30453d96a7b4c63c14a257118dbb9"}, + {file = "lxml-4.9.1.tar.gz", hash = "sha256:fe749b052bb7233fe5d072fcb549221a8cb1a16725c47c37e42b0b9cb3ff2c3f"}, +] +mako = [ + {file = "Mako-1.2.1-py3-none-any.whl", hash = "sha256:df3921c3081b013c8a2d5ff03c18375651684921ae83fd12e64800b7da923257"}, + {file = "Mako-1.2.1.tar.gz", hash = "sha256:f054a5ff4743492f1aa9ecc47172cb33b42b9d993cffcc146c9de17e717b0307"}, +] +markdown = [ + {file = "Markdown-3.4.1-py3-none-any.whl", hash = "sha256:08fb8465cffd03d10b9dd34a5c3fea908e20391a2a90b88d66362cb05beed186"}, + {file = "Markdown-3.4.1.tar.gz", hash = "sha256:3b809086bb6efad416156e00a0da66fe47618a5d6918dd688f53f40c8e4cfeff"}, +] +markupsafe = [ + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"}, + {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"}, + {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"}, + {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"}, + {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, + {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, +] +matplotlib = [ + {file = "matplotlib-3.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a206a1b762b39398efea838f528b3a6d60cdb26fe9d58b48265787e29cd1d693"}, + {file = "matplotlib-3.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cd45a6f3e93a780185f70f05cf2a383daed13c3489233faad83e81720f7ede24"}, + {file = "matplotlib-3.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d62880e1f60e5a30a2a8484432bcb3a5056969dc97258d7326ad465feb7ae069"}, + {file = "matplotlib-3.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ab29589cef03bc88acfa3a1490359000c18186fc30374d8aa77d33cc4a51a4a"}, + {file = "matplotlib-3.5.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2886cc009f40e2984c083687251821f305d811d38e3df8ded414265e4583f0c5"}, + {file = "matplotlib-3.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c995f7d9568f18b5db131ab124c64e51b6820a92d10246d4f2b3f3a66698a15b"}, + {file = "matplotlib-3.5.3-cp310-cp310-win32.whl", hash = "sha256:6bb93a0492d68461bd458eba878f52fdc8ac7bdb6c4acdfe43dba684787838c2"}, + {file = "matplotlib-3.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:2e6d184ebe291b9e8f7e78bbab7987d269c38ea3e062eace1fe7d898042ef804"}, + {file = "matplotlib-3.5.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6ea6aef5c4338e58d8d376068e28f80a24f54e69f09479d1c90b7172bad9f25b"}, + {file = "matplotlib-3.5.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:839d47b8ead7ad9669aaacdbc03f29656dc21f0d41a6fea2d473d856c39c8b1c"}, + {file = "matplotlib-3.5.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3b4fa56159dc3c7f9250df88f653f085068bcd32dcd38e479bba58909254af7f"}, + {file = "matplotlib-3.5.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:94ff86af56a3869a4ae26a9637a849effd7643858a1a04dd5ee50e9ab75069a7"}, + {file = "matplotlib-3.5.3-cp37-cp37m-win32.whl", hash = "sha256:35a8ad4dddebd51f94c5d24bec689ec0ec66173bf614374a1244c6241c1595e0"}, + {file = "matplotlib-3.5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:43e9d3fa077bf0cc95ded13d331d2156f9973dce17c6f0c8b49ccd57af94dbd9"}, + {file = "matplotlib-3.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:22227c976ad4dc8c5a5057540421f0d8708c6560744ad2ad638d48e2984e1dbc"}, + {file = "matplotlib-3.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bf618a825deb6205f015df6dfe6167a5d9b351203b03fab82043ae1d30f16511"}, + {file = "matplotlib-3.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9befa5954cdbc085e37d974ff6053da269474177921dd61facdad8023c4aeb51"}, + {file = "matplotlib-3.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3840c280ebc87a48488a46f760ea1c0c0c83fcf7abbe2e6baf99d033fd35fd8"}, + {file = "matplotlib-3.5.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dacddf5bfcec60e3f26ec5c0ae3d0274853a258b6c3fc5ef2f06a8eb23e042be"}, + {file = "matplotlib-3.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b428076a55fb1c084c76cb93e68006f27d247169f056412607c5c88828d08f88"}, + {file = "matplotlib-3.5.3-cp38-cp38-win32.whl", hash = "sha256:874df7505ba820e0400e7091199decf3ff1fde0583652120c50cd60d5820ca9a"}, + {file = "matplotlib-3.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:b28de401d928890187c589036857a270a032961411934bdac4cf12dde3d43094"}, + {file = "matplotlib-3.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3211ba82b9f1518d346f6309df137b50c3dc4421b4ed4815d1d7eadc617f45a1"}, + {file = "matplotlib-3.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6fe807e8a22620b4cd95cfbc795ba310dc80151d43b037257250faf0bfcd82bc"}, + {file = "matplotlib-3.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5c096363b206a3caf43773abebdbb5a23ea13faef71d701b21a9c27fdcef72f4"}, + {file = "matplotlib-3.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcdfcb0f976e1bac6721d7d457c17be23cf7501f977b6a38f9d38a3762841f7"}, + {file = "matplotlib-3.5.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1e64ac9be9da6bfff0a732e62116484b93b02a0b4d4b19934fb4f8e7ad26ad6a"}, + {file = "matplotlib-3.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:73dd93dc35c85dece610cca8358003bf0760d7986f70b223e2306b4ea6d1406b"}, + {file = "matplotlib-3.5.3-cp39-cp39-win32.whl", hash = "sha256:879c7e5fce4939c6aa04581dfe08d57eb6102a71f2e202e3314d5fbc072fd5a0"}, + {file = "matplotlib-3.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:ab8d26f07fe64f6f6736d635cce7bfd7f625320490ed5bfc347f2cdb4fae0e56"}, + {file = "matplotlib-3.5.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:99482b83ebf4eb6d5fc6813d7aacdefdd480f0d9c0b52dcf9f1cc3b2c4b3361a"}, + {file = "matplotlib-3.5.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f814504e459c68118bf2246a530ed953ebd18213dc20e3da524174d84ed010b2"}, + {file = "matplotlib-3.5.3-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57f1b4e69f438a99bb64d7f2c340db1b096b41ebaa515cf61ea72624279220ce"}, + {file = "matplotlib-3.5.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d2484b350bf3d32cae43f85dcfc89b3ed7bd2bcd781ef351f93eb6fb2cc483f9"}, + {file = "matplotlib-3.5.3.tar.gz", hash = "sha256:339cac48b80ddbc8bfd05daae0a3a73414651a8596904c2a881cfd1edb65f26c"}, +] +matplotlib-inline = [ + {file = "matplotlib-inline-0.1.5.tar.gz", hash = "sha256:a728d796a1a44265b310340ef04ba8aba4e89dcb76dfdd1272becab4923dd867"}, + {file = "matplotlib_inline-0.1.5-py3-none-any.whl", hash = "sha256:a68624e181d5b272bbfbaadb44412c9d3c9ebbcb703404502b9c937afc377ff5"}, +] +mccabe = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] +memory-profiler = [ + {file = "memory_profiler-0.60.0.tar.gz", hash = "sha256:6a12869511d6cebcb29b71ba26985675a58e16e06b3c523b49f67c5497a33d1c"}, +] +mergedeep = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] +mistune = [ + {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, + {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, +] +mkdocs = [ + {file = "mkdocs-1.2.4-py3-none-any.whl", hash = "sha256:f108e7ab5a7ed3e30826dbf82f37638f0d90d11161644616cc4f01a1e2ab3940"}, + {file = "mkdocs-1.2.4.tar.gz", hash = "sha256:8e7970a26183487fe2a1041940c6fd03aa0dbe5549e50c3e7194f565cb3c678a"}, +] +mkdocs-material = [ + {file = "mkdocs-material-7.3.0.tar.gz", hash = "sha256:07db0580fa96c3473aee99ec3fb4606a1a5a1e4f4467e64c0cd1ba8da5b6476e"}, + {file = "mkdocs_material-7.3.0-py2.py3-none-any.whl", hash = "sha256:b183c27dc0f44e631bbc32c51057f61a3e2ba8b3c1080e59f944167eeba9ff1d"}, +] +mkdocs-material-extensions = [ + {file = "mkdocs-material-extensions-1.0.3.tar.gz", hash = "sha256:bfd24dfdef7b41c312ede42648f9eb83476ea168ec163b613f9abd12bbfddba2"}, + {file = "mkdocs_material_extensions-1.0.3-py3-none-any.whl", hash = "sha256:a82b70e533ce060b2a5d9eb2bc2e1be201cf61f901f93704b4acf6e3d5983a44"}, +] +mpmath = [ + {file = "mpmath-1.2.1-py3-none-any.whl", hash = "sha256:604bc21bd22d2322a177c73bdb573994ef76e62edd595d17e00aff24b0667e5c"}, + {file = "mpmath-1.2.1.tar.gz", hash = "sha256:79ffb45cf9f4b101a807595bcb3e72e0396202e0b1d25d689134b48c4216a81a"}, +] +mypy = [ + {file = "mypy-0.971-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2899a3cbd394da157194f913a931edfd4be5f274a88041c9dc2d9cdcb1c315c"}, + {file = "mypy-0.971-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:98e02d56ebe93981c41211c05adb630d1d26c14195d04d95e49cd97dbc046dc5"}, + {file = "mypy-0.971-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:19830b7dba7d5356d3e26e2427a2ec91c994cd92d983142cbd025ebe81d69cf3"}, + {file = "mypy-0.971-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:02ef476f6dcb86e6f502ae39a16b93285fef97e7f1ff22932b657d1ef1f28655"}, + {file = "mypy-0.971-cp310-cp310-win_amd64.whl", hash = "sha256:25c5750ba5609a0c7550b73a33deb314ecfb559c350bb050b655505e8aed4103"}, + {file = "mypy-0.971-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d3348e7eb2eea2472db611486846742d5d52d1290576de99d59edeb7cd4a42ca"}, + {file = "mypy-0.971-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3fa7a477b9900be9b7dd4bab30a12759e5abe9586574ceb944bc29cddf8f0417"}, + {file = "mypy-0.971-cp36-cp36m-win_amd64.whl", hash = "sha256:2ad53cf9c3adc43cf3bea0a7d01a2f2e86db9fe7596dfecb4496a5dda63cbb09"}, + {file = "mypy-0.971-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:855048b6feb6dfe09d3353466004490b1872887150c5bb5caad7838b57328cc8"}, + {file = "mypy-0.971-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:23488a14a83bca6e54402c2e6435467a4138785df93ec85aeff64c6170077fb0"}, + {file = "mypy-0.971-cp37-cp37m-win_amd64.whl", hash = "sha256:4b21e5b1a70dfb972490035128f305c39bc4bc253f34e96a4adf9127cf943eb2"}, + {file = "mypy-0.971-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9796a2ba7b4b538649caa5cecd398d873f4022ed2333ffde58eaf604c4d2cb27"}, + {file = "mypy-0.971-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a361d92635ad4ada1b1b2d3630fc2f53f2127d51cf2def9db83cba32e47c856"}, + {file = "mypy-0.971-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b793b899f7cf563b1e7044a5c97361196b938e92f0a4343a5d27966a53d2ec71"}, + {file = "mypy-0.971-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d1ea5d12c8e2d266b5fb8c7a5d2e9c0219fedfeb493b7ed60cd350322384ac27"}, + {file = "mypy-0.971-cp38-cp38-win_amd64.whl", hash = "sha256:23c7ff43fff4b0df93a186581885c8512bc50fc4d4910e0f838e35d6bb6b5e58"}, + {file = "mypy-0.971-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1f7656b69974a6933e987ee8ffb951d836272d6c0f81d727f1d0e2696074d9e6"}, + {file = "mypy-0.971-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d2022bfadb7a5c2ef410d6a7c9763188afdb7f3533f22a0a32be10d571ee4bbe"}, + {file = "mypy-0.971-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef943c72a786b0f8d90fd76e9b39ce81fb7171172daf84bf43eaf937e9f220a9"}, + {file = "mypy-0.971-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d744f72eb39f69312bc6c2abf8ff6656973120e2eb3f3ec4f758ed47e414a4bf"}, + {file = "mypy-0.971-cp39-cp39-win_amd64.whl", hash = "sha256:77a514ea15d3007d33a9e2157b0ba9c267496acf12a7f2b9b9f8446337aac5b0"}, + {file = "mypy-0.971-py3-none-any.whl", hash = "sha256:0d054ef16b071149917085f51f89555a576e2618d5d9dd70bd6eea6410af3ac9"}, + {file = "mypy-0.971.tar.gz", hash = "sha256:40b0f21484238269ae6a57200c807d80debc6459d444c0489a102d7c6a75fa56"}, +] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] +nbclient = [ + {file = "nbclient-0.6.6-py3-none-any.whl", hash = "sha256:09bae4ea2df79fa6bc50aeb8278d8b79d2036792824337fa6eee834afae17312"}, + {file = "nbclient-0.6.6.tar.gz", hash = "sha256:0df76a7961d99a681b4796c74a1f2553b9f998851acc01896dce064ad19a9027"}, +] +nbconvert = [ + {file = "nbconvert-6.5.3-py3-none-any.whl", hash = "sha256:2564bb5125d862949f72475de0c0348392add7ea62cc950985347bfe7bbc2034"}, + {file = "nbconvert-6.5.3.tar.gz", hash = "sha256:10ed693c4cfd3c63583c87ca5c3a2f6ed874145103595f3824efcc8dfcb7522c"}, +] +nbformat = [ + {file = "nbformat-5.4.0-py3-none-any.whl", hash = "sha256:0d6072aaec95dddc39735c144ee8bbc6589c383fb462e4058abc855348152dad"}, + {file = "nbformat-5.4.0.tar.gz", hash = "sha256:44ba5ca6acb80c5d5a500f1e5b83ede8cbe364d5a495c4c8cf60aaf1ba656501"}, +] +nbsphinx = [ + {file = "nbsphinx-0.8.9-py3-none-any.whl", hash = "sha256:a7d743762249ee6bac3350a91eb3717a6e1c75f239f2c2a85491f9aca5a63be1"}, + {file = "nbsphinx-0.8.9.tar.gz", hash = "sha256:4ade86b2a41f8f41efd3ea99dae84c3368fe8ba3f837d50c8815ce9424c5994f"}, +] +nest-asyncio = [ + {file = "nest_asyncio-1.5.5-py3-none-any.whl", hash = "sha256:b98e3ec1b246135e4642eceffa5a6c23a3ab12c82ff816a92c612d68205813b2"}, + {file = "nest_asyncio-1.5.5.tar.gz", hash = "sha256:e442291cd942698be619823a17a86a5759eabe1f8613084790de189fe9e16d65"}, +] +networkx = [ + {file = "networkx-2.8.5-py3-none-any.whl", hash = "sha256:a762f4b385692d9c3a6f2912d058d76d29a827deaedf9e63ed14d397b8030687"}, + {file = "networkx-2.8.5.tar.gz", hash = "sha256:15a7b81a360791c458c55a417418ea136c13378cfdc06a2dcdc12bd2f9cf09c1"}, +] +numpy = [ + {file = "numpy-1.23.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e603ca1fb47b913942f3e660a15e55a9ebca906857edfea476ae5f0fe9b457d5"}, + {file = "numpy-1.23.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:633679a472934b1c20a12ed0c9a6c9eb167fbb4cb89031939bfd03dd9dbc62b8"}, + {file = "numpy-1.23.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17e5226674f6ea79e14e3b91bfbc153fdf3ac13f5cc54ee7bc8fdbe820a32da0"}, + {file = "numpy-1.23.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdc02c0235b261925102b1bd586579b7158e9d0d07ecb61148a1799214a4afd5"}, + {file = "numpy-1.23.2-cp310-cp310-win32.whl", hash = "sha256:df28dda02c9328e122661f399f7655cdcbcf22ea42daa3650a26bce08a187450"}, + {file = "numpy-1.23.2-cp310-cp310-win_amd64.whl", hash = "sha256:8ebf7e194b89bc66b78475bd3624d92980fca4e5bb86dda08d677d786fefc414"}, + {file = "numpy-1.23.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dc76bca1ca98f4b122114435f83f1fcf3c0fe48e4e6f660e07996abf2f53903c"}, + {file = "numpy-1.23.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ecfdd68d334a6b97472ed032b5b37a30d8217c097acfff15e8452c710e775524"}, + {file = "numpy-1.23.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5593f67e66dea4e237f5af998d31a43e447786b2154ba1ad833676c788f37cde"}, + {file = "numpy-1.23.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac987b35df8c2a2eab495ee206658117e9ce867acf3ccb376a19e83070e69418"}, + {file = "numpy-1.23.2-cp311-cp311-win32.whl", hash = "sha256:d98addfd3c8728ee8b2c49126f3c44c703e2b005d4a95998e2167af176a9e722"}, + {file = "numpy-1.23.2-cp311-cp311-win_amd64.whl", hash = "sha256:8ecb818231afe5f0f568c81f12ce50f2b828ff2b27487520d85eb44c71313b9e"}, + {file = "numpy-1.23.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:909c56c4d4341ec8315291a105169d8aae732cfb4c250fbc375a1efb7a844f8f"}, + {file = "numpy-1.23.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8247f01c4721479e482cc2f9f7d973f3f47810cbc8c65e38fd1bbd3141cc9842"}, + {file = "numpy-1.23.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8b97a8a87cadcd3f94659b4ef6ec056261fa1e1c3317f4193ac231d4df70215"}, + {file = "numpy-1.23.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd5b7ccae24e3d8501ee5563e82febc1771e73bd268eef82a1e8d2b4d556ae66"}, + {file = "numpy-1.23.2-cp38-cp38-win32.whl", hash = "sha256:9b83d48e464f393d46e8dd8171687394d39bc5abfe2978896b77dc2604e8635d"}, + {file = "numpy-1.23.2-cp38-cp38-win_amd64.whl", hash = "sha256:dec198619b7dbd6db58603cd256e092bcadef22a796f778bf87f8592b468441d"}, + {file = "numpy-1.23.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4f41f5bf20d9a521f8cab3a34557cd77b6f205ab2116651f12959714494268b0"}, + {file = "numpy-1.23.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:806cc25d5c43e240db709875e947076b2826f47c2c340a5a2f36da5bb10c58d6"}, + {file = "numpy-1.23.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f9d84a24889ebb4c641a9b99e54adb8cab50972f0166a3abc14c3b93163f074"}, + {file = "numpy-1.23.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c403c81bb8ffb1c993d0165a11493fd4bf1353d258f6997b3ee288b0a48fce77"}, + {file = "numpy-1.23.2-cp39-cp39-win32.whl", hash = "sha256:cf8c6aed12a935abf2e290860af8e77b26a042eb7f2582ff83dc7ed5f963340c"}, + {file = "numpy-1.23.2-cp39-cp39-win_amd64.whl", hash = "sha256:5e28cd64624dc2354a349152599e55308eb6ca95a13ce6a7d5679ebff2962913"}, + {file = "numpy-1.23.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:806970e69106556d1dd200e26647e9bee5e2b3f1814f9da104a943e8d548ca38"}, + {file = "numpy-1.23.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bd879d3ca4b6f39b7770829f73278b7c5e248c91d538aab1e506c628353e47f"}, + {file = "numpy-1.23.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:be6b350dfbc7f708d9d853663772a9310783ea58f6035eec649fb9c4371b5389"}, + {file = "numpy-1.23.2.tar.gz", hash = "sha256:b78d00e48261fbbd04aa0d7427cf78d18401ee0abd89c7559bbf422e5b1c7d01"}, +] +numpydoc = [ + {file = "numpydoc-1.4.0-py3-none-any.whl", hash = "sha256:fd26258868ebcc75c816fe68e1d41e3b55bd410941acfb969dee3eef6e5cf260"}, + {file = "numpydoc-1.4.0.tar.gz", hash = "sha256:9494daf1c7612f59905fa09e65c9b8a90bbacb3804d91f7a94e778831e6fcfa5"}, +] +packaging = [ + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, +] +pandas = [ + {file = "pandas-1.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d51674ed8e2551ef7773820ef5dab9322be0828629f2cbf8d1fc31a0c4fed640"}, + {file = "pandas-1.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:16ad23db55efcc93fa878f7837267973b61ea85d244fc5ff0ccbcfa5638706c5"}, + {file = "pandas-1.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:958a0588149190c22cdebbc0797e01972950c927a11a900fe6c2296f207b1d6f"}, + {file = "pandas-1.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e48fbb64165cda451c06a0f9e4c7a16b534fcabd32546d531b3c240ce2844112"}, + {file = "pandas-1.4.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f803320c9da732cc79210d7e8cc5c8019aad512589c910c66529eb1b1818230"}, + {file = "pandas-1.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:2893e923472a5e090c2d5e8db83e8f907364ec048572084c7d10ef93546be6d1"}, + {file = "pandas-1.4.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:24ea75f47bbd5574675dae21d51779a4948715416413b30614c1e8b480909f81"}, + {file = "pandas-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d5ebc990bd34f4ac3c73a2724c2dcc9ee7bf1ce6cf08e87bb25c6ad33507e318"}, + {file = "pandas-1.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d6c0106415ff1a10c326c49bc5dd9ea8b9897a6ca0c8688eb9c30ddec49535ef"}, + {file = "pandas-1.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78b00429161ccb0da252229bcda8010b445c4bf924e721265bec5a6e96a92e92"}, + {file = "pandas-1.4.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dfbf16b1ea4f4d0ee11084d9c026340514d1d30270eaa82a9f1297b6c8ecbf0"}, + {file = "pandas-1.4.3-cp38-cp38-win32.whl", hash = "sha256:48350592665ea3cbcd07efc8c12ff12d89be09cd47231c7925e3b8afada9d50d"}, + {file = "pandas-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:605d572126eb4ab2eadf5c59d5d69f0608df2bf7bcad5c5880a47a20a0699e3e"}, + {file = "pandas-1.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a3924692160e3d847e18702bb048dc38e0e13411d2b503fecb1adf0fcf950ba4"}, + {file = "pandas-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:07238a58d7cbc8a004855ade7b75bbd22c0db4b0ffccc721556bab8a095515f6"}, + {file = "pandas-1.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:755679c49460bd0d2f837ab99f0a26948e68fa0718b7e42afbabd074d945bf84"}, + {file = "pandas-1.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41fc406e374590a3d492325b889a2686b31e7a7780bec83db2512988550dadbf"}, + {file = "pandas-1.4.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d9382f72a4f0e93909feece6fef5500e838ce1c355a581b3d8f259839f2ea76"}, + {file = "pandas-1.4.3-cp39-cp39-win32.whl", hash = "sha256:0daf876dba6c622154b2e6741f29e87161f844e64f84801554f879d27ba63c0d"}, + {file = "pandas-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:721a3dd2f06ef942f83a819c0f3f6a648b2830b191a72bbe9451bcd49c3bd42e"}, + {file = "pandas-1.4.3.tar.gz", hash = "sha256:2ff7788468e75917574f080cd4681b27e1a7bf36461fe968b49a87b5a54d007c"}, +] +pandocfilters = [ + {file = "pandocfilters-1.5.0-py2.py3-none-any.whl", hash = "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f"}, + {file = "pandocfilters-1.5.0.tar.gz", hash = "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38"}, +] +parso = [ + {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, + {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, +] +pastel = [ + {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, + {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, +] +pathspec = [ + {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, + {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, +] +patsy = [ + {file = "patsy-0.5.2-py2.py3-none-any.whl", hash = "sha256:cc80955ae8c13a7e7c4051eda7b277c8f909f50bc7d73e124bc38e2ee3d95041"}, + {file = "patsy-0.5.2.tar.gz", hash = "sha256:5053de7804676aba62783dbb0f23a2b3d74e35e5bfa238b88b7cbf148a38b69d"}, +] +pbr = [ + {file = "pbr-5.10.0-py2.py3-none-any.whl", hash = "sha256:da3e18aac0a3c003e9eea1a81bd23e5a3a75d745670dcf736317b7d966887fdf"}, + {file = "pbr-5.10.0.tar.gz", hash = "sha256:cfcc4ff8e698256fc17ea3ff796478b050852585aa5bae79ecd05b2ab7b39b9a"}, +] +pdocs = [ + {file = "pdocs-1.1.1-py3-none-any.whl", hash = "sha256:4f5116cf5ce0fa9f13171cd74db224636d4d71370115eefce22d8945526fcfc0"}, + {file = "pdocs-1.1.1.tar.gz", hash = "sha256:f148034970220c9e05d2e04d8eb3fcec3575cf480af0966123ef9d6621b46e4f"}, +] +pexpect = [ + {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, + {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, +] +pickleshare = [ + {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, + {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, +] +pillow = [ + {file = "Pillow-9.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb"}, + {file = "Pillow-9.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544"}, + {file = "Pillow-9.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e"}, + {file = "Pillow-9.2.0-cp310-cp310-win32.whl", hash = "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28"}, + {file = "Pillow-9.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d"}, + {file = "Pillow-9.2.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:408673ed75594933714482501fe97e055a42996087eeca7e5d06e33218d05aa8"}, + {file = "Pillow-9.2.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:727dd1389bc5cb9827cbd1f9d40d2c2a1a0c9b32dd2261db522d22a604a6eec9"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a"}, + {file = "Pillow-9.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1"}, + {file = "Pillow-9.2.0-cp311-cp311-win32.whl", hash = "sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf"}, + {file = "Pillow-9.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c"}, + {file = "Pillow-9.2.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59"}, + {file = "Pillow-9.2.0-cp37-cp37m-win32.whl", hash = "sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc"}, + {file = "Pillow-9.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d"}, + {file = "Pillow-9.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14"}, + {file = "Pillow-9.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1"}, + {file = "Pillow-9.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76"}, + {file = "Pillow-9.2.0-cp38-cp38-win32.whl", hash = "sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f"}, + {file = "Pillow-9.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8"}, + {file = "Pillow-9.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc"}, + {file = "Pillow-9.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60"}, + {file = "Pillow-9.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4"}, + {file = "Pillow-9.2.0-cp39-cp39-win32.whl", hash = "sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885"}, + {file = "Pillow-9.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4"}, + {file = "Pillow-9.2.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3"}, + {file = "Pillow-9.2.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb"}, + {file = "Pillow-9.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be"}, + {file = "Pillow-9.2.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927"}, + {file = "Pillow-9.2.0.tar.gz", hash = "sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04"}, +] +pkgutil-resolve-name = [ + {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, + {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, +] +platformdirs = [ + {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, + {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, +] +pluggy = [ + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, +] +poethepoet = [ + {file = "poethepoet-0.16.0-py3-none-any.whl", hash = "sha256:87482ea8bba4e5db4abbd8e6360baee73b2ce0f3d5f5e99e81cdfa39d72d118f"}, + {file = "poethepoet-0.16.0.tar.gz", hash = "sha256:6455aec39f198be92dbf210a4416e1635119e967204c092b431c8b10024db1d1"}, +] +portray = [ + {file = "portray-1.7.0-py3-none-any.whl", hash = "sha256:fb4467105d948fabf0ec35b11af50f3c0c4f2aabaa31d5dcd657fadb1c6132e1"}, + {file = "portray-1.7.0.tar.gz", hash = "sha256:8f3c0a6a6841969329e4dd1e94e180220658c3ad0367a5bad81dd964a75ae1fe"}, +] +prompt-toolkit = [ + {file = "prompt_toolkit-3.0.30-py3-none-any.whl", hash = "sha256:d8916d3f62a7b67ab353a952ce4ced6a1d2587dfe9ef8ebc30dd7c386751f289"}, + {file = "prompt_toolkit-3.0.30.tar.gz", hash = "sha256:859b283c50bde45f5f97829f77a4674d1c1fcd88539364f1b28a37805cfd89c0"}, +] +psutil = [ + {file = "psutil-5.9.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:799759d809c31aab5fe4579e50addf84565e71c1dc9f1c31258f159ff70d3f87"}, + {file = "psutil-5.9.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9272167b5f5fbfe16945be3db475b3ce8d792386907e673a209da686176552af"}, + {file = "psutil-5.9.1-cp27-cp27m-win32.whl", hash = "sha256:0904727e0b0a038830b019551cf3204dd48ef5c6868adc776e06e93d615fc5fc"}, + {file = "psutil-5.9.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e7e10454cb1ab62cc6ce776e1c135a64045a11ec4c6d254d3f7689c16eb3efd2"}, + {file = "psutil-5.9.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:56960b9e8edcca1456f8c86a196f0c3d8e3e361320071c93378d41445ffd28b0"}, + {file = "psutil-5.9.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:44d1826150d49ffd62035785a9e2c56afcea66e55b43b8b630d7706276e87f22"}, + {file = "psutil-5.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7be9d7f5b0d206f0bbc3794b8e16fb7dbc53ec9e40bbe8787c6f2d38efcf6c9"}, + {file = "psutil-5.9.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd9246e4cdd5b554a2ddd97c157e292ac11ef3e7af25ac56b08b455c829dca8"}, + {file = "psutil-5.9.1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29a442e25fab1f4d05e2655bb1b8ab6887981838d22effa2396d584b740194de"}, + {file = "psutil-5.9.1-cp310-cp310-win32.whl", hash = "sha256:20b27771b077dcaa0de1de3ad52d22538fe101f9946d6dc7869e6f694f079329"}, + {file = "psutil-5.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:58678bbadae12e0db55186dc58f2888839228ac9f41cc7848853539b70490021"}, + {file = "psutil-5.9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3a76ad658641172d9c6e593de6fe248ddde825b5866464c3b2ee26c35da9d237"}, + {file = "psutil-5.9.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6a11e48cb93a5fa606306493f439b4aa7c56cb03fc9ace7f6bfa21aaf07c453"}, + {file = "psutil-5.9.1-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:068935df39055bf27a29824b95c801c7a5130f118b806eee663cad28dca97685"}, + {file = "psutil-5.9.1-cp36-cp36m-win32.whl", hash = "sha256:0f15a19a05f39a09327345bc279c1ba4a8cfb0172cc0d3c7f7d16c813b2e7d36"}, + {file = "psutil-5.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:db417f0865f90bdc07fa30e1aadc69b6f4cad7f86324b02aa842034efe8d8c4d"}, + {file = "psutil-5.9.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:91c7ff2a40c373d0cc9121d54bc5f31c4fa09c346528e6a08d1845bce5771ffc"}, + {file = "psutil-5.9.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fea896b54f3a4ae6f790ac1d017101252c93f6fe075d0e7571543510f11d2676"}, + {file = "psutil-5.9.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3054e923204b8e9c23a55b23b6df73a8089ae1d075cb0bf711d3e9da1724ded4"}, + {file = "psutil-5.9.1-cp37-cp37m-win32.whl", hash = "sha256:d2d006286fbcb60f0b391741f520862e9b69f4019b4d738a2a45728c7e952f1b"}, + {file = "psutil-5.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:b14ee12da9338f5e5b3a3ef7ca58b3cba30f5b66f7662159762932e6d0b8f680"}, + {file = "psutil-5.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:19f36c16012ba9cfc742604df189f2f28d2720e23ff7d1e81602dbe066be9fd1"}, + {file = "psutil-5.9.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:944c4b4b82dc4a1b805329c980f270f170fdc9945464223f2ec8e57563139cf4"}, + {file = "psutil-5.9.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b6750a73a9c4a4e689490ccb862d53c7b976a2a35c4e1846d049dcc3f17d83b"}, + {file = "psutil-5.9.1-cp38-cp38-win32.whl", hash = "sha256:a8746bfe4e8f659528c5c7e9af5090c5a7d252f32b2e859c584ef7d8efb1e689"}, + {file = "psutil-5.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:79c9108d9aa7fa6fba6e668b61b82facc067a6b81517cab34d07a84aa89f3df0"}, + {file = "psutil-5.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28976df6c64ddd6320d281128817f32c29b539a52bdae5e192537bc338a9ec81"}, + {file = "psutil-5.9.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b88f75005586131276634027f4219d06e0561292be8bd6bc7f2f00bdabd63c4e"}, + {file = "psutil-5.9.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:645bd4f7bb5b8633803e0b6746ff1628724668681a434482546887d22c7a9537"}, + {file = "psutil-5.9.1-cp39-cp39-win32.whl", hash = "sha256:32c52611756096ae91f5d1499fe6c53b86f4a9ada147ee42db4991ba1520e574"}, + {file = "psutil-5.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:f65f9a46d984b8cd9b3750c2bdb419b2996895b005aefa6cbaba9a143b1ce2c5"}, + {file = "psutil-5.9.1.tar.gz", hash = "sha256:57f1819b5d9e95cdfb0c881a8a5b7d542ed0b7c522d575706a80bedc848c8954"}, +] +ptyprocess = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] +py = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] +pybtex = [ + {file = "pybtex-0.24.0-py2.py3-none-any.whl", hash = "sha256:e1e0c8c69998452fea90e9179aa2a98ab103f3eed894405b7264e517cc2fcc0f"}, + {file = "pybtex-0.24.0.tar.gz", hash = "sha256:818eae35b61733e5c007c3fcd2cfb75ed1bc8b4173c1f70b56cc4c0802d34755"}, +] +pybtex-docutils = [ + {file = "pybtex-docutils-1.0.2.tar.gz", hash = "sha256:43aa353b6d498fd5ac30f0073a98e332d061d34fe619d3d50d1761f8fd4aa016"}, + {file = "pybtex_docutils-1.0.2-py3-none-any.whl", hash = "sha256:6f9e3c25a37bcaac8c4f69513272706ec6253bb708a93d8b4b173f43915ba239"}, +] +pycodestyle = [ + {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, + {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, +] +pycparser = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] +pydata-sphinx-theme = [ + {file = "pydata_sphinx_theme-0.9.0-py3-none-any.whl", hash = "sha256:b22b442a6d6437e5eaf0a1f057169ffcb31eaa9f10be7d5481a125e735c71c12"}, + {file = "pydata_sphinx_theme-0.9.0.tar.gz", hash = "sha256:03598a86915b596f4bf80bef79a4d33276a83e670bf360def699dbb9f99dc57a"}, +] +pydocstyle = [ + {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, + {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, +] +pydot = [ + {file = "pydot-1.4.2-py2.py3-none-any.whl", hash = "sha256:66c98190c65b8d2e2382a441b4c0edfdb4f4c025ef9cb9874de478fb0793a451"}, + {file = "pydot-1.4.2.tar.gz", hash = "sha256:248081a39bcb56784deb018977e428605c1c758f10897a339fce1dd728ff007d"}, +] +pyflakes = [ + {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, + {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, +] +pygments = [ + {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, + {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, +] +pymdown-extensions = [ + {file = "pymdown-extensions-7.1.tar.gz", hash = "sha256:5bf93d1ccd8281948cd7c559eb363e59b179b5373478e8a7195cf4b78e3c11b6"}, + {file = "pymdown_extensions-7.1-py2.py3-none-any.whl", hash = "sha256:8f415b21ee86d80bb2c3676f4478b274d0a8ccb13af672a4c86b9ffd22bd005c"}, +] +pyparsing = [ + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, +] +pyrsistent = [ + {file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"}, + {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"}, + {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e"}, + {file = "pyrsistent-0.18.1-cp310-cp310-win32.whl", hash = "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6"}, + {file = "pyrsistent-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8"}, + {file = "pyrsistent-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286"}, + {file = "pyrsistent-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"}, + {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec"}, + {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c"}, + {file = "pyrsistent-0.18.1-cp38-cp38-win32.whl", hash = "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca"}, + {file = "pyrsistent-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a"}, + {file = "pyrsistent-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5"}, + {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045"}, + {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c"}, + {file = "pyrsistent-0.18.1-cp39-cp39-win32.whl", hash = "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc"}, + {file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"}, + {file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"}, +] +pytest = [ + {file = "pytest-7.1.2-py3-none-any.whl", hash = "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c"}, + {file = "pytest-7.1.2.tar.gz", hash = "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45"}, +] +pytest-cov = [ + {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, + {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"}, +] +python-dateutil = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] +pytz = [ + {file = "pytz-2022.2.1-py2.py3-none-any.whl", hash = "sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197"}, + {file = "pytz-2022.2.1.tar.gz", hash = "sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5"}, +] +pywin32 = [ + {file = "pywin32-304-cp310-cp310-win32.whl", hash = "sha256:3c7bacf5e24298c86314f03fa20e16558a4e4138fc34615d7de4070c23e65af3"}, + {file = "pywin32-304-cp310-cp310-win_amd64.whl", hash = "sha256:4f32145913a2447736dad62495199a8e280a77a0ca662daa2332acf849f0be48"}, + {file = "pywin32-304-cp310-cp310-win_arm64.whl", hash = "sha256:d3ee45adff48e0551d1aa60d2ec066fec006083b791f5c3527c40cd8aefac71f"}, + {file = "pywin32-304-cp311-cp311-win32.whl", hash = "sha256:30c53d6ce44c12a316a06c153ea74152d3b1342610f1b99d40ba2795e5af0269"}, + {file = "pywin32-304-cp311-cp311-win_amd64.whl", hash = "sha256:7ffa0c0fa4ae4077e8b8aa73800540ef8c24530057768c3ac57c609f99a14fd4"}, + {file = "pywin32-304-cp311-cp311-win_arm64.whl", hash = "sha256:cbbe34dad39bdbaa2889a424d28752f1b4971939b14b1bb48cbf0182a3bcfc43"}, + {file = "pywin32-304-cp36-cp36m-win32.whl", hash = "sha256:be253e7b14bc601718f014d2832e4c18a5b023cbe72db826da63df76b77507a1"}, + {file = "pywin32-304-cp36-cp36m-win_amd64.whl", hash = "sha256:de9827c23321dcf43d2f288f09f3b6d772fee11e809015bdae9e69fe13213988"}, + {file = "pywin32-304-cp37-cp37m-win32.whl", hash = "sha256:f64c0377cf01b61bd5e76c25e1480ca8ab3b73f0c4add50538d332afdf8f69c5"}, + {file = "pywin32-304-cp37-cp37m-win_amd64.whl", hash = "sha256:bb2ea2aa81e96eee6a6b79d87e1d1648d3f8b87f9a64499e0b92b30d141e76df"}, + {file = "pywin32-304-cp38-cp38-win32.whl", hash = "sha256:94037b5259701988954931333aafd39cf897e990852115656b014ce72e052e96"}, + {file = "pywin32-304-cp38-cp38-win_amd64.whl", hash = "sha256:ead865a2e179b30fb717831f73cf4373401fc62fbc3455a0889a7ddac848f83e"}, + {file = "pywin32-304-cp39-cp39-win32.whl", hash = "sha256:25746d841201fd9f96b648a248f731c1dec851c9a08b8e33da8b56148e4c65cc"}, + {file = "pywin32-304-cp39-cp39-win_amd64.whl", hash = "sha256:d24a3382f013b21aa24a5cfbfad5a2cd9926610c0affde3e8ab5b3d7dbcf4ac9"}, +] +pyyaml = [ + {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, + {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, + {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, + {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, + {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, + {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, + {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, + {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, + {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, + {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, + {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, + {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, + {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, + {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, +] +pyyaml-env-tag = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] +pyzmq = [ + {file = "pyzmq-23.2.1-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:a3fd44b5046d247e7f0f1660bcafe7b5fb0db55d0934c05dd57dda9e1f823ce7"}, + {file = "pyzmq-23.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2141e6798d5981be04c08996d27962086a1aa3ea536fe9cf7e89817fd4523f86"}, + {file = "pyzmq-23.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a39ddb0431a68954bd318b923230fa5b649c9c62b0e8340388820c5f1b15bd2"}, + {file = "pyzmq-23.2.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e06747014a5ad1b28cebf5bc1ddcdaccfb44e9b441d35e6feb1286c8a72e54be"}, + {file = "pyzmq-23.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e0113d70b095339e99bb522fe7294f5ae6a7f3b2b8f52f659469a74b5cc7661"}, + {file = "pyzmq-23.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:71b32a1e827bdcbf73750e60370d3b07685816ff3d8695f450f0f8c3226503f8"}, + {file = "pyzmq-23.2.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:55568a020ad2cae9ae36da6058e7ca332a56df968f601cbdb7cf6efb2a77579a"}, + {file = "pyzmq-23.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8c02a0cd39dc01659b3d6cb70bb3a41aebd9885fd78239acdd8d9c91351c4568"}, + {file = "pyzmq-23.2.1-cp310-cp310-win32.whl", hash = "sha256:e1fe30bcd5aea5948c42685fad910cd285eacb2518ea4dc6c170d6b535bee95d"}, + {file = "pyzmq-23.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:650389bbfca73955b262b2230423d89992f38ec48033307ae80e700eaa2fbb63"}, + {file = "pyzmq-23.2.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:e753eee6d3b93c5354e8ba0a1d62956ee49355f0a36e00570823ef64e66183f5"}, + {file = "pyzmq-23.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f07016e3cf088dbfc6e7c5a7b3f540db5c23b0190d539e4fd3e2b5e6beffa4b5"}, + {file = "pyzmq-23.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4805af9614b0b41b7e57d17673459facf85604dac502a5a9244f6e8c9a4de658"}, + {file = "pyzmq-23.2.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:39dd252b683816935702825e5bf775df16090619ced9bb4ba68c2d0b6f0c9b18"}, + {file = "pyzmq-23.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:84678153432241bcdca2210cf4ff83560b200556867aea913ffbb960f5d5f340"}, + {file = "pyzmq-23.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:90d88f9d9a2ae6cfb1dc4ea2d1710cdf6456bc1b9a06dd1bb485c5d298f2517e"}, + {file = "pyzmq-23.2.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:794871988c34727c7f79bdfe2546e6854ae1fa2e1feb382784f23a9c6c63ecb3"}, + {file = "pyzmq-23.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c56b1a62a1fb87565343c57b6743fd5da6e138b8c6562361d7d9b5ce4acf399a"}, + {file = "pyzmq-23.2.1-cp311-cp311-win32.whl", hash = "sha256:c3ebf1668664d20c8f7d468955f18379b7d1f7bc8946b13243d050fa3888c7ff"}, + {file = "pyzmq-23.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:ec9803aca9491fd6f0d853d2a6147f19f8deaaa23b1b713d05c5d09e56ea7142"}, + {file = "pyzmq-23.2.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:385609812eafd9970c3752c51f2f6c4f224807e3e441bcfd8c8273877d00c8a8"}, + {file = "pyzmq-23.2.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b861db65f6b8906c8d6db51dde2448f266f0c66bf28db2c37aea50f58a849859"}, + {file = "pyzmq-23.2.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6b1e79bba24f6df1712e3188d5c32c480d8eda03e8ecff44dc8ecb0805fa62f3"}, + {file = "pyzmq-23.2.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:8dc66f109a245653b19df0f44a5af7a3f14cb8ad6c780ead506158a057bd36ce"}, + {file = "pyzmq-23.2.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:b815991c7d024bf461f358ad871f2be1135576274caed5749c4828859e40354e"}, + {file = "pyzmq-23.2.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:29b74774a0bfd3c4d98ac853f0bdca55bd9ec89d5b0def5486407cca54472ef8"}, + {file = "pyzmq-23.2.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:4bb798bef181648827019001f6be43e1c48b34b477763b37a8d27d8c06d197b8"}, + {file = "pyzmq-23.2.1-cp36-cp36m-win32.whl", hash = "sha256:565bd5ab81f6964fc4067ccf2e00877ad0fa917308975694bbb54378389215f8"}, + {file = "pyzmq-23.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:1f368a82b29f80071781b20663c0fc0c8f6b13273f9f5abe1526af939534f90f"}, + {file = "pyzmq-23.2.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c9cfaf530e6a7ff65f0afe275e99f983f68b54dfb23ea401f0bc297a632766b6"}, + {file = "pyzmq-23.2.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c558b50402fca1acc94329c5d8f12aa429738904a5cfb32b9ed3c61235221bb"}, + {file = "pyzmq-23.2.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:20bafc4095eab00f41a510579363a3f5e1f5c69d7ee10f1d88895c4df0259183"}, + {file = "pyzmq-23.2.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:f619fd38fc2641abfb53cca719c165182500600b82c695cc548a0f05f764be05"}, + {file = "pyzmq-23.2.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:044447ae4b2016a6b8697571fd633f799f860b19b76c4a2fd9b1140d52ee6745"}, + {file = "pyzmq-23.2.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:49d30ba7074f469e8167917abf9eb854c6503ae10153034a6d4df33618f1db5f"}, + {file = "pyzmq-23.2.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:48400b96788cdaca647021bf19a9cd668384f46e4d9c55cf045bdd17f65299c8"}, + {file = "pyzmq-23.2.1-cp37-cp37m-win32.whl", hash = "sha256:8a68f57b7a3f7b6b52ada79876be1efb97c8c0952423436e84d70cc139f16f0d"}, + {file = "pyzmq-23.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9e5bf6e7239fc9687239de7a283aa8b801ab85371116045b33ae20132a1325d6"}, + {file = "pyzmq-23.2.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ffc6b1623d0f9affb351db4ca61f432dca3628a5ee015f9bf2bfbe9c6836881c"}, + {file = "pyzmq-23.2.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4d6f110c56f7d5b4d64dde3a382ae61b6d48174e30742859d8e971b18b6c9e5c"}, + {file = "pyzmq-23.2.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9269fbfe3a4eb2009199120861c4571ef1655fdf6951c3e7f233567c94e8c602"}, + {file = "pyzmq-23.2.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12e62ff0d5223ec09b597ab6d73858b9f64a51221399f3cb08aa495e1dff7935"}, + {file = "pyzmq-23.2.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6fd5d0d50cbcf4bc376861529a907bed026a4cbe8c22a500ff8243231ef02433"}, + {file = "pyzmq-23.2.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9d0ab2936085c85a1fc6f9fd8f89d5235ae99b051e90ec5baa5e73ad44346e1f"}, + {file = "pyzmq-23.2.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:022cf5ea7bcaa8a06a03c2706e0ae66904b6138b2155577cd34c64bc7cc637ab"}, + {file = "pyzmq-23.2.1-cp38-cp38-win32.whl", hash = "sha256:28dbdb90b2f6b131f8f10e6081012e4e25234213433420e67e0c1162de537113"}, + {file = "pyzmq-23.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:10d1910ec381b851aeb024a042a13db178cb1edf125e76a4e9d2548ad103aadb"}, + {file = "pyzmq-23.2.1-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:99a5a77a10863493a1ee8dece02578c6b32025fb3afff91b40476bc489e81648"}, + {file = "pyzmq-23.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:aecd6ceaccc4b594e0092d6513ef3f1c0fa678dd89f86bb8ff1a47014b8fca35"}, + {file = "pyzmq-23.2.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:415ff62ac525d9add1e3550430a09b9928d2d24a20cc4ce809e67caac41219ab"}, + {file = "pyzmq-23.2.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:67975a9e1237b9ccc78f457bef17691bbdd2055a9d26e81ee914ba376846d0ce"}, + {file = "pyzmq-23.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38e106b64bad744fe469dc3dd864f2764d66399178c1bf39d45294cc7980f14f"}, + {file = "pyzmq-23.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8c842109d31a9281d678f668629241c405928afbebd913c48a5a8e7aee61f63d"}, + {file = "pyzmq-23.2.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fefdf9b685fda4141b95ebec975946076a5e0723ff70b037032b2085c5317684"}, + {file = "pyzmq-23.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:79a87831b47a9f6161ad23fa5e89d5469dc585abc49f90b9b07fea8905ae1234"}, + {file = "pyzmq-23.2.1-cp39-cp39-win32.whl", hash = "sha256:342ca3077f47ec2ee41b9825142b614e03e026347167cbc72a59b618c4f6106c"}, + {file = "pyzmq-23.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:5e05492be125dce279721d6b54fd1b956546ecc4bcdfcf8e7b4c413bc0874c10"}, + {file = "pyzmq-23.2.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:07ed8aaf7ffe150af873269690cc654ffeca7491f62aae0f3821baa181f8d5fe"}, + {file = "pyzmq-23.2.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ad28ddb40db8e450d7d4bf8a1d765d3f87b63b10e7e9a825a3c130c6371a8c03"}, + {file = "pyzmq-23.2.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2f67b63f53c6994d601404fd1a329e6d940ac3dd1d92946a93b2b9c70df67b9f"}, + {file = "pyzmq-23.2.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c890309296f53f9aa32ffcfc51d805705e1982bffd27c9692a8f1e1b8de279f4"}, + {file = "pyzmq-23.2.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:624fd38071a817644acdae075b92a23ea0bdd126a58148288e8284d23ec361ce"}, + {file = "pyzmq-23.2.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a114992a193577cb62233abf8cb2832970f9975805a64740e325d2f895e7f85a"}, + {file = "pyzmq-23.2.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c780acddd2934c6831ff832ecbf78a45a7b62d4eb216480f863854a8b7d54fa7"}, + {file = "pyzmq-23.2.1-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d904f6595acfaaf99a1a61881fea068500c40374d263e5e073aa4005e5f9c28a"}, + {file = "pyzmq-23.2.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:929d548b74c0f82f7f95b54e4a43f9e4ce2523cfb8a54d3f7141e45652304b2a"}, + {file = "pyzmq-23.2.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:f392cbea531b7142d1958c0d4a0c9c8d760dc451e5848d8dd3387804d3e3e62c"}, + {file = "pyzmq-23.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a0f09d85c45f58aa8e715b42f8b26beba68b3b63a8f7049113478aca26efbc30"}, + {file = "pyzmq-23.2.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23e708fbfdf4ee3107422b69ca65da1b9f056b431fc0888096a8c1d6cd908e8f"}, + {file = "pyzmq-23.2.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35e635343ff367f697d00fa1484262bb68e36bc74c9b80737eac5a1e04c4e1b1"}, + {file = "pyzmq-23.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efb9e38b2a590282704269585de7eb33bf43dc294cad092e1b172e23d4c217e5"}, + {file = "pyzmq-23.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:407f909c4e8fde62fbdad9ebd448319792258cc0550c2815567a4d9d8d9e6d18"}, + {file = "pyzmq-23.2.1.tar.gz", hash = "sha256:2b381aa867ece7d0a82f30a0c7f3d4387b7cf2e0697e33efaa5bed6c5784abcd"}, +] +requests = [ + {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, + {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, +] +scikit-learn = [ + {file = "scikit-learn-1.1.2.tar.gz", hash = "sha256:7c22d1305b16f08d57751a4ea36071e2215efb4c09cb79183faa4e8e82a3dbf8"}, + {file = "scikit_learn-1.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6c840f662b5d3377c4ccb8be1fc21bb52cb5d8b8790f8d6bf021739f84e543cf"}, + {file = "scikit_learn-1.1.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:2b8db962360c93554cab7bb3c096c4a24695da394dd4b3c3f13409f409b425bc"}, + {file = "scikit_learn-1.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e7d1fc817867a350133f937aaebcafbc06192517cbdf0cf7e5774ad4d1adb9f"}, + {file = "scikit_learn-1.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ec3ea40d467966821843210c02117d82b097b54276fdcfb50f4dfb5c60dbe39"}, + {file = "scikit_learn-1.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:bbef6ea1c012ff9f3e6f6e9ca006b8772d8383e177b898091e68fbd9b3f840f9"}, + {file = "scikit_learn-1.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a90ca42fe8242fd6ff56cda2fecc5fca586a88a24ab602d275d2d0dcc0b928fb"}, + {file = "scikit_learn-1.1.2-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a682ec0f82b6f30fb07486daed1c8001b6683cc66b51877644dfc532bece6a18"}, + {file = "scikit_learn-1.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c33e16e9a165af6012f5be530ccfbb672e2bc5f9b840238a05eb7f6694304e3f"}, + {file = "scikit_learn-1.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94c0146bad51daef919c402a3da8c1c6162619653e1c00c92baa168fda292f2"}, + {file = "scikit_learn-1.1.2-cp38-cp38-win32.whl", hash = "sha256:2f46c6e3ff1054a5ec701646dcfd61d43b8ecac4d416014daed8843cf4c33d4d"}, + {file = "scikit_learn-1.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:b1e706deca9b2ad87ae27dafd5ac4e8eff01b6db492ed5c12cef4735ec5f21ea"}, + {file = "scikit_learn-1.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:567417dbbe6a6278399c3e6daf1654414a5a1a4d818d28f251fa7fc28730a1bf"}, + {file = "scikit_learn-1.1.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:d6f232779023c3b060b80b5c82e5823723bc424dcac1d1a148aa2492c54d245d"}, + {file = "scikit_learn-1.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:589d46f28460469f444b898223b13d99db9463e1038dc581ba698111f612264b"}, + {file = "scikit_learn-1.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76800652fb6d6bf527bce36ecc2cc25738b28fe1a17bd294a218fff8e8bd6d50"}, + {file = "scikit_learn-1.1.2-cp39-cp39-win32.whl", hash = "sha256:1c8fecb7c9984d9ec2ea48898229f98aad681a0873e0935f2b7f724fbce4a047"}, + {file = "scikit_learn-1.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:407e9a1cb9e6ba458a539986a9bd25546a757088095b3aab91d465b79a760d37"}, +] +scipy = [ + {file = "scipy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0424d1bbbfa51d5ddaa16d067fd593863c9f2fb7c6840c32f8a08a8832f8e7a4"}, + {file = "scipy-1.9.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:8f2232c9d9119ec356240255a715a289b3a33be828c3e4abac11fd052ce15b1e"}, + {file = "scipy-1.9.0-cp310-cp310-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:e2004d2a3c397b26ca78e67c9d320153a1a9b71ae713ad33f4a3a3ab3d79cc65"}, + {file = "scipy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45f0d6c0d6e55582d3b8f5c58ad4ca4259a02affb190f89f06c8cc02e21bba81"}, + {file = "scipy-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79dd7876614fc2869bf5d311ef33962d2066ea888bc66c80fd4fa80f8772e5a9"}, + {file = "scipy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:10417935486b320d98536d732a58362e3d37e84add98c251e070c59a6bfe0863"}, + {file = "scipy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:adb6c438c6ef550e2bb83968e772b9690cb421f2c6073f9c2cb6af15ee538bc9"}, + {file = "scipy-1.9.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:8d541db2d441ef87afb60c4a2addb00c3af281633602a4967e733ef4b7050504"}, + {file = "scipy-1.9.0-cp38-cp38-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:97a1f1e51ea30782d7baa8d0c52f72c3f9f05cb609cf1b990664231c5102bccd"}, + {file = "scipy-1.9.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:16207622570af10f9e6a2cdc7da7a9660678852477adbcd056b6d1057a036fef"}, + {file = "scipy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb687d245b6963673c639f318eea7e875d1ba147a67925586abed3d6f39bb7d8"}, + {file = "scipy-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73b704c5eea9be811919cae4caacf3180dd9212d9aed08477c1d2ba14900a9de"}, + {file = "scipy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:12005d30894e4fe7b247f7233ba0801a341f887b62e2eb99034dd6f2a8a33ad6"}, + {file = "scipy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:fc58c3fcb8a724b703ffbc126afdca5a8353d4d5945d5c92db85617e165299e7"}, + {file = "scipy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:01c2015e132774feefe059d5354055fec6b751d7a7d70ad2cf5ce314e7426e2a"}, + {file = "scipy-1.9.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:f7c3c578ff556333f3890c2df6c056955d53537bb176698359088108af73a58f"}, + {file = "scipy-1.9.0-cp39-cp39-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:e2ac088ea4aa61115b96b47f5f3d94b3fa29554340b6629cd2bfe6b0521ee33b"}, + {file = "scipy-1.9.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5d1b9cf3771fd921f7213b4b886ab2606010343bb36259b544a816044576d69e"}, + {file = "scipy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3a326673ac5afa9ef5613a61626b9ec15c8f7222b4ecd1ce0fd8fcba7b83c59"}, + {file = "scipy-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693b3fe2e7736ce0dbc72b4d933798eb6ca8ce51b8b934e3f547cc06f48b2afb"}, + {file = "scipy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:7bad16b91918bf3288089a78a4157e04892ea6475fb7a1d9bcdf32c30c8a3dba"}, + {file = "scipy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:bd490f77f35800d5620f4d9af669e372d9a88db1f76ef219e1609cc4ecdd1a24"}, + {file = "scipy-1.9.0.tar.gz", hash = "sha256:c0dfd7d2429452e7e94904c6a3af63cbaa3cf51b348bd9d35b42db7e9ad42791"}, +] +semversioner = [ + {file = "semversioner-1.1.0-py2.py3-none-any.whl", hash = "sha256:3bc5a2f937bc5d61ae9e9ce2a5c1107dad96ca8e3b9b458091afb7d3eada63fe"}, + {file = "semversioner-1.1.0.tar.gz", hash = "sha256:1327e28f5e4f2511c86438f70cc33ff09ff76799b7fa3ee0b6e5da4a5f677dab"}, +] +setuptools-scm = [ + {file = "setuptools_scm-6.4.2-py3-none-any.whl", hash = "sha256:acea13255093849de7ccb11af9e1fb8bde7067783450cee9ef7a93139bddf6d4"}, + {file = "setuptools_scm-6.4.2.tar.gz", hash = "sha256:6833ac65c6ed9711a4d5d2266f8024cfa07c533a0e55f4c12f6eff280a5a9e30"}, +] +six = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] +smmap = [ + {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, + {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, +] +snowballstemmer = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] +soupsieve = [ + {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"}, + {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"}, +] +sphinx = [ + {file = "Sphinx-5.1.1-py3-none-any.whl", hash = "sha256:309a8da80cb6da9f4713438e5b55861877d5d7976b69d87e336733637ea12693"}, + {file = "Sphinx-5.1.1.tar.gz", hash = "sha256:ba3224a4e206e1fbdecf98a4fae4992ef9b24b85ebf7b584bb340156eaf08d89"}, +] +sphinx-copybutton = [ + {file = "sphinx-copybutton-0.5.0.tar.gz", hash = "sha256:a0c059daadd03c27ba750da534a92a63e7a36a7736dcf684f26ee346199787f6"}, + {file = "sphinx_copybutton-0.5.0-py3-none-any.whl", hash = "sha256:9684dec7434bd73f0eea58dda93f9bb879d24bff2d8b187b1f2ec08dfe7b5f48"}, +] +sphinx-gallery = [ + {file = "sphinx-gallery-0.11.0.tar.gz", hash = "sha256:930311a22d616fa51b9fd4541020652828277747cf9c6ab80beea31800ece08b"}, + {file = "sphinx_gallery-0.11.0-py3-none-any.whl", hash = "sha256:cb360f874d26754e2353e52661cbb5c916832f08b0b250f2605d2417f7f35a82"}, +] +sphinx-issues = [ + {file = "sphinx-issues-3.0.1.tar.gz", hash = "sha256:b7c1dc1f4808563c454d11c1112796f8c176cdecfee95f0fd2302ef98e21e3d6"}, + {file = "sphinx_issues-3.0.1-py3-none-any.whl", hash = "sha256:8b25dc0301159375468f563b3699af7a63720fd84caf81c1442036fcd418b20c"}, +] +sphinx-rtd-theme = [ + {file = "sphinx_rtd_theme-1.0.0-py2.py3-none-any.whl", hash = "sha256:4d35a56f4508cfee4c4fb604373ede6feae2a306731d533f409ef5c3496fdbd8"}, + {file = "sphinx_rtd_theme-1.0.0.tar.gz", hash = "sha256:eec6d497e4c2195fa0e8b2016b337532b8a699a68bcb22a512870e16925c6a5c"}, +] +sphinxcontrib-applehelp = [ + {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, + {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, +] +sphinxcontrib-bibtex = [ + {file = "sphinxcontrib-bibtex-2.4.2.tar.gz", hash = "sha256:65b023ee47f35f1f03ac4d71c824e67c624c7ecac1bb26e83623271a01f9da86"}, + {file = "sphinxcontrib_bibtex-2.4.2-py3-none-any.whl", hash = "sha256:608512afde6b732148cdc9123550bd560bf48e071d1fb7bb1bab4f4437ff04f4"}, +] +sphinxcontrib-devhelp = [ + {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, + {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, +] +sphinxcontrib-htmlhelp = [ + {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, + {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, +] +sphinxcontrib-jsmath = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] +sphinxcontrib-qthelp = [ + {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, + {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, +] +sphinxcontrib-serializinghtml = [ + {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, + {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, +] +statsmodels = [ + {file = "statsmodels-0.13.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3e7ca5b7e678c0bb7a24f5c735d58ac104a50eb61b17c484cce0e221a095560f"}, + {file = "statsmodels-0.13.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:066a75d5585378b2df972f81a90b9a3da5e567b7d4833300c1597438c1a35e29"}, + {file = "statsmodels-0.13.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f15f38dfc9c5c091662cb619e12322047368c67aef449c7554d9b324a15f7a94"}, + {file = "statsmodels-0.13.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c4ccc6b4744613367e8a233bd952c8a838db8f528f9fe033bda25aa13fc7d08"}, + {file = "statsmodels-0.13.2-cp310-cp310-win_amd64.whl", hash = "sha256:855b1cc2a91ab140b9bcf304b1731705805ce73223bf500b988804968554c0ed"}, + {file = "statsmodels-0.13.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b69c9af7606325095f7c40c581957bad9f28775653d41537c1ec4cd1b185ff5b"}, + {file = "statsmodels-0.13.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab31bac0f72b83bca1f217a12ec6f309a56485a50c4a705fbdd63112213d4da4"}, + {file = "statsmodels-0.13.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d680b910b57fc0aa87472662cdfe09aae0e21db4bdf19ccd6420fd4dffda892"}, + {file = "statsmodels-0.13.2-cp37-cp37m-win32.whl", hash = "sha256:9e9a3f661d372431850d55157d049e079493c97fc06f550d23d8c8c70805cc48"}, + {file = "statsmodels-0.13.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c9f6326870c095ef688f072cd476b932aff0906d60193eaa08e93ec23b29ca83"}, + {file = "statsmodels-0.13.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5bc050f25f1ba1221efef9ea01b751c60935ad787fcd4259f4ece986f2da9141"}, + {file = "statsmodels-0.13.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:426b1c8ea3918d3d27dbfa38f2bee36cabf41d32163e2cbb3adfb0178b24626a"}, + {file = "statsmodels-0.13.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45b80fac4a63308b1e93fa9dc27a8598930fd5dfd77c850ca077bb850254c6d7"}, + {file = "statsmodels-0.13.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78ee69ec0e0f79f627245c65f8a495b8581c2ea19084aac63941815feb15dcf3"}, + {file = "statsmodels-0.13.2-cp38-cp38-win32.whl", hash = "sha256:20483cc30e11aa072b30d307bb80470f86a23ae8fffa51439ca54509d7aa9b05"}, + {file = "statsmodels-0.13.2-cp38-cp38-win_amd64.whl", hash = "sha256:bf43051a92231ccb9de95e4b6d22d3b15e499ee5ee9bff0a20e6b6ad293e34cb"}, + {file = "statsmodels-0.13.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6bf0dfed5f5edb59b5922b295392cd276463b10a5e730f7e57ee4ff2d8e9a87e"}, + {file = "statsmodels-0.13.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a403b559c5586dab7ac0fc9e754c737b017c96cce0ddd66ff9094764cdaf293d"}, + {file = "statsmodels-0.13.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f23554dd025ea354ce072ba32bfaa840d2b856372e5734290e181d27a1f9e0c"}, + {file = "statsmodels-0.13.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:815f4df713e3eb6f40ae175c71f2a70d32f9219b5b4d23d4e0faab1171ba93ba"}, + {file = "statsmodels-0.13.2-cp39-cp39-win32.whl", hash = "sha256:461c82ab2265fa8457b96afc23ef3ca19f42eb070436e0241b57e58a38863901"}, + {file = "statsmodels-0.13.2-cp39-cp39-win_amd64.whl", hash = "sha256:39daab5a8a9332c8ea83d6464d065080c9ba65f236daf6a64aa18f64ef776fad"}, + {file = "statsmodels-0.13.2.tar.gz", hash = "sha256:77dc292c9939c036a476f1770f9d08976b05437daa229928da73231147cde7d4"}, +] +stevedore = [ + {file = "stevedore-4.0.0-py3-none-any.whl", hash = "sha256:87e4d27fe96d0d7e4fc24f0cbe3463baae4ec51e81d95fbe60d2474636e0c7d8"}, + {file = "stevedore-4.0.0.tar.gz", hash = "sha256:f82cc99a1ff552310d19c379827c2c64dd9f85a38bcd5559db2470161867b786"}, +] +sympy = [ + {file = "sympy-1.10.1-py3-none-any.whl", hash = "sha256:df75d738930f6fe9ebe7034e59d56698f29e85f443f743e51e47df0caccc2130"}, + {file = "sympy-1.10.1.tar.gz", hash = "sha256:5939eeffdf9e152172601463626c022a2c27e75cf6278de8d401d50c9d58787b"}, +] +threadpoolctl = [ + {file = "threadpoolctl-3.1.0-py3-none-any.whl", hash = "sha256:8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b"}, + {file = "threadpoolctl-3.1.0.tar.gz", hash = "sha256:a335baacfaa4400ae1f0d8e3a58d6674d2f8828e3716bb2802c44955ad391380"}, +] +tinycss2 = [ + {file = "tinycss2-1.1.1-py3-none-any.whl", hash = "sha256:fe794ceaadfe3cf3e686b22155d0da5780dd0e273471a51846d0a02bc204fec8"}, + {file = "tinycss2-1.1.1.tar.gz", hash = "sha256:b2e44dd8883c360c35dd0d1b5aad0b610e5156c2cb3b33434634e539ead9d8bf"}, +] +toml = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] +tomli = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] +tornado = [ + {file = "tornado-6.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:20f638fd8cc85f3cbae3c732326e96addff0a15e22d80f049e00121651e82e72"}, + {file = "tornado-6.2-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:87dcafae3e884462f90c90ecc200defe5e580a7fbbb4365eda7c7c1eb809ebc9"}, + {file = "tornado-6.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba09ef14ca9893954244fd872798b4ccb2367c165946ce2dd7376aebdde8e3ac"}, + {file = "tornado-6.2-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8150f721c101abdef99073bf66d3903e292d851bee51910839831caba341a75"}, + {file = "tornado-6.2-cp37-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3a2f5999215a3a06a4fc218026cd84c61b8b2b40ac5296a6db1f1451ef04c1e"}, + {file = "tornado-6.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5f8c52d219d4995388119af7ccaa0bcec289535747620116a58d830e7c25d8a8"}, + {file = "tornado-6.2-cp37-abi3-musllinux_1_1_i686.whl", hash = "sha256:6fdfabffd8dfcb6cf887428849d30cf19a3ea34c2c248461e1f7d718ad30b66b"}, + {file = "tornado-6.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:1d54d13ab8414ed44de07efecb97d4ef7c39f7438cf5e976ccd356bebb1b5fca"}, + {file = "tornado-6.2-cp37-abi3-win32.whl", hash = "sha256:5c87076709343557ef8032934ce5f637dbb552efa7b21d08e89ae7619ed0eb23"}, + {file = "tornado-6.2-cp37-abi3-win_amd64.whl", hash = "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b"}, + {file = "tornado-6.2.tar.gz", hash = "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13"}, +] +traitlets = [ + {file = "traitlets-5.3.0-py3-none-any.whl", hash = "sha256:65fa18961659635933100db8ca120ef6220555286949774b9cfc106f941d1c7a"}, + {file = "traitlets-5.3.0.tar.gz", hash = "sha256:0bb9f1f9f017aa8ec187d8b1b2a7a6626a2a1d877116baba52a129bfa124f8e2"}, +] +typing-extensions = [ + {file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"}, + {file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"}, +] +urllib3 = [ + {file = "urllib3-1.26.11-py2.py3-none-any.whl", hash = "sha256:c33ccba33c819596124764c23a97d25f32b28433ba0dedeb77d873a38722c9bc"}, + {file = "urllib3-1.26.11.tar.gz", hash = "sha256:ea6e8fb210b19d950fab93b60c9009226c63a28808bc8386e05301e25883ac0a"}, +] +watchdog = [ + {file = "watchdog-2.1.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a735a990a1095f75ca4f36ea2ef2752c99e6ee997c46b0de507ba40a09bf7330"}, + {file = "watchdog-2.1.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b17d302850c8d412784d9246cfe8d7e3af6bcd45f958abb2d08a6f8bedf695d"}, + {file = "watchdog-2.1.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee3e38a6cc050a8830089f79cbec8a3878ec2fe5160cdb2dc8ccb6def8552658"}, + {file = "watchdog-2.1.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64a27aed691408a6abd83394b38503e8176f69031ca25d64131d8d640a307591"}, + {file = "watchdog-2.1.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:195fc70c6e41237362ba720e9aaf394f8178bfc7fa68207f112d108edef1af33"}, + {file = "watchdog-2.1.9-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bfc4d351e6348d6ec51df007432e6fe80adb53fd41183716017026af03427846"}, + {file = "watchdog-2.1.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8250546a98388cbc00c3ee3cc5cf96799b5a595270dfcfa855491a64b86ef8c3"}, + {file = "watchdog-2.1.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:117ffc6ec261639a0209a3252546b12800670d4bf5f84fbd355957a0595fe654"}, + {file = "watchdog-2.1.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:97f9752208f5154e9e7b76acc8c4f5a58801b338de2af14e7e181ee3b28a5d39"}, + {file = "watchdog-2.1.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:247dcf1df956daa24828bfea5a138d0e7a7c98b1a47cf1fa5b0c3c16241fcbb7"}, + {file = "watchdog-2.1.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:226b3c6c468ce72051a4c15a4cc2ef317c32590d82ba0b330403cafd98a62cfd"}, + {file = "watchdog-2.1.9-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d9820fe47c20c13e3c9dd544d3706a2a26c02b2b43c993b62fcd8011bcc0adb3"}, + {file = "watchdog-2.1.9-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:70af927aa1613ded6a68089a9262a009fbdf819f46d09c1a908d4b36e1ba2b2d"}, + {file = "watchdog-2.1.9-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ed80a1628cee19f5cfc6bb74e173f1b4189eb532e705e2a13e3250312a62e0c9"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_aarch64.whl", hash = "sha256:9f05a5f7c12452f6a27203f76779ae3f46fa30f1dd833037ea8cbc2887c60213"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_armv7l.whl", hash = "sha256:255bb5758f7e89b1a13c05a5bceccec2219f8995a3a4c4d6968fe1de6a3b2892"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_i686.whl", hash = "sha256:d3dda00aca282b26194bdd0adec21e4c21e916956d972369359ba63ade616153"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_ppc64.whl", hash = "sha256:186f6c55abc5e03872ae14c2f294a153ec7292f807af99f57611acc8caa75306"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:083171652584e1b8829581f965b9b7723ca5f9a2cd7e20271edf264cfd7c1412"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_s390x.whl", hash = "sha256:b530ae007a5f5d50b7fbba96634c7ee21abec70dc3e7f0233339c81943848dc1"}, + {file = "watchdog-2.1.9-py3-none-manylinux2014_x86_64.whl", hash = "sha256:4f4e1c4aa54fb86316a62a87b3378c025e228178d55481d30d857c6c438897d6"}, + {file = "watchdog-2.1.9-py3-none-win32.whl", hash = "sha256:5952135968519e2447a01875a6f5fc8c03190b24d14ee52b0f4b1682259520b1"}, + {file = "watchdog-2.1.9-py3-none-win_amd64.whl", hash = "sha256:7a833211f49143c3d336729b0020ffd1274078e94b0ae42e22f596999f50279c"}, + {file = "watchdog-2.1.9-py3-none-win_ia64.whl", hash = "sha256:ad576a565260d8f99d97f2e64b0f97a48228317095908568a9d5c786c829d428"}, + {file = "watchdog-2.1.9.tar.gz", hash = "sha256:43ce20ebb36a51f21fa376f76d1d4692452b2527ccd601950d69ed36b9e21609"}, +] +wcwidth = [ + {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, + {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, +] +webencodings = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] +yaspin = [ + {file = "yaspin-0.15.0-py2.py3-none-any.whl", hash = "sha256:0ee4668936d0053de752c9a4963929faa3a832bd0ba823877d27855592dc80aa"}, + {file = "yaspin-0.15.0.tar.gz", hash = "sha256:5a938bdc7bab353fd8942d0619d56c6b5159a80997dc1c387a479b39e6dc9391"}, +] +zipp = [ + {file = "zipp-3.8.1-py3-none-any.whl", hash = "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009"}, + {file = "zipp-3.8.1.tar.gz", hash = "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2"}, +] diff --git a/pyproject.toml b/pyproject.toml index 4f3444de7..f9c6aec78 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,103 +1,120 @@ -[build-system] -requires = ['setuptools >= 61.0.0'] -build-backend = 'setuptools.build_meta' - -[project] -name = 'pywhy-graphs' -version = '0.1.dev0' -description = 'pywhy-graphs: Causal graphs from networkx.' -readme = 'README.md' -license = {file = 'LICENSE'} -requires-python = '~=3.8' -maintainers = [ - {name = 'Adam Li', email = 'adam.li@columbia.edu'}, -] -keywords = [ - 'machine-learning', - 'graphs', - 'networkx', - 'neuroscience', - 'causality', -] +[tool.poetry] +name = "pywhy-graphs" +# +# 0.0.0 is standard placeholder for poetry-dynamic-versioning +# any changes to this should not be checked in +# +version = "0.0.0" +description = "Causal Graphs for Python" +authors = ["PyWhy Community "] +license = "MIT" +documentation = "https://py-why.github.io/pywhy-graphs" +repository = "https://github.com/py-why/pywhy-graphs" +readme = "README.md" classifiers = [ - 'Operating System :: Microsoft :: Windows', - 'Operating System :: Unix', - 'Operating System :: MacOS', - 'Programming Language :: Python :: 3 :: Only', + 'Development Status :: 4 - Beta', + 'License :: OSI Approved :: MIT License', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', - 'Natural Language :: English', - 'License :: OSI Approved :: MIT License', - 'Intended Audience :: Science/Research', - 'Intended Audience :: Developers', - 'Topic :: Software Development', - 'Topic :: Scientific/Engineering', -] -dependencies = [ - 'numpy >= 1.16.0', - 'scipy >= 1.2.0', - 'networkx >= 2.8.3', - 'importlib-resources; python_version<"3.9"', ] +keywords = ['causality', 'graphs', 'causal-inference', 'graphical-model'] -[project.optional-dependencies] -build = [ - 'build', - 'twine', -] -doc = [ - 'memory_profiler', - 'numpydoc', - 'pydata-sphinx-theme', - 'PyQt5', - 'sphinx', - 'sphinxcontrib-bibtex', - 'sphinx-issues', - 'sphinx-copybutton', - 'sphinx-gallery', - 'sphinx_rtd_theme', - 'typing-extensions', - 'pydot', - 'pandas', - 'matplotlib', - 'graphviz', - 'dowhy', -] -style = [ - 'black', - 'codespell', - 'isort', - 'flake8', - 'mypy', - 'pydocstyle[toml]', -] -test = [ - 'pandas', - 'pytest', - 'pytest-cov', -] -all = [ - 'pywhy-graphs[build]', - 'pywhy-graphs[doc]', - 'pywhy-graphs[style]', - 'pywhy-graphs[test]', -] -full = [ - 'pywhy-graphs[all]', -] +[tool.poetry-dynamic-versioning] +enable = true +vcs = "git" -[project.urls] -documentation = 'https://py-why/pywhy-graphs' -source = 'https://github.com/py-why/pywhy-graphs' -tracker = 'https://github.com/py-why/pywhy-graphs/issues' +[tool.poetry-dynamic-versioning.substitution] +files = ["pywhy_graphs/__init__.py"] [tool.setuptools] include-package-data = false [tool.setuptools.packages.find] include = ['pywhy_graphs*'] -exclude = ['pywhy_graphs*tests'] +exclude = ['*tests'] + +[tool.poetry.dependencies] +python = ">=3.8,<3.11" +beartype = "^0.10.4" +numpy = "^1.23.0" +scipy = "^1.9.0" +networkx = "^2.8.3" +scikit-learn = "^1.1.0" +importlib-resources = { version = "*", python = "<3.9" } +graphs = { git = "https://github.com/py-why/graphs.git", branch = 'main' } + +[tool.poetry.dev-dependencies] +pytest = "^7.1.2" +pytest-cov = "^3.0.0" +mypy = "^0.971" +poethepoet = "^0.16.0" +black = "^22.6.0" +isort = "^5.10.1" +flake8 = "^5.0.4" +bandit = "^1.7.4" +portray = "^1.7.0" +semversioner = "^1.1.0" +pydocstyle = "^6.1.1" +codespell = "^2.1.0" +matplotlib = { version = "^3.5" } +memory_profiler = { version = "^0.60.0" } +numpydoc = { version = "^1.4" } +pydata-sphinx-theme = { version = "^0.9.0" } +sphinx = { version = "^5.1.1" } +sphinxcontrib-bibtex = { version = "^2.4.2" } +sphinx-issues = { version = "^3.0.1" } +sphinx-copybutton = { version = "^0.5.0" } +sphinx-gallery = { version = "^0.11.0" } +sphinx_rtd_theme = { version = "^1.0.0" } +pandas = { version = "^1.1" } +graphviz = { version = "^0.20.1" } +dowhy = { version = "^0.8" } +ipython = { version = "^7.4.0" } +nbsphinx = { version = "^0.8" } + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.poe.tasks] +_flake8 = 'flake8' +_bandit = 'bandit -r pywhy_graphs' +_black = 'black .' +_isort = 'isort .' +_black_check = 'black --check pywhy_graphs examples' +_isort_check = 'isort --check .' +_pydocstyle = 'pydocstyle .' +_codespell = 'codespell pywhy_graphs/ doc/ examples/ --ignore-words=.codespellignore --skip "**/_build/*"' +_changelog = 'semversioner changelog > CHANGELOG.md' +_apply_version = 'semversioner release' + +typecheck = 'mypy -p pywhy_graphs --config-file pyproject.toml' +unit_test = 'pytest ./pywhy_graphs --cov=pywhy_graphs --cov-report=xml --cov-config=pyproject.toml' +integration_test = 'pytest tests/integration_tests' +build_docs = 'make build-docs' + +[[tool.poe.tasks.lint]] +sequence = ['_flake8', '_bandit', '_codespell', '_pydocstyle'] +ignore_fail = 'return_non_zero' + +[[tool.poe.tasks.apply_format]] +sequence = ['_black', '_isort'] +ignore_fail = 'return_non_zero' + +[[tool.poe.tasks.check_format]] +sequence = ['_black_check', '_isort_check'] +ignore_fail = 'return_non_zero' + +# +# a standard verification sequence for use in pull requests +# +[[tool.poe.tasks.verify]] +sequence = ['apply_format', 'lint', 'typecheck', 'unit_test'] +ignore_fail = "return_non_zero" + +[[tool.poe.tasks.release]] +sequence = ['_changelog', '_apply_version'] [tool.black] line-length = 100 @@ -113,20 +130,20 @@ extend-exclude = ''' ) ''' +[tool.pylint] +max-line-length = 120 +disable = ["W0511"] + [tool.isort] profile = 'black' multi_line_output = 3 line_length = 100 py_version = 38 -extend_skip_glob = [ - 'setup.py', - 'docs/*', - 'examples/*', -] +extend_skip_glob = ['setup.py', 'docs/*', 'examples/*'] [tool.pydocstyle] convention = 'numpy' -ignore-decorators = '(copy_doc|property|.*setter|.*getter|pyqtSlot|Slot)' +ignore-decorators = '(copy_doc|property|.*setter|.*getter)' match = '^(?!setup|__init__|test_).*\.py' match-dir = '^pywhy_graphs.*' add_ignore = 'D100,D104,D107' @@ -143,17 +160,9 @@ filterwarnings = [] [tool.coverage.run] branch = true cover_pylib = false -source = [ - 'pywhy_graphs', -] -omit = [ - '**/__init__.py', - '**/tests/**', -] +source = ['pywhy_graphs'] +omit = ['**/__init__.py', '**/tests/**'] [tool.coverage.report] -exclude_lines = [ - 'pragma: no cover', - 'if __name__ == .__main__.:', -] +exclude_lines = ['pragma: no cover', 'if __name__ == .__main__.:'] precision = 2 From 2f7bc1e09f358c27e2c1e6f4129a0e4f2324d845 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 00:21:05 -0400 Subject: [PATCH 10/23] Try again --- .github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9b9a7efc3..50529f7fa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -151,12 +151,12 @@ jobs: run: pip install poetry-dynamic-versioning - name: Install packages via poetry run: | - python -m poetry install + poetry install - name: Install Networkx (main) if: "matrix.networkx == 'main'" run: | - python -m pip uninstall -yq networkx - python -m pip install --progress-bar off git+https://github.com/networkx/networkx + pip uninstall -yq networkx + pip install --progress-bar off git+https://github.com/networkx/networkx - name: Run pytest # headless via Xvfb on linux run: poetry run poe unit_test - name: Upload coverage stats to codecov From 9c459db028986182f027fbd600567f7b82a416d9 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 11:00:47 -0400 Subject: [PATCH 11/23] Try again Signed-off-by: Adam Li --- .circleci/config.yml | 398 +++++++++++++++++-------------------- .github/workflows/main.yml | 4 +- pywhy_graphs/__init__.py | 3 +- pywhy_graphs/_version.py | 9 + 4 files changed, 198 insertions(+), 216 deletions(-) create mode 100644 pywhy_graphs/_version.py diff --git a/.circleci/config.yml b/.circleci/config.yml index 326442b08..a96a7544f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,219 +1,196 @@ version: 2.1 +orbs: + python: circleci/python@2.0.3 + jobs: - build_doc: - docker: - - image: cimg/base:stable-20.04 - steps: - - restore_cache: - name: Restore .git - keys: - - source-cache-graphs - - checkout - - run: - name: Complete checkout - command: | - if ! git remote -v | grep upstream; then - git remote add upstream https://github.com/py-why/pywhy-graphs.git - fi - git remote set-url upstream https://github.com/py-why/pywhy-graphs.git - git fetch upstream - - save_cache: - name: Save .git - key: source-cache-graphs - paths: - - ".git" - - run: - name: Check-skip - command: | - set -e - export COMMIT_MESSAGE=$(git log --format=oneline -n 1); - if [[ -v CIRCLE_PULL_REQUEST ]] && ([[ "$COMMIT_MESSAGE" == *"[skip circle]"* ]] || [[ "$COMMIT_MESSAGE" == *"[circle skip]"* ]]); then - echo "Skip detected, exiting job ${CIRCLE_JOB} for PR ${CIRCLE_PULL_REQUEST}." - circleci-agent step halt; - fi - - run: - name: Merge with upstream - command: | - echo $(git log -1 --pretty=%B) | tee gitlog.txt - echo ${CI_PULL_REQUEST//*pull\//} | tee merge.txt - if [[ $(cat merge.txt) != "" ]]; then - echo "Merging $(cat merge.txt)"; - git pull --ff-only upstream "refs/pull/$(cat merge.txt)/merge"; - fi - - run: - name: Set BASH_ENV - command: | - set -e - sudo apt install -qq graphviz optipng python3.8-venv python3-venv libxft2 - python3.8 -m venv ~/python_env - echo "set -e" >> $BASH_ENV - echo "export OPENBLAS_NUM_THREADS=4" >> $BASH_ENV - echo "export XDG_RUNTIME_DIR=/tmp/runtime-circleci" >> $BASH_ENV - echo "export PATH=~/.local/bin/:$PATH" >> $BASH_ENV - echo "export DISPLAY=:99" >> $BASH_ENV - echo "source ~/python_env/bin/activate" >> $BASH_ENV - mkdir -p ~/.local/bin - ln -s ~/python_env/bin/python ~/.local/bin/python - echo "BASH_ENV:" - cat $BASH_ENV - - run: - name: Setup pandoc - command: sudo apt update && sudo apt install -y pandoc optipng - - restore_cache: - name: Restore pip cache - keys: - - pip-cache - - restore_cache: - name: Restore install-bin-cache - keys: - - user-install-bin-cache - - run: - name: Get Python running and install dependencies - command: | - python -m pip install --progress-bar off --upgrade pip setuptools wheel - python -m pip install --progress-bar off . - python -m pip install --progress-bar off .[doc,gui] - python -m pip install --progress-bar off git+https://github.com/py-why/pywhy-graphs - - save_cache: - name: Save pip cache - key: pip-cache - paths: - - ~/.cache/pip - - save_cache: - name: Save install-bin-cache - key: user-install-bin-cache - paths: - - ~/.local/lib/python3.8/site-packages - - ~/.local/bin - - run: - name: Check pip package versions - command: pip freeze - - run: - name: Check installation - command: | - LIBGL_DEBUG=verbose python -c "import matplotlib.pyplot as plt; plt.figure()" - python -c "import pywhy_graphs;" - python -c "import numpy; numpy.show_config()" - - run: - name: Build documentation - command: | - cd doc - make html - # Save the example test results - - store_test_results: - path: doc/_build/test-results - - store_artifacts: - path: doc/_build/test-results - destination: test-results - # Save the SG RST - - store_artifacts: - path: doc/auto_examples.zip - - store_artifacts: - path: doc/generated.zip - # Save the outputs - - store_artifacts: - path: doc/_build/html/ - destination: dev - - store_artifacts: - path: doc/_build/html_stable/ - destination: stable - - persist_to_workspace: - root: doc/_build - paths: - - html - - html_stable + build_doc: + executor: python/default + steps: + - restore_cache: + name: Restore .git + keys: + - source-cache-graphs + - checkout + - run: + name: Complete checkout + command: | + if ! git remote -v | grep upstream; then + git remote add upstream https://github.com/py-why/pywhy-graphs.git + fi + git remote set-url upstream https://github.com/py-why/pywhy-graphs.git + git fetch upstream + - save_cache: + name: Save .git + key: source-cache-graphs + paths: + - ".git" + - run: + name: Check-skip + command: | + set -e + export COMMIT_MESSAGE=$(git log --format=oneline -n 1); + if [[ -v CIRCLE_PULL_REQUEST ]] && ([[ "$COMMIT_MESSAGE" == *"[skip circle]"* ]] || [[ "$COMMIT_MESSAGE" == *"[circle skip]"* ]]); then + echo "Skip detected, exiting job ${CIRCLE_JOB} for PR ${CIRCLE_PULL_REQUEST}." + circleci-agent step halt; + fi + - run: + name: Merge with upstream + command: | + echo $(git log -1 --pretty=%B) | tee gitlog.txt + echo ${CI_PULL_REQUEST//*pull\//} | tee merge.txt + if [[ $(cat merge.txt) != "" ]]; then + echo "Merging $(cat merge.txt)"; + git pull --ff-only upstream "refs/pull/$(cat merge.txt)/merge"; + fi + - run: + name: Install the latest version of Poetry + command: | + curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | POETRY_UNINSTALL=1 python - + curl -sSL https://install.python-poetry.org | python3 - + - python/install-packages: + pkg-manager: poetry + cache-version: "v1" # change to clear cache + - run: + name: Check poetry package versions + command: | + poetry --version + poetry show + - run: + name: Set BASH_ENV + command: | + set -e + sudo apt update + sudo apt install -qq graphviz optipng libxft2 + echo "set -e" >> $BASH_ENV + echo "export OPENBLAS_NUM_THREADS=4" >> $BASH_ENV + echo "export XDG_RUNTIME_DIR=/tmp/runtime-circleci" >> $BASH_ENV + echo "export PATH=~/.local/bin/:$PATH" >> $BASH_ENV + echo "export DISPLAY=:99" >> $BASH_ENV + echo "BASH_ENV:" + cat $BASH_ENV + - run: + name: Setup pandoc + command: sudo apt update && sudo apt install -y pandoc optipng + - run: + name: Check installation + command: | + poetry run python -c "import dodiscover;" + poetry run python -c "import numpy; numpy.show_config()" + LIBGL_DEBUG=verbose poetry run python -c "import matplotlib.pyplot as plt; plt.figure()" + - run: + name: Build documentation + command: | + cd doc + poetry run make html + # Save the example test results + - store_test_results: + path: doc/_build/test-results + - store_artifacts: + path: doc/_build/test-results + destination: test-results + # Save the SG RST + - store_artifacts: + path: doc/auto_examples.zip + - store_artifacts: + path: doc/generated.zip + # Save the outputs + - store_artifacts: + path: doc/_build/html/ + destination: dev + - store_artifacts: + path: doc/_build/html_stable/ + destination: stable + - persist_to_workspace: + root: doc/_build + paths: + - html + - html_stable - linkcheck: - parameters: - scheduled: - type: string - default: "false" - docker: - - image: cimg/python:3.9.2 - steps: - - restore_cache: - keys: - - source-cache-graphs - - checkout - - run: - name: Check-skip - command: | - export COMMIT_MESSAGE=$(git log --format=oneline -n 1); - if [[ "$COMMIT_MESSAGE" != *"[circle linkcheck]"* ]] && [ "<< parameters.scheduled >>" != "true" ]; then - echo "Skip detected, exiting job ${CIRCLE_JOB}." - circleci-agent step halt; - fi - - run: - name: Set BASH_ENV - command: | - set -e - echo "set -e" >> $BASH_ENV - echo "export PATH=~/.local/bin/:$PATH" >> $BASH_ENV - - restore_cache: - keys: - - pip-cache - - run: - name: Get Python running - command: | - python -m pip install --progress-bar off --upgrade pip setuptools wheel - python -m pip install --progress-bar off .[doc] - - run: - name: make linkcheck - command: | - make -C doc linkcheck - - run: - name: make linkcheck-grep - when: always - command: | - make -C doc linkcheck-grep - - store_artifacts: - path: doc/_build/linkcheck - destination: linkcheck + linkcheck: + parameters: + scheduled: + type: string + default: "false" + executor: python/default + steps: + - restore_cache: + keys: + - source-cache-graphs + - checkout + - run: + name: Check-skip + command: | + export COMMIT_MESSAGE=$(git log --format=oneline -n 1); + if [[ "$COMMIT_MESSAGE" != *"[circle linkcheck]"* ]] && [ "<< parameters.scheduled >>" != "true" ]; then + echo "Skip detected, exiting job ${CIRCLE_JOB}." + circleci-agent step halt; + fi + - run: + name: Set BASH_ENV + command: | + set -e + echo "set -e" >> $BASH_ENV + echo "export PATH=~/.local/bin/:$PATH" >> $BASH_ENV + - python/install-packages: + pkg-manager: poetry + cache-version: "v1" # change to clear cache + - run: + name: make linkcheck + command: | + make -C doc linkcheck + - run: + name: make linkcheck-grep + when: always + command: | + make -C doc linkcheck-grep + - store_artifacts: + path: doc/_build/linkcheck + destination: linkcheck - deploy: - docker: - - image: cimg/node:lts - steps: - - checkout + deploy: + docker: + - image: cimg/node:lts + steps: + - checkout - - attach_workspace: - at: doc/_build - - run: - name: Set BASH_ENV - command: | - set -e - echo "set -e" >> $BASH_ENV - # Don't try to deploy if nothing is there or not on the right branch - - run: - name: Check docs - command: | - if [ ! -f doc/_build/html/index.html ] && [ ! -f doc/_build/html_stable/index.html ]; then - echo "No files found to upload (build: ${CIRCLE_BRANCH})."; - circleci-agent step halt; - fi; - - run: - name: Install and configure dependencies - # do not update gh-pages above 3.0.0 - # see: https://github.com/tschaub/gh-pages/issues/354 - command: | - npm install gh-pages@3.0 - git config --global user.email "circle@pywhy.com" - git config --global user.name "Circle Ci" - - add_ssh_keys: - fingerprints: - - "b5:1e:a1:6d:8d:48:f2:8f:dd:bd:2d:66:a9:30:fe:b9" - - run: - # push built doc into the `dev` directory on the `gh-pages` branch - name: Deploy doc to gh-pages branch - command: | - if [ "${CIRCLE_BRANCH}" == "main" ]; then - echo "Deploying dev doc for ${CIRCLE_BRANCH}."; - node_modules/gh-pages/bin/gh-pages.js --dotfiles --message "doc updates [skip ci]" --dist doc/_build/html --dest ./dev - else - echo "Deploying stable doc for ${CIRCLE_BRANCH}."; - node_modules/gh-pages/bin/gh-pages.js --dotfiles --message "doc updates [skip ci]" --dist doc/_build/html_stable --dest ./stable - fi; + - attach_workspace: + at: doc/_build + - run: + name: Set BASH_ENV + command: | + set -e + echo "set -e" >> $BASH_ENV + # Don't try to deploy if nothing is there or not on the right branch + - run: + name: Check docs + command: | + if [ ! -f doc/_build/html/index.html ] && [ ! -f doc/_build/html_stable/index.html ]; then + echo "No files found to upload (build: ${CIRCLE_BRANCH})."; + circleci-agent step halt; + fi; + - run: + name: Install and configure dependencies + # do not update gh-pages above 3.0.0 + # see: https://github.com/tschaub/gh-pages/issues/354 + command: | + npm install gh-pages@3.0 + git config --global user.email "circle@pywhy.com" + git config --global user.name "Circle Ci" + - add_ssh_keys: + fingerprints: + - "b5:1e:a1:6d:8d:48:f2:8f:dd:bd:2d:66:a9:30:fe:b9" + - run: + # push built doc into the `dev` directory on the `gh-pages` branch + name: Deploy doc to gh-pages branch + command: | + if [ "${CIRCLE_BRANCH}" == "main" ]; then + echo "Deploying dev doc for ${CIRCLE_BRANCH}."; + node_modules/gh-pages/bin/gh-pages.js --dotfiles --message "doc updates [skip ci]" --dist doc/_build/html --dest ./dev + else + echo "Deploying stable doc for ${CIRCLE_BRANCH}."; + node_modules/gh-pages/bin/gh-pages.js --dotfiles --message "doc updates [skip ci]" --dist doc/_build/html_stable --dest ./stable + fi; workflows: default: @@ -229,7 +206,6 @@ workflows: branches: only: - main - - maint/0.2 main: jobs: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 50529f7fa..4a85d3619 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -55,7 +55,7 @@ jobs: skip: './.git,./build,./.mypy_cache,./.pytest_cache' ignore_words_file: ./.codespellignore - name: Run pydocstyle - run: pydocstyle . + run: poetry run pydocstyle . - name: Run mypy uses: jpetrucciani/mypy-check@master with: @@ -136,8 +136,6 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - with: - path: main # clone repository in a sub-directory - name: Setup Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: diff --git a/pywhy_graphs/__init__.py b/pywhy_graphs/__init__.py index 08c37bfc1..cdede0f92 100644 --- a/pywhy_graphs/__init__.py +++ b/pywhy_graphs/__init__.py @@ -1,5 +1,4 @@ +from ._version import __version__ # noqa: F401 from .admg import ADMG from .cpdag import CPDAG from .scm import StructuralCausalModel - -__version__ = "v0.1dev0" diff --git a/pywhy_graphs/_version.py b/pywhy_graphs/_version.py new file mode 100644 index 000000000..369e226dc --- /dev/null +++ b/pywhy_graphs/_version.py @@ -0,0 +1,9 @@ +"""Version number.""" + +# TODO: Remove try/except once the minimum python requirement is bumped to 3.8 +try: + from importlib.metadata import version # type: ignore +except ImportError: + from importlib_metadata import version # type: ignore + +__version__ = version(__package__) From d01c99e55b4d2a19ecc6a0321fde584c01bef543 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 11:39:38 -0400 Subject: [PATCH 12/23] Try again Signed-off-by: Adam Li --- .github/workflows/main.yml | 2 +- poetry.lock | 6 +++--- pyproject.toml | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4a85d3619..a5e404c95 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -91,7 +91,7 @@ jobs: run: pip install poetry-dynamic-versioning - name: Install from source run: | - python -m pip install -e . + poetry install - name: Test package install run: python -c "import pywhy_graphs; print(pywhy_graphs.__version__)" - name: Remove package install diff --git a/poetry.lock b/poetry.lock index 61f6367f0..e913101ae 100644 --- a/poetry.lock +++ b/poetry.lock @@ -570,7 +570,7 @@ python-versions = ">=3.6" [[package]] name = "jsonschema" -version = "4.10.0" +version = "4.10.1" description = "An implementation of JSON Schema validation for Python" category = "dev" optional = false @@ -2241,8 +2241,8 @@ joblib = [ {file = "joblib-1.1.0.tar.gz", hash = "sha256:4158fcecd13733f8be669be0683b96ebdbbd38d23559f54dca7205aea1bf1e35"}, ] jsonschema = [ - {file = "jsonschema-4.10.0-py3-none-any.whl", hash = "sha256:92128509e5b700bf0f1fd08a7d018252b16a1454465dfa6b899558eeae584241"}, - {file = "jsonschema-4.10.0.tar.gz", hash = "sha256:8ff7b44c6a99c6bfd55ca9ac45261c649cefd40aaba1124c29aaef1bcb378d84"}, + {file = "jsonschema-4.10.1-py3-none-any.whl", hash = "sha256:dfe58bed8554d619a719aa535e9c4269b26170aa9c520a1768745eb791825b19"}, + {file = "jsonschema-4.10.1.tar.gz", hash = "sha256:79a1eec5a40a79bc9e0791e110d1474bf453aff02df4e8a33ad1f4046e549e9d"}, ] jupyter-client = [ {file = "jupyter_client-7.3.4-py3-none-any.whl", hash = "sha256:17d74b0d0a7b24f1c8c527b24fcf4607c56bee542ffe8e3418e50b21e514b621"}, diff --git a/pyproject.toml b/pyproject.toml index f9c6aec78..c50e8a219 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,10 @@ scikit-learn = "^1.1.0" importlib-resources = { version = "*", python = "<3.9" } graphs = { git = "https://github.com/py-why/graphs.git", branch = 'main' } +# TODO: the below needs to be refactored into separate dev-dependencies +# https://github.com/python-poetry/poetry/is +# it is inefficient to have to install every single dependencey to run +# e.g. a style check. [tool.poetry.dev-dependencies] pytest = "^7.1.2" pytest-cov = "^3.0.0" From 30d726444a78af95759f61e91552fb9c39392646 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 13:36:02 -0400 Subject: [PATCH 13/23] Try again Signed-off-by: Adam Li --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c50e8a219..c5a3a0aa2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.poetry] -name = "pywhy-graphs" +name = "pywhy_graphs" # # 0.0.0 is standard placeholder for poetry-dynamic-versioning # any changes to this should not be checked in From 9a9cb02ce837b870e0f500d7b9698f58dcb0493f Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 13:36:26 -0400 Subject: [PATCH 14/23] Try again Signed-off-by: Adam Li --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a96a7544f..3445e3210 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -75,7 +75,7 @@ jobs: - run: name: Check installation command: | - poetry run python -c "import dodiscover;" + poetry run python -c "import pywhy_graphs;" poetry run python -c "import numpy; numpy.show_config()" LIBGL_DEBUG=verbose poetry run python -c "import matplotlib.pyplot as plt; plt.figure()" - run: From af9ba4d9b3a5aca6500a4ebf0e46ed33d199080e Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 14:02:53 -0400 Subject: [PATCH 15/23] Try again Signed-off-by: Adam Li --- .circleci/config.yml | 26 +++++++++++++------------- .github/workflows/main.yml | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3445e3210..3890eaf91 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -81,28 +81,28 @@ jobs: - run: name: Build documentation command: | - cd doc + cd docs poetry run make html # Save the example test results - store_test_results: - path: doc/_build/test-results + path: docs/_build/test-results - store_artifacts: - path: doc/_build/test-results + path: docs/_build/test-results destination: test-results # Save the SG RST - store_artifacts: - path: doc/auto_examples.zip + path: docs/auto_examples.zip - store_artifacts: - path: doc/generated.zip + path: docs/generated.zip # Save the outputs - store_artifacts: - path: doc/_build/html/ + path: docs/_build/html/ destination: dev - store_artifacts: - path: doc/_build/html_stable/ + path: docs/_build/html_stable/ destination: stable - persist_to_workspace: - root: doc/_build + root: docs/_build paths: - html - html_stable @@ -145,7 +145,7 @@ jobs: command: | make -C doc linkcheck-grep - store_artifacts: - path: doc/_build/linkcheck + path: docs/_build/linkcheck destination: linkcheck deploy: @@ -155,7 +155,7 @@ jobs: - checkout - attach_workspace: - at: doc/_build + at: docs/_build - run: name: Set BASH_ENV command: | @@ -165,7 +165,7 @@ jobs: - run: name: Check docs command: | - if [ ! -f doc/_build/html/index.html ] && [ ! -f doc/_build/html_stable/index.html ]; then + if [ ! -f docs/_build/html/index.html ] && [ ! -f docs/_build/html_stable/index.html ]; then echo "No files found to upload (build: ${CIRCLE_BRANCH})."; circleci-agent step halt; fi; @@ -186,10 +186,10 @@ jobs: command: | if [ "${CIRCLE_BRANCH}" == "main" ]; then echo "Deploying dev doc for ${CIRCLE_BRANCH}."; - node_modules/gh-pages/bin/gh-pages.js --dotfiles --message "doc updates [skip ci]" --dist doc/_build/html --dest ./dev + node_modules/gh-pages/bin/gh-pages.js --dotfiles --message "doc updates [skip ci]" --dist docs/_build/html --dest ./dev else echo "Deploying stable doc for ${CIRCLE_BRANCH}."; - node_modules/gh-pages/bin/gh-pages.js --dotfiles --message "doc updates [skip ci]" --dist doc/_build/html_stable --dest ./stable + node_modules/gh-pages/bin/gh-pages.js --dotfiles --message "doc updates [skip ci]" --dist docs/_build/html_stable --dest ./stable fi; workflows: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a5e404c95..4a85d3619 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -91,7 +91,7 @@ jobs: run: pip install poetry-dynamic-versioning - name: Install from source run: | - poetry install + python -m pip install -e . - name: Test package install run: python -c "import pywhy_graphs; print(pywhy_graphs.__version__)" - name: Remove package install From 0474f1dbc76c74db55dbd91cb4a2d57b56492ec9 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 14:51:06 -0400 Subject: [PATCH 16/23] Try again Signed-off-by: Adam Li --- docs/api.rst | 9 ----- docs/conf.py | 35 +++++++++------- docs/graph_api.rst | 90 ----------------------------------------- docs/index.rst | 3 +- docs/tutorials.rst | 16 -------- docs/whats_new/v0.1.rst | 2 +- examples/plot_admg.py | 0 pywhy_graphs/admg.py | 14 ++++--- pywhy_graphs/cpdag.py | 10 ++--- 9 files changed, 36 insertions(+), 143 deletions(-) delete mode 100644 docs/graph_api.rst delete mode 100644 docs/tutorials.rst delete mode 100644 examples/plot_admg.py diff --git a/docs/api.rst b/docs/api.rst index 77806da58..c15c3f4c2 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -25,12 +25,3 @@ graphs encountered in the literature. CPDAG ADMG - -Converting Graphs -================= -.. currentmodule:: pywhy_graphs.algorithms - -.. autosummary:: - :toctree: generated/ - - dag2cpdag diff --git a/docs/conf.py b/docs/conf.py index b0604921d..455fdef35 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,7 +20,7 @@ sys.path.insert(0, os.path.abspath("../")) -from pywhy_graphs.version import VERSION, VERSION_SHORT # noqa: E402 +import pywhy_graphs # noqa: E402 curdir = os.path.dirname(__file__) sys.path.append(os.path.abspath(os.path.join(curdir, ".."))) @@ -31,8 +31,7 @@ project = "pywhy-graphs" copyright = f"{datetime.today().year}, Adam Li" author = "Adam Li" -version = VERSION_SHORT -release = VERSION +version = pywhy_graphs.__version__ # -- General configuration --------------------------------------------------- @@ -66,9 +65,11 @@ # generate autosummary even if no references # -- sphinx.ext.autosummary autosummary_generate = True - autodoc_default_options = {"inherited-members": None} -autodoc_typehints = "signature" +# autodoc_typehints = "signature" + +# TODO: remove when MixedEdgeGraph PRed to networkx +autodoc_inherit_docstrings = True # -- numpydoc # Below is needed to prevent errors @@ -78,6 +79,9 @@ numpydoc_use_blockquotes = True numpydoc_validate = True +# TODO: remove once MixedEdgeGraph is PRed to networkx +numpydoc_validation_exclude = {"graphs"} + numpydoc_xref_ignore = { # words "instance", @@ -105,12 +109,15 @@ "keyword", "arguments", "no", - "attributes", + "attributes", "dictionary", "DAG", "causal", "CPDAG", "PAG", "ADMG", # networkx "node", "nodes", "graph", + "directed", "bidirected", "undirected", "single", "G.name", "n in G", + "MixedEdgeGraph", "collection", "u", "v", "EdgeView", "AdjacencyView", + "DegreeView", "Graph", "sets", "value", # shapes "n_times", "obj", @@ -126,7 +133,10 @@ # Networkx "nx.Graph": "networkx.Graph", "nx.DiGraph": "networkx.DiGraph", + "Graph": "networkx.Graph", + "DiGraph": "networkx.DiGraph", "nx.MultiDiGraph": "networkx.MultiDiGraph", + "NetworkXError": "networkx.NetworkXError", "pgmpy.models.BayesianNetwork": "pgmpy.models.BayesianNetwork", # pywhy-graphs "ADMG": "pywhy_graphs.ADMG", @@ -141,7 +151,7 @@ "column": "pandas.DataFrame.columns", } -default_role = "py:obj" +default_role = "obj" # Tell myst-parser to assign header anchors for h1-h3. # myst_heading_anchors = 3 @@ -167,11 +177,8 @@ "sklearn": ("https://scikit-learn.org/stable", None), "joblib": ("https://joblib.readthedocs.io/en/latest", None), "networkx": ("https://networkx.org/documentation/latest/", None), + "nx-guides": ("https://networkx.org/nx-guides/", None), "matplotlib": ("https://matplotlib.org/stable", None), - # Uncomment these if you use them in your codebase: - # "torch": ("https://pytorch.org/docs/stable", None), - # "datasets": ("https://huggingface.co/docs/datasets/master/en", None), - # "transformers": ("https://huggingface.co/docs/transformers/master/en", None), } intersphinx_timeout = 5 @@ -195,7 +202,7 @@ html_theme = "pydata_sphinx_theme" -html_title = f"pywhy-graphs v{VERSION}" +html_title = f"pywhy-graphs v{version}" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, @@ -251,5 +258,5 @@ # Enable nitpicky mode - which ensures that all references in the docs # resolve. -nitpicky = True -nitpick_ignore = [] +nitpicky = False +nitpick_ignore = [('py:obj', 'MixedEdgeGraph')] diff --git a/docs/graph_api.rst b/docs/graph_api.rst deleted file mode 100644 index 634e5efdb..000000000 --- a/docs/graph_api.rst +++ /dev/null @@ -1,90 +0,0 @@ -:orphan: - -.. _graph_api: - -*** -DAG -*** - -All basic causal graphs stem from the ``DAG`` class, so feel free to refer to basic -graph operations based on the ``DAG`` class. Other more complicated graph structures, -such as the CPDAG, ADMG, or PAG have the same API and structure, but add on -different types of edges. - -Overview -******** -.. currentmodule:: pywhy_graphs.graphs.base - -All causal graphs are subclassed from the following abstract classes. These -are provided, so that users may extend the graph classes. - -.. autosummary:: - :toctree: generated - - MarkovianGraph - SemiMarkovianGraph - MarkovEquivalenceClass - -.. currentmodule:: pywhy_graphs.graphs.dag - -Copying -------- -.. autosummary:: - :toctree: generated - - DAG.copy - DAG.to_adjacency_graph - -Information about nodes and edges ---------------------------------- -.. autosummary:: - :toctree: generated - - DAG.name - DAG.parents - DAG.children - DAG.successors - DAG.predecessors - DAG.edges - DAG.nodes - DAG.has_adjacency - DAG.has_edge - DAG.has_node - DAG.number_of_edges - DAG.number_of_nodes - DAG.size - DAG.degree - DAG.markov_blanket_of - -Graph modification ------------------- -.. autosummary:: - :toctree: generated - - DAG.add_node - DAG.add_nodes_from - DAG.remove_node - DAG.remove_nodes_from - DAG.remove_edge - DAG.remove_edges_from - DAG.add_edge - DAG.add_edges_from - DAG.clear - DAG.clear_edges - -Ordering --------- -.. autosummary:: - :toctree: generated - - DAG.order - -Conversion to/from other formats --------------------------------- -.. autosummary:: - :toctree: generated - - DAG.to_dot_graph - DAG.to_networkx - DAG.to_numpy - DAG.save \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 2a483825b..3d481a713 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,7 +3,7 @@ pywhy-graphs is a Python package for representing causal graphs. For example, Acyclic Directed Mixed Graphs (ADMG), also known as causal DAGs and Partial Ancestral Graphs (PAGs). -We build on top of ``networkx's`` `MixedEdgeGraph` such that we maintain all the well-tested and efficient +We build on top of ``networkx's`` ``MixedEdgeGraph`` such that we maintain all the well-tested and efficient algorithms and data structures of ``networkx``. We encourage you to use the package for your causal inference research and also build on top @@ -21,7 +21,6 @@ Contents installation api use - tutorials whats_new .. toctree:: diff --git a/docs/tutorials.rst b/docs/tutorials.rst deleted file mode 100644 index b83ddfdb3..000000000 --- a/docs/tutorials.rst +++ /dev/null @@ -1,16 +0,0 @@ -:orphan: - -******** -Tutorial -******** - -.. _pywhy_graphs_tutorials: - -Using pywhy-graphs -===================== -This tutorial shows how to use pywhy-graphs - -.. toctree:: - :maxdepth: 0 - - tutorials/cgm diff --git a/docs/whats_new/v0.1.rst b/docs/whats_new/v0.1.rst index b0869d1a4..c53353f04 100644 --- a/docs/whats_new/v0.1.rst +++ b/docs/whats_new/v0.1.rst @@ -26,7 +26,7 @@ Version 0.1 Changelog --------- -- |Feature| Implement and test the :class:`pywhy_graphs.CPDAG` for CPDAGs, by `Adam Li`_ (:gh:`6`) +- |Feature| Implement and test the :class:`pywhy_graphs.CPDAG` for CPDAGs, by `Adam Li`_ (:pr:`6`) Code and Documentation Contributors ----------------------------------- diff --git a/examples/plot_admg.py b/examples/plot_admg.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/pywhy_graphs/admg.py b/pywhy_graphs/admg.py index cc6920183..4edad4aa7 100644 --- a/pywhy_graphs/admg.py +++ b/pywhy_graphs/admg.py @@ -1,3 +1,5 @@ +from typing import Iterable, Mapping + import networkx as nx from graphs import MixedEdgeGraph @@ -97,18 +99,18 @@ def c_components(self): # return [comp for comp in c_comps if len(comp) > 1] @property - def bidirected_edges(self) -> nx.reportviews.EdgeView: - """`EdgeView` of the bidirected edges.""" + def bidirected_edges(self) -> Mapping: + """``EdgeView`` of the bidirected edges.""" return self.get_graphs(self._bidirected_name).edges @property - def undirected_edges(self) -> nx.reportviews.EdgeView: - """`EdgeView` of the undirected edges.""" + def undirected_edges(self) -> Mapping: + """``EdgeView`` of the undirected edges.""" return self.get_graphs(self._undirected_name).edges @property - def directed_edges(self) -> nx.reportviews.EdgeView: - """`EdgeView` of the directed edges.""" + def directed_edges(self) -> Mapping: + """``EdgeView`` of the directed edges.""" return self.get_graphs(self._directed_name).edges def sub_directed_graph(self) -> nx.DiGraph: diff --git a/pywhy_graphs/cpdag.py b/pywhy_graphs/cpdag.py index 512c60505..5d5b0e50d 100644 --- a/pywhy_graphs/cpdag.py +++ b/pywhy_graphs/cpdag.py @@ -1,4 +1,4 @@ -from typing import Dict, FrozenSet, Iterator +from typing import Dict, FrozenSet, Iterable, Iterator import networkx as nx from graphs import MixedEdgeGraph @@ -77,13 +77,13 @@ def directed_edge_name(self): return self._directed_name @property - def undirected_edges(self) -> nx.reportviews.EdgeView: - """`EdgeView` of the undirected edges.""" + def undirected_edges(self) -> Iterable: + """``EdgeView`` of the undirected edges.""" return self.get_graphs(self._undirected_name).edges @property - def directed_edges(self) -> nx.reportviews.EdgeView: - """`EdgeView` of the directed edges.""" + def directed_edges(self) -> Iterable: + """``EdgeView`` of the directed edges.""" return self.get_graphs(self._directed_name).edges def sub_directed_graph(self) -> nx.DiGraph: From 96698d91c4ea20de403ac71d6edaff3913f4ba81 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 15:53:22 -0400 Subject: [PATCH 17/23] Try again... Signed-off-by: Adam Li --- .github/workflows/main.yml | 2 +- pywhy_graphs/admg.py | 2 +- pywhy_graphs/cpdag.py | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4a85d3619..a5e404c95 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -91,7 +91,7 @@ jobs: run: pip install poetry-dynamic-versioning - name: Install from source run: | - python -m pip install -e . + poetry install - name: Test package install run: python -c "import pywhy_graphs; print(pywhy_graphs.__version__)" - name: Remove package install diff --git a/pywhy_graphs/admg.py b/pywhy_graphs/admg.py index 4edad4aa7..c84114f41 100644 --- a/pywhy_graphs/admg.py +++ b/pywhy_graphs/admg.py @@ -1,4 +1,4 @@ -from typing import Iterable, Mapping +from typing import Mapping import networkx as nx from graphs import MixedEdgeGraph diff --git a/pywhy_graphs/cpdag.py b/pywhy_graphs/cpdag.py index 5d5b0e50d..079cafa83 100644 --- a/pywhy_graphs/cpdag.py +++ b/pywhy_graphs/cpdag.py @@ -1,4 +1,4 @@ -from typing import Dict, FrozenSet, Iterable, Iterator +from typing import Dict, FrozenSet, Iterator, Mapping import networkx as nx from graphs import MixedEdgeGraph @@ -77,12 +77,12 @@ def directed_edge_name(self): return self._directed_name @property - def undirected_edges(self) -> Iterable: + def undirected_edges(self) -> Mapping: """``EdgeView`` of the undirected edges.""" return self.get_graphs(self._undirected_name).edges @property - def directed_edges(self) -> Iterable: + def directed_edges(self) -> Mapping: """``EdgeView`` of the directed edges.""" return self.get_graphs(self._directed_name).edges @@ -94,7 +94,7 @@ def sub_undirected_graph(self) -> nx.Graph: """Sub-graph of just the undirected edges.""" return self._get_internal_graph(self._undirected_name) - def orient_uncertain_edge(self, u, v): + def orient_uncertain_edge(self, u, v) -> None: """Orient undirected edge into an arrowhead. If there is an undirected edge u - v, then the arrowhead From 9f978369ba52bb5b5ad16480c60301880a5e84cb Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 16:01:26 -0400 Subject: [PATCH 18/23] Try again... Signed-off-by: Adam Li --- .github/workflows/main.yml | 2 +- .github/workflows/pr_checks.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a5e404c95..9acedcdc7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -93,7 +93,7 @@ jobs: run: | poetry install - name: Test package install - run: python -c "import pywhy_graphs; print(pywhy_graphs.__version__)" + run: poetry run python -c "import pywhy_graphs; print(pywhy_graphs.__version__)" - name: Remove package install run: python -m pip uninstall -yq pywhy_graphs - name: Check poetry lock file diff --git a/.github/workflows/pr_checks.yml b/.github/workflows/pr_checks.yml index e6c1e1f75..986b2b118 100644 --- a/.github/workflows/pr_checks.yml +++ b/.github/workflows/pr_checks.yml @@ -38,14 +38,14 @@ jobs: exit 0 fi all_changelogs=$(cat ./docs/whats_new/v*.rst) - if [[ "$all_changelogs" =~ :gh:\`$PR_NUMBER\` ]] + if [[ "$all_changelogs" =~ :pr:\`$PR_NUMBER\` ]] then echo "Changelog has been updated." # If the pull request is milestoned check the correspondent changelog if exist -f ./docs/whats_new/v${TAGGED_MILESTONE:0:4}.rst then expected_changelog=$(cat ./docs/whats_new/v${TAGGED_MILESTONE:0:4}.rst) - if [[ "$expected_changelog" =~ :gh:\`$PR_NUMBER\` ]] + if [[ "$expected_changelog" =~ :pr:\`$PR_NUMBER\` ]] then echo "Changelog and milestone correspond." else @@ -63,7 +63,7 @@ jobs: echo "in time for the next release of pywhy-graphs." echo "" echo "Look at other entries in that file for inspiration and please" - echo "reference this pull request using the ':gh:' directive and" + echo "reference this pull request using the ':pr:' directive and" echo "credit yourself (and other contributors if applicable) with" echo "the ':user:' directive." echo "" From bb076583c08cf57aeb8e449bde60a14780d13e89 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 16:19:40 -0400 Subject: [PATCH 19/23] Try again... Signed-off-by: Adam Li --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c5a3a0aa2..34f9d0521 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,6 +41,7 @@ numpy = "^1.23.0" scipy = "^1.9.0" networkx = "^2.8.3" scikit-learn = "^1.1.0" +pandas = "^1.1" importlib-resources = { version = "*", python = "<3.9" } graphs = { git = "https://github.com/py-why/graphs.git", branch = 'main' } @@ -71,7 +72,6 @@ sphinx-issues = { version = "^3.0.1" } sphinx-copybutton = { version = "^0.5.0" } sphinx-gallery = { version = "^0.11.0" } sphinx_rtd_theme = { version = "^1.0.0" } -pandas = { version = "^1.1" } graphviz = { version = "^0.20.1" } dowhy = { version = "^0.8" } ipython = { version = "^7.4.0" } From 417c32c7362afd288f8ab76ffcb56123a6ff6dc9 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 16:33:04 -0400 Subject: [PATCH 20/23] Try again... Signed-off-by: Adam Li --- Makefile | 2 +- pyproject.toml | 2 +- pywhy_graphs/cpdag.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index f0c371d36..9d0fd7627 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# simple makefile to simplify repetetive build env management tasks under posix +# simple makefile to simplify repetitive build env management tasks under posix # caution: testing won't work on windows PYTHON ?= python diff --git a/pyproject.toml b/pyproject.toml index 34f9d0521..f91dbc7aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ graphs = { git = "https://github.com/py-why/graphs.git", branch = 'main' } # TODO: the below needs to be refactored into separate dev-dependencies # https://github.com/python-poetry/poetry/is -# it is inefficient to have to install every single dependencey to run +# it is inefficient to have to install every single dependency to run # e.g. a style check. [tool.poetry.dev-dependencies] pytest = "^7.1.2" diff --git a/pywhy_graphs/cpdag.py b/pywhy_graphs/cpdag.py index 079cafa83..38259edef 100644 --- a/pywhy_graphs/cpdag.py +++ b/pywhy_graphs/cpdag.py @@ -40,7 +40,7 @@ class CPDAG(MixedEdgeGraph, AncestralMixin): CPDAGs are Markov equivalence class of causal DAGs. The implicit assumption in these causal graphs are the Structural Causal Model (or SCM) is Markovian, inducing causal sufficiency, where there is no unobserved latent confounder. This allows CPDAGs - to be learned from score-based (such as the GES algorithm) and constraint-based + to be learned from score-based (such as the "GES" algorithm) and constraint-based (such as the PC algorithm) approaches for causal structure learning. One should not use CPDAGs if they suspect their data has unobserved latent confounders. From 204c208788939bf47a165a778aee5c7389728927 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 16:54:46 -0400 Subject: [PATCH 21/23] Fix codespell Signed-off-by: Adam Li --- .codespellignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.codespellignore b/.codespellignore index 77cb00804..3d37b9b36 100644 --- a/.codespellignore +++ b/.codespellignore @@ -1 +1,2 @@ raison +GES \ No newline at end of file From 351d9ccc7e5670fd6b5e3fddbdbbda39ccafd116 Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 17:02:15 -0400 Subject: [PATCH 22/23] Fix ci Signed-off-by: Adam Li --- .circleci/config.yml | 2 +- .github/workflows/main.yml | 37 +++++++++++++------------------------ 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3890eaf91..a8fcc7ef8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -50,7 +50,7 @@ jobs: curl -sSL https://install.python-poetry.org | python3 - - python/install-packages: pkg-manager: poetry - cache-version: "v1" # change to clear cache + cache-version: "v2" # change to clear cache - run: name: Check poetry package versions command: | diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9acedcdc7..c7a5dd10d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -35,32 +35,21 @@ jobs: poetry-version: ${{ matrix.poetry-version }} - name: Install Poetry Dynamic Versioning Plugin run: pip install poetry-dynamic-versioning + + # TODO: once poetry v1.2 is release, we want to only install dev dependencies - name: Install dependencies run: poetry install - - name: Run flake8 - uses: py-actions/flake8@v2 - with: - path: "pywhy_graphs" - - name: Run isort - uses: isort/isort-action@master - - name: Run black - uses: psf/black@stable - with: - options: "--check --verbose" - - name: Run codespell - uses: codespell-project/actions-codespell@master - with: - check_filenames: true - check_hidden: true - skip: './.git,./build,./.mypy_cache,./.pytest_cache' - ignore_words_file: ./.codespellignore - - name: Run pydocstyle - run: poetry run pydocstyle . - - name: Run mypy - uses: jpetrucciani/mypy-check@master - with: - path: './pywhy_graphs' - mypy_flags: '--config-file pyproject.toml' + + # check formatting of the code style + - name: Check code formatting + run: poetry run poe check_format + + # this applies various linting + - name: Lint codebase + run: poetry run poe lint + + - name: Typecheck + run: poetry run poe typecheck build: timeout-minutes: 10 From 3506e1c18bd25cd3ce081c6904a62c680bcfadcf Mon Sep 17 00:00:00 2001 From: Adam Li Date: Wed, 17 Aug 2022 17:21:57 -0400 Subject: [PATCH 23/23] Fix bandit Signed-off-by: Adam Li --- pyproject.toml | 5 ++++- pywhy_graphs/export.py | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f91dbc7aa..4aa4477d9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,7 +83,7 @@ build-backend = "poetry.core.masonry.api" [tool.poe.tasks] _flake8 = 'flake8' -_bandit = 'bandit -r pywhy_graphs' +_bandit = 'bandit -r pywhy_graphs -c pyproject.toml' _black = 'black .' _isort = 'isort .' _black_check = 'black --check pywhy_graphs examples' @@ -170,3 +170,6 @@ omit = ['**/__init__.py', '**/tests/**'] [tool.coverage.report] exclude_lines = ['pragma: no cover', 'if __name__ == .__main__.:'] precision = 2 + +[tool.bandit] +exclude_dirs = ["tests"] \ No newline at end of file diff --git a/pywhy_graphs/export.py b/pywhy_graphs/export.py index 64f372050..a5edc531b 100644 --- a/pywhy_graphs/export.py +++ b/pywhy_graphs/export.py @@ -106,7 +106,8 @@ def to_numpy(causal_graph): # ADMGs can have two edges between any 2 nodes if type(causal_graph).__name__ == "ADMG": # we handle this case separately from the other graphs - assert len(graph_map) == 1 + if len(graph_map) != 1: + raise AssertionError("The number of graph maps should be 1...") # set all bidirected edges with value 10 bidirected_graph_arr[bidirected_graph_arr != 0] = 10