or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Future F-strings

1

2

A backport of Python 3.6+ f-string syntax to older Python versions (2.7, 3.4, 3.5). Works by implementing a custom UTF-8 compatible codec that performs source code transformation, converting f-string syntax into equivalent `.format()` calls. Includes both a runtime codec that automatically transforms code when imported and a command-line tool for pre-transforming source files.

3

4

## Package Information

5

6

- **Package Name**: future-fstrings

7

- **Language**: Python

8

- **Installation**: `pip install future-fstrings`

9

- **Optional Dependencies**: `pip install future-fstrings[rewrite]` (for command-line tool on modern Python)

10

11

## Core Imports

12

13

```python

14

import future_fstrings

15

```

16

17

## Basic Usage

18

19

### Automatic Codec Registration (Recommended)

20

21

The package automatically registers its codec during installation via a `.pth` file, enabling f-string syntax in any file with the appropriate encoding cookie:

22

23

```python

24

# -*- coding: future_fstrings -*-

25

name = "world"

26

message = f"Hello {name}!"

27

print(message) # Outputs: Hello world!

28

```

29

30

### Manual Codec Registration

31

32

```python

33

import future_fstrings

34

future_fstrings.register()

35

36

# Now f-string files with the encoding cookie will work

37

```

38

39

### Command-line Source Transformation

40

41

Transform f-string source files for deployment to platforms that don't support f-strings:

42

43

```bash

44

future-fstrings-show input.py > output.py

45

```

46

47

Input file:

48

```python

49

# -*- coding: future_fstrings -*-

50

name = "Python"

51

print(f"Hello {name}!")

52

```

53

54

Output:

55

```python

56

# -*- coding: future_fstrings -*-

57

name = "Python"

58

print("Hello {}!".format((name)))

59

```

60

61

## Capabilities

62

63

### Codec Registration

64

65

Register the future-fstrings codec with Python's codec registry to enable automatic f-string transformation.

66

67

```python { .api }

68

def register():

69

"""

70

Register the future-fstrings codec with Python's codec registry.

71

72

This enables automatic transformation of f-strings in files that use

73

the 'future_fstrings' or 'future-fstrings' encoding declaration.

74

75

Returns:

76

None

77

"""

78

```

79

80

### Source Code Transformation

81

82

Transform Python source code containing f-strings into equivalent `.format()` calls.

83

84

```python { .api }

85

def decode(b, errors='strict'):

86

"""

87

Decode bytes containing f-string syntax into transformed source code.

88

89

Parameters:

90

b (bytes): Source code bytes to decode and transform

91

errors (str): Error handling mode ('strict', 'ignore', 'replace')

92

93

Returns:

94

tuple: (transformed_source_string, byte_length)

95

96

Raises:

97

SyntaxError: If f-string syntax is invalid

98

TokenSyntaxError: If tokenization fails with additional context

99

100

Note:

101

Requires tokenize-rt package for source transformation.

102

"""

103

104

fstring_decode = decode

105

"""

106

Alias for the decode function. Provides alternative name for accessing

107

the main f-string transformation functionality.

108

"""

109

```

110

111

### Command-line Interface

112

113

Transform and display f-string source files from the command line.

114

115

```python { .api }

116

def main(argv=None):

117

"""

118

Command-line interface for transforming f-string source files.

119

120

Reads a Python file, transforms f-strings to .format() calls,

121

and writes the result to stdout.

122

123

Parameters:

124

argv (list, optional): Command line arguments. If None, uses sys.argv

125

126

Usage:

127

future-fstrings-show filename.py

128

129

Returns:

130

None (exits with status code)

131

"""

132

```

133

134

### Platform Detection

135

136

Check if the current Python version natively supports f-strings.

137

138

```python { .api }

139

SUPPORTS_FSTRINGS: bool

140

"""

141

Boolean constant indicating whether the current Python version

142

natively supports f-string syntax (True for Python 3.6+).

143

"""

144

```

145

146

## Exception Types

147

148

```python { .api }

149

class TokenSyntaxError(SyntaxError):

150

"""

151

Specialized syntax error for f-string tokenization failures.

152

153

Provides enhanced error reporting with token context for better

154

debugging of f-string syntax issues.

155

156

Attributes:

157

e: The original exception that occurred

158

token: The token where the error was detected

159

"""

160

161

def __init__(self, e, token):

162

"""

163

Initialize TokenSyntaxError with original exception and token context.

164

165

Parameters:

166

e: Original exception

167

token: Token where error occurred

168

"""

169

```

170

171

## Codec Implementation Classes

172

173

These classes implement the Python codec interface for the future-fstrings transformation:

174

175

```python { .api }

176

class IncrementalDecoder(codecs.BufferedIncrementalDecoder):

177

"""

178

Incremental decoder implementation for the future-fstrings codec.

179

180

Handles streaming decode operations by buffering input until

181

a complete decode operation can be performed.

182

"""

183

184

def _buffer_decode(self, input, errors, final):

185

"""

186

Internal method for buffered decoding.

187

188

Parameters:

189

input (bytes): Input bytes to decode

190

errors (str): Error handling mode

191

final (bool): Whether this is the final decode call

192

193

Returns:

194

tuple: (decoded_string, bytes_consumed)

195

"""

196

197

class StreamReader(utf_8.streamreader, object):

198

"""

199

Stream reader that defers f-string decoding for better error messages.

200

201

Provides lazy decoding to maintain source position information

202

for more accurate error reporting when f-string syntax errors occur.

203

"""

204

205

@property

206

def stream(self):

207

"""Access the underlying stream with lazy decoding."""

208

209

@stream.setter

210

def stream(self, stream):

211

"""Set the underlying stream and reset decode state."""

212

```

213

214

## Version-Specific Behavior

215

216

The package behaves differently depending on Python version support for f-strings:

217

218

```python { .api }

219

# On Python 3.6+ where f-strings are natively supported:

220

# decode, IncrementalDecoder, and StreamReader are automatically

221

# reassigned to use standard UTF-8 codec components for better performance

222

223

if SUPPORTS_FSTRINGS: # Python 3.6+

224

decode = utf_8.decode

225

IncrementalDecoder = utf_8.incrementaldecoder

226

StreamReader = utf_8.streamreader

227

```

228

229

This conditional behavior ensures optimal performance while maintaining compatibility. On older Python versions, the custom transformation classes are used, while on newer versions that natively support f-strings, the standard UTF-8 codec components are used instead.

230

231

## Advanced Usage

232

233

### Codec Information

234

235

Access codec configuration details:

236

237

```python { .api }

238

codec_map: dict

239

"""

240

Dictionary mapping codec names ('future-fstrings', 'future_fstrings')

241

to CodecInfo objects containing the complete codec implementation.

242

"""

243

```

244

245

### Error Handling

246

247

The package provides detailed error reporting for f-string syntax issues:

248

249

- **SyntaxError**: Standard Python syntax errors for malformed f-strings

250

- **TokenSyntaxError**: Enhanced errors with token context for better debugging

251

252

Common f-string syntax restrictions that trigger errors:

253

- Backslashes in expression parts: `f"bad: {'\n'}"`

254

- Comments in expressions: `f"bad: {x # comment}"`

255

- Unmatched braces: `f"bad: {x"`

256

- Nested f-strings beyond 2 levels deep

257

258

### Usage Examples

259

260

**Basic string interpolation:**

261

```python

262

# -*- coding: future_fstrings -*-

263

name = "Alice"

264

age = 30

265

print(f"Hello, {name}! You are {age} years old.")

266

```

267

268

**Expressions and formatting:**

269

```python

270

# -*- coding: future_fstrings -*-

271

import math

272

radius = 5

273

print(f"Circle area: {math.pi * radius**2:.2f}")

274

```

275

276

**Multiple f-strings:**

277

```python

278

# -*- coding: future_fstrings -*-

279

first, last = "John", "Doe"

280

email = f"{first.lower()}.{last.lower()}@example.com"

281

print(f"User: {first} {last} ({email})")

282

```