or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-functions.mddistribution-classes.mdentry-points.mdindex.mdpath-file-management.md

entry-points.mddocs/

0

# Entry Points System

1

2

Comprehensive entry point discovery and management, including entry point objects, collections, and selection mechanisms for package-defined executable scripts and plugins. Entry points allow packages to advertise functionality that can be discovered and loaded at runtime.

3

4

## Capabilities

5

6

### EntryPoint Class

7

8

Individual entry point objects representing package-defined entry points:

9

10

```python { .api }

11

class EntryPoint:

12

"""

13

An entry point as defined by Python packaging conventions.

14

15

Entry points allow packages to advertise components for discovery by other packages.

16

Common uses include console scripts, plugin systems, and extensible applications.

17

"""

18

19

name: str # Entry point name

20

value: str # Entry point value specification (module:attribute)

21

group: str # Entry point group (e.g., 'console_scripts')

22

dist: Distribution | None # Associated distribution (optional)

23

24

def __init__(self, name: str, value: str, group: str) -> None:

25

"""

26

Create an entry point.

27

28

Parameters:

29

- name: Entry point name

30

- value: Entry point value (e.g., 'package.module:function')

31

- group: Entry point group (e.g., 'console_scripts')

32

"""

33

34

def load(self) -> Any:

35

"""

36

Load the entry point from its definition.

37

38

If only a module is indicated by the value, return that module.

39

Otherwise, return the named object.

40

41

Returns:

42

Any: The loaded object or module

43

"""

44

45

def matches(self, **params) -> bool:

46

"""

47

Check if EntryPoint matches the given parameters.

48

49

Parameters:

50

- **params: Parameters to match against (name, group, module, attr, extras)

51

52

Returns:

53

bool: True if all parameters match

54

55

Raises:

56

ValueError: If 'dist' parameter is provided (not suitable for matching)

57

"""

58

59

@property

60

def module(self) -> str:

61

"""Return the module name from the entry point value."""

62

63

@property

64

def attr(self) -> str:

65

"""Return the attribute name from the entry point value."""

66

67

@property

68

def extras(self) -> list[str]:

69

"""Return the list of extras from the entry point value."""

70

71

# Class attributes

72

pattern: re.Pattern[str] # Regular expression for parsing entry point values

73

74

# Internal methods

75

def _for(self, dist: Distribution) -> EntryPoint:

76

"""

77

Associate this entry point with a distribution.

78

79

Parameters:

80

- dist: Distribution to associate with

81

82

Returns:

83

EntryPoint: This entry point with distribution associated

84

"""

85

86

def _key(self) -> tuple[str, str, str]:

87

"""

88

Return comparison key for sorting and equality.

89

90

Returns:

91

tuple[str, str, str]: Tuple of (name, value, group)

92

"""

93

94

# Comparison and representation methods

95

def __lt__(self, other: EntryPoint) -> bool:

96

"""Less than comparison for sorting."""

97

98

def __eq__(self, other: object) -> bool:

99

"""Equality comparison."""

100

101

def __hash__(self) -> int:

102

"""Hash for use in sets and dictionaries."""

103

104

def __repr__(self) -> str:

105

"""String representation of entry point."""

106

107

def __setattr__(self, name: str, value: Any) -> None:

108

"""

109

Prevent attribute modification (EntryPoint objects are immutable).

110

111

Raises:

112

AttributeError: Always, as EntryPoint objects are immutable

113

"""

114

```

115

116

#### Usage Examples

117

118

```python

119

import importlib_metadata

120

121

# Get entry points and work with individual ones

122

eps = importlib_metadata.entry_points(group='console_scripts')

123

if eps:

124

ep = next(iter(eps))

125

print(f"Entry point: {ep.name}")

126

print(f"Module: {ep.module}")

127

print(f"Attribute: {ep.attr}")

128

print(f"Group: {ep.group}")

129

print(f"Extras: {ep.extras}")

130

131

# Load the actual object

132

try:

133

obj = ep.load()

134

print(f"Loaded: {obj}")

135

except ImportError as e:

136

print(f"Failed to load: {e}")

137

138

# Check if entry point matches criteria

139

pip_eps = importlib_metadata.entry_points(name='pip')

140

for ep in pip_eps:

141

if ep.matches(group='console_scripts'):

142

print(f"Found pip console script: {ep.value}")

143

```

144

145

### EntryPoints Collection

146

147

Immutable collection class for working with multiple entry points:

148

149

```python { .api }

150

class EntryPoints(tuple):

151

"""

152

An immutable collection of selectable EntryPoint objects.

153

154

Provides methods for filtering and accessing entry points by various criteria.

155

"""

156

157

def __getitem__(self, name: str) -> EntryPoint:

158

"""

159

Get the EntryPoint in self matching name.

160

161

Parameters:

162

- name: Entry point name to find

163

164

Returns:

165

EntryPoint: The matching entry point

166

167

Raises:

168

KeyError: If no entry point with the given name is found

169

"""

170

171

def select(self, **params) -> EntryPoints:

172

"""

173

Select entry points from self that match the given parameters.

174

175

Parameters:

176

- **params: Selection criteria (typically group and/or name)

177

178

Returns:

179

EntryPoints: New EntryPoints collection with matching entry points

180

"""

181

182

@property

183

def names(self) -> set[str]:

184

"""

185

Return the set of all names of all entry points.

186

187

Returns:

188

set[str]: Set of entry point names

189

"""

190

191

@property

192

def groups(self) -> set[str]:

193

"""

194

Return the set of all groups of all entry points.

195

196

Returns:

197

set[str]: Set of entry point groups

198

"""

199

200

# Class attributes

201

__slots__ = () # Memory optimization for tuple subclass

202

203

# Class methods for construction

204

@classmethod

205

def _from_text_for(cls, text: str | None, dist: Distribution) -> EntryPoints:

206

"""

207

Create EntryPoints from text with associated distribution.

208

209

Parameters:

210

- text: Entry points text content (e.g., from entry_points.txt)

211

- dist: Distribution to associate with entry points

212

213

Returns:

214

EntryPoints: Collection of entry points with distribution associated

215

"""

216

217

@staticmethod

218

def _from_text(text: str | None) -> Iterator[EntryPoint]:

219

"""

220

Parse entry points from text content.

221

222

Parameters:

223

- text: Entry points text content in INI format

224

225

Returns:

226

Iterator[EntryPoint]: Iterator of parsed entry points

227

"""

228

229

# Representation method

230

def __repr__(self) -> str:

231

"""

232

Custom representation showing class name and tuple content.

233

234

Returns:

235

str: String representation like 'EntryPoints([...])'

236

"""

237

```

238

239

#### Usage Examples

240

241

```python

242

import importlib_metadata

243

244

# Get all entry points

245

all_eps = importlib_metadata.entry_points()

246

print(f"Total entry points: {len(all_eps)}")

247

print(f"Available groups: {all_eps.groups}")

248

print(f"Available names: {len(all_eps.names)} unique names")

249

250

# Select by group

251

console_scripts = all_eps.select(group='console_scripts')

252

print(f"Console scripts: {len(console_scripts)}")

253

254

# Select by name

255

pip_eps = all_eps.select(name='pip')

256

print(f"Entry points named 'pip': {len(pip_eps)}")

257

258

# Combine selection criteria

259

specific_eps = all_eps.select(group='console_scripts', name='pip')

260

print(f"pip console scripts: {len(specific_eps)}")

261

262

# Access by name (dictionary-like)

263

if 'pip' in console_scripts.names:

264

pip_ep = console_scripts['pip']

265

print(f"pip script: {pip_ep.value}")

266

```

267

268

### Entry Point Parsing and Validation

269

270

Entry points use a specific syntax for the value specification. The EntryPoint class uses a compiled regular expression pattern to parse these values:

271

272

```python { .api }

273

# EntryPoint.pattern - Regular expression for parsing entry point values

274

# Pattern: r'(?P<module>[\w.]+)\s*(:\s*(?P<attr>[\w.]+)\s*)?((?P<extras>\[.*\])\s*)?$'

275

276

# Entry point value patterns (examples):

277

# - "module" # Module only

278

# - "package.module" # Package and module

279

# - "package.module:attribute" # Module with attribute

280

# - "package.module:object.attribute" # Nested attribute

281

# - "package.module:attr [extra1, extra2]" # With extras

282

283

# The pattern captures three groups:

284

# - module: Required module/package name ([\w.]+)

285

# - attr: Optional attribute name after colon ([\w.]+)

286

# - extras: Optional extras specification in brackets (\[.*\])

287

```

288

289

The pattern is lenient about whitespace around the colon, following the attribute, and following any extras. Invalid entry point references raise ValueError with a descriptive message pointing to the packaging specification.

290

291

#### Usage Examples

292

293

```python

294

import importlib_metadata

295

296

# Create entry point manually (for testing/examples)

297

ep = importlib_metadata.EntryPoint(

298

name='my-script',

299

value='mypackage.cli:main',

300

group='console_scripts'

301

)

302

303

print(f"Entry point module: {ep.module}") # 'mypackage.cli'

304

print(f"Entry point attr: {ep.attr}") # 'main'

305

print(f"Entry point extras: {ep.extras}") # []

306

307

# Entry point with extras

308

ep_with_extras = importlib_metadata.EntryPoint(

309

name='advanced-script',

310

value='mypackage.advanced:run [dev, test]',

311

group='console_scripts'

312

)

313

print(f"Extras: {ep_with_extras.extras}") # ['dev', 'test']

314

```

315

316

### Distribution-Specific Entry Points

317

318

Entry points are associated with specific distributions and can be accessed through Distribution objects:

319

320

```python

321

import importlib_metadata

322

323

# Get entry points for a specific distribution

324

dist = importlib_metadata.distribution('pip')

325

dist_eps = dist.entry_points

326

327

# Filter distribution entry points

328

console_scripts = dist_eps.select(group='console_scripts')

329

for ep in console_scripts:

330

print(f"pip provides script: {ep.name} -> {ep.value}")

331

print(f"Associated distribution: {ep.dist.name if ep.dist else 'None'}")

332

```

333

334

## Error Handling

335

336

Entry point operations can raise various exceptions:

337

338

```python

339

import importlib_metadata

340

341

eps = importlib_metadata.entry_points(group='console_scripts')

342

343

# KeyError when accessing non-existent entry point

344

try:

345

ep = eps['nonexistent-script']

346

except KeyError:

347

print("Entry point not found")

348

349

# ImportError when loading entry point

350

try:

351

ep = next(iter(eps))

352

obj = ep.load()

353

except ImportError as e:

354

print(f"Failed to load entry point: {e}")

355

356

# ValueError when matching with 'dist' parameter

357

try:

358

ep = next(iter(eps))

359

ep.matches(dist=dist) # Not allowed

360

except ValueError:

361

print("Cannot match on 'dist' parameter")

362

363

# ValueError when creating entry point with invalid value

364

try:

365

invalid_ep = importlib_metadata.EntryPoint(

366

name='bad-script',

367

value='invalid-name', # Invalid module name

368

group='console_scripts'

369

)

370

except ValueError as e:

371

print(f"Invalid entry point reference: {e}")

372

373

# AttributeError when trying to modify entry point (immutable)

374

try:

375

ep = next(iter(eps))

376

ep.name = 'new-name' # Not allowed

377

except AttributeError:

378

print("EntryPoint objects are immutable")

379

```