or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

constants.mdexpressions.mdfactories.mdindex.mdlicensing.mdsymbols.md

symbols.mddocs/

0

# License Symbol Management

1

2

License symbols represent individual licenses and exceptions within license expressions. The library provides several symbol classes to handle different types of license identifiers, including standard licenses, license-like symbols, and complex WITH exception constructs.

3

4

## Capabilities

5

6

### LicenseSymbol Class

7

8

The primary class for representing individual licenses within expressions.

9

10

```python { .api }

11

class LicenseSymbol:

12

"""

13

Represents a license symbol with key, aliases, and metadata.

14

"""

15

16

def __init__(self, key: str, aliases: tuple = tuple(), is_deprecated: bool = False, is_exception: bool = False, *args, **kwargs):

17

"""

18

Create a license symbol.

19

20

Parameters:

21

- key: Primary identifier for the license

22

- aliases: Tuple of alternative names/identifiers (default: empty tuple)

23

- is_deprecated: Whether this license identifier is deprecated (default: False)

24

- is_exception: Whether this symbol represents a license exception (default: False)

25

- *args, **kwargs: Additional arguments for extensibility

26

"""

27

28

@property

29

def key(self) -> str:

30

"""Primary license identifier."""

31

32

@property

33

def aliases(self) -> tuple:

34

"""Tuple of alternative identifiers for this license."""

35

36

@property

37

def is_deprecated(self) -> bool:

38

"""True if this license identifier is deprecated."""

39

40

@property

41

def is_exception(self) -> bool:

42

"""True if this symbol represents a license exception."""

43

44

def __eq__(self, other) -> bool:

45

"""License symbols are equal if they have the same key."""

46

47

def __hash__(self) -> int:

48

"""Hash based on the license key."""

49

50

def __str__(self) -> str:

51

"""String representation using the key."""

52

```

53

54

### LicenseSymbolLike Class

55

56

A symbol class for licenses that should match similar or related licenses.

57

58

```python { .api }

59

class LicenseSymbolLike(LicenseSymbol):

60

"""

61

License symbol that matches similar licenses with flexible matching.

62

Extends LicenseSymbol with similarity-based matching capabilities.

63

"""

64

65

def __init__(self, key: str, aliases: list = None, is_exception: bool = False):

66

"""

67

Create a license-like symbol with flexible matching.

68

69

Parameters:

70

- key: Primary identifier for the license

71

- aliases: List of alternative names/identifiers

72

- is_exception: Whether this symbol represents a license exception

73

"""

74

```

75

76

### LicenseWithExceptionSymbol Class

77

78

Represents complex license WITH exception constructs.

79

80

```python { .api }

81

class LicenseWithExceptionSymbol:

82

"""

83

Represents a license WITH exception construct (e.g., 'GPL-2.0 WITH Classpath-exception-2.0').

84

"""

85

86

def __init__(self, license_symbol: LicenseSymbol, exception_symbol: LicenseSymbol, strict: bool = False):

87

"""

88

Create a license WITH exception symbol.

89

90

Parameters:

91

- license_symbol: The main license symbol

92

- exception_symbol: The exception symbol (must have is_exception=True)

93

- strict: Validate that license_symbol is not an exception and exception_symbol is an exception (default: False)

94

"""

95

96

@property

97

def license_symbol(self) -> LicenseSymbol:

98

"""The main license symbol."""

99

100

@property

101

def exception_symbol(self) -> LicenseSymbol:

102

"""The exception symbol."""

103

104

@property

105

def key(self) -> str:

106

"""Combined key representing the license WITH exception."""

107

108

def __eq__(self, other) -> bool:

109

"""Equality based on both license and exception symbols."""

110

111

def __str__(self) -> str:

112

"""String representation as 'license WITH exception'."""

113

```

114

115

### BaseSymbol Class

116

117

Abstract base class for all license symbols.

118

119

```python { .api }

120

class BaseSymbol:

121

"""

122

Base class for all license symbols providing common functionality.

123

"""

124

125

def render(self, template: str = None) -> str:

126

"""

127

Render the symbol using a template string.

128

129

Parameters:

130

- template: Format template (default: '{symbol.key}')

131

132

Returns:

133

Formatted string representation

134

"""

135

136

def decompose(self):

137

"""

138

Yield the underlying symbols of this symbol.

139

For most symbols, this yields the symbol itself.

140

"""

141

142

def __contains__(self, other) -> bool:

143

"""

144

Test if the other symbol is contained in this symbol.

145

"""

146

```

147

148

### Renderable Class

149

150

Base interface class for renderable objects.

151

152

```python { .api }

153

class Renderable:

154

"""

155

Interface for renderable objects that can be formatted as strings.

156

"""

157

158

def render(self, template: str = "{symbol.key}", *args, **kwargs) -> str:

159

"""

160

Return a formatted string rendering for this object.

161

162

Parameters:

163

- template: Format string template

164

- *args, **kwargs: Additional arguments for rendering

165

166

Returns:

167

Formatted string representation

168

"""

169

170

def render_as_readable(self, template: str = "{symbol.key}", *args, **kwargs) -> str:

171

"""

172

Return a formatted string with extra parentheses for improved readability.

173

174

Parameters:

175

- template: Format string template

176

- *args, **kwargs: Additional arguments for rendering

177

178

Returns:

179

Formatted string with improved readability

180

"""

181

```

182

183

### RenderableFunction Class

184

185

Base class for renderable boolean functions (AND/OR operators).

186

187

```python { .api }

188

class RenderableFunction(Renderable):

189

"""

190

Base class for renderable boolean functions like AND and OR operators.

191

"""

192

193

def render(self, template: str = "{symbol.key}", *args, **kwargs) -> str:

194

"""

195

Render a boolean expression recursively applying the template to symbols.

196

197

Parameters:

198

- template: Format string template for symbols

199

- *args, **kwargs: Additional arguments passed to symbol render methods

200

201

Returns:

202

Formatted boolean expression string

203

"""

204

```

205

206

## Usage Examples

207

208

### Creating License Symbols

209

210

```python

211

from license_expression import LicenseSymbol

212

213

# Create a standard license symbol

214

mit = LicenseSymbol('MIT', ['MIT License', 'Expat'])

215

print(mit.key) # 'MIT'

216

print(mit.aliases) # ('MIT License', 'Expat')

217

print(mit.is_exception) # False

218

219

# Create an exception symbol

220

classpath = LicenseSymbol('Classpath-exception-2.0', is_exception=True)

221

print(classpath.is_exception) # True

222

```

223

224

### Working with License-Like Symbols

225

226

```python

227

from license_expression import LicenseSymbolLike

228

229

# Create a symbol that matches similar licenses

230

generic_gpl = LicenseSymbolLike('GPL', ['GNU GPL', 'General Public License'])

231

```

232

233

### Creating WITH Exception Symbols

234

235

```python

236

from license_expression import LicenseSymbol, LicenseWithExceptionSymbol

237

238

# Create license and exception symbols

239

gpl = LicenseSymbol('GPL-2.0')

240

classpath = LicenseSymbol('Classpath-exception-2.0', is_exception=True)

241

242

# Combine into WITH exception symbol

243

gpl_with_classpath = LicenseWithExceptionSymbol(gpl, classpath)

244

print(str(gpl_with_classpath)) # 'GPL-2.0 WITH Classpath-exception-2.0'

245

print(gpl_with_classpath.license_symbol.key) # 'GPL-2.0'

246

print(gpl_with_classpath.exception_symbol.key) # 'Classpath-exception-2.0'

247

```

248

249

### Symbol Equality and Comparison

250

251

```python

252

# Symbol equality is based on keys

253

mit1 = LicenseSymbol('MIT', ['MIT License'])

254

mit2 = LicenseSymbol('MIT', ['Expat License'])

255

print(mit1 == mit2) # True - same key

256

257

# Different keys are not equal

258

mit = LicenseSymbol('MIT')

259

apache = LicenseSymbol('Apache-2.0')

260

print(mit == apache) # False

261

```

262

263

### Using Symbols in Sets and Dictionaries

264

265

```python

266

# Symbols can be used in sets (hashable by key)

267

symbols = {

268

LicenseSymbol('MIT'),

269

LicenseSymbol('Apache-2.0'),

270

LicenseSymbol('MIT', ['Expat']) # Duplicate key, won't be added twice

271

}

272

print(len(symbols)) # 2

273

274

# Use as dictionary keys

275

license_info = {

276

LicenseSymbol('MIT'): 'Permissive license',

277

LicenseSymbol('GPL-2.0'): 'Copyleft license'

278

}

279

```

280

281

### Custom Rendering

282

283

```python

284

# Render symbols with custom templates

285

mit = LicenseSymbol('MIT', ['MIT License'])

286

print(mit.render()) # 'MIT' (default)

287

print(mit.render('{symbol.key}')) # 'MIT'

288

print(mit.render('License: {symbol.key}')) # 'License: MIT'

289

```

290

291

## Symbol Validation

292

293

The library provides utilities for validating collections of symbols:

294

295

```python

296

from license_expression import validate_symbols, LicenseSymbol

297

298

symbols = [

299

LicenseSymbol('MIT'),

300

LicenseSymbol('Apache-2.0'),

301

LicenseSymbol('GPL-2.0', is_exception=True), # Invalid: GPL-2.0 is not an exception

302

]

303

304

warnings, errors = validate_symbols(symbols, validate_keys=True)

305

print(errors) # List of validation errors

306

```