From 437146f76f607001a3682b411cffb7987d4f7d0d Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 27 Jun 2021 04:48:49 -0400 Subject: [PATCH] Get ready for release 2.3.0 Fix lint errors --- .editorconfig | 28 +++++++++++++++++++++++ .pre-commit-config.yaml | 12 ++++++++++ NEWS.md | 9 ++++++++ README.rst | 6 ++--- pymathics/graph/__init__.py | 18 ++++++++++----- pymathics/graph/__main__.py | 7 +++--- pymathics/graph/algorithms.py | 26 ++++++++++++++------- pymathics/graph/generators.py | 36 +++++++++++++++++------------ pymathics/graph/harary.py | 1 - pymathics/graph/tree.py | 13 +++++++---- pymathics/graph/version.py | 3 ++- setup.cfg | 43 +++++++++++++++++++++++++++++++++++ setup.py | 4 +++- 13 files changed, 163 insertions(+), 43 deletions(-) create mode 100644 .editorconfig create mode 100644 .pre-commit-config.yaml create mode 100644 setup.cfg diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c521b5a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,28 @@ +# THis is an EditorConfig file +# https://EditorConfig.org + +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +indent_style = tab +indent_size = 4 +insert_final_newline = true + +[*.yml] +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true + +[*.py] +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true + +# Tab indentation (no size specified) +[Makefile] +indent_style = tab diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..71d7793 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,12 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.0.0 + hooks: + - id: debug-statements + - id: end-of-file-fixer +- repo: https://github.com/psf/black + rev: 20.8b1 + hooks: + - id: black + language_version: python3 + exclude: 'mathicsscript/version.py' diff --git a/NEWS.md b/NEWS.md index ce3c6e6..b38c34b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +2.3.0 +----- + +Small API changes to track Mathics 3.0.0. + +Blacken everything + + + 2.2.0 ----- diff --git a/README.rst b/README.rst index 6d1f01e..e9a3f81 100644 --- a/README.rst +++ b/README.rst @@ -8,11 +8,11 @@ Example Session :: $ mathicsscript - Mathics 1.1.1 + Mathics 3.0.1 on CPython 3.6.12 (default, Oct 24 2020, 10:34:18) - using SymPy 1.8.dev, mpmath 1.1.0, cython 0.29.21 + using SymPy 1.8, mpmath 1.2.1, cython 0.29.22 - Copyright (C) 2011-2020 The Mathics Team. + Copyright (C) 2011-2021 The Mathics Team. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. diff --git a/pymathics/graph/__init__.py b/pymathics/graph/__init__.py index 0ba8cdc..089ed86 100644 --- a/pymathics/graph/__init__.py +++ b/pymathics/graph/__init__.py @@ -1,15 +1,21 @@ -"""Pymathics Graph - Working with Graphs (Vertices and Edgies) +"""Pymathics Graph - Working with Graphs (Vertices and Edges) This module provides functions and variables for workting with graphs. -""" +Example: + In[1]:= LoadModule["pymathics.graph"] + Out[1]= pymathics.graph + In[2]:= BinomialTree[3] + In[3]:= BinomialTree[6] + In[4]:= CompleteKaryTree[3, VertexLabels->True] +""" from pymathics.graph.version import __version__ -from pymathics.graph.__main__ import * -from pymathics.graph.tree import * -from pymathics.graph.generators import * -from pymathics.graph.algorithms import * +from pymathics.graph.__main__ import * # noqa +from pymathics.graph.tree import * # qoqa +from pymathics.graph.generators import * # noqa +from pymathics.graph.algorithms import * # noqa pymathics_version_data = { "author": "The Mathics Team", diff --git a/pymathics/graph/__main__.py b/pymathics/graph/__main__.py index 7e720fe..239dd94 100644 --- a/pymathics/graph/__main__.py +++ b/pymathics/graph/__main__.py @@ -10,13 +10,12 @@ # uses networkx from mathics.builtin.base import Builtin, AtomBuiltin -from mathics.builtin.graphics import GraphicsBox +from mathics.builtin.box.graphics import GraphicsBox from mathics.core.expression import ( Atom, Expression, Integer, Real, - String, Symbol, ) from mathics.builtin.patterns import Matcher @@ -730,7 +729,7 @@ def full_new_edge_properties(new_edge_style): attr_dict = attr_dict or empty_dict G.add_edge(u, v, **attr_dict) - edge_collection = _EdgeCollection( + _EdgeCollection( edges, edge_properties, n_directed=len(directed_edges), @@ -1804,7 +1803,7 @@ def apply_s_t(self, graph, s, t, expression, evaluation, options): def _convert_networkx_graph(G, options): mapping = dict((v, Integer(i)) for i, v in enumerate(G.nodes)) G = nx.relabel_nodes(G, mapping) - edges = [Expression("System`UndirectedEdge", u, v) for u, v in G.edges] + [Expression("System`UndirectedEdge", u, v) for u, v in G.edges] return Graph( G, **options, diff --git a/pymathics/graph/algorithms.py b/pymathics/graph/algorithms.py index 648f925..60132f5 100644 --- a/pymathics/graph/algorithms.py +++ b/pymathics/graph/algorithms.py @@ -22,6 +22,7 @@ # SymbolFalse = Symbol("System`False") # SymbolTrue = Symbol("System`True") + class ConnectedComponents(_NetworkXBuiltin): """ >> g = Graph[{1 -> 2, 2 -> 3, 3 <-> 4}]; ConnectedComponents[g] @@ -38,10 +39,12 @@ def apply(self, graph, expression, evaluation, options): "ConnectedComponents[graph_, OptionsPattern[%(name)s]]" graph = self._build_graph(graph, evaluation, options, expression) if graph: - connect_fn = nx.strongly_connected_components if graph.G.is_directed() else nx.connected_components - components = [ - Expression("List", *c) for c in connect_fn(graph.G) - ] + connect_fn = ( + nx.strongly_connected_components + if graph.G.is_directed() + else nx.connected_components + ) + components = [Expression("List", *c) for c in connect_fn(graph.G)] return Expression("List", *components) @@ -63,6 +66,7 @@ def apply(self, graph, expression, evaluation, options): # # int_path = map(Integer, path) # return Expression("List", *path) + class GraphDistance(_NetworkXBuiltin): """
@@ -110,9 +114,7 @@ def apply_s(self, graph, s, expression, evaluation, options): weight = graph.update_weights(evaluation) d = nx.shortest_path_length(graph.G, source=s, weight=weight) inf = Expression("DirectedInfinity", 1) - return Expression( - "List", *[d.get(v, inf) for v in graph.vertices] - ) + return Expression("List", *[d.get(v, inf) for v in graph.vertices]) def apply_s_t(self, graph, s, t, expression, evaluation, options): "%(name)s[graph_, s_, t_, OptionsPattern[%(name)s]]" @@ -133,6 +135,7 @@ def apply_s_t(self, graph, s, t, expression, evaluation, options): except nx.exception.NetworkXNoPath: return Expression("DirectedInfinity", 1) + class FindSpanningTree(_NetworkXBuiltin): """
@@ -144,6 +147,7 @@ class FindSpanningTree(_NetworkXBuiltin): """ options = DEFAULT_GRAPH_OPTIONS + def apply(self, graph, expression, evaluation, options): "%(name)s[graph_, OptionsPattern[%(name)s]]" graph = self._build_graph(graph, evaluation, options, expression) @@ -151,7 +155,10 @@ def apply(self, graph, expression, evaluation, options): weight = graph.update_weights(evaluation) edge_type = "DirectedEdge" if graph.G.is_directed() else "UndirectedEdge" # FIXME: put in edge to Graph conversion function? - edges = [Expression("UndirectedEdge", u, v) for u, v in nx.minimum_spanning_edges(graph.G, data=False)] + edges = [ + Expression("UndirectedEdge", u, v) + for u, v in nx.minimum_spanning_edges(graph.G, data=False) + ] g = _create_graph(edges, [None] * len(edges), options) if not hasattr(g.G, "graph_layout"): if hasattr(graph.G, "graph_layout"): @@ -160,6 +167,7 @@ def apply(self, graph, expression, evaluation, options): g.G.graph_layout = "tree" return g + class PlanarGraphQ(_NetworkXBuiltin): """
@@ -174,6 +182,7 @@ class PlanarGraphQ(_NetworkXBuiltin): """ options = DEFAULT_GRAPH_OPTIONS + def apply(self, graph, expression, evaluation, options): "%(name)s[graph_, OptionsPattern[%(name)s]]" graph = self._build_graph(graph, evaluation, options, expression) @@ -182,6 +191,7 @@ def apply(self, graph, expression, evaluation, options): is_planar, _ = nx.check_planarity(graph.G) return Symbol("System`True") if is_planar else Symbol("System`False") + class WeaklyConnectedComponents(_NetworkXBuiltin): """ >> g = Graph[{1 -> 2, 2 -> 3, 3 <-> 4}]; WeaklyConnectedComponents[g] diff --git a/pymathics/graph/generators.py b/pymathics/graph/generators.py index 1ee4c07..8c64034 100644 --- a/pymathics/graph/generators.py +++ b/pymathics/graph/generators.py @@ -6,11 +6,9 @@ """ from mathics.builtin.numbers.randomnumbers import RandomEnv -from mathics.core.expression import String from pymathics.graph.__main__ import ( Graph, - WL_MARKER_TO_NETWORKX, _NetworkXBuiltin, _convert_networkx_graph, _graph_from_list, @@ -32,6 +30,7 @@ def graph_helper( options: dict, can_digraph: bool, graph_layout: str, + evaluation, root: Optional[int] = None, *args, **kwargs @@ -94,7 +93,7 @@ def apply(self, r, h, expression, evaluation, options): return None args = (py_r, py_h) - g = graph_helper(nx.balanced_tree, options, True, "tree", 0, *args) + g = graph_helper(nx.balanced_tree, options, True, "tree", evaluation, 0, *args) if not g: return None g.G.r = r @@ -133,7 +132,7 @@ def apply(self, m1, m2, expression, evaluation, options): return args = (py_m1, py_m2) - g = graph_helper(nx.barbell_graph, options, False, "spring", None, *args) + g = graph_helper(nx.barbell_graph, options, False, "spring", evaluation, None, *args) if not g: return None @@ -205,7 +204,7 @@ def apply(self, n, expression, evaluation, options): return args = (py_n,) - g = graph_helper(binomial_tree, options, True, "tree", 0, *args) + g = graph_helper(binomial_tree, options, True, "tree", evaluation, 0, *args) if not g: return None g.G.n = n @@ -220,7 +219,7 @@ def complete_graph_apply(self, n, expression, evaluation, options): return args = (py_n,) - g = graph_helper(nx.complete_graph, options, False, "circular", None, *args) + g = graph_helper(nx.complete_graph, options, False, "circular", evaluation, None, *args) if not g: return None @@ -333,7 +332,7 @@ def f_r_t_apply(self, r, n, expression, evaluation, options): return args = (py_r, py_n) - g = graph_helper(nx.full_rary_tree, options, True, "tree", 0, *args) + g = graph_helper(nx.full_rary_tree, options, True, "tree", evaluation, 0, *args) if not g: return None @@ -395,7 +394,7 @@ def apply(self, n, expression, evaluation, options): return args = (py_n,) - g = graph_helper(nx.graph_atlas, options, False, "spring", None, *args) + g = graph_helper(nx.graph_atlas, options, False, "spring", evaluation, None, *args) if not g: return None g.n = n @@ -417,7 +416,7 @@ def hkn_harary_apply(self, k, n, expression, evaluation, options): from pymathics.graph.harary import hkn_harary_graph args = (py_k, py_n) - g = graph_helper(hkn_harary_graph, options, False, "circular", None, *args) + g = graph_helper(hkn_harary_graph, options, False, "circular", evaluation, None, *args) if not g: return None g.k = py_k @@ -490,7 +489,7 @@ def apply(self, n, m, expression, evaluation, options): from pymathics.graph.harary import hnm_harary_graph args = (py_n, py_m) - g = graph_helper(hmn_harary_graph, options, False, "circular", None, *args) + g = graph_helper(hnm_harary_graph, options, False, "circular", evaluation, None, *args) if not g: return None g.n = py_n @@ -557,12 +556,13 @@ def apply(self, n, expression, evaluation, options): return args = (py_n,) - g = graph_helper(nx.ladder_graph, options, False, "spring", 0, *args) + g = graph_helper(nx.ladder_graph, options, False, "spring", evaluation, 0, *args) if not g: return None g.G.n = n return g + class PathGraph(_NetworkXBuiltin): """
@@ -582,7 +582,9 @@ def edges(): yield Expression("UndirectedEdge", u, v) g = _graph_from_list(edges(), options) - g.G.graph_layout = options["System`GraphLayout"].get_string_value() or "spiral_equidistant" + g.G.graph_layout = ( + options["System`GraphLayout"].get_string_value() or "spiral_equidistant" + ) return g @@ -645,7 +647,7 @@ def apply(self, n, expression, evaluation, options): return args = (py_n,) - g = graph_helper(nx.random_tree, options, False, "tree", 0, *args) + g = graph_helper(nx.random_tree, options, False, "tree", evaluation, 0, *args) if not g: return None g.G.n = n @@ -676,12 +678,13 @@ def apply(self, n, expression, evaluation, options): return args = (py_n,) - g = graph_helper(nx.star_graph, options, False, "spring", 0, *args) + g = graph_helper(nx.star_graph, options, False, "spring", evaluation, 0, *args) if not g: return None g.G.n = n return g + WL_TO_NETWORKX_FN = { "DodecahedralGraph": (nx.dodecahedral_graph, None), "DiamondGraph": (nx.diamond_graph, "spring"), @@ -690,6 +693,7 @@ def apply(self, n, expression, evaluation, options): "PetersenGraph": (nx.petersen_graph, None), } + class GraphData(_NetworkXBuiltin): """
@@ -699,6 +703,7 @@ class GraphData(_NetworkXBuiltin): >> GraphData["PappusGraph"] """ + def apply(self, name, expression, evaluation, options): "%(name)s[name_String, OptionsPattern[%(name)s]]" py_name = name.get_string_value() @@ -710,11 +715,12 @@ def apply(self, name, expression, evaluation, options): # These graphs require parameters return import inspect + fn = dict(inspect.getmembers(nx, inspect.isfunction)).get(py_name, None) # parameters = inspect.signature(nx.diamond_graph).parameters.values() # if len([p for p in list(parameters) if p.kind in [inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_OR_KEYWORD]]) != 0: # return if fn: - g = graph_helper(fn, options, False, layout) + g = graph_helper(fn, options, False, evaluation, layout) g.G.name = py_name return g diff --git a/pymathics/graph/harary.py b/pymathics/graph/harary.py index dd0649f..8d3ccd8 100644 --- a/pymathics/graph/harary.py +++ b/pymathics/graph/harary.py @@ -113,7 +113,6 @@ def hnm_harary_graph(n, m, create_using=None): return H - def hkn_harary_graph(k, n, create_using=None): """Returns the Harary graph with given node connectivity and node number. diff --git a/pymathics/graph/tree.py b/pymathics/graph/tree.py index 704b8b7..d216fcb 100644 --- a/pymathics/graph/tree.py +++ b/pymathics/graph/tree.py @@ -1,13 +1,18 @@ import networkx as nx -from pymathics.graph.__main__ import Graph, _graph_from_list, DEFAULT_GRAPH_OPTIONS, _NetworkXBuiltin, WL_MARKER_TO_NETWORKX -from mathics.core.expression import String, Symbol +from pymathics.graph.__main__ import ( + Graph, + _graph_from_list, + DEFAULT_GRAPH_OPTIONS, + _NetworkXBuiltin, +) +from mathics.core.expression import Atom, Symbol DEFAULT_TREE_OPTIONS = { **DEFAULT_GRAPH_OPTIONS, **{"GraphLayout": '"tree"'}, } -from mathics.builtin.base import Builtin, AtomBuiltin +from mathics.builtin.base import AtomBuiltin class TreeGraphAtom(AtomBuiltin): @@ -60,7 +65,7 @@ class TreeGraph(Graph): def __init__(self, G, **kwargs): super(Graph, self).__init__() if not nx.is_tree(G): - evaluation.message(self.get_name(), "notree") + raise ValueError self.G = G diff --git a/pymathics/graph/version.py b/pymathics/graph/version.py index edecee3..61ef52c 100644 --- a/pymathics/graph/version.py +++ b/pymathics/graph/version.py @@ -5,4 +5,5 @@ # This file is suitable for sourcing inside POSIX shell as # well as importing into Python. That's why there is no # space around "=" below. -__version__="2.2.0" +# fmt: off +__version__="2.3.0" diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..ca6e317 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,43 @@ +[bdist_wheel] +universal = 1 + +[metadata] +description_file = README.rst + +# Recommended flake8 settings while editing zoom, we use Black for the final +# linting/say in how code is formatted +# +# pip install flake8 flake8-bugbear +# +# This will warn/error on things that black does not fix, on purpose. + +# This config file MUST be ASCII to prevent weird flake8 dropouts + +[flake8] +# max-line-length setting: NO we do not want everyone writing 120-character lines! +# We are setting the maximum line length big here because there are longer +# lines allowed by black in some cases that are forbidden by flake8. Since +# black has the final say about code formatting issues, this setting is here to +# make sure that flake8 doesn't fail the build on longer lines allowed by +# black. +max-line-length = 120 +max-complexity = 12 +select = E,F,W,C,B,B9 +ignore = + # E123 closing bracket does not match indentation of opening bracket's line + E123 + # E203 whitespace before ':' (Not PEP8 compliant, Python Black) + E203 + # E501 line too long (82 > 79 characters) (replaced by B950 from flake8-bugbear, + # https://github.com/PyCQA/flake8-bugbear) + E501 + # W503 line break before binary operator (Not PEP8 compliant, Python Black) + W503 + # W504 line break after binary operator (Not PEP8 compliant, Python Black) + W504 + # C901 function too complex - since many of zz9 functions are too complex with a lot + # of if branching + C901 + # module level import not at top of file. This is too restrictive. Can't even have a + # docstring higher. + E402 diff --git a/setup.py b/setup.py index e2deafd..07a94e9 100644 --- a/setup.py +++ b/setup.py @@ -11,6 +11,7 @@ print("Mathics support Python 3.6 and above; you have %d.%d" % sys.version_info[:2]) sys.exit(-1) + def get_srcdir(): filename = osp.normcase(osp.dirname(osp.abspath(__file__))) return osp.realpath(filename) @@ -30,10 +31,11 @@ def read(*rnames): name="pymathics-graph", version=__version__, packages=find_namespace_packages(include=["pymathics.*"]), - install_requires=["Mathics3>=2.2.0", "networkx", "pydot", "matplotlib"], + install_requires=["Mathics3>=3.0.0", "networkx", "pydot", "matplotlib"], # don't pack Mathics in egg because of media files, etc. zip_safe=False, maintainer="Mathics Group", + maintainer_email="rb@dustyfeet.com", long_description=long_description, long_description_content_type="text/x-rst", # metadata for upload to PyPI