py-trees 2.2.3__tar.gz → 2.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. {py_trees-2.2.3 → py_trees-2.4.0}/PKG-INFO +52 -83
  2. {py_trees-2.2.3 → py_trees-2.4.0}/README.md +43 -77
  3. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/behaviour.py +12 -10
  4. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/behaviours.py +130 -10
  5. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/blackboard.py +5 -5
  6. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/common.py +6 -6
  7. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/composites.py +39 -29
  8. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/decorators.py +83 -10
  9. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/action.py +1 -1
  10. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/blackboard.py +1 -1
  11. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/blackboard_namespaces.py +1 -1
  12. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/context_switching.py +1 -1
  13. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/dot_graphs.py +1 -1
  14. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/either_or.py +1 -1
  15. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/eternal_guard.py +1 -1
  16. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/lifecycle.py +1 -1
  17. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/logging.py +1 -1
  18. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/pick_up_where_you_left_off.py +1 -1
  19. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/selector.py +1 -1
  20. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/sequence.py +1 -1
  21. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/stewardship.py +1 -1
  22. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/tests.py +1 -1
  23. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/timers.py +1 -1
  24. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/trees.py +18 -11
  25. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/version.py +1 -1
  26. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/visitors.py +1 -1
  27. {py_trees-2.2.3 → py_trees-2.4.0}/pyproject.toml +4 -4
  28. py_trees-2.2.3/setup.py +0 -60
  29. {py_trees-2.2.3 → py_trees-2.4.0}/LICENSE +0 -0
  30. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/__init__.py +0 -0
  31. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/console.py +0 -0
  32. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/README.md +0 -0
  33. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/__init__.py +0 -0
  34. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/blackboard_remappings.py +0 -0
  35. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/demos/display_modes.py +0 -0
  36. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/display.py +0 -0
  37. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/idioms.py +0 -0
  38. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/logging.py +0 -0
  39. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/meta.py +0 -0
  40. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/programs/__init__.py +0 -0
  41. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/programs/render.py +0 -0
  42. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/py.typed +0 -0
  43. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/syntax_highlighting.py +0 -0
  44. {py_trees-2.2.3 → py_trees-2.4.0}/py_trees/utilities.py +0 -0
@@ -1,61 +1,65 @@
1
- Metadata-Version: 2.1
2
- Name: py-trees
3
- Version: 2.2.3
1
+ Metadata-Version: 2.4
2
+ Name: py_trees
3
+ Version: 2.4.0
4
4
  Summary: pythonic implementation of behaviour trees
5
- Home-page: https://github.com/splintered-reality/py_trees
6
5
  License: BSD
6
+ License-File: LICENSE
7
7
  Keywords: py_trees,py-trees,behaviour-trees
8
8
  Author: Daniel Stonier
9
9
  Maintainer: Daniel Stonier
10
10
  Maintainer-email: d.stonier@gmail.com
11
- Requires-Python: >=3.8,<4.0
11
+ Requires-Python: >=3.9,<4.0
12
12
  Classifier: Environment :: Console
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: License :: OSI Approved :: BSD License
15
15
  Classifier: License :: Other/Proprietary License
16
16
  Classifier: Programming Language :: Python
17
17
  Classifier: Programming Language :: Python :: 3
18
- Classifier: Programming Language :: Python :: 3.8
19
18
  Classifier: Programming Language :: Python :: 3.9
20
19
  Classifier: Programming Language :: Python :: 3.10
21
20
  Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3.14
22
24
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
25
  Classifier: Topic :: Software Development :: Libraries
24
26
  Requires-Dist: pydot (>=1.4)
25
27
  Project-URL: Documentation, https://py-trees.readthedocs.io/en/devel/
28
+ Project-URL: Homepage, https://github.com/splintered-reality/py_trees
26
29
  Project-URL: Repository, https://github.com/splintered-reality/py_trees
27
30
  Description-Content-Type: text/markdown
28
31
 
29
- # Py Trees
32
+ # PyTrees
30
33
 
31
- [[About](#about)] [[What's New?](#whats-new)] [[Documentation](#documentation)] [[Getting Started](#getting-started)] [[Next Steps](#next-steps)] [[Releases](#releases)] [[Developers](#developers)]
34
+ [[About](#about)] [[What's New?](#whats-new)] [[Documentation](#documentation)] [[Getting Started](#getting-started)] [[Next Steps](#next-steps)] [[Releases](#releases)]
32
35
 
33
36
  ----
34
37
 
35
38
  ## About
36
39
 
37
- PyTrees is a python implementation of behaviour trees designed to facilitate the rapid development of medium sized decision making engines for use in fields like robotics. Brief feature list:
40
+ PyTrees is a Python implementation of behaviour trees designed to facilitate the rapid development of medium sized decision making engines for use in fields like robotics.
41
+
42
+ Brief feature list:
38
43
 
39
44
  * Behaviours, Decorators, Sequences, Selectors, Parallels and BehaviourTree.
40
45
  * Blackboards for data sharing.
41
- * A useful library of behaviours, decorators and idioms.
46
+ * A useful library of behaviours, decorators, and idioms.
42
47
  * Serialise to a dot graph or render to ascii/unicode in a terminal.
43
48
  * Tested on Linux and Mac (YMMV with Windows).
44
49
 
45
50
  ## What's New?
46
51
 
47
- * [2023-01-28] The [2.2.x Release][new-2.2.x] is out! Sequences and Selectors with AND without memory.
48
- * [2023-01-28] [Get Started](#getting-started) with py_trees in under 5mins.
49
- * [2023-01-28] This is now a `poetry` project with configuration governed by `pyproject.toml`.
50
- * The vestigial `setup.py` is only to assist distribution where [PEP-517](https://peps.python.org/pep-0517/) is not yet well supported.
52
+ * [2025-11-13] New `ForEach` decorator.
53
+ * [2025-11-13] New `CompareBlackboardVariables` behaviour, with comparison expressions that allow callables.
54
+ * [2025-01-11] Support for Python 3.12 was added, and Python 3.8 was dropped.
51
55
 
52
56
  ## Documentation
53
57
 
54
- [![devel][docs-devel-image]][docs-devel] [![2.2.x][docs-2.2.x-image]][docs-2.2.x] [![2.1.x][docs-2.1.x-image]][docs-2.1.x] [![0.7.x][docs-0.7.x-image]][docs-0.7.x] [![0.6.x][docs-0.6.x-image]][docs-0.6.x]
58
+ [![devel][docs-devel-image]][docs-devel] [![2.4.x][docs-2.4.x-image]][docs-2.4.x] [![2.3.x][docs-2.3.x-image]][docs-2.3.x] [![2.2.x][docs-2.2.x-image]][docs-2.2.x] [![2.1.x][docs-2.1.x-image]][docs-2.1.x]
55
59
 
56
60
  ## Getting Started
57
61
 
58
- You can get started on CodeSpaces (with no mismatched environment issues and in under 5mins) [1]:
62
+ You can get started on Codespaces (with no mismatched environment issues and in under 5 minutes) [1]:
59
63
 
60
64
  1. Fork the project to your personal account
61
65
  2. Click on Code -> Codespaces -> + Create a Codespace
@@ -67,24 +71,24 @@ You can get started on CodeSpaces (with no mismatched environment issues and in
67
71
 
68
72
  # Explore the demos
69
73
  (docker) zen@py_trees:/workspaces/py_trees$ poetry shell
70
- (py-trees-py3.8) (docker) zen@py_trees:/workspaces/py_trees$ py-trees-demo-<tab>-<tab>
74
+ (py-trees-py3.10) (docker) zen@py_trees:/workspaces/py_trees$ py-trees-demo-<tab>-<tab>
71
75
  py-trees-demo-action-behaviour py-trees-demo-context-switching py-trees-demo-logging
72
76
  py-trees-demo-behaviour-lifecycle py-trees-demo-display-modes py-trees-demo-pick-up-where-you-left-off
73
77
  py-trees-demo-blackboard py-trees-demo-dot-graphs py-trees-demo-selector
74
78
  py-trees-demo-blackboard-namespaces py-trees-demo-either-or py-trees-demo-sequence
75
79
  py-trees-demo-blackboard-remappings py-trees-demo-eternal-guard py-trees-demo-tree-stewardship
76
- (py-trees-py3.8) (docker) zen@py_trees:/workspaces/py_trees$ py-trees-demo-blackboard
80
+ (py-trees-py3.10) (docker) zen@py_trees:/workspaces/py_trees$ py-trees-demo-blackboard
77
81
  ...
78
- (py-trees-py3.8) (docker) zen@py_trees:/workspaces/py_trees$ exit
82
+ (py-trees-py3.10) (docker) zen@py_trees:/workspaces/py_trees$ exit
79
83
 
80
84
  # Hack some Code
81
85
 
82
86
  # Run the Formatter, Tests, Linters and Mypy
83
87
  (docker) zen@py_trees:/workspaces/py_trees$ poetry run tox -l
84
- py38 py310 format check mypy38 mypy310
88
+ py310 py312 format check mypy310 mypy312
85
89
  (docker) zen@py_trees:/workspaces/py_trees$ poetry run tox -e format
86
90
  ...
87
- (docker) zen@py_trees:/workspaces/py_trees$ poetry run tox -e py38
91
+ (docker) zen@py_trees:/workspaces/py_trees$ poetry run tox -e py310
88
92
  ...
89
93
  (docker) zen@py_trees:/workspaces/py_trees$ poetry run tox -e check
90
94
  ...
@@ -93,8 +97,8 @@ py38 py310 format check mypy38 mypy310
93
97
  # https://github.com/splintered-reality/py_trees/blob/devel/CONTRIBUTING.md
94
98
  ```
95
99
 
96
- [1] All of the above will, of course, work in a local environment if you have `poetry` installed. If you're using `VSCode`
97
- you don't even need that, just reopen the project in the [devcontainer](.devcontainer/devcontainer.json) and be froody.
100
+ [1] All of the above will, of course, work in a local environment if you have `poetry` installed.
101
+ If you're using `VSCode` you don't even need that, just reopen the project in the [devcontainer](.devcontainer/devcontainer.json) and be froody.
98
102
 
99
103
  ## Next Steps
100
104
 
@@ -103,7 +107,7 @@ On PyPi:
103
107
  * [py_trees_js](https://pypi.org/project/py-trees-js/)
104
108
 
105
109
  Examples:
106
- * [ReadTheDocs - PyTrees ROS Tutorials](https://py-trees-ros-tutorials.readthedocs.io/en/release-2.0.x/index.html) - significantly more edifying than the demos, these incrementally walk through the process of building a decision making layer for a robot. These use ROS2 (sparsely), but merely browsing should be enlightening regardless.
110
+ * [ReadTheDocs - PyTrees ROS Tutorials](https://py-trees-ros-tutorials.readthedocs.io/en/devel/index.html) - significantly more edifying than the demos, these incrementally walk through the process of building a decision making layer for a robot. These use ROS2 (sparsely), but merely browsing should be enlightening regardless.
107
111
 
108
112
  Visualisation:
109
113
  * [py_trees_js](https://github.com/splintered-reality/py_trees_js) - a javascript library for building your own runtime visualisation tool
@@ -114,6 +118,8 @@ Robotics:
114
118
 
115
119
  ## Releases
116
120
 
121
+ * `2.4.x` - New ForEach decorator, new CompareBlackboardVariables behaviour, and callables in comparison expressions.
122
+ * `2.3.x` - Support for Python 3.12 was added, and Python 3.8 was dropped.
117
123
  * `2.2.x` - Selectors, Sequences with and without memory. Improved testing and style/type checking.
118
124
  * `2.1.x` - Chooser deprecated. API housekeeping.
119
125
  * `2.0.x` - Blackboards V2!
@@ -122,83 +128,38 @@ Robotics:
122
128
  * `1.0.x` - Behaviours, Decorators, Composites, Blackboards, Tree Management and Viz tools.
123
129
  * `0.y.x` - First open source pre-releases.
124
130
 
125
- | | Devel | 2.2.x | 2.1.x | 2.0.x | 1.2.x | 0.7.x | 0.6.x |
126
- |:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
127
- | Sources | [![devel][sources-devel-image]][sources-devel] | [![2.1.x][sources-2.2.x-image]][sources-2.2.x] | [![2.1.x][sources-2.1.x-image]][sources-2.1.x] | [![2.0.x][sources-2.0.x-image]][sources-2.0.x] | [![1.2.x][sources-1.2.x-image]][sources-1.2.x] | [![0.7.x][sources-0.7.x-image]][sources-0.7.x] | [![0.6.x][sources-0.6.x-image]][sources-0.6.x]
128
- | Compatibility | [![Python 3.10][python310-image]][python310-docs] [![Python 3.8][python38-image]][python38-docs] | [![Python 3.10][python310-image]][python310-docs] [![Python 3.8][python38-image]][python38-docs] | [![Python 3.6][python36-image]][python36-docs] | [![Python 3.6][python36-image]][python36-docs] | [![Python 3.6][python36-image]][python36-docs] | [![Python 3.6][python36-image]][python36-docs] | [![Python 2.7][python27-image]][python27-docs]
129
- | CI | [![devel-Status][devel-build-status-image]][devel-build-status] | [![2.2.x-Status][2.2.x-build-status-image]][2.2.x-build-status] | - | - | - | - | - |
130
- | Documentation | [![devel-Docs][rtd-devel-image]][docs-devel] | [![2.2.x-Docs][rtd-2.2.x-image]][docs-2.2.x] | [![2.1.x-Docs][rtd-2.1.x-image]][docs-2.1.x] | [![2.0.x-Docs][rtd-2.0.x-image]][docs-2.0.x] | [![1.2.x-Docs][rtd-1.2.x-image]][docs-1.2.x] | [![0.7.x-Docs][rtd-0.7.x-image]][docs-0.7.x] | [![0.6.x-Docs][rtd-0.6.x-image]][docs-0.6.x]
131
-
132
- ## Developers
133
-
134
- ### Format, Check, MyPy, Test
135
-
136
- Check against at least one of py38 / py310 [1].
137
-
138
- ```
139
- # Auto-format your code (if using VSCode, install the ufmt extension)
140
- $ poetry run tox -e format
141
-
142
- # Style, Format
143
- $ poetry run tox -e check
131
+ | | Devel | 2.4.x | 2.3.x | 2.2.x | 2.1.x | 2.0.x |
132
+ |:---:|:---:|:---:|:---:|:---:|:---:|:---:|
133
+ | Sources | [![devel][sources-devel-image]][sources-devel] | [![2.4.x][sources-2.4.x-image]][sources-2.4.x] | [![2.3.x][sources-2.3.x-image]][sources-2.3.x] | [![2.2.x][sources-2.2.x-image]][sources-2.2.x] | [![2.1.x][sources-2.1.x-image]][sources-2.1.x] | [![2.0.x][sources-2.0.x-image]][sources-2.0.x] |
134
+ | Compatibility | [![Python 3.12][python312-image]][python312-docs]<br/>[![Python 3.10][python310-image]][python310-docs] | [![Python 3.12][python312-image]][python312-docs]<br/>[![Python 3.10][python310-image]][python310-docs] | [![Python 3.12][python312-image]][python312-docs]<br/>[![Python 3.10][python310-image]][python310-docs] | [![Python 3.10][python310-image]][python310-docs]<br/>[![Python 3.8][python38-image]][python38-docs] | [![Python 3.6][python36-image]][python36-docs] | [![Python 3.6][python36-image]][python36-docs] | [![Python 3.6][python36-image]][python36-docs] |
135
+ | CI | [![devel-Status][devel-build-status-image]][devel-build-status] | [![2.4.x-Status][2.4.x-build-status-image]][2.4.x-build-status] | [![2.3.x-Status][2.3.x-build-status-image]][2.3.x-build-status] | [![2.2.x-Status][2.2.x-build-status-image]][2.2.x-build-status] | - | - | - | - |
136
+ | Documentation | [![devel-Docs][rtd-devel-image]][docs-devel] | [![2.4.x-Docs][rtd-2.4.x-image]][docs-2.4.x] | [![2.3.x-Docs][rtd-2.3.x-image]][docs-2.3.x] | [![2.2.x-Docs][rtd-2.2.x-image]][docs-2.2.x] | [![2.1.x-Docs][rtd-2.1.x-image]][docs-2.1.x] | [![2.0.x-Docs][rtd-2.0.x-image]][docs-2.0.x] |
144
137
 
145
- # Type-Check
146
- $ poetry run mypy38
147
-
148
- # Tests
149
- $ poetry run tox -e py38
150
- ```
151
-
152
- [1] CI will test against both python versions for you, but should you wish to do so locally, open up two VSCode windows, one with the project opened in the default [py38 devcontainer](.devcontainer) and the other with the [py310 devcontainer](.devcontainer/py310).
153
-
154
- ### Generate Documentation
155
-
156
- Generate the docs, view them from `./docs/html` in a browser.
157
-
158
- ```
159
- # Install dependencies
160
- $ poetry install --with docs
161
-
162
- # Build
163
- $ poetry run make -C docs html
164
- ```
165
-
166
- On Doc dependency changes, export the requirements for ReadTheDocs
167
-
168
- ```
169
- $ poetry export -f requirements.txt --with docs -o docs/requirements.txt
170
- ```
171
-
172
- ### Publish to PyPi
173
-
174
- If you have permission to publish on pypi:
175
-
176
- ```
177
- $ poetry config http-basic.pypi ${POETRY_HTTP_BASIC_PYPI_USERNAME} ${POETRY_HTTP_BASIC_PYPI_PASSWORD}
178
- $ poetry publish
179
- ```
180
138
 
181
139
  [license-image]: https://img.shields.io/badge/License-BSD%203--Clause-orange.svg?style=plastic
182
140
  [license]: LICENSE
183
141
 
142
+ [python312-image]: https://img.shields.io/badge/python-3.12-green.svg?style=plastic
143
+ [python312-docs]: https://docs.python.org/3.12/
184
144
  [python310-image]: https://img.shields.io/badge/python-3.10-green.svg?style=plastic
185
145
  [python310-docs]: https://docs.python.org/3.10/
186
146
  [python38-image]: https://img.shields.io/badge/python-3.8-green.svg?style=plastic
187
147
  [python38-docs]: https://docs.python.org/3.8/
188
148
  [python36-image]: https://img.shields.io/badge/python-3.6-green.svg?style=plastic
189
149
  [python36-docs]: https://docs.python.org/3.6/
190
- [python27-image]: https://img.shields.io/badge/python-2.7-green.svg?style=plastic
191
- [python27-docs]: https://docs.python.org/2.7/
192
150
 
193
151
  [devel-build-status-image]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml/badge.svg
194
152
  [devel-build-status]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml
153
+ [2.4.x-build-status-image]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml/badge.svg??branch=release/2.4.x
154
+ [2.4.x-build-status]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml
155
+ [2.3.x-build-status-image]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml/badge.svg??branch=release/2.3.x
156
+ [2.3.x-build-status]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml
195
157
  [2.2.x-build-status-image]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml/badge.svg??branch=release/2.2.x
196
158
  [2.2.x-build-status]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml
197
159
 
198
- [new-2.2.x]: https://github.com/splintered-reality/py_trees/blob/devel/CHANGELOG.rst#22x-2023-01-23---sequences-and-selectors-with-and-without-memory
199
-
200
-
201
160
  [docs-devel]: http://py-trees.readthedocs.io/
161
+ [docs-2.4.x]: http://py-trees.readthedocs.io/en/release-2.4.x/
162
+ [docs-2.3.x]: http://py-trees.readthedocs.io/en/release-2.3.x/
202
163
  [docs-2.2.x]: http://py-trees.readthedocs.io/en/release-2.2.x/
203
164
  [docs-2.1.x]: http://py-trees.readthedocs.io/en/release-2.1.x/
204
165
  [docs-2.0.x]: http://py-trees.readthedocs.io/en/release-2.0.x/
@@ -209,6 +170,8 @@ $ poetry publish
209
170
  [docs-0.5.x]: http://docs.ros.org/kinetic/api/py_trees/html/
210
171
 
211
172
  [docs-devel-image]: http://img.shields.io/badge/docs-devel-brightgreen.svg?style=plastic
173
+ [docs-2.4.x-image]: http://img.shields.io/badge/docs-2.4.x-brightgreen.svg?style=plastic
174
+ [docs-2.3.x-image]: http://img.shields.io/badge/docs-2.3.x-brightgreen.svg?style=plastic
212
175
  [docs-2.2.x-image]: http://img.shields.io/badge/docs-2.2.x-brightgreen.svg?style=plastic
213
176
  [docs-2.1.x-image]: http://img.shields.io/badge/docs-2.1.x-brightgreen.svg?style=plastic
214
177
  [docs-2.0.x-image]: http://img.shields.io/badge/docs-2.0.x-brightgreen.svg?style=plastic
@@ -219,6 +182,8 @@ $ poetry publish
219
182
  [docs-0.5.x-image]: http://img.shields.io/badge/docs-0.5.x-brightgreen.svg?style=plastic
220
183
 
221
184
  [rtd-devel-image]: https://readthedocs.org/projects/py-trees/badge/?version=devel&style=plastic
185
+ [rtd-2.4.x-image]: https://readthedocs.org/projects/py-trees/badge/?version=release-2.4.x&style=plastic
186
+ [rtd-2.3.x-image]: https://readthedocs.org/projects/py-trees/badge/?version=release-2.3.x&style=plastic
222
187
  [rtd-2.2.x-image]: https://readthedocs.org/projects/py-trees/badge/?version=release-2.2.x&style=plastic
223
188
  [rtd-2.1.x-image]: https://readthedocs.org/projects/py-trees/badge/?version=release-2.1.x&style=plastic
224
189
  [rtd-2.0.x-image]: https://readthedocs.org/projects/py-trees/badge/?version=release-2.0.x&style=plastic
@@ -230,6 +195,8 @@ $ poetry publish
230
195
  [not-available-docs-image]: http://img.shields.io/badge/docs-n/a-yellow.svg?style=plastic
231
196
 
232
197
  [sources-devel]: https://github.com/splintered-reality/py_trees/tree/devel
198
+ [sources-2.4.x]: https://github.com/splintered-reality/py_trees/tree/release/2.4.x
199
+ [sources-2.3.x]: https://github.com/splintered-reality/py_trees/tree/release/2.3.x
233
200
  [sources-2.2.x]: https://github.com/splintered-reality/py_trees/tree/release/2.2.x
234
201
  [sources-2.1.x]: https://github.com/splintered-reality/py_trees/tree/release/2.1.x
235
202
  [sources-2.0.x]: https://github.com/splintered-reality/py_trees/tree/release/2.0.x
@@ -240,6 +207,8 @@ $ poetry publish
240
207
  [sources-0.5.x]: https://github.com/splintered-reality/py_trees/tree/release/0.5.x
241
208
 
242
209
  [sources-devel-image]: http://img.shields.io/badge/sources-devel-blue.svg?style=plastic
210
+ [sources-2.4.x-image]: http://img.shields.io/badge/sources-2.4.x-blue.svg?style=plastic
211
+ [sources-2.3.x-image]: http://img.shields.io/badge/sources-2.3.x-blue.svg?style=plastic
243
212
  [sources-2.2.x-image]: http://img.shields.io/badge/sources-2.2.x-blue.svg?style=plastic
244
213
  [sources-2.1.x-image]: http://img.shields.io/badge/sources-2.1.x-blue.svg?style=plastic
245
214
  [sources-2.0.x-image]: http://img.shields.io/badge/sources-2.0.x-blue.svg?style=plastic
@@ -1,33 +1,34 @@
1
- # Py Trees
1
+ # PyTrees
2
2
 
3
- [[About](#about)] [[What's New?](#whats-new)] [[Documentation](#documentation)] [[Getting Started](#getting-started)] [[Next Steps](#next-steps)] [[Releases](#releases)] [[Developers](#developers)]
3
+ [[About](#about)] [[What's New?](#whats-new)] [[Documentation](#documentation)] [[Getting Started](#getting-started)] [[Next Steps](#next-steps)] [[Releases](#releases)]
4
4
 
5
5
  ----
6
6
 
7
7
  ## About
8
8
 
9
- PyTrees is a python implementation of behaviour trees designed to facilitate the rapid development of medium sized decision making engines for use in fields like robotics. Brief feature list:
9
+ PyTrees is a Python implementation of behaviour trees designed to facilitate the rapid development of medium sized decision making engines for use in fields like robotics.
10
+
11
+ Brief feature list:
10
12
 
11
13
  * Behaviours, Decorators, Sequences, Selectors, Parallels and BehaviourTree.
12
14
  * Blackboards for data sharing.
13
- * A useful library of behaviours, decorators and idioms.
15
+ * A useful library of behaviours, decorators, and idioms.
14
16
  * Serialise to a dot graph or render to ascii/unicode in a terminal.
15
17
  * Tested on Linux and Mac (YMMV with Windows).
16
18
 
17
19
  ## What's New?
18
20
 
19
- * [2023-01-28] The [2.2.x Release][new-2.2.x] is out! Sequences and Selectors with AND without memory.
20
- * [2023-01-28] [Get Started](#getting-started) with py_trees in under 5mins.
21
- * [2023-01-28] This is now a `poetry` project with configuration governed by `pyproject.toml`.
22
- * The vestigial `setup.py` is only to assist distribution where [PEP-517](https://peps.python.org/pep-0517/) is not yet well supported.
21
+ * [2025-11-13] New `ForEach` decorator.
22
+ * [2025-11-13] New `CompareBlackboardVariables` behaviour, with comparison expressions that allow callables.
23
+ * [2025-01-11] Support for Python 3.12 was added, and Python 3.8 was dropped.
23
24
 
24
25
  ## Documentation
25
26
 
26
- [![devel][docs-devel-image]][docs-devel] [![2.2.x][docs-2.2.x-image]][docs-2.2.x] [![2.1.x][docs-2.1.x-image]][docs-2.1.x] [![0.7.x][docs-0.7.x-image]][docs-0.7.x] [![0.6.x][docs-0.6.x-image]][docs-0.6.x]
27
+ [![devel][docs-devel-image]][docs-devel] [![2.4.x][docs-2.4.x-image]][docs-2.4.x] [![2.3.x][docs-2.3.x-image]][docs-2.3.x] [![2.2.x][docs-2.2.x-image]][docs-2.2.x] [![2.1.x][docs-2.1.x-image]][docs-2.1.x]
27
28
 
28
29
  ## Getting Started
29
30
 
30
- You can get started on CodeSpaces (with no mismatched environment issues and in under 5mins) [1]:
31
+ You can get started on Codespaces (with no mismatched environment issues and in under 5 minutes) [1]:
31
32
 
32
33
  1. Fork the project to your personal account
33
34
  2. Click on Code -> Codespaces -> + Create a Codespace
@@ -39,24 +40,24 @@ You can get started on CodeSpaces (with no mismatched environment issues and in
39
40
 
40
41
  # Explore the demos
41
42
  (docker) zen@py_trees:/workspaces/py_trees$ poetry shell
42
- (py-trees-py3.8) (docker) zen@py_trees:/workspaces/py_trees$ py-trees-demo-<tab>-<tab>
43
+ (py-trees-py3.10) (docker) zen@py_trees:/workspaces/py_trees$ py-trees-demo-<tab>-<tab>
43
44
  py-trees-demo-action-behaviour py-trees-demo-context-switching py-trees-demo-logging
44
45
  py-trees-demo-behaviour-lifecycle py-trees-demo-display-modes py-trees-demo-pick-up-where-you-left-off
45
46
  py-trees-demo-blackboard py-trees-demo-dot-graphs py-trees-demo-selector
46
47
  py-trees-demo-blackboard-namespaces py-trees-demo-either-or py-trees-demo-sequence
47
48
  py-trees-demo-blackboard-remappings py-trees-demo-eternal-guard py-trees-demo-tree-stewardship
48
- (py-trees-py3.8) (docker) zen@py_trees:/workspaces/py_trees$ py-trees-demo-blackboard
49
+ (py-trees-py3.10) (docker) zen@py_trees:/workspaces/py_trees$ py-trees-demo-blackboard
49
50
  ...
50
- (py-trees-py3.8) (docker) zen@py_trees:/workspaces/py_trees$ exit
51
+ (py-trees-py3.10) (docker) zen@py_trees:/workspaces/py_trees$ exit
51
52
 
52
53
  # Hack some Code
53
54
 
54
55
  # Run the Formatter, Tests, Linters and Mypy
55
56
  (docker) zen@py_trees:/workspaces/py_trees$ poetry run tox -l
56
- py38 py310 format check mypy38 mypy310
57
+ py310 py312 format check mypy310 mypy312
57
58
  (docker) zen@py_trees:/workspaces/py_trees$ poetry run tox -e format
58
59
  ...
59
- (docker) zen@py_trees:/workspaces/py_trees$ poetry run tox -e py38
60
+ (docker) zen@py_trees:/workspaces/py_trees$ poetry run tox -e py310
60
61
  ...
61
62
  (docker) zen@py_trees:/workspaces/py_trees$ poetry run tox -e check
62
63
  ...
@@ -65,8 +66,8 @@ py38 py310 format check mypy38 mypy310
65
66
  # https://github.com/splintered-reality/py_trees/blob/devel/CONTRIBUTING.md
66
67
  ```
67
68
 
68
- [1] All of the above will, of course, work in a local environment if you have `poetry` installed. If you're using `VSCode`
69
- you don't even need that, just reopen the project in the [devcontainer](.devcontainer/devcontainer.json) and be froody.
69
+ [1] All of the above will, of course, work in a local environment if you have `poetry` installed.
70
+ If you're using `VSCode` you don't even need that, just reopen the project in the [devcontainer](.devcontainer/devcontainer.json) and be froody.
70
71
 
71
72
  ## Next Steps
72
73
 
@@ -75,7 +76,7 @@ On PyPi:
75
76
  * [py_trees_js](https://pypi.org/project/py-trees-js/)
76
77
 
77
78
  Examples:
78
- * [ReadTheDocs - PyTrees ROS Tutorials](https://py-trees-ros-tutorials.readthedocs.io/en/release-2.0.x/index.html) - significantly more edifying than the demos, these incrementally walk through the process of building a decision making layer for a robot. These use ROS2 (sparsely), but merely browsing should be enlightening regardless.
79
+ * [ReadTheDocs - PyTrees ROS Tutorials](https://py-trees-ros-tutorials.readthedocs.io/en/devel/index.html) - significantly more edifying than the demos, these incrementally walk through the process of building a decision making layer for a robot. These use ROS2 (sparsely), but merely browsing should be enlightening regardless.
79
80
 
80
81
  Visualisation:
81
82
  * [py_trees_js](https://github.com/splintered-reality/py_trees_js) - a javascript library for building your own runtime visualisation tool
@@ -86,6 +87,8 @@ Robotics:
86
87
 
87
88
  ## Releases
88
89
 
90
+ * `2.4.x` - New ForEach decorator, new CompareBlackboardVariables behaviour, and callables in comparison expressions.
91
+ * `2.3.x` - Support for Python 3.12 was added, and Python 3.8 was dropped.
89
92
  * `2.2.x` - Selectors, Sequences with and without memory. Improved testing and style/type checking.
90
93
  * `2.1.x` - Chooser deprecated. API housekeeping.
91
94
  * `2.0.x` - Blackboards V2!
@@ -94,83 +97,38 @@ Robotics:
94
97
  * `1.0.x` - Behaviours, Decorators, Composites, Blackboards, Tree Management and Viz tools.
95
98
  * `0.y.x` - First open source pre-releases.
96
99
 
97
- | | Devel | 2.2.x | 2.1.x | 2.0.x | 1.2.x | 0.7.x | 0.6.x |
98
- |:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
99
- | Sources | [![devel][sources-devel-image]][sources-devel] | [![2.1.x][sources-2.2.x-image]][sources-2.2.x] | [![2.1.x][sources-2.1.x-image]][sources-2.1.x] | [![2.0.x][sources-2.0.x-image]][sources-2.0.x] | [![1.2.x][sources-1.2.x-image]][sources-1.2.x] | [![0.7.x][sources-0.7.x-image]][sources-0.7.x] | [![0.6.x][sources-0.6.x-image]][sources-0.6.x]
100
- | Compatibility | [![Python 3.10][python310-image]][python310-docs] [![Python 3.8][python38-image]][python38-docs] | [![Python 3.10][python310-image]][python310-docs] [![Python 3.8][python38-image]][python38-docs] | [![Python 3.6][python36-image]][python36-docs] | [![Python 3.6][python36-image]][python36-docs] | [![Python 3.6][python36-image]][python36-docs] | [![Python 3.6][python36-image]][python36-docs] | [![Python 2.7][python27-image]][python27-docs]
101
- | CI | [![devel-Status][devel-build-status-image]][devel-build-status] | [![2.2.x-Status][2.2.x-build-status-image]][2.2.x-build-status] | - | - | - | - | - |
102
- | Documentation | [![devel-Docs][rtd-devel-image]][docs-devel] | [![2.2.x-Docs][rtd-2.2.x-image]][docs-2.2.x] | [![2.1.x-Docs][rtd-2.1.x-image]][docs-2.1.x] | [![2.0.x-Docs][rtd-2.0.x-image]][docs-2.0.x] | [![1.2.x-Docs][rtd-1.2.x-image]][docs-1.2.x] | [![0.7.x-Docs][rtd-0.7.x-image]][docs-0.7.x] | [![0.6.x-Docs][rtd-0.6.x-image]][docs-0.6.x]
103
-
104
- ## Developers
105
-
106
- ### Format, Check, MyPy, Test
107
-
108
- Check against at least one of py38 / py310 [1].
109
-
110
- ```
111
- # Auto-format your code (if using VSCode, install the ufmt extension)
112
- $ poetry run tox -e format
113
-
114
- # Style, Format
115
- $ poetry run tox -e check
100
+ | | Devel | 2.4.x | 2.3.x | 2.2.x | 2.1.x | 2.0.x |
101
+ |:---:|:---:|:---:|:---:|:---:|:---:|:---:|
102
+ | Sources | [![devel][sources-devel-image]][sources-devel] | [![2.4.x][sources-2.4.x-image]][sources-2.4.x] | [![2.3.x][sources-2.3.x-image]][sources-2.3.x] | [![2.2.x][sources-2.2.x-image]][sources-2.2.x] | [![2.1.x][sources-2.1.x-image]][sources-2.1.x] | [![2.0.x][sources-2.0.x-image]][sources-2.0.x] |
103
+ | Compatibility | [![Python 3.12][python312-image]][python312-docs]<br/>[![Python 3.10][python310-image]][python310-docs] | [![Python 3.12][python312-image]][python312-docs]<br/>[![Python 3.10][python310-image]][python310-docs] | [![Python 3.12][python312-image]][python312-docs]<br/>[![Python 3.10][python310-image]][python310-docs] | [![Python 3.10][python310-image]][python310-docs]<br/>[![Python 3.8][python38-image]][python38-docs] | [![Python 3.6][python36-image]][python36-docs] | [![Python 3.6][python36-image]][python36-docs] | [![Python 3.6][python36-image]][python36-docs] |
104
+ | CI | [![devel-Status][devel-build-status-image]][devel-build-status] | [![2.4.x-Status][2.4.x-build-status-image]][2.4.x-build-status] | [![2.3.x-Status][2.3.x-build-status-image]][2.3.x-build-status] | [![2.2.x-Status][2.2.x-build-status-image]][2.2.x-build-status] | - | - | - | - |
105
+ | Documentation | [![devel-Docs][rtd-devel-image]][docs-devel] | [![2.4.x-Docs][rtd-2.4.x-image]][docs-2.4.x] | [![2.3.x-Docs][rtd-2.3.x-image]][docs-2.3.x] | [![2.2.x-Docs][rtd-2.2.x-image]][docs-2.2.x] | [![2.1.x-Docs][rtd-2.1.x-image]][docs-2.1.x] | [![2.0.x-Docs][rtd-2.0.x-image]][docs-2.0.x] |
116
106
 
117
- # Type-Check
118
- $ poetry run mypy38
119
-
120
- # Tests
121
- $ poetry run tox -e py38
122
- ```
123
-
124
- [1] CI will test against both python versions for you, but should you wish to do so locally, open up two VSCode windows, one with the project opened in the default [py38 devcontainer](.devcontainer) and the other with the [py310 devcontainer](.devcontainer/py310).
125
-
126
- ### Generate Documentation
127
-
128
- Generate the docs, view them from `./docs/html` in a browser.
129
-
130
- ```
131
- # Install dependencies
132
- $ poetry install --with docs
133
-
134
- # Build
135
- $ poetry run make -C docs html
136
- ```
137
-
138
- On Doc dependency changes, export the requirements for ReadTheDocs
139
-
140
- ```
141
- $ poetry export -f requirements.txt --with docs -o docs/requirements.txt
142
- ```
143
-
144
- ### Publish to PyPi
145
-
146
- If you have permission to publish on pypi:
147
-
148
- ```
149
- $ poetry config http-basic.pypi ${POETRY_HTTP_BASIC_PYPI_USERNAME} ${POETRY_HTTP_BASIC_PYPI_PASSWORD}
150
- $ poetry publish
151
- ```
152
107
 
153
108
  [license-image]: https://img.shields.io/badge/License-BSD%203--Clause-orange.svg?style=plastic
154
109
  [license]: LICENSE
155
110
 
111
+ [python312-image]: https://img.shields.io/badge/python-3.12-green.svg?style=plastic
112
+ [python312-docs]: https://docs.python.org/3.12/
156
113
  [python310-image]: https://img.shields.io/badge/python-3.10-green.svg?style=plastic
157
114
  [python310-docs]: https://docs.python.org/3.10/
158
115
  [python38-image]: https://img.shields.io/badge/python-3.8-green.svg?style=plastic
159
116
  [python38-docs]: https://docs.python.org/3.8/
160
117
  [python36-image]: https://img.shields.io/badge/python-3.6-green.svg?style=plastic
161
118
  [python36-docs]: https://docs.python.org/3.6/
162
- [python27-image]: https://img.shields.io/badge/python-2.7-green.svg?style=plastic
163
- [python27-docs]: https://docs.python.org/2.7/
164
119
 
165
120
  [devel-build-status-image]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml/badge.svg
166
121
  [devel-build-status]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml
122
+ [2.4.x-build-status-image]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml/badge.svg??branch=release/2.4.x
123
+ [2.4.x-build-status]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml
124
+ [2.3.x-build-status-image]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml/badge.svg??branch=release/2.3.x
125
+ [2.3.x-build-status]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml
167
126
  [2.2.x-build-status-image]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml/badge.svg??branch=release/2.2.x
168
127
  [2.2.x-build-status]: https://github.com/splintered-reality/py_trees/actions/workflows/pre-merge.yaml
169
128
 
170
- [new-2.2.x]: https://github.com/splintered-reality/py_trees/blob/devel/CHANGELOG.rst#22x-2023-01-23---sequences-and-selectors-with-and-without-memory
171
-
172
-
173
129
  [docs-devel]: http://py-trees.readthedocs.io/
130
+ [docs-2.4.x]: http://py-trees.readthedocs.io/en/release-2.4.x/
131
+ [docs-2.3.x]: http://py-trees.readthedocs.io/en/release-2.3.x/
174
132
  [docs-2.2.x]: http://py-trees.readthedocs.io/en/release-2.2.x/
175
133
  [docs-2.1.x]: http://py-trees.readthedocs.io/en/release-2.1.x/
176
134
  [docs-2.0.x]: http://py-trees.readthedocs.io/en/release-2.0.x/
@@ -181,6 +139,8 @@ $ poetry publish
181
139
  [docs-0.5.x]: http://docs.ros.org/kinetic/api/py_trees/html/
182
140
 
183
141
  [docs-devel-image]: http://img.shields.io/badge/docs-devel-brightgreen.svg?style=plastic
142
+ [docs-2.4.x-image]: http://img.shields.io/badge/docs-2.4.x-brightgreen.svg?style=plastic
143
+ [docs-2.3.x-image]: http://img.shields.io/badge/docs-2.3.x-brightgreen.svg?style=plastic
184
144
  [docs-2.2.x-image]: http://img.shields.io/badge/docs-2.2.x-brightgreen.svg?style=plastic
185
145
  [docs-2.1.x-image]: http://img.shields.io/badge/docs-2.1.x-brightgreen.svg?style=plastic
186
146
  [docs-2.0.x-image]: http://img.shields.io/badge/docs-2.0.x-brightgreen.svg?style=plastic
@@ -191,6 +151,8 @@ $ poetry publish
191
151
  [docs-0.5.x-image]: http://img.shields.io/badge/docs-0.5.x-brightgreen.svg?style=plastic
192
152
 
193
153
  [rtd-devel-image]: https://readthedocs.org/projects/py-trees/badge/?version=devel&style=plastic
154
+ [rtd-2.4.x-image]: https://readthedocs.org/projects/py-trees/badge/?version=release-2.4.x&style=plastic
155
+ [rtd-2.3.x-image]: https://readthedocs.org/projects/py-trees/badge/?version=release-2.3.x&style=plastic
194
156
  [rtd-2.2.x-image]: https://readthedocs.org/projects/py-trees/badge/?version=release-2.2.x&style=plastic
195
157
  [rtd-2.1.x-image]: https://readthedocs.org/projects/py-trees/badge/?version=release-2.1.x&style=plastic
196
158
  [rtd-2.0.x-image]: https://readthedocs.org/projects/py-trees/badge/?version=release-2.0.x&style=plastic
@@ -202,6 +164,8 @@ $ poetry publish
202
164
  [not-available-docs-image]: http://img.shields.io/badge/docs-n/a-yellow.svg?style=plastic
203
165
 
204
166
  [sources-devel]: https://github.com/splintered-reality/py_trees/tree/devel
167
+ [sources-2.4.x]: https://github.com/splintered-reality/py_trees/tree/release/2.4.x
168
+ [sources-2.3.x]: https://github.com/splintered-reality/py_trees/tree/release/2.3.x
205
169
  [sources-2.2.x]: https://github.com/splintered-reality/py_trees/tree/release/2.2.x
206
170
  [sources-2.1.x]: https://github.com/splintered-reality/py_trees/tree/release/2.1.x
207
171
  [sources-2.0.x]: https://github.com/splintered-reality/py_trees/tree/release/2.0.x
@@ -212,6 +176,8 @@ $ poetry publish
212
176
  [sources-0.5.x]: https://github.com/splintered-reality/py_trees/tree/release/0.5.x
213
177
 
214
178
  [sources-devel-image]: http://img.shields.io/badge/sources-devel-blue.svg?style=plastic
179
+ [sources-2.4.x-image]: http://img.shields.io/badge/sources-2.4.x-blue.svg?style=plastic
180
+ [sources-2.3.x-image]: http://img.shields.io/badge/sources-2.3.x-blue.svg?style=plastic
215
181
  [sources-2.2.x-image]: http://img.shields.io/badge/sources-2.2.x-blue.svg?style=plastic
216
182
  [sources-2.1.x-image]: http://img.shields.io/badge/sources-2.1.x-blue.svg?style=plastic
217
183
  [sources-2.0.x-image]: http://img.shields.io/badge/sources-2.0.x-blue.svg?style=plastic
@@ -79,9 +79,9 @@ class Behaviour(abc.ABC):
79
79
  ) # convenience
80
80
  self.status = common.Status.INVALID
81
81
  self.iterator = self.tick()
82
- self.parent: typing.Optional[
83
- Behaviour
84
- ] = None # will get set if a behaviour is added to a composite
82
+ self.parent: typing.Optional[Behaviour] = (
83
+ None # will get set if a behaviour is added to a composite
84
+ )
85
85
  self.children: typing.List[Behaviour] = [] # only set by composite behaviours
86
86
  self.logger = logging.Logger(name)
87
87
  self.feedback_message = "" # useful for debugging, or human readable updates, but not necessary to implement
@@ -146,7 +146,7 @@ class Behaviour(abc.ABC):
146
146
 
147
147
  Args:
148
148
  **kwargs: distribute arguments to this
149
- behaviour and in turn, all of it's children
149
+ behaviour and in turn, all of its children
150
150
 
151
151
  Raises:
152
152
  Exception: if this behaviour has a fault in construction or configuration
@@ -261,7 +261,7 @@ class Behaviour(abc.ABC):
261
261
  ############################################
262
262
 
263
263
  def setup_with_descendants(self) -> None:
264
- """Call setup on this child, it's children (it's children's children, )."""
264
+ """Call setup on this child, its children (its children's children, )."""
265
265
  for child in self.children:
266
266
  for node in child.iterate():
267
267
  node.setup()
@@ -321,7 +321,7 @@ class Behaviour(abc.ABC):
321
321
 
322
322
  def iterate(self, direct_descendants: bool = False) -> typing.Iterator[Behaviour]:
323
323
  """
324
- Iterate over this child and it's children.
324
+ Iterate over this child and its children.
325
325
 
326
326
  This utilises python generators for looping. To traverse the entire tree:
327
327
 
@@ -334,7 +334,7 @@ class Behaviour(abc.ABC):
334
334
  direct_descendants (:obj:`bool`): only yield children one step away from this behaviour.
335
335
 
336
336
  Yields:
337
- :class:`~py_trees.behaviour.Behaviour`: one of it's children
337
+ :class:`~py_trees.behaviour.Behaviour`: one of its children
338
338
  """
339
339
  for child in self.children:
340
340
  if not direct_descendants:
@@ -376,9 +376,11 @@ class Behaviour(abc.ABC):
376
376
  "%s.stop(%s)"
377
377
  % (
378
378
  self.__class__.__name__,
379
- "%s->%s" % (self.status, new_status)
380
- if self.status != new_status
381
- else "%s" % new_status,
379
+ (
380
+ "%s->%s" % (self.status, new_status)
381
+ if self.status != new_status
382
+ else "%s" % new_status
383
+ ),
382
384
  )
383
385
  )
384
386
  self.terminate(new_status)