diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a74fff9893..74fd93636f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -108,6 +108,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 924d999441..1741166760 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,10 +1,14 @@ # Contributing -First read the overall project contributing guidelines. These are all -included in the qiskit documentation: +First read the overall Qiskit project contribution guidelines. These are all +included in the Qiskit documentation: https://qiskit.org/documentation/contributing_to_qiskit.html +While it's not all directly applicable since most of it is about the Qiskit +project itself and retworkx is an independent library developed in tandem +with Qiskit; the general guidelines and advice still apply here. + ## Contributing to retworkx In addition to the general guidelines there are specific details for @@ -28,6 +32,48 @@ the root of the repo, this is because retworkx packaging shim will conflict with imports from retworkx the installed version of retworkx (which contains the compiled extension). +### Style + +#### Rust + +Rust is the primary language of retworkx and all the functional code in the +libraries is written in Rust. The Rust code in retworkx uses +[rustfmt](https://github.com/rust-lang/rustfmt) to enfore consistent style. +CI jobs are configured to ensure to check this. Luckily adapting your code is +as simple as running: + +```bash +cargo fmt +``` + +locally. This will automatically restyle the rust code in retworkx to match +what CI is checking. + +##### Lint + +An additional step is to run [clippy](https://github.com/rust-lang/rust-clippy) +on your changes. While this is not run in CI (because it's very dependent on +the rust/cargo version) it can often catch issues in your code. You can run it +by running: + +```bash +cargo clippy +``` + +#### Python + +Python is used primarily for tests and some small pieces of packaging +and namespace configuration code in the actual library. +[flake8](https://flake8.pycqa.org/en/latest/) is used to enforce consistent +style in the python code in the repository. You can run it via tox using: + +```bash +tox -elint +``` + +This will also run `cargo fmt` in check mode to ensure that you ran `cargo fmt` +and will fail if the Rust code doesn't conform to the style rules. + ### Building documentation Just like with tests building documentation is done via tox. This will handle @@ -38,3 +84,131 @@ tox -edocs ``` which will output the html rendered documentation in `docs/build/html` which you can view locally in a web browser. + +### Release Notes + +It is important to document any end user facing changes when we release a new +version of retworkx. The expectation is that if your code contribution has +user facing changes that you will write the release documentation for these +changes. This documentation must explain what was changed, why it was changed, +and how users can either use or adapt to the change. The idea behind release +documentation is that when a naive user with limited internal knowledge of the +project is upgrading from the previous release to the new one, they should be +able to read the release notes, understand if they need to update their +program which uses retworkx, and how they would go about doing that. It +ideally should explain why they need to make this change too, to provide the +necessary context. + +To make sure we don't forget a release note or if the details of user facing +changes over a release cycle we require that all user facing changes include +documentation at the same time as the code. To accomplish this we use the +[reno](https://docs.openstack.org/reno/latest/) tool which enables a git based +workflow for writing and compiling release notes. + +#### Adding a new release note + +Making a new release note is quite straightforward. Ensure that you have reno +installed with:: + + pip install -U reno + +Once you have reno installed you can make a new release note by running in +your local repository checkout's root:: + + reno new short-description-string + +where short-description-string is a brief string (with no spaces) that describes +what's in the release note. This will become the prefix for the release note +file. Once that is run it will create a new yaml file in releasenotes/notes. +Then open that yaml file in a text editor and write the release note. The basic +structure of a release note is restructured text in yaml lists under category +keys. You add individual items under each category and they will be grouped +automatically by release when the release notes are compiled. A single file +can have as many entries in it as needed, but to avoid potential conflicts +you'll want to create a new file for each pull request that has user facing +changes. When you open the newly created file it will be a full template of +the different categories with a description of a category as a single entry +in each category. You'll want to delete all the sections you aren't using and +update the contents for those you are. For example, the end result should +look something like:: + +```yaml +features: + - | + Added a new function, :func:`~retworkx.foo` that adds support for doing + something to :class:`~retworkx.PyDiGraph` objects. + - | + The :class:`~retworkx.PyDiGraph` class has a new method + :meth:`~retworkx.PyDiGraph.foo``. This is the equivalent of calling the + :func:`~retworkx.foo` function to do something to your + :class:`~retworkx.PyDiGraph` object, but provides the convenience of running + it natively on an object. For example:: + + from retworkx import PyDiGraph + + g = PyDiGraph. + g.foo() + +deprecations: + - | + The ``retworkx.bar`` function has been deprecated and will be removed in a + future release. It has been superseded by the + :meth:`~retworkx.PyDiGraph.foo` method and :func:`~retworkx.foo` function + which provides similar functionality but with more accurate results and + better performance. You should update your calls + ``retworkx.bar()`` calls to use ``retworkx.foo()`` instead. +``` + +You can also look at other release notes for other examples. + +You can use any +[sphinx feature](https://www.sphinx-doc.org/en/3.x/usage/restructuredtext/) +in them (code sections, tables, enumerated lists, bulleted list, etc) to express +what is being changed as needed. In general you want the release notes to +include as much detail as needed so that users will understand what has changed, +why it changed, and how they'll have to update their code. + +After you've finished writing your release notes you'll want to add the note +file to your commit with `git add` and commit them to your PR branch to make +sure they're included with the code in your PR. + +##### Linking to issues + +If you need to link to an issue or other Github artifact as part of the release +note this should be done using an inline link with the text being the issue +number. For example you would write a release note with a link to issue 12345 +as: + +```yaml +fixes: + - | + Fixes a race condition in the function ``foo()``. Refer to + `#12345 `__ for more + details. +``` + +#### Generating the release notes + +After release notes have been added if you want to see what the full output of +the release notes. Reno is used to combine the release note yaml files into a +single rst (ReStructuredText) document that +[sphinx](https://www.sphinx-doc.org/en/master/) will then compile for us as part +of the documentation builds. If you want to generate the rst file you +use the ``reno report`` command. If you want to generate the full retworkx +release notes for all releases (since we started using reno during 0.8) you just +run:: + + reno report + +but you can also use the ``--version`` argument to view a single release (after +it has been tagged:: + + reno report --version 0.8.0 + +#### Building release notes locally + +Building the release notes is part of the standard retworkx documentation +builds. To check what the rendered html output of the release notes will look +like for the current state of the repo you can run: `tox -edocs` which will +build all the documentation into `docs/_build/html` and the release notes in +particular will be located at `docs/_build/html/release_notes.html` diff --git a/Cargo.lock b/Cargo.lock index 6d030c9a73..acd92469a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -537,7 +537,7 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "retworkx" -version = "0.7.0" +version = "0.7.1" dependencies = [ "fixedbitset", "hashbrown", diff --git a/docs/source/CONTRIBUTING.md b/docs/source/CONTRIBUTING.md new file mode 100644 index 0000000000..f2c987c718 --- /dev/null +++ b/docs/source/CONTRIBUTING.md @@ -0,0 +1 @@ +.. mdinclude:: ../../CONTRIBUTING.md diff --git a/docs/source/_templates/autosummary/base.rst b/docs/source/_templates/autosummary/base.rst deleted file mode 100644 index a58aa35ff9..0000000000 --- a/docs/source/_templates/autosummary/base.rst +++ /dev/null @@ -1,10 +0,0 @@ -{% if referencefile %} -.. include:: {{ referencefile }} -{% endif %} - -{{ objname }} -{{ underline }} - -.. currentmodule:: {{ module }} - -.. auto{{ objtype }}:: {{ objname }} diff --git a/docs/source/_templates/autosummary/class.rst b/docs/source/_templates/autosummary/class.rst deleted file mode 100644 index e4d661a008..0000000000 --- a/docs/source/_templates/autosummary/class.rst +++ /dev/null @@ -1,49 +0,0 @@ -{% if referencefile %} -.. include:: {{ referencefile }} -{% endif %} - -{{ objname }} -{{ underline }} - -.. currentmodule:: {{ module }} - -.. autoclass:: {{ objname }} - :no-members: - :no-inherited-members: - :no-special-members: - - {% block attributes_summary %} - {% if attributes %} - - .. rubric:: Attributes - - .. autosummary:: - :toctree: ../stubs/ - {% for item in all_attributes %} - {%- if not item.startswith('_') %} - {{ name }}.{{ item }} - {%- endif -%} - {%- endfor %} - {% endif %} - {% endblock %} - - {% block methods_summary %} - {% if methods %} - - .. rubric:: Methods - - .. autosummary:: - :toctree: ../stubs/ - {% for item in all_methods %} - {%- if not item.startswith('_') or item in ['__call__', '__mul__', '__getitem__', '__len__'] %} - {{ name }}.{{ item }} - {%- endif -%} - {%- endfor %} - {% for item in inherited_members %} - {%- if item in ['__call__', '__mul__', '__getitem__', '__len__'] %} - {{ name }}.{{ item }} - {%- endif -%} - {%- endfor %} - - {% endif %} - {% endblock %} diff --git a/docs/source/_templates/autosummary/module.rst b/docs/source/_templates/autosummary/module.rst deleted file mode 100644 index 11208a25c6..0000000000 --- a/docs/source/_templates/autosummary/module.rst +++ /dev/null @@ -1,41 +0,0 @@ -{% if referencefile %} -.. include:: {{ referencefile }} -{% endif %} - -{{ objname }} -{{ underline }} - -.. automodule:: {{ fullname }} - - {% block functions %} - {% if functions %} - .. rubric:: Functions - - .. autosummary:: - {% for item in functions %} - {{ item }} - {%- endfor %} - {% endif %} - {% endblock %} - - {% block classes %} - {% if classes %} - .. rubric:: Classes - - .. autosummary:: - {% for item in classes %} - {{ item }} - {%- endfor %} - {% endif %} - {% endblock %} - - {% block exceptions %} - {% if exceptions %} - .. rubric:: Exceptions - - .. autosummary:: - {% for item in exceptions %} - {{ item }} - {%- endfor %} - {% endif %} - {% endblock %} diff --git a/docs/source/_templates/page.html b/docs/source/_templates/page.html deleted file mode 100644 index 429a7dedd9..0000000000 --- a/docs/source/_templates/page.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "!page.html" %} - -{% block footer %} - -{% endblock %} \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 40ccdf9eca..7f69d28945 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -32,6 +32,7 @@ 'sphinx.ext.viewcode', 'm2r2', 'jupyter_sphinx.execute', + 'reno.sphinxext', ] html_static_path = ['_static'] templates_path = ['_templates'] @@ -122,14 +123,13 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'sphinx_rtd_theme' +html_theme = 'qiskit_sphinx_theme' html_theme_options = { 'logo_only': False, 'display_version': True, 'prev_next_buttons_location': 'bottom', 'style_external_links': True, - 'style_nav_header_background': '#212121', } # Theme options are theme-specific and customize the look and feel of a theme diff --git a/docs/source/index.rst b/docs/source/index.rst index 970a809eae..a2087aff72 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -9,6 +9,8 @@ Contents: README Retworkx API + Release Notes + Contributing Guide .. Hiding - Indices and tables :ref:`genindex` diff --git a/docs/source/release_notes.rst b/docs/source/release_notes.rst new file mode 100644 index 0000000000..adfd39f069 --- /dev/null +++ b/docs/source/release_notes.rst @@ -0,0 +1,369 @@ +.. release-notes:: Release Notes + +0.7.1 +===== + +This release includes a fix for an oversight in the previous 0.7.0 and +0.6.0 releases. Those releases both added custom return types +:class:`~retworkx.BFSSuccessors`, :class:`~retworkx.NodeIndices`, +:class:`~retworkx.EdgeList`, and :class:`~retworkx.WeightedEdgeList` that +implemented the Python sequence protocol which were used in place of +lists for certain functions and methods. However, none of those classes +had support for being pickled, which was causing compatibility issues +for users that were using the return in a context where it would be +pickled (for example as an argument to or return of a function called +with multiprocessing). This release has a single change over 0.7.0 which +is to add the missing support for pickling :class:`~retworkx.BFSSuccessors`, +:class:`~retworkx.NodeIndices`, :class:`~retworkx.EdgeList`, and +:class:`~retworkx.WeightedEdgeList` which fixes that issue. + +0.7.0 +===== + +This release includes several new features and bug fixes. + +This release also dropped support for Python 3.5. If you want to use +retworkx with Python 3.5 that last version which supports Python 3.5 +is 0.6.0. + +New Features +------------ + +- New generator functions for two new generator types, mesh and grid + were added to :mod:`retworkx.generators` for generating all to all and grid + graphs respectively. These functions are: + :func:`~retworkx.generators.mesh_graph`, + :func:`~retworkx.generators.directed_mesh_graph`, + :func:`~retworkx.generators.grid_graph`, and + :func:`~retworkx.generators.directed_grid_graph` +- A new function, :func:`retworkx.digraph_union`, for taking the union between + two :class:`~retworkx.PyDiGraph` objects has been added. +- A new :class:`~retworkx.PyDiGraph` method + :meth:`~retworkx.PyDiGraph.merge_nodes` has been added. This method can be + used to merge 2 nodes in a graph if they have the same weight/data payload. +- A new :class:`~retworkx.PyDiGraph` method + :meth:`~retworkx.PyDiGraph.find_node_by_weight()` which can be used to lookup + a node index by a given weight/data payload. +- A new return type :class:`~retworkx.NodeIndices` has been added. This class + is returned by functions and methods that return a list of node indices. It + implements the Python sequence protocol and can be used as list. +- Two new return types :class:`~retworkx.EdgeList` and + :class:`~retworkx.WeightedEdgeList`. These classes are returned from functions + and methods that return a list of edge tuples and a list of edge tuples with + weights. They both implement the Python sequence protocol and can be used as + a list +- A new function :func:`~retworkx.collect_runs` has been added. This function is + used to find linear paths of nodes that match a given condition. + +Upgrade Notes +------------- + +- Support for running retworkx on Python 3.5 has been dropped. The last + release with support for Python 3.5 is 0.6.0. +- The :meth:`retworkx.PyDiGraph.node_indexes`, + :meth:`retworkx.PyDiGraph.neighbors`, + :meth:`retworkx.PyDiGraph.successor_indices`, + :meth:`retworkx.PyDiGraph.predecessor_indices`, + :meth:`retworkx.PyDiGraph.add_nodes_from`, + :meth:`retworkx.PyGraph.node_indexes`, + :meth:`retworkx.PyGraph.add_nodes_from`, and + :meth:`retworkx.PyGraph.neighbors` methods and the + :func:`~retworkx.dag_longest_path`, :func:`~retworkx.topological_sort`, + :func:`~retworkx.graph_astar_shortest_path`, and + :func:`~retworkx.digraph_astar_shortest_path` functions now return a + :class:`~retworkx.NodeIndices` object instead of a list of integers. This + should not require any changes unless explicit type checking for a list was + used. +- The :meth:`retworkx.PyDiGraph.edge_list`, and + :meth:`retworkx.PyGraph.edge_list` methods and + :func:`~retworkx.digraph_dfs_edges`, :func:`~retworkx.graph_dfs_edges`, + and :func:`~retworkx.digraph_find_cycle` functions now return an + :class:`~retworkx.EdgeList` object instead of a list of integers. This should + not require any changes unless explicit type checking for a list was used. +- The :meth:`retworkx.PyDiGraph.weighted_edge_list`, + :meth:`retworkx.PyDiGraph.in_edges`, :meth:`retworkx.PyDiGraph.out_edges`, + and `retworkx.PyGraph.weighted_edge_list` methods now return a + :class:`~retworkx.WeightedEdgeList` object instead of a list of integers. + This should not require any changes unless explicit type checking for a list + was used. + +Fixes +----- +- :class:`~retworkx.BFSSuccessors` objects now can be compared with ``==`` and + ``!=`` to any other Python sequence type. +- The built and published sdist packages for retworkx were previously + not including the Cargo.lock file. This meant that the reproducible + build versions of the rust dependencies were not passed through to + source. This has been fixed so building from sdist will always use + known working versions that we use for testing in CI. + +0.6.0 +===== + +This release includes a number of new features and bug fixes. The main focus of +this release was to expand the retworkx API functionality to include some +commonly needed functions that were missing. + +This release is also the first release to provide full support for running with +Python 3.9. On previous releases Python 3.9 would likely work, but it would +require building retworkx from source. Also this will likely be the final +release that supports Python 3.5. + +New Features +------------ + +- Two new functions, :func:`~retworkx.digraph_k_shortest_path_lengths` and + :func:`~retworkx.graph_k_shortest_path_lengths`, for finding the k shortest + path lengths from a node in a :class:`~retworkx.PyDiGraph` and + :class:`~retworkx.PyGraph`. +- A new method, :meth:`~retworkx.PyDiGraph.is_symmetric`, to the + :class:`~retworkx.PyDiGraph` class. This method will check whether the graph + is symmetric or not +- A new kwarg, ``as_undirected``, was added to the + :func:`~retworkx.digraph_floyd_warshall_numpy()` function. This can be used + to treat the input :class:`~retworkx.PyDiGraph` object as if it was + undirected for the generated output matrix. +- A new function, :func:`~retworkx.digraph_find_cycle()`, which will return the + first cycle during a depth first search of a :class:`~retworkx.PyDiGraph` + object. +- Two new functions, :func:`~retworkx.directed_gnm_random_graph()` and + :func:`~retworkx.undirected_gnm_random_graph()`, for generating random + :math:`G(n, m)` graphs. +- A new method, :meth:`~retworkx.PyDiGraph.remove_edges_from`, was added to + :class:`~retworkx.PyDiGraph` and :class:`~retworkx.PyGraph` + (:meth:`~retworkx.PyGraph.removed_edges_from`). This can be used to remove + multiple edges from a graph object in a single call. +- A new method, :meth:`~retworkx.PyDiGraph.subgraph`, was added to + :class:`~retworkx.PyDiGraph` and :class:`~retworkx.PyGraph` + (:meth:`~retworkx.PyGraph.subgraph`) which takes in a list of node indices + and will return a new object of the same type representing a subgraph + containing the node indices in that list. +- Support for running with Python 3.9 +- A new method, :meth:`~retworkx.PyDiGraph.to_undirected`, was added to + :class:`~retworkx.PyDiGraph`. This method will generate an undirected + :class:`~retworkx.PyGraph` object from the :class:`~retworkx.PyDiGraph` + object. +- A new kwarg, ``bidirectional``, was added to the directed generator functions + :func:`~retworkx.generators.directed_cycle_graph`, + :func:`~retworkx.generators.directed_path_graph`, and + :func:`~retworkx.generators.directed_star_graph`. When set to ``True`` the + directed graphs generated by these functions will add edges in both directions. +- Added two new functions, :func:`~retworkx.is_weakly_connected()` and + :func:`~retworkx.weakly_connected_components`, which will either check if a + :class:`~retworkx.PyDiGraph` object is weakly connected or return the list of + the weakly connected components of an input :class:`~retworkx.PyDiGraph`. +- The ``weight_fn`` kwarg for :func:`~retworkx.graph_adjacency_matrix`, + :func:`~retworkx.digraph_adjacency_matrix`, + :func:`~retworkx.graph_floyd_warshall_numpy`, and + :func:`~retworkx.digraph_floyd_warshall_numpy` is now optional. Previously, + it always had to be specified when calling these function. But, instead you + can now rely on a default weight float (which defaults to ``1.0``) to be used + for all the edges in the graph. +- Add a :meth:`~retworkx.PyGraph.neighbors` method to + :class:`~retworkx.PyGraph` and :class:`~retworkx.PyDiGraph` + (:meth:`~retworkx.PyDiGraph.neighbors`). This function will return the node + indices of the neighbor nodes for a given input node. +- Two new methods, :meth:`~retworkx.PyDiGraph.successor_indices` and + :meth:`~retworkx.PyDiGraph.predecessor_indices`, were added to + :class:`~retworkx.PyDiGraph`. These methods will return the node indices for + the successor and predecessor nodes of a given input node. +- Two new functions, :func:`~retworkx.graph_distance_matrix` and + :func:`~retworkx.digraph_distance_matrix`, were added for generating a + distance matrix from an input :class:`~retworkx.PyGraph` and + :class:`~retworkx.PyDiGraph`. +- Two new functions, :func:`~retworkx.digraph_dijkstra_shortest_paths` and + :func:`~retworkx.graph_dijkstra_shortest_path`, were added for returning the + shortest paths from a node in a :class:`~retworkx.PyDiGraph` and a + :class:`~retworkx.PyGraph` object. +- Four new methods, :meth:`~retworkx.PyDiGraph.insert_node_on_in_edges`, + :meth:`~retworkx.PyDiGraph.insert_node_on_out_edges`, + :meth:`~retworkx.PyDiGraph.insert_node_on_in_edges_multiple`, and + :meth:`~retworkx.PyDiGraph.insert_node_on_out_edges_multiple` were added to + :class:`~retworkx.PyDiGraph`. These functions are used to insert an existing + node in between an reference node(s) and all it's predecessors or successors. +- Two new functions, :func:`~retworkx.graph_dfs_edges` and + :func:`~retworkx.digraph_dfs_edges`, were added to get an edge list in depth + first order from a :class:`~retworkx.PyGraph` and + :class:`~retworkx.PyDiGraph`. + +Upgrade Notes +------------- + +- The numpy arrays returned by :func:`~retworkx.graph_floyd_warshall_numpy`, + :func:`~retworkx.digraph_floyd_warshall_numpy`, + :func:`~retworkx.digraph_adjacency_matrix`, and + :func:`~retworkx.graph_adjacency_matrix` will now be in a contiguous C array + memory layout. Previously, they would return arrays in a column-major fortran + layout. This was change was made to make it easier to interface the arrays + returned by these functions with other C Python extensions. There should be + no change when interacting with the numpy arrays via numpy's API. +- The :func:`~retworkx.bfs_successors` method now returns an object of a custom + type :class:`~retworkx.BFSSuccessors` instead of a list. The + :class:`~retworkx.BFSSuccessors` type implements the Python sequence protocol + so it can be used in place like a list (except for where explicit type checking + is used). This was done to defer the type conversion between Rust and Python + since doing it all at once can be a performance bottleneck especially for + large graphs. The :class:`~retworkx.BFSSuccessors` class will only do the type + conversion when an element is accessed. + +Fixes +----- +- When pickling :class:`~retworkx.PyDiGraph` objects the original node indices + will be preserved across the pickle. +- The random :math:`G(n, p)` functions, + :func:`~retworkx.directed_gnp_random_graph` and + :func:`~retworkx.undirected_gnp_random_graph`, will now also handle exact 0 or + 1 probabilities. Previously it would fail in these cases. Fixes + `#172 `__ + + +0.5.0 +===== + +This release include a number of new features and bug fixes. The main +focus of the improvements of this release was to increase the ease of +interacting with graph objects. This includes adding support for generating dot +output which can be used with graphviz (or similar tools) for visualizing +graphs adding more methods to query the state of graph, adding a generator +module for easily creating graphs of certain shape, and implementing the +mapping protocol so you can directly interact with graph objects. + +New Features +------------ + +- A new method, :meth:`~retworkx.PyGraph.to_dot`, was added to + :class:`~retworkx.PyGraph` and :class:`~retworkx.PyDiGraph` + (:meth:`~retworkx.PyDiGraph.to_dot`). It will generate a + `dot format `__ representation of + the object which can be used with `Graphivz `__ (or + similar tooling) to generate visualizations of graphs. +- Added a new function, :func:`~retworkx.strongly_connected_components`, to get + the list of strongly connected components of a :class:`~retworkx.PyDiGraph` + object. +- A new method, :meth:`~retworkx.PyGraph.compose`, for composing another graph + object of the same type into a graph was added to :class:`~retworkx.PyGraph` + and :class:`~retworkx.PyDiGraph` (:meth:`~retworkx.PyDiGraph.compose`). +- The :class:`~retworkx.PyGraph` and :class:`~retworkx.PyDigraph` classes now + implement the Python mapping protocol for interacting with graph nodes. You + can now access and interact with node data directly by using standard map + access patterns in Python. For example, accessing a graph like ``graph[1]`` + will return the weight/data payload for the node at index 1. +- A new module, :mod:`retworkx.generators`, has been added. Functions in this + module can be used for quickly generating graphs of certain shape. To start + it includes: + + - :func:`retworkx.generators.cycle_graph` + - :func:`retworkx.generators.directed_cycle_graph` + - :func:`retworkx.generators.path_graph` + - :func:`retworkx.generators.directed_path_graph` + - :func:`retworkx.generators.star_graph` + - :func:`retworkx.generators.directed_star_graph` + +- A new method, :meth:`~retworkx.PyDiGraph.remove_node_retain_edges`, has been + added to the :class:`~retworkx.PyDiGraph` class. This method can be used to + remove a node and add edges from its predecesors to its successors. +- Two new methods, :meth:`~retworkx.PyGraph.edge_list` and + :meth:`~retworkx.PyGraph.weighted_edge_list`, for getting a list of tuples + with the edge source and target (with or without edge weights) have been + added to :class:`~retworkx.PyGraph` and :class:`~retworkx.PyDiGraph` + (:meth:`~retworkx.PyDiGraph.edge_list` and + :meth:`~retworkx.PyDiGraph.weighted_edge_list`) +- A new function, :func:`~retworkx.cycle_basis`, for getting a list of cycles + which form a basis for cycles of a :class:`~retworkx.PyGraph` object. +- Two new functions, :func:`~retworkx.graph_floyd_warshall_numpy` and + :func:`~retworkx.digraph_floyd_warshall_numpy`, were added for running the + Floyd Warshall algorithm and returning all the shortest path lengths as a + distance matrix. +- A new constructor method, :meth:`~retworkx.PyGraph.read_edge_list`, has been + added to :class:`~retworkx.PyGraph` and :class:`~retworkx.PyDigraph` + (:meth:`~retworkx.read_edge_list`). This method will take in a path to an + edge list file and will read that file and generate a new object from the + contents. +- Two new methods, :meth:`~retworkx.PyGraph.extend_from_edge_list` and + :meth:`~retworkx.PyGraoh.extend_from_weighted_edge_list` has been added + to :class:`~retworkx.PyGraph` and :class:`~retworkx.PyDiGraph` + (:meth:`~retworkx.PyDiGraph.extend_from_edge_list` and + :meth:`~retworkx.PyDiGraph.extend_from_weighted_edge_list`). This method + takes in an edge list and will add both the edges and nodes (if a node index + used doesn't exist yet) in the list to the graph. + +Fixes +----- + +- The limitation with the :func:`~retworkx.is_isomorphic` and + :func:`~retworkx.is_isomorphic_node_match` functions that would cause + segfaults when comparing graphs with node removals has been fixed. You can + now run either function with any + :class:`~retworkx.PyDiGraph`/:class:`~retworkx.PyDAG` objects, even if there + are node removals. Fixes + `#27 `__ +- If an invalid node index was passed as part of the ``first_layer`` + argument to the :func:`~retworkx.layers` function it would previously raise + a ``PanicException`` that included a Rust backtrace and no other user + actionable details which was caused by an unhandled error. This has been + fixed so that an ``IndexError`` is raised and the problematic node index + is included in the exception message. + +0.4.0 +===== + +This release includes many new features and fixes, including improved +performance and better documentation. But, the biggest change for this +release is that this is the first release of retworkx that supports +compilation with a stable released version of rust. This was made +possible thanks to all the hard work of the PyO3 maintainers and +contributors in the PyO3 0.11.0 release. + +New Features +------------ + +- A new class for undirected graphs, :class:`~retworkx.PyGraph`, was added. +- 2 new functions :func:`~retworkx.graph_adjacency_matrix` and + :func:`~retworkx.digraph_adjacency_matrix` to get the adjacency matrix of a + :class:`~retworkx.PyGraph` and :class:`~retworkx.PyDiGraph` object. +- A new :class:`~retworkx.PyDiGraph` method, + :meth:`~retworkx.PyDiGraph.find_adjacent_node_by_edge`, was added. This is + used to locate an adjacent node given a condition based on the edge between them. +- New methods, :meth:`~retworkx.PyDiGraph.add_nodes_from`, + :meth:`~retworkx.PyDiGraph.add_edges_from`, + :meth:`~retworkx.PyDiGraph.add_edges_from_no_data`, and + :meth:`~retworkx.PyDiGraph.remove_nodes_from` were added to + :class:`~retworkx.PyDiGraph`. These methods allow for the addition (and + removal) of multiple nodes or edges from a graph in a single call. +- A new function, :func:`~retworkx.graph_greedy_color`, which is used to + return a coloring map from a :class:`~retworkx.PyGraph` object. +- 2 new functions, :func:`~retworkx.graph_astar_shortest_path` and + :func:`~retworkx.digraph_astar_shortest_path`, to find the shortest path + from a node to a specified goal using the A* search algorithm. +- 2 new functions, :func:`~retworkx.graph_all_simple_paths` and + :func:`~retworkx.digraph_all_simple_paths`, to return a list of all the + simple paths between 2 nodes in a :class:`~retworkx.PyGraph` or a + :class:`~retworkx.PyDiGraph` object. +- 2 new functions, :func:`~retworkx.directed_gnp_random_graph` and + :func:`~retworkx.undirected_gnp_random_graph`, to generate :math:`G_{np}` + random :class:`~retworkx.PyDiGraph` and :class:`~retworkx.PyGraph` objects. +- 2 new functions, :func:`~retworkx.graph_dijkstra_shortest_path_lengths` and + :func:`~retworkx.digraph_dijkstra_shortest_path_lengths`, were added for find + the shortest path length between nodes in :class:`~retworkx.PyGraph` or + :class:`~retworkx.PyDiGraph` object using Dijkstra's algorithm. + +Upgrade Notes +------------- + +- The :class:`~retworkx.PyDAG` class was renamed :class:`~retworkx.PyDiGraph` + to better reflect it's functionality. For backwards compatibility + :class:`~retworkx.PyDAG` still exists as a Python subclass of + :class:`~retworkx.PyDiGraph`. No changes should be required for existing + users. +- `numpy `__ is now a dependency of retworkx. This is used + for the adjacency matrix functions to return numpy arrays. The minimum + version of numpy supported is 1.16.0. + +Fixes +----- + +- The retworkx exception classes are now properly exported from the + retworkx module. In prior releases it was not possible to import the + exception classes (normally to catch one being raised) requiring users + to catch the base Exception class. This has been fixed so a + specialized retworkx exception class can be used. diff --git a/docs/source/requirements.txt b/docs/source/requirements.txt index bf6266b267..b31c5e21cf 100644 --- a/docs/source/requirements.txt +++ b/docs/source/requirements.txt @@ -4,3 +4,5 @@ sphinx_rtd_theme jupyter-sphinx==0.2.3 pydot pillow>=4.2.1 +reno>=3.2.0 +qiskit-sphinx-theme>=1.7 diff --git a/releasenotes/config.yaml b/releasenotes/config.yaml new file mode 100644 index 0000000000..fa9f8f379e --- /dev/null +++ b/releasenotes/config.yaml @@ -0,0 +1,2 @@ +--- +encoding: utf8