or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-framework.mdcommand-line-tools.mdindex.mdpath-management.mdutility-functions.md

utility-functions.mddocs/

0

# Utility Functions

1

2

Core utility functions for directory management, deprecation warnings, async support, and platform-specific operations. These utilities are used throughout the Jupyter ecosystem to provide consistent behavior and functionality.

3

4

## Capabilities

5

6

### Directory Management

7

8

Utilities for creating and managing directories with proper permissions and error handling.

9

10

```python { .api }

11

def ensure_dir_exists(path: str | Path, mode: int = 0o777) -> None:

12

"""Ensure that a directory exists.

13

14

If it doesn't exist, try to create it, protecting against race conditions

15

if another process is doing the same. The default permissions are

16

determined by the current umask.

17

18

Args:

19

path: Directory path to create

20

mode: Directory permissions (default: 0o777, modified by umask)

21

22

Raises:

23

OSError: If directory cannot be created or path exists but is not a directory

24

"""

25

```

26

27

**Usage Example:**

28

29

```python

30

from jupyter_core.utils import ensure_dir_exists

31

from pathlib import Path

32

33

# Ensure a config directory exists

34

config_dir = Path.home() / ".jupyter" / "custom"

35

ensure_dir_exists(config_dir, mode=0o700) # User-only permissions

36

37

# Safe to use even if directory already exists

38

ensure_dir_exists(config_dir) # No error if already exists

39

```

40

41

### Deprecation Support

42

43

Utilities for generating deprecation warnings with proper stack level calculation to point to the actual calling code rather than internal frames.

44

45

```python { .api }

46

def deprecation(message: str, internal: str | list[str] = "jupyter_core/") -> None:

47

"""Generate a deprecation warning targeting the first frame that is not 'internal'.

48

49

Automatically calculates the correct stack level to ensure the warning

50

points to user code rather than internal library code.

51

52

Args:

53

message: Deprecation warning message

54

internal: String or list of strings identifying internal code paths

55

(if these appear in frame filenames, frames are considered internal)

56

"""

57

```

58

59

**Usage Example:**

60

61

```python

62

from jupyter_core.utils import deprecation

63

64

def old_function():

65

deprecation(

66

"old_function is deprecated, use new_function instead",

67

internal=["jupyter_core/", "mypackage/internal/"]

68

)

69

# Function implementation...

70

71

# When called by user code, warning points to user's call site

72

old_function() # Warning shows this line, not internal deprecation() call

73

```

74

75

### Async Utilities

76

77

Functions for managing asyncio event loops and running async code in sync contexts.

78

79

```python { .api }

80

def ensure_event_loop(prefer_selector_loop: bool = False) -> asyncio.AbstractEventLoop:

81

"""Ensure an asyncio event loop exists and return it.

82

83

Gets the current event loop, or creates a new one if none exists.

84

Handles platform-specific loop selection.

85

86

Args:

87

prefer_selector_loop: On Windows, prefer SelectorEventLoop over default

88

(useful for Tornado compatibility)

89

90

Returns:

91

asyncio.AbstractEventLoop: Current or newly created event loop

92

"""

93

94

def run_sync(coro: Callable[..., Awaitable[T]]) -> Callable[..., T]:

95

"""Wraps coroutine in a function that blocks until it has executed.

96

97

Allows calling async functions from sync code. Handles both cases

98

where an event loop is already running (uses background thread) and

99

where no loop exists (runs loop directly).

100

101

Args:

102

coro: Coroutine function to wrap

103

104

Returns:

105

Callable: Synchronous wrapper function

106

"""

107

108

async def ensure_async(obj: Awaitable[T] | T) -> T:

109

"""Convert a non-awaitable object to a coroutine if needed.

110

111

Handles functions that may return either sync values or awaitables,

112

ensuring consistent async handling.

113

114

Args:

115

obj: Object that may or may not be awaitable

116

117

Returns:

118

T: The result, whether it was originally sync or async

119

"""

120

```

121

122

**Usage Example:**

123

124

```python

125

from jupyter_core.utils import run_sync, ensure_event_loop

126

import asyncio

127

128

# Wrap an async function to be callable from sync code

129

@run_sync

130

async def async_operation(data):

131

await asyncio.sleep(1)

132

return f"Processed: {data}"

133

134

# Can now call async function synchronously

135

result = async_operation("test data")

136

print(result) # "Processed: test data"

137

138

# Ensure event loop exists

139

loop = ensure_event_loop()

140

print(f"Loop type: {type(loop)}")

141

```

142

143

### Internal Async Classes

144

145

Internal classes that support the async utilities. These are typically not used directly but are part of the implementation.

146

147

```python { .api }

148

class _TaskRunner:

149

"""A task runner that runs an asyncio event loop on a background thread.

150

151

Used internally by run_sync() to handle cases where an event loop

152

is already running in the current thread.

153

"""

154

155

def __init__(self) -> None:

156

"""Initialize the task runner."""

157

158

def run(self, coro) -> Any:

159

"""Synchronously run a coroutine on a background thread.

160

161

Args:

162

coro: Coroutine to execute

163

164

Returns:

165

Any: Result of coroutine execution

166

"""

167

```

168

169

### Stack Inspection Utilities

170

171

Internal utilities for inspecting the call stack, used by the deprecation system.

172

173

```python { .api }

174

def _get_frame(level: int) -> FrameType | None:

175

"""Get the frame at the given stack level.

176

177

Uses sys._getframe if available (faster) or falls back to inspect.stack.

178

179

Args:

180

level: Stack level to retrieve (0 = current frame)

181

182

Returns:

183

FrameType | None: Frame object or None if level is invalid

184

"""

185

186

def _external_stacklevel(internal: list[str]) -> int:

187

"""Find the stacklevel of the first frame that doesn't contain internal strings.

188

189

Used by deprecation() to calculate the correct stacklevel for warnings.

190

191

Args:

192

internal: List of strings that identify internal code paths

193

194

Returns:

195

int: Stack level of first external frame

196

"""

197

```

198

199

## Type Support

200

201

Type variables and aliases used throughout the utility functions.

202

203

```python { .api }

204

from typing import Any, Awaitable, Callable, TypeVar

205

from types import FrameType

206

from contextvars import ContextVar

207

import asyncio

208

209

# Type variable for generic async functions

210

T = TypeVar("T")

211

212

# Context variable for tracking event loops

213

_loop: ContextVar[asyncio.AbstractEventLoop | None]

214

215

# Internal registry for task runners

216

_runner_map: dict[str, _TaskRunner]

217

```

218

219

## Platform-Specific Behavior

220

221

### Windows

222

- **Event Loop Selection**: Can prefer SelectorEventLoop over default ProactorEventLoop for Tornado compatibility

223

- **Thread Naming**: Uses descriptive thread names for background async runners

224

- **Frame Inspection**: Handles differences in stack frame availability

225

226

### Unix/Linux/macOS

227

- **Event Loop**: Uses default event loop policy for the platform

228

- **Thread Safety**: Proper handling of event loops across threads

229

- **Signal Handling**: Respects platform signal handling in async contexts

230

231

## Integration with Jupyter Ecosystem

232

233

These utilities are used throughout Jupyter components:

234

235

### Directory Management

236

- **Config directories**: Ensuring Jupyter config directories exist with proper permissions

237

- **Data directories**: Creating kernel spec directories, extension directories

238

- **Runtime directories**: Setting up directories for kernels, servers

239

- **Custom directories**: User-defined locations for notebooks, kernels

240

241

### Deprecation Warnings

242

- **API Changes**: Warning about deprecated function signatures

243

- **Configuration Changes**: Alerting to deprecated config options

244

- **Path Changes**: Warning about legacy path usage patterns

245

- **Import Changes**: Deprecating old module locations

246

247

### Async Support

248

- **Kernel Management**: Running async kernel operations from sync contexts

249

- **Server Integration**: Supporting both sync and async server implementations

250

- **Widget Communication**: Handling async widget comm messages

251

- **Extension Loading**: Supporting async extension initialization

252

253

## Error Handling

254

255

The utilities include robust error handling:

256

257

- **Directory Creation**: Race condition protection, permission error handling

258

- **Stack Inspection**: Fallback methods when sys._getframe unavailable

259

- **Event Loop Management**: Cleanup on application exit, thread safety

260

- **Async Conversion**: Handling already-awaited coroutines, runtime errors

261

262

This comprehensive error handling ensures the utilities work reliably across different Python implementations, platforms, and usage contexts.