Skip to content

Commit

Permalink
Merge pull request #51 from life4/run-more-snippets
Browse files Browse the repository at this point in the history
Make more snippets runnable
  • Loading branch information
orsinium committed Aug 1, 2023
2 parents f0354b9 + 8ebf77b commit 0134286
Show file tree
Hide file tree
Showing 15 changed files with 44 additions and 29 deletions.
2 changes: 1 addition & 1 deletion posts/assert.md
Expand Up @@ -25,7 +25,7 @@ However, there are few advantages of assert as directive over assert as a functi

2. The message is lazy and executed only when needed:

```python
```python {shield:AssertionError} {no-print}
assert False, print("executed")
# executed
# AssertionError: None
Expand Down
6 changes: 5 additions & 1 deletion posts/cached-property.md
Expand Up @@ -11,7 +11,11 @@ python: "3.8"

Decorator `@cached_property` is an amazing way to simplify your code. It's like the regular `@property` but remembers the value after the first call:

```python
```python {hide}
from functools import cached_property
```

```python {continue} {no-print}
class C:
@cached_property
def p(self):
Expand Down
2 changes: 1 addition & 1 deletion posts/class-body.md
Expand Up @@ -10,7 +10,7 @@ traces:

The class body is the same as, let's say, the function body, [with only a few limitations](https://t.me/pythonetc/438). You can put any statements inside, reuse previous results and so on:

```python
```python {no-print}
class A:
print('hello')
a = 1
Expand Down
4 changes: 2 additions & 2 deletions posts/data-descriptors.md
Expand Up @@ -10,7 +10,7 @@ author: orsinium

Non-data descriptor:

```python
```python {no-print}
class D:
def __get__(self, obj, owner):
print('get', obj, owner)
Expand All @@ -30,7 +30,7 @@ c.d

Data descriptor:

```python
```python {no-print}
class D:
def __get__(self, obj, owner):
print('get', obj, owner)
Expand Down
6 changes: 3 additions & 3 deletions posts/decorators.md
Expand Up @@ -22,7 +22,7 @@ def f(): pass

Python 3.9 (via [PEP-614](https://www.python.org/dev/peps/pep-0614/)) relaxes with restriction allowing to have any expression as a decorator:

```python
```python {continue}
decos = {
'id': lambda x: x,
}
Expand All @@ -36,7 +36,7 @@ f

You can use matrix multiplication to make it confusing (don't try it at home!):

```python
```python {no-print}
class D:
f = None
def __init__(self, name):
Expand Down Expand Up @@ -66,7 +66,7 @@ f()

You can use a simple wrapper function to have any expression in older python versions:

```python
```python {continue}
_ = lambda x: x

@_(D('a') @ D('b'))
Expand Down
2 changes: 1 addition & 1 deletion posts/final.md
Expand Up @@ -12,7 +12,7 @@ traces:

Some languages, like Java, allow you to mark a class as `final` that means you can't inherit from it. There is how it can be implemented in a few lines (thanks to [Nikita Sobolev](https://github.com/sobolevn) for the implementation!):

```python
```python {shield:TypeError}
def _init_subclass(cls, *args, **kwargs) -> None:
raise TypeError('no subclassing!')

Expand Down
2 changes: 1 addition & 1 deletion posts/generic-types.md
Expand Up @@ -27,7 +27,7 @@ So, now, `from typing` import will become much shorter! Hooray! The next step wo

The only purpose of these types is type annotations. They don't make any runtime type checks:

```python
```python {shield:TypeError}
list[str]({1, 2, 3})
# [1, 2, 3]

Expand Down
4 changes: 2 additions & 2 deletions posts/license.md
Expand Up @@ -8,7 +8,7 @@ author: orsinium

Python provides 2 useless but interesting built-in functions: `copyright` and `license`. `copyright` gives a short overview who owned Python in different moments of history:

```python
```python {no-run}
>>> copyright()
Copyright (c) 2001-2020 Python Software Foundation.
All Rights Reserved.
Expand All @@ -25,7 +25,7 @@ All Rights Reserved.

An `license` gives not only all Python licenses but also an interesting reading about Python history:

```python
```python {no-run}
>>> license()
A. HISTORY OF THE SOFTWARE
==========================
Expand Down
5 changes: 3 additions & 2 deletions posts/literal-eval.md
Expand Up @@ -10,7 +10,8 @@ traces:

`ast.literal_eval` is a restricted version of `eval` that evaluates only literals:

```python
```python {shield:ValueError}
import ast
ast.literal_eval('[1, True, "three"]')
# [1, True, 'three']

Expand All @@ -20,7 +21,7 @@ ast.literal_eval('1+2')

This can be used for safely evaluating strings containing Python values from untrusted sources. For example, to support types for environment variables. However, be aware that too large and complex string can crash the interpreter:

```python
```python {no-run}
>>> import ast
>>> ast.literal_eval('1+1'*1000000)
[1] 32177 segmentation fault python3
Expand Down
14 changes: 8 additions & 6 deletions posts/match.md
Expand Up @@ -41,12 +41,12 @@ def inspect(obj) -> None:
print(f'the first element is {x}')
case {'route': route}: # matching dicts
print(f'dict with ONLY `route` key which is {route}')
case {'route': _, **_}: # matching rest for dicts
print(f'dict with `route` key')
# case {'route': _, **_}: # matching rest for dicts
# print(f'dict with `route` key')
case str() | bytes(): # matching types
print('something string-like')
case [x := [_, *_]]: # walrus and sub-patterns
print('non-empty list inside a list')
# case [x := [_, *_]]: # walrus and sub-patterns
# print('non-empty list inside a list')
case _: # default case
print('something else')
```
Expand All @@ -63,12 +63,13 @@ class object:

Also, it is possible to match objects' attributes:

```python
```python {no-print}
class Point:
def __init__(self, x, y):
self.x = x
self.y = y

obj = Point(1, 2)
match obj:
case Point(x=0, y=0):
print('both x and y are zero')
Expand All @@ -82,12 +83,13 @@ Also, if a class has `__match_args__`, the given arguments can be positional in

```python
class Point:
__match_args__ = ['x', 'y']
__match_args__ = ('x', 'y')

def __init__(self, x, y):
self.x = x
self.y = y

obj = Point(1, 2)
match obj:
case Point(0, 0): # here args are positional now
print('both x and y are zero')
Expand Down
13 changes: 9 additions & 4 deletions posts/merge-dicts.md
Expand Up @@ -12,30 +12,35 @@ python: "3.9"

There are a lot of ways to merge two dicts:

```python {hide}
d1 = {}
d2 = {}
```

1. Long but simple:

```python
```python {continue}
merged = d1.copy()
merged.update(d2)
```

2. [Unpacking](https://t.me/pythonetc/538):

```python
```python {continue}
merged = {**d1, **d2}
```

3. Unpacking again (keys must be strings):

```python
```python {continue}
merged = dict(d1, **d2)
```

4. `collections.ChainMap`. Result is not `dict` but so.

In python 3.9, [PEP-584](https://www.python.org/dev/peps/pep-0584/) introduced the 5th way. Meet the `|` operator for `dict`!

```python
```python {continue}
merged = d1 | d2
```

Expand Down
1 change: 1 addition & 0 deletions posts/recursion.md
Expand Up @@ -12,6 +12,7 @@ traces:
Python doesn't support [tail recursion](https://t.me/pythonetc/239). Hence, it's easy to face `RecursionError` when implementing recursive algorithms. You can get and change maximum recursion depth with [sys.getrecursionlimit](https://docs.python.org/3/library/sys.html#sys.getrecursionlimit) and [sys.setrecursionlimit](https://docs.python.org/3/library/sys.html#sys.setrecursionlimit) functions:

```python
import sys
sys.getrecursionlimit()
# 3000

Expand Down
4 changes: 3 additions & 1 deletion posts/set-name.md
Expand Up @@ -4,6 +4,8 @@ id: 582
author: orsinium
pep: 487
python: "3.6"
depends_on:
- cached_property
traces:
- [type: object, method: __set_name__]
---
Expand All @@ -19,7 +21,7 @@ So, the best solution is to store data in the class itself. But how to name the

`@cached_property` that we implemented above, relies on the passed function name and it is wrong:

```python
```python {no-run}
class C:
@cached_property
def a(self):
Expand Down
4 changes: 2 additions & 2 deletions posts/zen.md
Expand Up @@ -9,7 +9,7 @@ pep: 20

The famous "Zen of Python" was introduced in [PEP-20](https://www.python.org/dev/peps/pep-0020/). This is 19 aphorisms [authored by Tim Peters](https://mail.python.org/pipermail/python-list/1999-June/001951.html). Do `import this` in the Python interpreter to see them:

```python
```python {no-run}
>>> import this
The Zen of Python, by Tim Peters

Expand All @@ -36,7 +36,7 @@ Namespaces are one honking great idea -- let's do more of those!

The fun thing is how this module looks like. The original text is encoded by [ROT13](https://en.wikipedia.org/wiki/ROT13) algorithm and is decoded on the fly:

```python
```python {no-print}
s = """Gur Mra bs Clguba, ol Gvz Crgref
...
"""
Expand Down
4 changes: 2 additions & 2 deletions sdk/commands/_check_all.py
Expand Up @@ -18,11 +18,11 @@ def run(self) -> int:
for path in sorted(Path('posts').iterdir()):
if path.suffix != '.md':
continue
print(path.name)
# print(path.name)
post = Post.from_path(path)
if error := post.validate():
raise ValueError(f'invalid {post.path.name}: {error}')
if post.id is not None and post.id <= 560:
if post.id is not None and post.id <= 600:
try:
post.run_code() # TODO: all posts should be runnable
except BaseException as exc:
Expand Down

0 comments on commit 0134286

Please sign in to comment.