Skip to content

Commit

Permalink
Add 3.12 release video
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesmurphy-mc committed Oct 16, 2023
1 parent 00fd985 commit c13fcff
Show file tree
Hide file tree
Showing 9 changed files with 284 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ James and his team are available for consulting, contracting, code reviews, and

| N | Code | Video |
|-----| --- |--- |
| 130 | [src](videos/130_python_312_release) | [Python 3.12 is HERE!](https://youtu.be/8l4UWz48Elc) |
| 129 | [src](videos/129_lambda_in_a_loop_is_a_code_smell) | [Lambda in a Loop is a Code Smell](https://youtu.be/fZE6ZWde-Os) |
| 128 | [src](videos/128_id_mapping) | [A forbidden Python technique to put ANYTHING in a dict or set.](https://youtu.be/NpdNDTncxwA) |
| 127 | [src](videos/127_accidentally_quadratic_unique_sum) | [Don't make this big O mistake!](https://youtu.be/PXWL_Xzyrp4) |
Expand Down
20 changes: 20 additions & 0 deletions videos/130_python_312_release/buffer-defs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// From cpython/Include/pybuffer.h

typedef struct {
void *buf;
PyObject *obj;
Py_ssize_t len;
Py_ssize_t itemsize;
int readonly;
int ndim;
char *format;
Py_ssize_t *shape;
Py_ssize_t *strides;
Py_ssize_t *suboffsets;
void *internal;
} Py_buffer;

typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
typedef void (*releasebufferproc)(PyObject *, Py_buffer *);


41 changes: 41 additions & 0 deletions videos/130_python_312_release/buffer_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Example from PEP 688

import inspect

# Implements __buffer__, __release_buffer__
class MyBuffer:
def __init__(self, data: bytes):
self.data = bytearray(data)
self.view = None

def __buffer__(self, flags: int) -> memoryview:
if flags != inspect.BufferFlags.FULL_RO:
raise TypeError("Only BufferFlags.FULL_RO supported")
if self.view is not None:
raise RuntimeError("Buffer already held")
self.view = memoryview(self.data)
return self.view

def __release_buffer__(self, view: memoryview) -> None:
assert self.view is view # guaranteed to be true
self.view.release()
self.view = None

def extend(self, b: bytes) -> None:
if self.view is not None:
raise RuntimeError("Cannot extend held buffer")
self.data.extend(b)

def main():
buffer = MyBuffer(b"capybara")

# __buffer__ called here in memoryview:
# vvvvvvvvvvvvvvvvvv
with memoryview(buffer) as view:
view[0] = ord("C")
# __release_buffer__ called exiting with block

# buffer now contains b"Capybara"

if __name__ == "__main__":
main()
16 changes: 16 additions & 0 deletions videos/130_python_312_release/itertools_batched.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import itertools


def print_batches():
data = [1, 2, 3, 4, 5, 6, 7, 8]
for batch in itertools.batched(data, 3):
print(batch)
# (1, 2, 3)
# (4, 5, 6)
# (7, 8)

def main():
print_batches()

if __name__ == '__main__':
main()
24 changes: 24 additions & 0 deletions videos/130_python_312_release/monitoring_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import sys

def my_trace_call(code, instruction_offset, call, arg0):
print("Event: call")

def my_trace_line(code, line_number):
print("Event: line")

def setup_monitoring():
mo = sys.monitoring
events = mo.events
mo.use_tool_id(0, "my_debugger")
mo.set_events(0, events.CALL | events.LINE)
mo.register_callback(0, events.CALL, my_trace_call)
mo.register_callback(0, events.LINE, my_trace_line)

def main():
for x in range(5):
print(x)

if __name__ == "__main__":
setup_monitoring()
main()

9 changes: 9 additions & 0 deletions videos/130_python_312_release/none_refcount_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import sys

def main():
count = sys.getrefcount(None)
print(f"0b{count:b}")


if __name__ == "__main__":
main()
13 changes: 13 additions & 0 deletions videos/130_python_312_release/refcount_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import sys

def main():
my_list = [1, 2, 3]
print(sys.getrefcount(my_list)) # 2
use_list(my_list)

def use_list(lst):
print(sys.getrefcount(lst)) # 3


if __name__ == "__main__":
main()
14 changes: 14 additions & 0 deletions videos/130_python_312_release/settrace_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import sys

def my_trace(frame, event, arg):
print(f"Event: {event}")
return my_trace

def main():
for x in range(5):
print(x)

if __name__ == "__main__":
sys.settrace(my_trace)
main()

146 changes: 146 additions & 0 deletions videos/130_python_312_release/slow_debug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# -*- coding: utf-8 -*-
import collections
import itertools
import os
import pathlib
import sys
import time

import numpy as np

# For Linux/Wayland users.
if os.getenv("XDG_SESSION_TYPE") == "wayland":
os.environ["XDG_SESSION_TYPE"] = "x11"

import glfw
import OpenGL.GL as gl
import imgui
from imgui.integrations.glfw import GlfwRenderer

DRIFT_SPEED = 100
TAIL_LENGTH = 1000

frame_time = 0.0


def tick():
global frame_time
frame_time = time.perf_counter()


bm = collections.deque([np.array([0., 0.])] * 10, maxlen=TAIL_LENGTH)

IS_DEBUG = (sys.gettrace() is not None)


def frame_commands():
last_time = frame_time
tick()
curr_time = frame_time
dt = curr_time - last_time
try:
fps = int(1 / dt)
except ZeroDivisionError:
fps = 0

io = imgui.get_io()

if io.key_ctrl and io.keys_down[glfw.KEY_Q]:
sys.exit(0)

with imgui.begin_main_menu_bar() as main_menu_bar:
if main_menu_bar.opened:
with imgui.begin_menu("File", True) as file_menu:
if file_menu.opened:
clicked_quit, selected_quit = imgui.menu_item("Quit", "Ctrl+Q")
if clicked_quit:
sys.exit(0)

with imgui.begin("FPS"):
imgui.text(f"Debug: ")
imgui.same_line()
if IS_DEBUG:
imgui.text_colored("ON", 0., 1., 0.)
else:
imgui.text_colored("OFF", 1., 0., 0.)
imgui.text(f"FPS: {fps}")

scale = np.sqrt(dt) * 200
dbm = np.random.multivariate_normal(mean=(0.0, 0.0), cov=scale * np.eye(2))
next_bm = bm[len(bm) - 1] + dbm
next_bm = np.maximum(next_bm, 0.0)
next_bm = np.minimum(next_bm, np.array(glfw.get_window_size(glfw.get_current_context())))
bm.append(next_bm)
if tuple(io.mouse_pos) != (-1, -1):
drift = (np.array(io.mouse_pos) - next_bm) / DRIFT_SPEED
next_bm += drift
draw_list = imgui.get_overlay_draw_list()
for idx, ((x1, y1), (x2, y2)) in enumerate(itertools.pairwise(bm)):
color = imgui.get_color_u32_rgba(1., 1., 1., idx / (len(bm) - 1))
draw_list.add_line(x1, y1, x2, y2, color, thickness=1.0)


def render_frame(impl, window, font):
glfw.poll_events()
impl.process_inputs()
imgui.new_frame()

gl.glClearColor(0.1, 0.1, 0.1, 1)
gl.glClear(gl.GL_COLOR_BUFFER_BIT)

imgui.push_font(font)
frame_commands()
imgui.pop_font()

imgui.render()
impl.render(imgui.get_draw_data())
glfw.swap_buffers(window)


def impl_glfw_init():
width, height = 600, 600
window_name = "Brownian motion demo"

if not glfw.init():
print("Could not initialize OpenGL context")
sys.exit(1)

glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, gl.GL_TRUE)

window = glfw.create_window(int(width), int(height), window_name, None, None)
glfw.make_context_current(window)
glfw.swap_interval(0)

if not window:
glfw.terminate()
print("Could not initialize Window")
sys.exit(1)

return window


def main():
imgui.create_context()
window = impl_glfw_init()

impl = GlfwRenderer(window)

font_path = pathlib.Path(__file__).with_name("Montserrat-ExtraBold.ttf")
try:
font = imgui.get_io().fonts.add_font_from_file_ttf(str(font_path), 80)
except imgui.ImGuiError:
font = imgui.get_io().fonts.add_font_default()
impl.refresh_font_texture()

while not glfw.window_should_close(window):
render_frame(impl, window, font)

impl.shutdown()
glfw.terminate()


if __name__ == "__main__":
main()

0 comments on commit c13fcff

Please sign in to comment.