or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-commands.mdindex.mdpackage-conversion.mdtag-management.mdwheelfile-ops.md

package-conversion.mddocs/

0

# Package Conversion

1

2

Convert legacy Python package formats (.egg files and Windows installers) to modern wheel format. Supports both zipped .egg files and unpacked .egg directories, as well as Windows executable installers created with bdist_wininst.

3

4

## Capabilities

5

6

### Main Conversion Function

7

8

Convert multiple package files to wheel format with metadata transformation and platform detection.

9

10

```python { .api }

11

def convert(files: list[str], dest_dir: str, verbose: bool) -> None:

12

"""

13

Convert .egg files and Windows installers to wheels.

14

15

Parameters:

16

- files: List of file patterns (supports glob patterns)

17

- dest_dir: Output directory for converted wheels

18

- verbose: Print conversion progress messages

19

20

Supported formats:

21

- .egg files (zipped archives)

22

- .egg directories (unpacked)

23

- .exe files (Windows bdist_wininst installers)

24

"""

25

```

26

27

### Conversion Source Classes

28

29

Abstract base class and implementations for different package formats.

30

31

```python { .api }

32

class ConvertSource(metaclass=ABCMeta):

33

"""

34

Abstract base class for conversion sources.

35

"""

36

37

name: str

38

"""Package name (normalized)."""

39

40

version: str

41

"""Package version."""

42

43

pyver: str

44

"""Python version tags (default: "py2.py3")."""

45

46

abi: str

47

"""ABI tags (default: "none")."""

48

49

platform: str

50

"""Platform tags (default: "any")."""

51

52

metadata: Message

53

"""Email message object containing package metadata."""

54

55

@property

56

def dist_info_dir(self) -> str:

57

"""Get .dist-info directory name."""

58

return f"{self.name}-{self.version}.dist-info"

59

60

@abstractmethod

61

def generate_contents(self) -> Iterator[tuple[str, bytes]]:

62

"""Generate (filename, content) pairs for wheel contents."""

63

pass

64

```

65

66

### Egg File Conversion

67

68

Convert zipped .egg files to wheel format with metadata transformation.

69

70

```python { .api }

71

class EggFileSource(ConvertSource):

72

"""

73

Convert .egg files to wheels.

74

75

Handles:

76

- Binary wheels detection (assumes CPython)

77

- PKG-INFO metadata conversion

78

- requires.txt dependency conversion

79

- entry_points.txt preservation

80

"""

81

82

def __init__(self, path: Path):

83

"""

84

Initialize from .egg file path.

85

86

Parameters:

87

- path: Path to .egg file

88

89

Raises:

90

- ValueError: If filename doesn't match .egg pattern

91

"""

92

93

def generate_contents(self) -> Iterator[tuple[str, bytes]]:

94

"""

95

Generate wheel contents from .egg file.

96

97

Yields:

98

Tuples of (archive_path, file_content)

99

100

Processing:

101

- Converts EGG-INFO/ to .dist-info/

102

- Transforms PKG-INFO to METADATA

103

- Converts requires.txt to Requires-Dist headers

104

- Preserves entry_points.txt

105

"""

106

```

107

108

### Egg Directory Conversion

109

110

Convert unpacked .egg directories to wheel format.

111

112

```python { .api }

113

class EggDirectorySource(EggFileSource):

114

"""

115

Convert .egg directories to wheels.

116

117

Similar to EggFileSource but reads from filesystem directory

118

instead of zip archive.

119

"""

120

121

def generate_contents(self) -> Iterator[tuple[str, bytes]]:

122

"""

123

Generate wheel contents from .egg directory.

124

125

Yields:

126

Tuples of (archive_path, file_content)

127

128

Updates name and version from PKG-INFO if available.

129

"""

130

```

131

132

### Windows Installer Conversion

133

134

Convert Windows executable installers to wheel format with platform detection.

135

136

```python { .api }

137

class WininstFileSource(ConvertSource):

138

"""

139

Convert Windows bdist_wininst installers to wheels.

140

141

Handles:

142

- Platform detection from installer filename

143

- .pyd file ABI detection

144

- .egg-info metadata extraction

145

- SCRIPTS directory mapping to .data/scripts/

146

"""

147

148

def __init__(self, path: Path):

149

"""

150

Initialize from Windows installer path.

151

152

Parameters:

153

- path: Path to .exe installer file

154

155

Processing:

156

- Extracts platform from filename pattern

157

- Scans for .egg-info and .pyd files for metadata

158

- Determines Python version and ABI from content

159

"""

160

161

def generate_contents(self) -> Iterator[tuple[str, bytes]]:

162

"""

163

Generate wheel contents from Windows installer.

164

165

Yields:

166

Tuples of (archive_path, file_content)

167

168

Mapping:

169

- SCRIPTS/ -> {name}-{version}.data/scripts/

170

- .egg-info/ -> .dist-info/ (with metadata conversion)

171

"""

172

```

173

174

### Metadata Conversion Functions

175

176

Utility functions for converting between metadata formats.

177

178

```python { .api }

179

def convert_requires(requires: str, metadata: Message) -> None:

180

"""

181

Convert requires.txt format to Requires-Dist headers.

182

183

Parameters:

184

- requires: Content of requires.txt file

185

- metadata: Message object to add headers to

186

187

Format handling:

188

- [extra] sections become conditional requirements

189

- Requirement lines converted to Requires-Dist format

190

- Generates Provides-Extra headers for extras

191

"""

192

193

def convert_pkg_info(pkginfo: str, metadata: Message) -> None:

194

"""

195

Convert PKG-INFO format to Metadata 2.4 format.

196

197

Parameters:

198

- pkginfo: PKG-INFO file content

199

- metadata: Message object to populate

200

201

Transformations:

202

- Updates Metadata-Version to 2.4

203

- Converts Description to message body

204

- Maps Home-page to Project-URL: Homepage

205

- Maps Download-URL to Project-URL: Download

206

- Filters out "UNKNOWN" values

207

"""

208

209

def normalize(name: str) -> str:

210

"""

211

Normalize package name for wheel filename.

212

213

Parameters:

214

- name: Package name to normalize

215

216

Returns:

217

Normalized name ([-_.] replaced with underscores, lowercased)

218

"""

219

```

220

221

### Usage Examples

222

223

#### Converting Egg Files

224

225

```python

226

from wheel._commands.convert import convert

227

import os

228

229

# Convert all .egg files in current directory

230

egg_files = ['package-1.0-py2.7.egg', 'another-2.0.egg']

231

convert(egg_files, dest_dir='wheels/', verbose=True)

232

233

# Using glob patterns

234

convert(['*.egg'], dest_dir='dist/', verbose=False)

235

```

236

237

#### Programmatic Conversion with Custom Source

238

239

```python

240

from wheel._commands.convert import EggFileSource

241

from wheel.wheelfile import WheelFile

242

from pathlib import Path

243

244

# Create custom conversion

245

egg_path = Path('package-1.0.egg')

246

source = EggFileSource(egg_path)

247

248

# Generate wheel

249

wheel_path = f"{source.name}-{source.version}-{source.pyver}-{source.abi}-{source.platform}.whl"

250

with WheelFile(wheel_path, 'w') as wf:

251

for name, content in source.generate_contents():

252

wf.writestr(name, content)

253

254

# Add generated metadata

255

wf.writestr(

256

f"{source.dist_info_dir}/METADATA",

257

source.metadata.as_string(policy=serialization_policy).encode('utf-8')

258

)

259

```

260

261

#### Windows Installer Conversion

262

263

```python

264

from wheel._commands.convert import convert

265

266

# Convert Windows installers

267

convert(['package-1.0.win32-py3.8.exe'], dest_dir='wheels/', verbose=True)

268

269

# Results in: package-1.0-py38-cp38-win32.whl

270

```

271

272

## Constants and Types

273

274

```python { .api }

275

import re

276

from email.message import Message

277

from email.policy import EmailPolicy

278

from abc import ABCMeta, abstractmethod

279

from collections.abc import Iterator

280

from pathlib import Path

281

282

# Filename parsing patterns

283

egg_filename_re: re.Pattern[str]

284

"""Pattern for parsing .egg filenames: name-version(-pyver)(-arch).egg"""

285

286

egg_info_re: re.Pattern[str]

287

"""Pattern for parsing .egg-info directory names"""

288

289

wininst_re: re.Pattern[str]

290

"""Pattern for parsing Windows installer filenames"""

291

292

pyd_re: re.Pattern[str]

293

"""Pattern for parsing .pyd file extensions for ABI detection"""

294

295

# Email serialization policy

296

serialization_policy: EmailPolicy

297

"""Email policy for metadata serialization (UTF-8, no line wrapping)"""

298

299

GENERATOR: str

300

"""Generator string for WHEEL files (f"wheel {__version__}")"""

301

```