Curses Programming with Python

Curses Programming with Python¶
- Author:
A.M. Kuchling, Eric S. Raymond
- Release:
2.04
What is curses?¶
The curses library supplies a terminal-independent screen-painting and keyboard-handling facility for text-based terminals; such terminals include VT100s, the Linux console, and the simulated terminal provided by various programs. Display terminals support various control codes to perform common operations such as moving the cursor, scrolling the screen, and erasing areas. Different terminals use widely differing codes, and often have their own minor quirks.
In a world of graphical displays, one might ask “why bother”? It’s true that character-cell display terminals are an obsolete technology, but there are niches in which being able to do fancy things with them are still valuable. One niche is on small-footprint or embedded Unixes that don’t run an X server. Another is tools such as OS installers and kernel configurators that may have to run before any graphical support is available.
The curses library provides fairly basic functionality, providing the programmer with an abstraction of a display containing multiple non-overlapping windows of text. The contents of a window can be changed in various ways—adding text, erasing it, changing its appearance—and the curses library will figure out what control codes need to be sent to the terminal to produce the right output. curses doesn’t provide many user-interface concepts such as buttons, checkboxes, or dialogs; if you need such features, consider a user interface library such as Urwid.
The curses library was originally written for BSD Unix; the later System V versions of Unix from AT&T added many enhancements and new functions. BSD curses is no longer maintained, having been replaced by ncurses, which is an open-source implementation of the AT&T interface. If you’re using an open-source Unix such as Linux or FreeBSD, your system almost certainly uses ncurses. Since most current commercial Unix versions are based on System V code, all the functions described here will probably be available. The older versions of curses carried by some proprietary Unixes may not support everything, though.
The Windows version of Python doesn’t include the curses
module. A ported version called UniCurses is available.
The Python curses module¶
The Python module is a fairly simple wrapper over the C functions provided by
curses; if you’re already familiar with curses programming in C, it’s really
easy to transfer that knowledge to Python. The biggest difference is that the
Python interface makes things simpler by merging different C functions such as
addstr()
, mvaddstr()
, and mvwaddstr()
into a single
addstr()
method. You’ll see this covered in more
detail later.
This HOWTO is an introduction to writing text-mode programs with curses and Python. It doesn’t attempt to be a complete guide to the curses API; for that, see the Python library guide’s section on ncurses, and the C manual pages for ncurses. It will, however, give you the basic ideas.
Starting and ending a curses application¶
Before doing anything, curses must be initialized. This is done by
calling the initscr()
function, which will determine the
terminal type, send any required setup codes to the terminal, and
create various internal data structures. If successful,
initscr()
returns a window object representing the entire
screen; this is usually called stdscr
after the name of the
corresponding C variable.
import curses
stdscr = curses.initscr()
Usually curses applications turn off automatic echoing of keys to the
screen, in order to be able to read keys and only display them under
certain circumstances. This requires calling the
noecho()
function.
curses.noecho()
Applications will also commonly need to react to keys instantly, without requiring the Enter key to be pressed; this is called cbreak mode, as opposed to the usual buffered input mode.
curses.cbreak()
Terminals usually return special keys, such as the cursor keys or navigation
keys such as Page Up and Home, as a multibyte escape sequence. While you could
write your application to expect such sequences and process them accordingly,
curses can do it for you, returning a special value such as
curses.KEY_LEFT
. To get curses to do the job, you’ll have to enable
keypad mode.
stdscr.keypad(True)
Terminating a curses application is much easier than starting one. You’ll need to call:
curses.nocbreak()
stdscr.keypad(False)
curses.echo()
to reverse the curses-friendly terminal settings. Then call the
endwin()
function to restore the terminal to its original
operating mode.
curses.endwin()
A common problem when debugging a curses application is to get your terminal messed up when the application dies without restoring the terminal to its previous state. In Python this commonly happens when your code is buggy and raises an uncaught exception. Keys are no longer echoed to the screen when you type them, for example, which makes using the shell difficult.
In Python you can avoid these complications and make debugging much easier by
importing the curses.wrapper()
function and using it like this:
from curses import wrapper
def main(stdscr):
# Clear screen
stdscr.clear()
# This raises ZeroDivisionError when i == 10.
for i in range(0, 11):
v = i-10
stdscr.addstr(i, 0, '10 divided by {} is {}'.format(v, 10/v))
stdscr.refresh()
stdscr.getkey()
wrapper(main)
The wrapper()
function takes a callable object and does the
initializations described above, also initializing colors if color
support is present. wrapper()
then runs your provided callable.
Once the callable returns, wrapper()
will restore the original
state of the terminal. The callable is called inside a
try
…except
that catches exceptions, restores
the state of the terminal, and then re-raises the exception. Therefore
your terminal won’t be left in a funny state on exception and you’ll be
able to read the exception’s message and traceback.
Windows and Pads¶
Windows are the basic abstraction in curses. A window object represents a rectangular area of the screen, and supports methods to display text, erase it, allow the user to input strings, and so forth.
The stdscr
object returned by the initscr()
function is a
window object that covers the entire screen. Many programs may need
only this single window, but you might wish to divide the screen into
smaller windows, in order to redraw or clear them separately. The
newwin()
function creates a new window of a given size,
returning the new window object.
begin_x = 20; begin_y = 7
height = 5; width = 40
win = curses.newwin(height, width, begin_y, begin_x)
Note that the coordinate system used in curses is unusual. Coordinates are always passed in the order y,x, and the top-left corner of a window is coordinate (0,0). This breaks the normal convention for handling coordinates where the x coordinate comes first. This is an unfortunate difference from most other computer applications, but it’s been part of curses since it was first written, and it’s too late to change things now.
Your application can determine the size of the screen by using the
curses.LINES
and curses.COLS
variables to obtain the y and
x sizes. Legal coordinates will then extend from (0,0)
to
(curses.LINES - 1, curses.COLS - 1)
.
When you call a method to display or erase text, the effect doesn’t
immediately show up on the display. Instead you must call the
refresh()
method of window objects to update the
screen.
This is because curses was originally written with slow 300-baud
terminal connections in mind; with these terminals, minimizing the
time required to redraw the screen was very important. Instead curses
accumulates changes to the screen and displays them in the most
efficient manner when you call refresh()
. For example, if your
program displays some text in a window and then clears the window,
there’s no need to send the original text because they’re never
visible.
In practice, explicitly telling curses to redraw a window doesn’t
really complicate programming with curses much. Most programs go into a flurry
of activity, and then pause waiting for a keypress or some other action on the
part of the user. All you have to do is to be sure that the screen has been
redrawn before pausing to wait for user input, by first calling
stdscr.refresh()
or the refresh()
method of some other relevant
window.
A pad is a special case of a window; it can be larger than the actual display screen, and only a portion of the pad displayed at a time. Creating a pad requires the pad’s height and width, while refreshing a pad requires giving the coordinates of the on-screen area where a subsection of the pad will be displayed.
pad = curses.newpad(100, 100)
# These loops fill the pad with letters; addch() is
# explained in the next section
for y in range(0, 99):
for x in range(0, 99):
pad.addch(y,x, ord('a') + (x*x+y*y) % 26)
# Displays a section of the pad in the middle of the screen.
# (0,0) : coordinate of upper-left corner of pad area to display.
# (5,5) : coordinate of upper-left corner of window area to be filled
# with pad content.
# (20, 75) : coordinate of lower-right corner of window area to be
# : filled with pad content.
pad.refresh( 0,0, 5,5, 20,75)
The refresh()
call displays a section of the pad in the rectangle
extending from coordinate (5,5) to coordinate (20,75) on the screen; the upper
left corner of the displayed section is coordinate (0,0) on the pad. Beyond
that difference, pads are exactly like ordinary windows and support the same
methods.
If you have multiple windows and pads on screen there is a more
efficient way to update the screen and prevent annoying screen flicker
as each part of the screen gets updated. refresh()
actually
does two things:
Calls the
noutrefresh()
method of each window to update an underlying data structure representing the desired state of the screen.Calls the function
doupdate()
function to change the physical screen to match the desired state recorded in the data structure.
Instead you can call noutrefresh()
on a number of windows to
update the data structure, and then call doupdate()
to update
the screen.
Displaying Text¶
From a C programmer’s point of view, curses may sometimes look like a
twisty maze of functions, all subtly different. For example,
addstr()
displays a string at the current cursor location in
the stdscr
window, while mvaddstr()
moves to a given y,x
coordinate first before displaying the string. waddstr()
is just
like addstr()
, but allows specifying a window to use instead of
using stdscr
by default. mvwaddstr()
allows specifying both
a window and a coordinate.
Fortunately the Python interface hides all these details. stdscr
is a window object like any other, and methods such as
addstr()
accept multiple argument forms. Usually there
are four different forms.
Form |
Description |
|---|---|
str or ch |
Display the string str or character ch at the current position |
str or ch, attr |
Display the string str or character ch, using attribute attr at the current position |
y, x, str or ch |
Move to position y,x within the window, and display str or ch |
y, x, str or ch, attr |
Move to position y,x within the window, and display str or ch, using attribute attr |
Attributes allow displaying text in highlighted forms such as boldface, underline, reverse code, or in color. They’ll be explained in more detail in the next subsection.
The addstr()
method takes a Python string or
bytestring as the value to be displayed. The contents of bytestrings
are sent to the terminal as-is. Strings are encoded to bytes using
the value of the window’s encoding
attribute; this defaults to
the default system encoding as returned by locale.getencoding()
.
The addch()
methods take a character, which can be
either a string of length 1, a bytestring of length 1, or an integer.
Constants are provided for extension characters; these constants are
integers greater than 255. For example, ACS_PLMINUS
is a +/-
symbol, and ACS_ULCORNER
is the upper left corner of a box
(handy for drawing borders). You can also use the appropriate Unicode
character.
Windows remember where the cursor was left after the last operation, so if you
leave out the y,x coordinates, the string or character will be displayed
wherever the last operation left off. You can also move the cursor with the
move(y,x)
method. Because some terminals always display a flashing cursor,
you may want to ensure that the cursor is positioned in some location where it
won’t be distracting; it can be confusing to have the cursor blinking at some
apparently random location.
If your application doesn’t need a blinking cursor at all, you can
call curs_set(False)
to make it invisible. For compatibility
with older curses versions, there’s a leaveok(bool)
function
that’s a synonym for curs_set()
. When bool is true, the
curses library will attempt to suppress the flashing cursor, and you
won’t need to worry about leaving it in odd locations.
Attributes and Color¶
Characters can be displayed in different ways. Status lines in a text-based application are commonly shown in reverse video, or a text viewer may need to highlight certain words. curses supports this by allowing you to specify an attribute for each cell on the screen.
An attribute is an integer, each bit representing a different attribute. You can try to display text with multiple attribute bits set, but curses doesn’t guarantee that all the possible combinations are available, or that they’re all visually distinct. That depends on the ability of the terminal being used, so it’s safest to stick to the most commonly available attributes, listed here.
Attribute |
Description |
|---|---|
Blinking text |
|
Extra bright or bold text |
|
Half bright text |
|
Reverse-video text |
|
The best highlighting mode available |
|
Underlined text |
So, to display a reverse-video status line on the top line of the screen, you could code:
stdscr.addstr(0, 0, "Current mode: Typing mode",
curses.A_REVERSE)
stdscr.refresh()
The curses library also supports color on those terminals that provide it. The most common such terminal is probably the Linux console, followed by color xterms.
To use color, you must call the start_color()
function soon
after calling initscr()
, to initialize the default color set
(the curses.wrapper()
function does this automatically). Once that’s
done, the has_colors()
function returns TRUE if the terminal
in use can
actually display color. (Note: curses uses the American spelling ‘color’,
instead of the Canadian/British spelling ‘colour’. If you’re used to the
British spelling, you’ll have to resign yourself to misspelling it for the sake
of these functions.)
The curses library maintains a finite number of color pairs, containing a
foreground (or text) color and a background color. You can get the attribute
value corresponding to a color pair with the color_pair()
function; this can be bitwise-OR’ed with other attributes such as
A_REVERSE
, but again, such combinations are not guaranteed to work
on all terminals.
An example, which displays a line of text using color pair 1:
stdscr.addstr("Pretty text", curses.color_pair(1))
stdscr.refresh()
As I said before, a color pair consists of a foreground and background color.
The init_pair(n, f, b)
function changes the definition of color pair n, to
foreground color f and background color b. Color pair 0 is hard-wired to white
on black, and cannot be changed.
Colors are numbered, and start_color()
initializes 8 basic
colors when it activates color mode. They are: 0:black, 1:red,
2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The curses
module defines named constants for each of these colors:
curses.COLOR_BLACK
, curses.COLOR_RED
, and so forth.
Let’s put all this together. To change color 1 to red text on a white background, you would call:
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_WHITE)
When you change a color pair, any text already displayed using that color pair will change to the new colors. You can also display new text in this color with:
stdscr.addstr(0,0, "RED ALERT!", curses.color_pair(1))
Very fancy terminals can change the definitions of the actual colors to a given
RGB value. This lets you change color 1, which is usually red, to purple or
blue or any other color you like. Unfortunately, the Linux console doesn’t
support this, so I’m unable to try it out, and can’t provide any examples. You
can check if your terminal can do this by calling
can_change_color()
, which returns True
if the capability is
there. If you’re lucky enough to have such a talented terminal, consult your
system’s man pages for more information.
User Input¶
The C curses library offers only very simple input mechanisms. Python’s
curses
module adds a basic text-input widget. (Other libraries
such as Urwid have more extensive collections of widgets.)
There are two methods for getting input from a window:
getch()
refreshes the screen and then waits for the user to hit a key, displaying the key ifecho()
has been called earlier. You can optionally specify a coordinate to which the cursor should be moved before pausing.getkey()
does the same thing but converts the integer to a string. Individual characters are returned as 1-character strings, and special keys such as function keys return longer strings containing a key name such asKEY_UP
or^G
.
It’s possible to not wait for the user using the
nodelay()
window method. After nodelay(True)
,
getch()
and getkey()
for the window become
non-blocking. To signal that no input is ready, getch()
returns
curses.ERR
(a value of -1) and getkey()
raises an exception.
There’s also a halfdelay()
function, which can be used to (in
effect) set a timer on each getch()
; if no input becomes
available within a specified delay (measured in tenths of a second),
curses raises an exception.
The getch()
method returns an integer; if it’s between 0 and 255, it
represents the ASCII code of the key pressed. Values greater than 255 are
special keys such as Page Up, Home, or the cursor keys. You can compare the
value returned to constants such as curses.KEY_PPAGE
,
curses.KEY_HOME
, or curses.KEY_LEFT
. The main loop of
your program may look something like this:
while True:
c = stdscr.getch()
if c == ord('p'):
PrintDocument()
elif c == ord('q'):
break # Exit the while loop
elif c == curses.KEY_HOME:
x = y = 0
The curses.ascii
module supplies ASCII class membership functions that
take either integer or 1-character string arguments; these may be useful in
writing more readable tests for such loops. It also supplies
conversion functions that take either integer or 1-character-string arguments
and return the same type. For example, curses.ascii.ctrl()
returns the
control character corresponding to its argument.
There’s also a method to retrieve an entire string,
getstr()
. It isn’t used very often, because its
functionality is quite limited; the only editing keys available are
the backspace key and the Enter key, which terminates the string. It
can optionally be limited to a fixed number of characters.
curses.echo() # Enable echoing of characters
# Get a 15-character string, with the cursor on the top line
s = stdscr.getstr(0,0, 15)
The curses.textpad
module supplies a text box that supports an
Emacs-like set of keybindings. Various methods of the
Textbox
class support editing with input
validation and gathering the edit results either with or without
trailing spaces. Here’s an example:
import curses
from curses.textpad import Textbox, rectangle
def main(stdscr):
stdscr.addstr(0, 0, "Enter IM message: (hit Ctrl-G to send)")
editwin = curses.newwin(5,30, 2,1)
rectangle(stdscr, 1,0, 1+5+1, 1+30+1)
stdscr.refresh()
box = Textbox(editwin)
# Let the user edit until Ctrl-G is struck.
box.edit()
# Get resulting contents
message = box.gather()
See the library documentation on curses.textpad
for more details.
For More Information¶
This HOWTO doesn’t cover some advanced topics, such as reading the
contents of the screen or capturing mouse events from an xterm
instance, but the Python library page for the curses
module is now
reasonably complete. You should browse it next.
If you’re in doubt about the detailed behavior of the curses functions, consult the manual pages for your curses implementation, whether it’s ncurses or a proprietary Unix vendor’s. The manual pages will document any quirks, and provide complete lists of all the functions, attributes, and ACS_* characters available to you.
Because the curses API is so large, some functions aren’t supported in the Python interface. Often this isn’t because they’re difficult to implement, but because no one has needed them yet. Also, Python doesn’t yet support the menu library associated with ncurses. Patches adding support for these would be welcome; see the Python Developer’s Guide to learn more about submitting patches to Python.
Writing Programs with NCURSES: a lengthy tutorial for C programmers.
“Use curses… don’t swear”: video of a PyCon 2013 talk on controlling terminals using curses or Urwid.
“Console Applications with Urwid”: video of a PyCon CA 2012 talk demonstrating some applications written using Urwid.


: Generating MIME documents

email.generator
: Generating MIME documents¶
Source code: Lib/email/generator.py
One of the most common tasks is to generate the flat (serialized) version of
the email message represented by a message object structure. You will need to
do this if you want to send your message via smtplib.SMTP.sendmail()
,
or print the message on the console. Taking a
message object structure and producing a serialized representation is the job
of the generator classes.
As with the email.parser
module, you aren’t limited to the functionality
of the bundled generator; you could write one from scratch yourself. However
the bundled generator knows how to generate most email in a standards-compliant
way, should handle MIME and non-MIME email messages just fine, and is designed
so that the bytes-oriented parsing and generation operations are inverses,
assuming the same non-transforming policy
is used for both. That
is, parsing the serialized byte stream via the
BytesParser
class and then regenerating the serialized
byte stream using BytesGenerator
should produce output identical to
the input [1]. (On the other hand, using the generator on an
EmailMessage
constructed by program may result in
changes to the EmailMessage
object as defaults are
filled in.)
The Generator
class can be used to flatten a message into a text (as
opposed to binary) serialized representation, but since Unicode cannot
represent binary data directly, the message is of necessity transformed into
something that contains only ASCII characters, using the standard email RFC
Content Transfer Encoding techniques for encoding email messages for transport
over channels that are not “8 bit clean”.
To accommodate reproducible processing of SMIME-signed messages
Generator
disables header folding for message parts of type
multipart/signed
and all subparts.
- class email.generator.BytesGenerator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)¶
Return a
BytesGenerator
object that will write any message provided to theflatten()
method, or any surrogateescape encoded text provided to thewrite()
method, to the file-like object outfp. outfp must support awrite
method that accepts binary data.If optional mangle_from_ is
True
, put a>
character in front of any line in the body that starts with the exact string"From "
, that isFrom
followed by a space at the beginning of a line. mangle_from_ defaults to the value of themangle_from_
setting of the policy (which isTrue
for thecompat32
policy andFalse
for all others). mangle_from_ is intended for use when messages are stored in Unix mbox format (seemailbox
and WHY THE CONTENT-LENGTH FORMAT IS BAD).If maxheaderlen is not
None
, refold any header lines that are longer than maxheaderlen, or if0
, do not rewrap any headers. If manheaderlen isNone
(the default), wrap headers and other message lines according to the policy settings.If policy is specified, use that policy to control message generation. If policy is
None
(the default), use the policy associated with theMessage
orEmailMessage
object passed toflatten
to control the message generation. Seeemail.policy
for details on what policy controls.Added in version 3.2.
Changed in version 3.3: Added the policy keyword.
Changed in version 3.6: The default behavior of the mangle_from_ and maxheaderlen parameters is to follow the policy.
- flatten(msg, unixfrom=False, linesep=None)¶
Print the textual representation of the message object structure rooted at msg to the output file specified when the
BytesGenerator
instance was created.If the
policy
optioncte_type
is8bit
(the default), copy any headers in the original parsed message that have not been modified to the output with any bytes with the high bit set reproduced as in the original, and preserve the non-ASCII Content-Transfer-Encoding of any body parts that have them. Ifcte_type
is7bit
, convert the bytes with the high bit set as needed using an ASCII-compatible Content-Transfer-Encoding. That is, transform parts with non-ASCII Content-Transfer-Encoding (Content-Transfer-Encoding: 8bit) to an ASCII compatible Content-Transfer-Encoding, and encode RFC-invalid non-ASCII bytes in headers using the MIMEunknown-8bit
character set, thus rendering them RFC-compliant.If unixfrom is
True
, print the envelope header delimiter used by the Unix mailbox format (seemailbox
) before the first of the RFC 5322 headers of the root message object. If the root object has no envelope header, craft a standard one. The default isFalse
. Note that for subparts, no envelope header is ever printed.If linesep is not
None
, use it as the separator character between all the lines of the flattened message. If linesep isNone
(the default), use the value specified in the policy.
- clone(fp)¶
Return an independent clone of this
BytesGenerator
instance with the exact same option settings, and fp as the new outfp.
- write(s)¶
Encode s using the
ASCII
codec and thesurrogateescape
error handler, and pass it to the write method of the outfp passed to theBytesGenerator
’s constructor.
As a convenience, EmailMessage
provides the methods
as_bytes()
and bytes(aMessage)
(a.k.a.
__bytes__()
), which simplify the generation of
a serialized binary representation of a message object. For more detail, see
email.message
.
Because strings cannot represent binary data, the Generator
class must
convert any binary data in any message it flattens to an ASCII compatible
format, by converting them to an ASCII compatible
Content-Transfer_Encoding. Using the terminology of the email
RFCs, you can think of this as Generator
serializing to an I/O stream
that is not “8 bit clean”. In other words, most applications will want
to be using BytesGenerator
, and not Generator
.
- class email.generator.Generator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)¶
Return a
Generator
object that will write any message provided to theflatten()
method, or any text provided to thewrite()
method, to the file-like object outfp. outfp must support awrite
method that accepts string data.If optional mangle_from_ is
True
, put a>
character in front of any line in the body that starts with the exact string"From "
, that isFrom
followed by a space at the beginning of a line. mangle_from_ defaults to the value of themangle_from_
setting of the policy (which isTrue
for thecompat32
policy andFalse
for all others). mangle_from_ is intended for use when messages are stored in Unix mbox format (seemailbox
and WHY THE CONTENT-LENGTH FORMAT IS BAD).If maxheaderlen is not
None
, refold any header lines that are longer than maxheaderlen, or if0
, do not rewrap any headers. If manheaderlen isNone
(the default), wrap headers and other message lines according to the policy settings.If policy is specified, use that policy to control message generation. If policy is
None
(the default), use the policy associated with theMessage
orEmailMessage
object passed toflatten
to control the message generation. Seeemail.policy
for details on what policy controls.Changed in version 3.3: Added the policy keyword.
Changed in version 3.6: The default behavior of the mangle_from_ and maxheaderlen parameters is to follow the policy.
- flatten(msg, unixfrom=False, linesep=None)¶
Print the textual representation of the message object structure rooted at msg to the output file specified when the
Generator
instance was created.If the
policy
optioncte_type
is8bit
, generate the message as if the option were set to7bit
. (This is required because strings cannot represent non-ASCII bytes.) Convert any bytes with the high bit set as needed using an ASCII-compatible Content-Transfer-Encoding. That is, transform parts with non-ASCII Content-Transfer-Encoding (Content-Transfer-Encoding: 8bit) to an ASCII compatible Content-Transfer-Encoding, and encode RFC-invalid non-ASCII bytes in headers using the MIMEunknown-8bit
character set, thus rendering them RFC-compliant.If unixfrom is
True
, print the envelope header delimiter used by the Unix mailbox format (seemailbox
) before the first of the RFC 5322 headers of the root message object. If the root object has no envelope header, craft a standard one. The default isFalse
. Note that for subparts, no envelope header is ever printed.If linesep is not
None
, use it as the separator character between all the lines of the flattened message. If linesep isNone
(the default), use the value specified in the policy.Changed in version 3.2: Added support for re-encoding
8bit
message bodies, and the linesep argument.
As a convenience, EmailMessage
provides the methods
as_string()
and str(aMessage)
(a.k.a.
__str__()
), which simplify the generation of
a formatted string representation of a message object. For more detail, see
email.message
.
The email.generator
module also provides a derived class,
DecodedGenerator
, which is like the Generator
base class,
except that non-text parts are not serialized, but are instead
represented in the output stream by a string derived from a template filled
in with information about the part.
- class email.generator.DecodedGenerator(outfp, mangle_from_=None, maxheaderlen=None, fmt=None, *, policy=None)¶
Act like
Generator
, except that for any subpart of the message passed toGenerator.flatten()
, if the subpart is of main type text, print the decoded payload of the subpart, and if the main type is not text, instead of printing it fill in the string fmt using information from the part and print the resulting filled-in string.To fill in fmt, execute
fmt % part_info
, wherepart_info
is a dictionary composed of the following keys and values:type
– Full MIME type of the non-text partmaintype
– Main MIME type of the non-text partsubtype
– Sub-MIME type of the non-text partfilename
– Filename of the non-text partdescription
– Description associated with the non-text partencoding
– Content transfer encoding of the non-text part
If fmt is
None
, use the following default fmt:“[Non-text (%(type)s) part of message omitted, filename %(filename)s]”
Optional _mangle_from_ and maxheaderlen are as with the
Generator
base class.
Footnotes


Memory Management

Memory Management¶
Overview¶
Memory management in Python involves a private heap containing all Python objects and data structures. The management of this private heap is ensured internally by the Python memory manager. The Python memory manager has different components which deal with various dynamic storage management aspects, like sharing, segmentation, preallocation or caching.
At the lowest level, a raw memory allocator ensures that there is enough room in the private heap for storing all Python-related data by interacting with the memory manager of the operating system. On top of the raw memory allocator, several object-specific allocators operate on the same heap and implement distinct memory management policies adapted to the peculiarities of every object type. For example, integer objects are managed differently within the heap than strings, tuples or dictionaries because integers imply different storage requirements and speed/space tradeoffs. The Python memory manager thus delegates some of the work to the object-specific allocators, but ensures that the latter operate within the bounds of the private heap.
It is important to understand that the management of the Python heap is performed by the interpreter itself and that the user has no control over it, even if they regularly manipulate object pointers to memory blocks inside that heap. The allocation of heap space for Python objects and other internal buffers is performed on demand by the Python memory manager through the Python/C API functions listed in this document.
To avoid memory corruption, extension writers should never try to operate on
Python objects with the functions exported by the C library: malloc()
,
calloc()
, realloc()
and free()
. This will result in mixed
calls between the C allocator and the Python memory manager with fatal
consequences, because they implement different algorithms and operate on
different heaps. However, one may safely allocate and release memory blocks
with the C library allocator for individual purposes, as shown in the following
example:
PyObject *res;
char *buf = (char *) malloc(BUFSIZ); /* for I/O */
if (buf == NULL)
return PyErr_NoMemory();
...Do some I/O operation involving buf...
res = PyBytes_FromString(buf);
free(buf); /* malloc'ed */
return res;
In this example, the memory request for the I/O buffer is handled by the C library allocator. The Python memory manager is involved only in the allocation of the bytes object returned as a result.
In most situations, however, it is recommended to allocate memory from the Python heap specifically because the latter is under control of the Python memory manager. For example, this is required when the interpreter is extended with new object types written in C. Another reason for using the Python heap is the desire to inform the Python memory manager about the memory needs of the extension module. Even when the requested memory is used exclusively for internal, highly specific purposes, delegating all memory requests to the Python memory manager causes the interpreter to have a more accurate image of its memory footprint as a whole. Consequently, under certain circumstances, the Python memory manager may or may not trigger appropriate actions, like garbage collection, memory compaction or other preventive procedures. Note that by using the C library allocator as shown in the previous example, the allocated memory for the I/O buffer escapes completely the Python memory manager.
See also
The PYTHONMALLOC
environment variable can be used to configure
the memory allocators used by Python.
The PYTHONMALLOCSTATS
environment variable can be used to print
statistics of the pymalloc memory allocator every time a
new pymalloc object arena is created, and on shutdown.
Allocator Domains¶
All allocating functions belong to one of three different “domains” (see also
PyMemAllocatorDomain
). These domains represent different allocation
strategies and are optimized for different purposes. The specific details on
how every domain allocates memory or what internal functions each domain calls
is considered an implementation detail, but for debugging purposes a simplified
table can be found at Default Memory Allocators.
The APIs used to allocate and free a block of memory must be from the same domain.
For example, PyMem_Free()
must be used to free memory allocated using PyMem_Malloc()
.
The three allocation domains are:
Raw domain: intended for allocating memory for general-purpose memory buffers where the allocation must go to the system allocator or where the allocator can operate without an attached thread state. The memory is requested directly from the system. See Raw Memory Interface.
“Mem” domain: intended for allocating memory for Python buffers and general-purpose memory buffers where the allocation must be performed with an attached thread state. The memory is taken from the Python private heap. See Memory Interface.
Object domain: intended for allocating memory for Python objects. The memory is taken from the Python private heap. See Object allocators.
Note
The free-threaded build requires that only Python objects are allocated using the “object” domain and that all Python objects are allocated using that domain. This differs from the prior Python versions, where this was only a best practice and not a hard requirement.
For example, buffers (non-Python objects) should be allocated using PyMem_Malloc()
,
PyMem_RawMalloc()
, or malloc()
, but not PyObject_Malloc()
.
Raw Memory Interface¶
The following function sets are wrappers to the system allocator. These functions are thread-safe, so a thread state does not need to be attached.
The default raw memory allocator uses
the following functions: malloc()
, calloc()
, realloc()
and free()
; call malloc(1)
(or calloc(1, 1)
) when requesting
zero bytes.
Added in version 3.4.
-
void *PyMem_RawMalloc(size_t n)¶
- Part of the Stable ABI since version 3.13.
Allocates n bytes and returns a pointer of type void* to the allocated memory, or
NULL
if the request fails.Requesting zero bytes returns a distinct non-
NULL
pointer if possible, as ifPyMem_RawMalloc(1)
had been called instead. The memory will not have been initialized in any way.
-
void *PyMem_RawCalloc(size_t nelem, size_t elsize)¶
- Part of the Stable ABI since version 3.13.
Allocates nelem elements each whose size in bytes is elsize and returns a pointer of type void* to the allocated memory, or
NULL
if the request fails. The memory is initialized to zeros.Requesting zero elements or elements of size zero bytes returns a distinct non-
NULL
pointer if possible, as ifPyMem_RawCalloc(1, 1)
had been called instead.Added in version 3.5.
-
void *PyMem_RawRealloc(void *p, size_t n)¶
- Part of the Stable ABI since version 3.13.
Resizes the memory block pointed to by p to n bytes. The contents will be unchanged to the minimum of the old and the new sizes.
If p is
NULL
, the call is equivalent toPyMem_RawMalloc(n)
; else if n is equal to zero, the memory block is resized but is not freed, and the returned pointer is non-NULL
.Unless p is
NULL
, it must have been returned by a previous call toPyMem_RawMalloc()
,PyMem_RawRealloc()
orPyMem_RawCalloc()
.If the request fails,
PyMem_RawRealloc()
returnsNULL
and p remains a valid pointer to the previous memory area.
-
void PyMem_RawFree(void *p)¶
- Part of the Stable ABI since version 3.13.
Frees the memory block pointed to by p, which must have been returned by a previous call to
PyMem_RawMalloc()
,PyMem_RawRealloc()
orPyMem_RawCalloc()
. Otherwise, or ifPyMem_RawFree(p)
has been called before, undefined behavior occurs.If p is
NULL
, no operation is performed.
Memory Interface¶
The following function sets, modeled after the ANSI C standard, but specifying behavior when requesting zero bytes, are available for allocating and releasing memory from the Python heap.
The default memory allocator uses the pymalloc memory allocator.
Warning
There must be an attached thread state when using these functions.
Changed in version 3.6: The default allocator is now pymalloc instead of system malloc()
.
-
void *PyMem_Malloc(size_t n)¶
- Part of the Stable ABI.
Allocates n bytes and returns a pointer of type void* to the allocated memory, or
NULL
if the request fails.Requesting zero bytes returns a distinct non-
NULL
pointer if possible, as ifPyMem_Malloc(1)
had been called instead. The memory will not have been initialized in any way.
-
void *PyMem_Calloc(size_t nelem, size_t elsize)¶
- Part of the Stable ABI since version 3.7.
Allocates nelem elements each whose size in bytes is elsize and returns a pointer of type void* to the allocated memory, or
NULL
if the request fails. The memory is initialized to zeros.Requesting zero elements or elements of size zero bytes returns a distinct non-
NULL
pointer if possible, as ifPyMem_Calloc(1, 1)
had been called instead.Added in version 3.5.
-
void *PyMem_Realloc(void *p, size_t n)¶
- Part of the Stable ABI.
Resizes the memory block pointed to by p to n bytes. The contents will be unchanged to the minimum of the old and the new sizes.
If p is
NULL
, the call is equivalent toPyMem_Malloc(n)
; else if n is equal to zero, the memory block is resized but is not freed, and the returned pointer is non-NULL
.Unless p is
NULL
, it must have been returned by a previous call toPyMem_Malloc()
,PyMem_Realloc()
orPyMem_Calloc()
.If the request fails,
PyMem_Realloc()
returnsNULL
and p remains a valid pointer to the previous memory area.
-
void PyMem_Free(void *p)¶
- Part of the Stable ABI.
Frees the memory block pointed to by p, which must have been returned by a previous call to
PyMem_Malloc()
,PyMem_Realloc()
orPyMem_Calloc()
. Otherwise, or ifPyMem_Free(p)
has been called before, undefined behavior occurs.If p is
NULL
, no operation is performed.
The following type-oriented macros are provided for convenience. Note that TYPE refers to any C type.
-
PyMem_New(TYPE, n)¶
Same as
PyMem_Malloc()
, but allocates(n * sizeof(TYPE))
bytes of memory. Returns a pointer cast toTYPE*
. The memory will not have been initialized in any way.
-
PyMem_Resize(p, TYPE, n)¶
Same as
PyMem_Realloc()
, but the memory block is resized to(n * sizeof(TYPE))
bytes. Returns a pointer cast toTYPE*
. On return, p will be a pointer to the new memory area, orNULL
in the event of failure.This is a C preprocessor macro; p is always reassigned. Save the original value of p to avoid losing memory when handling errors.
-
void PyMem_Del(void *p)¶
Same as
PyMem_Free()
.
Deprecated aliases¶
These are soft deprecated aliases to existing functions and macros. They exist solely for backwards compatibility.
Deprecated alias |
Corresponding function or macro |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
Changed in version 3.4: The macros are now aliases of the corresponding functions and macros. Previously, their behavior was the same, but their use did not necessarily preserve binary compatibility across Python versions.
Deprecated since version 2.0.
Object allocators¶
The following function sets, modeled after the ANSI C standard, but specifying behavior when requesting zero bytes, are available for allocating and releasing memory from the Python heap.
Note
There is no guarantee that the memory returned by these allocators can be successfully cast to a Python object when intercepting the allocating functions in this domain by the methods described in the Customize Memory Allocators section.
The default object allocator uses the pymalloc memory allocator.
Warning
There must be an attached thread state when using these functions.
-
void *PyObject_Malloc(size_t n)¶
- Part of the Stable ABI.
Allocates n bytes and returns a pointer of type void* to the allocated memory, or
NULL
if the request fails.Requesting zero bytes returns a distinct non-
NULL
pointer if possible, as ifPyObject_Malloc(1)
had been called instead. The memory will not have been initialized in any way.
-
void *PyObject_Calloc(size_t nelem, size_t elsize)¶
- Part of the Stable ABI since version 3.7.
Allocates nelem elements each whose size in bytes is elsize and returns a pointer of type void* to the allocated memory, or
NULL
if the request fails. The memory is initialized to zeros.Requesting zero elements or elements of size zero bytes returns a distinct non-
NULL
pointer if possible, as ifPyObject_Calloc(1, 1)
had been called instead.Added in version 3.5.
-
void *PyObject_Realloc(void *p, size_t n)¶
- Part of the Stable ABI.
Resizes the memory block pointed to by p to n bytes. The contents will be unchanged to the minimum of the old and the new sizes.
If p is
NULL
, the call is equivalent toPyObject_Malloc(n)
; else if n is equal to zero, the memory block is resized but is not freed, and the returned pointer is non-NULL
.Unless p is
NULL
, it must have been returned by a previous call toPyObject_Malloc()
,PyObject_Realloc()
orPyObject_Calloc()
.If the request fails,
PyObject_Realloc()
returnsNULL
and p remains a valid pointer to the previous memory area.
-
void PyObject_Free(void *p)¶
- Part of the Stable ABI.
Frees the memory block pointed to by p, which must have been returned by a previous call to
PyObject_Malloc()
,PyObject_Realloc()
orPyObject_Calloc()
. Otherwise, or ifPyObject_Free(p)
has been called before, undefined behavior occurs.If p is
NULL
, no operation is performed.Do not call this directly to free an object’s memory; call the type’s
tp_free
slot instead.Do not use this for memory allocated by
PyObject_GC_New
orPyObject_GC_NewVar
; usePyObject_GC_Del()
instead.See also
PyObject_GC_Del()
is the equivalent of this function for memory allocated by types that support garbage collection.
Default Memory Allocators¶
Default memory allocators:
Configuration |
Name |
PyMem_RawMalloc |
PyMem_Malloc |
PyObject_Malloc |
|---|---|---|---|---|
Release build |
|
|
|
|
Debug build |
|
|
|
|
Release build, without pymalloc |
|
|
|
|
Debug build, without pymalloc |
|
|
|
|
Legend:
Name: value for
PYTHONMALLOC
environment variable.malloc
: system allocators from the standard C library, C functions:malloc()
,calloc()
,realloc()
andfree()
.pymalloc
: pymalloc memory allocator.mimalloc
: mimalloc memory allocator. The pymalloc allocator will be used if mimalloc support isn’t available.“+ debug”: with debug hooks on the Python memory allocators.
“Debug build”: Python build in debug mode.
Customize Memory Allocators¶
Added in version 3.4.
-
type PyMemAllocatorEx¶
Structure used to describe a memory block allocator. The structure has the following fields:
Field
Meaning
void *ctx
user context passed as first argument
void* malloc(void *ctx, size_t size)
allocate a memory block
void* calloc(void *ctx, size_t nelem, size_t elsize)
allocate a memory block initialized with zeros
void* realloc(void *ctx, void *ptr, size_t new_size)
allocate or resize a memory block
void free(void *ctx, void *ptr)
free a memory block
Changed in version 3.5: The
PyMemAllocator
structure was renamed toPyMemAllocatorEx
and a newcalloc
field was added.
-
type PyMemAllocatorDomain¶
Enum used to identify an allocator domain. Domains:
-
PYMEM_DOMAIN_RAW¶
Functions:
-
PYMEM_DOMAIN_MEM¶
Functions:
-
PYMEM_DOMAIN_OBJ¶
Functions:
-
PYMEM_DOMAIN_RAW¶
-
void PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator)¶
Get the memory block allocator of the specified domain.
-
void PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator)¶
Set the memory block allocator of the specified domain.
The new allocator must return a distinct non-
NULL
pointer when requesting zero bytes.For the
PYMEM_DOMAIN_RAW
domain, the allocator must be thread-safe: a thread state is not attached when the allocator is called.For the remaining domains, the allocator must also be thread-safe: the allocator may be called in different interpreters that do not share a GIL.
If the new allocator is not a hook (does not call the previous allocator), the
PyMem_SetupDebugHooks()
function must be called to reinstall the debug hooks on top on the new allocator.See also
PyPreConfig.allocator
and Preinitialize Python with PyPreConfig.Warning
PyMem_SetAllocator()
does have the following contract:It can be called after
Py_PreInitialize()
and beforePy_InitializeFromConfig()
to install a custom memory allocator. There are no restrictions over the installed allocator other than the ones imposed by the domain (for instance, the Raw Domain allows the allocator to be called without an attached thread state). See the section on allocator domains for more information.If called after Python has finish initializing (after
Py_InitializeFromConfig()
has been called) the allocator must wrap the existing allocator. Substituting the current allocator for some other arbitrary one is not supported.
Changed in version 3.12: All allocators must be thread-safe.
-
void PyMem_SetupDebugHooks(void)¶
Setup debug hooks in the Python memory allocators to detect memory errors.
Debug hooks on the Python memory allocators¶
When Python is built in debug mode, the
PyMem_SetupDebugHooks()
function is called at the Python
preinitialization to setup debug hooks on Python memory allocators
to detect memory errors.
The PYTHONMALLOC
environment variable can be used to install debug
hooks on a Python compiled in release mode (ex: PYTHONMALLOC=debug
).
The PyMem_SetupDebugHooks()
function can be used to set debug hooks
after calling PyMem_SetAllocator()
.
These debug hooks fill dynamically allocated memory blocks with special,
recognizable bit patterns. Newly allocated memory is filled with the byte
0xCD
(PYMEM_CLEANBYTE
), freed memory is filled with the byte 0xDD
(PYMEM_DEADBYTE
). Memory blocks are surrounded by “forbidden bytes”
filled with the byte 0xFD
(PYMEM_FORBIDDENBYTE
). Strings of these bytes
are unlikely to be valid addresses, floats, or ASCII strings.
Runtime checks:
Detect API violations. For example, detect if
PyObject_Free()
is called on a memory block allocated byPyMem_Malloc()
.Detect write before the start of the buffer (buffer underflow).
Detect write after the end of the buffer (buffer overflow).
Check that there is an attached thread state when allocator functions of
PYMEM_DOMAIN_OBJ
(ex:PyObject_Malloc()
) andPYMEM_DOMAIN_MEM
(ex:PyMem_Malloc()
) domains are called.
On error, the debug hooks use the tracemalloc
module to get the
traceback where a memory block was allocated. The traceback is only displayed
if tracemalloc
is tracing Python memory allocations and the memory block
was traced.
Let S = sizeof(size_t)
. 2*S
bytes are added at each end of each block
of N bytes requested. The memory layout is like so, where p represents the
address returned by a malloc-like or realloc-like function (p[i:j]
means
the slice of bytes from *(p+i)
inclusive up to *(p+j)
exclusive; note
that the treatment of negative indices differs from a Python slice):
p[-2*S:-S]
Number of bytes originally asked for. This is a size_t, big-endian (easier to read in a memory dump).
p[-S]
API identifier (ASCII character):
'r'
forPYMEM_DOMAIN_RAW
.'m'
forPYMEM_DOMAIN_MEM
.'o'
forPYMEM_DOMAIN_OBJ
.
p[-S+1:0]
Copies of PYMEM_FORBIDDENBYTE. Used to catch under- writes and reads.
p[0:N]
The requested memory, filled with copies of PYMEM_CLEANBYTE, used to catch reference to uninitialized memory. When a realloc-like function is called requesting a larger memory block, the new excess bytes are also filled with PYMEM_CLEANBYTE. When a free-like function is called, these are overwritten with PYMEM_DEADBYTE, to catch reference to freed memory. When a realloc- like function is called requesting a smaller memory block, the excess old bytes are also filled with PYMEM_DEADBYTE.
p[N:N+S]
Copies of PYMEM_FORBIDDENBYTE. Used to catch over- writes and reads.
p[N+S:N+2*S]
Only used if the
PYMEM_DEBUG_SERIALNO
macro is defined (not defined by default).A serial number, incremented by 1 on each call to a malloc-like or realloc-like function. Big-endian
size_t
. If “bad memory” is detected later, the serial number gives an excellent way to set a breakpoint on the next run, to capture the instant at which this block was passed out. The static function bumpserialno() in obmalloc.c is the only place the serial number is incremented, and exists so you can set such a breakpoint easily.
A realloc-like or free-like function first checks that the PYMEM_FORBIDDENBYTE bytes at each end are intact. If they’ve been altered, diagnostic output is written to stderr, and the program is aborted via Py_FatalError(). The other main failure mode is provoking a memory error when a program reads up one of the special bit patterns and tries to use it as an address. If you get in a debugger then and look at the object, you’re likely to see that it’s entirely filled with PYMEM_DEADBYTE (meaning freed memory is getting used) or PYMEM_CLEANBYTE (meaning uninitialized memory is getting used).
Changed in version 3.6: The PyMem_SetupDebugHooks()
function now also works on Python
compiled in release mode. On error, the debug hooks now use
tracemalloc
to get the traceback where a memory block was allocated.
The debug hooks now also check if there is an attached thread state when
functions of PYMEM_DOMAIN_OBJ
and PYMEM_DOMAIN_MEM
domains are
called.
Changed in version 3.8: Byte patterns 0xCB
(PYMEM_CLEANBYTE
), 0xDB
(PYMEM_DEADBYTE
)
and 0xFB
(PYMEM_FORBIDDENBYTE
) have been replaced with 0xCD
,
0xDD
and 0xFD
to use the same values than Windows CRT debug
malloc()
and free()
.
The pymalloc allocator¶
Python has a pymalloc allocator optimized for small objects (smaller or equal
to 512 bytes) with a short lifetime. It uses memory mappings called “arenas”
with a fixed size of either 256 KiB on 32-bit platforms or 1 MiB on 64-bit
platforms. It falls back to PyMem_RawMalloc()
and
PyMem_RawRealloc()
for allocations larger than 512 bytes.
pymalloc is the default allocator of the
PYMEM_DOMAIN_MEM
(ex: PyMem_Malloc()
) and
PYMEM_DOMAIN_OBJ
(ex: PyObject_Malloc()
) domains.
The arena allocator uses the following functions:
VirtualAlloc()
andVirtualFree()
on Windows,mmap()
andmunmap()
if available,malloc()
andfree()
otherwise.
This allocator is disabled if Python is configured with the
--without-pymalloc
option. It can also be disabled at runtime using
the PYTHONMALLOC
environment variable (ex: PYTHONMALLOC=malloc
).
Typically, it makes sense to disable the pymalloc allocator when building
Python with AddressSanitizer (--with-address-sanitizer
) which helps
uncover low level bugs within the C code.
Customize pymalloc Arena Allocator¶
Added in version 3.4.
-
type PyObjectArenaAllocator¶
Structure used to describe an arena allocator. The structure has three fields:
Field
Meaning
void *ctx
user context passed as first argument
void* alloc(void *ctx, size_t size)
allocate an arena of size bytes
void free(void *ctx, void *ptr, size_t size)
free an arena
-
void PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator)¶
Get the arena allocator.
-
void PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator)¶
Set the arena allocator.
The mimalloc allocator¶
Added in version 3.13.
Python supports the mimalloc allocator when the underlying platform support is available. mimalloc “is a general purpose allocator with excellent performance characteristics. Initially developed by Daan Leijen for the runtime systems of the Koka and Lean languages.”
tracemalloc C API¶
Added in version 3.7.
-
int PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size)¶
Track an allocated memory block in the
tracemalloc
module.Return
0
on success, return-1
on error (failed to allocate memory to store the trace). Return-2
if tracemalloc is disabled.If memory block is already tracked, update the existing trace.
-
int PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr)¶
Untrack an allocated memory block in the
tracemalloc
module. Do nothing if the block was not tracked.Return
-2
if tracemalloc is disabled, otherwise return0
.
Examples¶
Here is the example from section Overview, rewritten so that the I/O buffer is allocated from the Python heap by using the first function set:
PyObject *res;
char *buf = (char *) PyMem_Malloc(BUFSIZ); /* for I/O */
if (buf == NULL)
return PyErr_NoMemory();
/* ...Do some I/O operation involving buf... */
res = PyBytes_FromString(buf);
PyMem_Free(buf); /* allocated with PyMem_Malloc */
return res;
The same code using the type-oriented function set:
PyObject *res;
char *buf = PyMem_New(char, BUFSIZ); /* for I/O */
if (buf == NULL)
return PyErr_NoMemory();
/* ...Do some I/O operation involving buf... */
res = PyBytes_FromString(buf);
PyMem_Free(buf); /* allocated with PyMem_New */
return res;
Note that in the two examples above, the buffer is always manipulated via functions belonging to the same set. Indeed, it is required to use the same memory API family for a given memory block, so that the risk of mixing different allocators is reduced to a minimum. The following code sequence contains two errors, one of which is labeled as fatal because it mixes two different allocators operating on different heaps.
char *buf1 = PyMem_New(char, BUFSIZ);
char *buf2 = (char *) malloc(BUFSIZ);
char *buf3 = (char *) PyMem_Malloc(BUFSIZ);
...
PyMem_Del(buf3); /* Wrong -- should be PyMem_Free() */
free(buf2); /* Right -- allocated via malloc() */
free(buf1); /* Fatal -- should be PyMem_Free() */
In addition to the functions aimed at handling raw memory blocks from the Python
heap, objects in Python are allocated and released with PyObject_New
,
PyObject_NewVar
and PyObject_Free()
.
These will be explained in the next chapter on defining and implementing new object types in C.