Mastering Python Second Edition Release Code

This commit is contained in:
Rick van Hattem
2022-05-05 18:25:55 +02:00
commit 3223a43fe3
454 changed files with 20230 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
Chapter 2, Interactive Python Shells
##############################################################################
@@ -0,0 +1,2 @@
>>> 'Hello world!'
'Hello world!'
@@ -0,0 +1,27 @@
# Adding default imports
>>> from pprint import pprint as pp
>>> from pprint import pformat as pf
>>> pp(dict(spam=0xA, eggs=0xB))
{'eggs': 11, 'spam': 10}
>>> pf(dict(spam=0xA, eggs=0xB))
"{'eggs': 11, 'spam': 10}"
# Modifying prompt
>>> if True:
... print('Hello!')
Hello!
>>> import sys
>>> sys.ps1 = '> '
>>> sys.ps2 = '. '
# With modified prompt
> if True:
. print('Hello!')
Hello!
@@ -0,0 +1,76 @@
import __main__
import re
import atexit
import readline
import rlcompleter
class Completer(rlcompleter.Completer):
ITEM_RE = re.compile(r'(?P<expression>.+?)\[(?P<key>[^\[]*)')
def complete(self, text, state):
# Init namespace. From `rlcompleter.Completer.complete`
if self.use_main_ns:
self.namespace = __main__.__dict__
# If we find a [, try and return the keys
if '[' in text:
# At state 0 we need to prefetch the matches, after
# that we use the cached results
if state == 0:
self.matches = list(self.item_matches(text))
# Try and return the match if it exists
try:
return self.matches[state]
except IndexError:
pass
else:
# Fallback to the normal completion
return super().complete(text, state)
def item_matches(self, text):
# Look for the pattern expression[key
match = self.ITEM_RE.match(text)
if match:
search_key = match.group('key').lstrip()
expression = match.group('expression')
# Strip quotes from the key
if search_key and search_key[0] in {"'", '"'}:
search_key = search_key.strip(search_key[0])
# Fetch the object from the namespace
object_ = eval(expression, self.namespace)
# Duck typing, check if we have a `keys()` attribute
if hasattr(object_, 'keys'):
# Fetch the keys by executing the `keys()` method
# Can you guess where the bug is?
keys = object_.keys()
for i, key in enumerate(keys):
# Limit to 25 items for safety, could be
# infinite
if i >= 25:
break
# Only return matching results
if key.startswith(search_key):
yield f'{expression}[{key!r}]'
# By default readline doesn't call the autocompleter for [ because
# it's considered a delimiter. With a little bit of work we can
# fix this however :)
delims = readline.get_completer_delims()
# Remove [, ' and " from the delimiters
delims = delims.replace('[', '').replace('"', '').replace("'", '')
# Set the delimiters
readline.set_completer_delims(delims)
# Create and set the completer
completer = Completer()
readline.set_completer(completer.complete)
# Add a cleanup call on Python exit
atexit.register(lambda: readline.set_completer(None))
@@ -0,0 +1,15 @@
>>> sandwich = dict(spam=2, eggs=1, sausage=1)
>>> sandwich.<TAB> # doctest: +SKIP
sandwich.clear( sandwich.fromkeys( sandwich.items( sandwich.pop(
sandwich.setdefault( sandwich.values( sandwich.copy( sandwich.get(
sandwich.keys( sandwich.popitem( sandwich.update(
>>> sandwich[ # doctest: +SKIP
>>> sandwich = dict(spam=2, eggs=1, sausage=1)
>>> sandwich['<TAB> # doctest: +SKIP
sandwich['eggs'] sandwich['sausage'] sandwich['spam']
>>> import T_02_modifying_autocompletion
>>> autocompletion = T_02_modifying_autocompletion
@@ -0,0 +1,25 @@
Note: missing_ok was added in Python 3.8
>>> import pathlib
>>> pathlib.Path('bpython.txt').unlink(missing_ok=True)
>>> with open('bpython.txt', 'a') as fh:
... fh.write('x')
...
1
>>> with open('bpython.txt') as fh:
... print(fh.read())
...
x
>>> sandwich = dict(spam=2, eggs=1, sausage=1)
>>> with open('bpython.txt', 'a') as fh:
... fh.write('x')
...
1
>>> with open('bpython.txt') as fh:
... print(fh.read())
...
xx
>>>
@@ -0,0 +1,4 @@
with open('reload.txt', 'a+') as fh:
fh.write('x')
fh.seek(0)
print(fh.read())
+7
View File
@@ -0,0 +1,7 @@
import sys
import pathlib
# Little hack to add the current directory to sys.path so we can
# find the imports
path = pathlib.Path(__file__).parent
sys.path.append(str(path.resolve()))
+1
View File
@@ -0,0 +1 @@
xxxxx
@@ -0,0 +1,3 @@
# coding: utf-8
sandwich = dict(spam=2, eggs=1, sausage=1)