0
# Session Management
1
2
Runtime state coordination and environment selection for tox execution. The session management system controls the overall execution flow, manages environment lifecycle, and provides access to configuration and runtime state throughout the tox run.
3
4
## Capabilities
5
6
### State Management
7
8
The central coordinator that manages the entire tox execution lifecycle, providing access to configuration, environments, and runtime state.
9
10
```python { .api }
11
class State:
12
"""Runtime state holder for tox execution."""
13
14
def __init__(self, options: Options, args: Sequence[str]) -> None:
15
"""
16
Initialize state for tox run.
17
18
Args:
19
options: Parsed command line options
20
args: Raw command line arguments
21
"""
22
23
@property
24
def conf(self) -> Config:
25
"""Access to configuration object."""
26
27
@property
28
def envs(self) -> EnvSelector:
29
"""Access to environment selector."""
30
31
args: Sequence[str]
32
"""Raw command line arguments."""
33
```
34
35
Usage example:
36
```python
37
from tox.run import setup_state
38
39
# Create state
40
state = setup_state(['-e', 'py311,py312'])
41
42
# Access configuration
43
print(f"Work dir: {state.conf.work_dir}")
44
print(f"Root dir: {state.conf.root}")
45
46
# Access environments
47
envs = state.envs
48
for name, env in envs.iter():
49
print(f"Environment: {name}")
50
```
51
52
### Environment Selection
53
54
Manages the selection and coordination of tox environments, providing access to environment configurations and instances.
55
56
```python { .api }
57
class EnvSelector:
58
"""Environment selection and management."""
59
60
@property
61
def _defined_envs(self) -> dict[str, _ToxEnvInfo]:
62
"""
63
Get all defined environments.
64
65
Returns:
66
dict[str, _ToxEnvInfo]: Mapping of environment names to environment info
67
"""
68
69
def iter(self, *, only_active: bool = True, package: bool = False) -> Iterator[str]:
70
"""
71
Get tox environments.
72
73
Args:
74
only_active: Active environments marked to be executed
75
package: Return package environments
76
77
Yields:
78
str: Environment names
79
"""
80
81
def __getitem__(self, item: str) -> RunToxEnv | PackageToxEnv:
82
"""
83
Get specific environment by name.
84
85
Args:
86
item: Environment name
87
88
Returns:
89
RunToxEnv | PackageToxEnv: Environment instance
90
91
Raises:
92
KeyError: If environment not found
93
"""
94
```
95
96
Usage example:
97
```python
98
# Get all environments
99
all_envs = state.envs._defined_envs
100
print(f"Available environments: {list(all_envs.keys())}")
101
102
# Get specific environment
103
py311_env = state.envs['py311']
104
print(f"Environment name: {py311_env.name}")
105
106
# Iterate over active environments
107
for name in state.envs.iter():
108
env = state.envs[name]
109
print(f"Processing {name}: {env.conf['basepython']}")
110
```
111
112
### Journal System
113
114
Tracks execution runs and results for reporting and analysis.
115
116
```python { .api }
117
class Journal:
118
"""Execution journal for tracking tox runs."""
119
120
def __init__(self, is_result_json: bool) -> None:
121
"""
122
Initialize journal.
123
124
Args:
125
is_result_json: Whether to track for JSON result output
126
"""
127
128
def add_run(self, env_name: str, run_id: str, outcome: Outcome) -> None:
129
"""
130
Add execution run to journal.
131
132
Args:
133
env_name: Name of environment
134
run_id: Unique run identifier
135
outcome: Execution outcome
136
"""
137
138
def get_runs(self, env_name: str | None = None) -> list[JournalRun]:
139
"""
140
Get execution runs.
141
142
Args:
143
env_name: Filter by environment name (None for all)
144
145
Returns:
146
list[JournalRun]: List of execution runs
147
"""
148
149
def write(self, path: Path) -> None:
150
"""
151
Write journal to file.
152
153
Args:
154
path: Output file path
155
"""
156
157
class JournalRun:
158
"""Single execution run record."""
159
160
@property
161
def env_name(self) -> str:
162
"""Environment name."""
163
164
@property
165
def run_id(self) -> str:
166
"""Run identifier."""
167
168
@property
169
def outcome(self) -> Outcome:
170
"""Execution outcome."""
171
```
172
173
## Session Commands
174
175
### Sequential Execution
176
177
Execute environments one after another in sequence.
178
179
```python { .api }
180
def run_sequential(state: State) -> int:
181
"""
182
Run environments sequentially.
183
184
Args:
185
state: Runtime state
186
187
Returns:
188
int: Exit code (0 for success)
189
"""
190
```
191
192
### Parallel Execution
193
194
Execute multiple environments concurrently.
195
196
```python { .api }
197
def run_parallel(state: State) -> int:
198
"""
199
Run environments in parallel.
200
201
Args:
202
state: Runtime state
203
204
Returns:
205
int: Exit code (0 for success)
206
"""
207
```
208
209
### Single Environment Execution
210
211
Execute a single environment with full lifecycle management.
212
213
```python { .api }
214
def execute(state: State, env: ToxEnv) -> int:
215
"""
216
Execute single environment.
217
218
Args:
219
state: Runtime state
220
env: Environment to execute
221
222
Returns:
223
int: Exit code (0 for success)
224
"""
225
```
226
227
## Environment Lifecycle
228
229
The session management system coordinates the environment lifecycle:
230
231
1. **Discovery**: Find and configure available environments
232
2. **Selection**: Select environments based on CLI arguments and configuration
233
3. **Creation**: Create virtual environments as needed
234
4. **Setup**: Install dependencies and prepare environment
235
5. **Execution**: Run commands within environment
236
6. **Teardown**: Clean up environment resources
237
238
```python
239
# Example lifecycle coordination
240
state = setup_state(['-e', 'py311'])
241
242
# Get environment
243
env = state.envs.get('py311')
244
245
# Execute with lifecycle management
246
try:
247
env.create()
248
env.setup()
249
status = env.execute(ExecuteRequest(['pytest']))
250
print(f"Exit code: {status.exit_code}")
251
finally:
252
env.tear_down()
253
```
254
255
## Session Configuration
256
257
Session behavior is controlled through configuration and CLI options:
258
259
### Parallel Execution Options
260
261
- `--parallel`: Enable parallel execution
262
- `--parallel-no-spinner`: Disable progress spinner
263
- `--parallel-live`: Show live output during parallel execution
264
265
### Environment Selection
266
267
- `-e, --env`: Specify environments to run
268
- `--skip-missing-interpreters`: Skip unavailable Python interpreters
269
- `--develop`: Install package in development mode
270
271
### Working Directory Control
272
273
- `--workdir`: Override working directory
274
- `--temp-dir`: Override temporary directory
275
276
## Error Handling
277
278
Session management includes comprehensive error handling:
279
280
```python { .api }
281
class Skip(Exception):
282
"""Signal to skip an environment."""
283
284
class Fail(Exception):
285
"""Signal environment failure."""
286
```
287
288
The session system catches and handles these exceptions appropriately:
289
290
- `Skip`: Environment is marked as skipped and execution continues
291
- `Fail`: Environment is marked as failed but other environments continue
292
- Other exceptions: Cause session to terminate with error
293
294
## State Access Patterns
295
296
Common patterns for accessing state information:
297
298
```python
299
# Configuration access
300
work_dir = state.conf.work_dir
301
core_config = state.conf.core
302
env_config = state.conf.get_env('py311')
303
304
# Environment access
305
all_envs = state.envs.all()
306
active_envs = list(state.envs.iter())
307
specific_env = state.envs.get('py311')
308
309
# Journal access
310
journal = state.journal
311
runs = journal.get_runs('py311')
312
```
313
314
This provides a clean separation between configuration, environment management, and execution tracking while maintaining easy access to all necessary state information.