final executable
BIN
build/exe.win-amd64-3.7/VCRUNTIME140.dll
Normal file
7
build/exe.win-amd64-3.7/colours.py
Normal file
@ -0,0 +1,7 @@
|
||||
# colours variables
|
||||
|
||||
WHITE=(245, 245, 245)
|
||||
BLACK=(10, 10, 10)
|
||||
RED=(245, 0, 0)
|
||||
BLUE=(0, 0, 245)
|
||||
BGCOLOR=(87,156,135)
|
32
build/exe.win-amd64-3.7/config.py
Normal file
@ -0,0 +1,32 @@
|
||||
# Config variables
|
||||
import pygame
|
||||
from pygame.locals import *
|
||||
|
||||
# Runtime settings
|
||||
WINDOW_WIDTH = 720
|
||||
WINDOW_HEIGHT = 1000
|
||||
FPS = 30
|
||||
WIN_NAME = "Kostschevsky's shooter"
|
||||
|
||||
PLAYER_HP=100
|
||||
|
||||
# Controls
|
||||
|
||||
# player 1
|
||||
P1_UP=pygame.K_w
|
||||
P1_DOWN=pygame.K_s
|
||||
P1_RIGHT=pygame.K_d
|
||||
P1_LEFT=pygame.K_a
|
||||
P1_SHOOT=pygame.K_LCTRL
|
||||
|
||||
# player 2
|
||||
P2_UP=pygame.K_UP
|
||||
P2_DOWN=pygame.K_DOWN
|
||||
P2_RIGHT=pygame.K_RIGHT
|
||||
P2_LEFT=pygame.K_LEFT
|
||||
P2_SHOOT=pygame.K_RCTRL
|
||||
|
||||
# bullets
|
||||
BULLET_SPEED=20
|
||||
SHOOT_SPEED=200
|
||||
BULLET_DMG=20
|
BIN
build/exe.win-amd64-3.7/data/graphics/bg.png
Normal file
After Width: | Height: | Size: 92 KiB |
BIN
build/exe.win-amd64-3.7/data/graphics/bullet.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
build/exe.win-amd64-3.7/data/graphics/end0.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
build/exe.win-amd64-3.7/data/graphics/endp1.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
build/exe.win-amd64-3.7/data/graphics/endp2.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
build/exe.win-amd64-3.7/data/graphics/p1.png
Normal file
After Width: | Height: | Size: 211 B |
BIN
build/exe.win-amd64-3.7/data/graphics/p2.png
Normal file
After Width: | Height: | Size: 239 B |
BIN
build/exe.win-amd64-3.7/data/graphics/splash.png
Normal file
After Width: | Height: | Size: 26 KiB |
134
build/exe.win-amd64-3.7/events.py
Normal file
@ -0,0 +1,134 @@
|
||||
import os, sys
|
||||
import pygame
|
||||
from pygame.locals import *
|
||||
|
||||
from sprites import *
|
||||
from config import *
|
||||
|
||||
mainloop=True
|
||||
running=True
|
||||
players=[]
|
||||
|
||||
p1_group=pygame.sprite.Group()
|
||||
p2_group=pygame.sprite.Group()
|
||||
p1_bullet=[]
|
||||
p2_bullet=[]
|
||||
|
||||
p1_bullet_group=pygame.sprite.Group()
|
||||
p2_bullet_group=pygame.sprite.Group()
|
||||
|
||||
clock=pygame.time.Clock()
|
||||
clock.tick()
|
||||
timer1=1000
|
||||
clock2=pygame.time.Clock()
|
||||
clock2.tick()
|
||||
timer2=1000
|
||||
|
||||
bars=[]
|
||||
|
||||
def events():
|
||||
global running
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
#running=False
|
||||
|
||||
def collision_check(p):
|
||||
# collision between players
|
||||
if players[0].rect.colliderect(players[1].rect):
|
||||
if p==1:
|
||||
players[0].colliding=True
|
||||
direction=players[1].facing
|
||||
players[0].image=pygame.transform.rotate(players[0].image, players[0].facing*90-((direction+2)%4)*90)
|
||||
players[0].facing=(direction+2)%4
|
||||
return True
|
||||
elif p==0:
|
||||
players[1].colliding=True
|
||||
direction=players[0].facing
|
||||
players[1].image=pygame.transform.rotate(players[1].image, players[1].facing*90-((direction+2)%4)*90)
|
||||
players[1].facing=(direction+2)%4
|
||||
return True
|
||||
else:
|
||||
players[0].colliding=True
|
||||
players[1].colliding=True
|
||||
|
||||
else:
|
||||
return False
|
||||
|
||||
def bullethits():
|
||||
hits1=pygame.sprite.groupcollide(p2_group, p1_bullet_group, False, True)
|
||||
hits2=pygame.sprite.groupcollide(p1_group, p2_bullet_group, False, True)
|
||||
if hits1:
|
||||
players[1].gothit()
|
||||
bars[1].gothit()
|
||||
if hits2:
|
||||
players[0].gothit()
|
||||
bars[0].gothit()
|
||||
|
||||
def player1_input(keys):
|
||||
if keys[P1_SHOOT]:
|
||||
global timer1
|
||||
p1_bullet.append(Bullet('bullet', players[0].pos.x, players[0].pos.y, players[0].facing))
|
||||
if timer1>SHOOT_SPEED:
|
||||
p1_bullet_group.add(p1_bullet[-1])
|
||||
all_sprites.add(p1_bullet[-1])
|
||||
p1_bullet[-1].direction=players[0].facing
|
||||
p1_bullet[-1].shoot()
|
||||
timer1=clock.tick()
|
||||
else:
|
||||
del p1_bullet[-1]
|
||||
if not (keys[P1_UP] or keys[P1_DOWN] or keys[P1_RIGHT] or keys[P1_LEFT]):
|
||||
players[0].stopmoving()
|
||||
elif not collision_check(0):
|
||||
if keys[P1_RIGHT]:
|
||||
players[0].moveright()
|
||||
if keys[P1_LEFT]:
|
||||
players[0].moveleft()
|
||||
if keys[P1_UP]:
|
||||
players[0].moveup()
|
||||
if keys[P1_DOWN]:
|
||||
players[0].movedown()
|
||||
|
||||
def player2_input(keys):
|
||||
if keys[P2_SHOOT]:
|
||||
global timer2
|
||||
p2_bullet.append(Bullet('bullet', players[1].pos.x, players[1].pos.y, players[1].facing))
|
||||
if timer2>SHOOT_SPEED:
|
||||
p2_bullet_group.add(p2_bullet[-1])
|
||||
all_sprites.add(p2_bullet[-1])
|
||||
p2_bullet[-1].direction=players[1].facing
|
||||
p2_bullet[-1].shoot()
|
||||
timer2=clock.tick()
|
||||
else:
|
||||
del p2_bullet[-1]
|
||||
if not (keys[P2_UP] or keys[P2_DOWN] or keys[P2_RIGHT] or keys[P2_LEFT]):
|
||||
players[1].stopmoving()
|
||||
elif not collision_check(1):
|
||||
if keys[P2_RIGHT]:
|
||||
players[1].moveright()
|
||||
if keys[P2_LEFT]:
|
||||
players[1].moveleft()
|
||||
if keys[P2_UP]:
|
||||
players[1].moveup()
|
||||
if keys[P2_DOWN]:
|
||||
players[1].movedown()
|
||||
def dead():
|
||||
if players[0].alive and players[1].alive:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def event_handler():
|
||||
global timer1
|
||||
global timer2
|
||||
events()
|
||||
keys=pygame.key.get_pressed()
|
||||
collision_check(-1)
|
||||
bullethits()
|
||||
timer1+=clock.tick()
|
||||
timer2+=clock2.tick()
|
||||
player1_input(keys)
|
||||
player2_input(keys)
|
||||
|
||||
|
BIN
build/exe.win-amd64-3.7/lib/VCRUNTIME140.dll
Normal file
BIN
build/exe.win-amd64-3.7/lib/_bz2.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_contextvars.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_ctypes.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_decimal.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_elementtree.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_hashlib.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_lzma.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_multiprocessing.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_queue.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_socket.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_ssl.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_testcapi.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_tkinter.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/_win32sysloader.pyd
Normal file
BIN
build/exe.win-amd64-3.7/lib/collections/__init__.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/collections/abc.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/ctypes/__init__.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/ctypes/_aix.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/ctypes/_endian.pyc
Normal file
@ -0,0 +1,7 @@
|
||||
Files in this directory come from Bob Ippolito's py2app.
|
||||
|
||||
License: Any components of the py2app suite may be distributed under
|
||||
the MIT or PSF open source licenses.
|
||||
|
||||
This is version 1.0, SVN revision 789, from 2006/01/25.
|
||||
The main repository is http://svn.red-bean.com/bob/macholib/trunk/macholib/
|
BIN
build/exe.win-amd64-3.7/lib/ctypes/macholib/__init__.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/ctypes/macholib/dyld.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/ctypes/macholib/dylib.pyc
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
svn export --force http://svn.red-bean.com/bob/macholib/trunk/macholib/ .
|
@ -0,0 +1 @@
|
||||
svn export --force http://svn.red-bean.com/bob/macholib/trunk/macholib/ .
|
BIN
build/exe.win-amd64-3.7/lib/ctypes/macholib/framework.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/ctypes/util.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/ctypes/wintypes.pyc
Normal file
13
build/exe.win-amd64-3.7/lib/distutils/README
Normal file
@ -0,0 +1,13 @@
|
||||
This directory contains the Distutils package.
|
||||
|
||||
There's a full documentation available at:
|
||||
|
||||
http://docs.python.org/distutils/
|
||||
|
||||
The Distutils-SIG web page is also a good starting point:
|
||||
|
||||
http://www.python.org/sigs/distutils-sig/
|
||||
|
||||
WARNING : Distutils must remain compatible with 2.3
|
||||
|
||||
$Id$
|
BIN
build/exe.win-amd64-3.7/lib/distutils/__init__.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/ccompiler.pyc
Normal file
@ -0,0 +1,33 @@
|
||||
"""distutils.command.x
|
||||
|
||||
Implements the Distutils 'x' command.
|
||||
"""
|
||||
|
||||
# created 2000/mm/dd, John Doe
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
from distutils.core import Command
|
||||
|
||||
|
||||
class x(Command):
|
||||
|
||||
# Brief (40-50 characters) description of the command
|
||||
description = ""
|
||||
|
||||
# List of option tuples: long name, short name (None if no short
|
||||
# name), and help string.
|
||||
user_options = [('', '',
|
||||
""),
|
||||
]
|
||||
|
||||
def initialize_options(self):
|
||||
self. = None
|
||||
self. = None
|
||||
self. = None
|
||||
|
||||
def finalize_options(self):
|
||||
if self.x is None:
|
||||
self.x =
|
||||
|
||||
def run(self):
|
BIN
build/exe.win-amd64-3.7/lib/distutils/command/wininst-10.0.exe
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/command/wininst-14.0.exe
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/command/wininst-6.0.exe
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/command/wininst-7.1.exe
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/command/wininst-8.0.exe
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/command/wininst-9.0.exe
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/debug.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/dep_util.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/dir_util.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/errors.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/fancy_getopt.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/file_util.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/filelist.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/log.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/spawn.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/sysconfig.pyc
Normal file
67
build/exe.win-amd64-3.7/lib/distutils/tests/Setup.sample
Normal file
@ -0,0 +1,67 @@
|
||||
# Setup file from the pygame project
|
||||
|
||||
#--StartConfig
|
||||
SDL = -I/usr/include/SDL -D_REENTRANT -lSDL
|
||||
FONT = -lSDL_ttf
|
||||
IMAGE = -lSDL_image
|
||||
MIXER = -lSDL_mixer
|
||||
SMPEG = -lsmpeg
|
||||
PNG = -lpng
|
||||
JPEG = -ljpeg
|
||||
SCRAP = -lX11
|
||||
PORTMIDI = -lportmidi
|
||||
PORTTIME = -lporttime
|
||||
#--EndConfig
|
||||
|
||||
#DEBUG = -C-W -C-Wall
|
||||
DEBUG =
|
||||
|
||||
#the following modules are optional. you will want to compile
|
||||
#everything you can, but you can ignore ones you don't have
|
||||
#dependencies for, just comment them out
|
||||
|
||||
imageext src/imageext.c $(SDL) $(IMAGE) $(PNG) $(JPEG) $(DEBUG)
|
||||
font src/font.c $(SDL) $(FONT) $(DEBUG)
|
||||
mixer src/mixer.c $(SDL) $(MIXER) $(DEBUG)
|
||||
mixer_music src/music.c $(SDL) $(MIXER) $(DEBUG)
|
||||
_numericsurfarray src/_numericsurfarray.c $(SDL) $(DEBUG)
|
||||
_numericsndarray src/_numericsndarray.c $(SDL) $(MIXER) $(DEBUG)
|
||||
movie src/movie.c $(SDL) $(SMPEG) $(DEBUG)
|
||||
scrap src/scrap.c $(SDL) $(SCRAP) $(DEBUG)
|
||||
_camera src/_camera.c src/camera_v4l2.c src/camera_v4l.c $(SDL) $(DEBUG)
|
||||
pypm src/pypm.c $(SDL) $(PORTMIDI) $(PORTTIME) $(DEBUG)
|
||||
|
||||
GFX = src/SDL_gfx/SDL_gfxPrimitives.c
|
||||
#GFX = src/SDL_gfx/SDL_gfxBlitFunc.c src/SDL_gfx/SDL_gfxPrimitives.c
|
||||
gfxdraw src/gfxdraw.c $(SDL) $(GFX) $(DEBUG)
|
||||
|
||||
|
||||
|
||||
#these modules are required for pygame to run. they only require
|
||||
#SDL as a dependency. these should not be altered
|
||||
|
||||
base src/base.c $(SDL) $(DEBUG)
|
||||
cdrom src/cdrom.c $(SDL) $(DEBUG)
|
||||
color src/color.c $(SDL) $(DEBUG)
|
||||
constants src/constants.c $(SDL) $(DEBUG)
|
||||
display src/display.c $(SDL) $(DEBUG)
|
||||
event src/event.c $(SDL) $(DEBUG)
|
||||
fastevent src/fastevent.c src/fastevents.c $(SDL) $(DEBUG)
|
||||
key src/key.c $(SDL) $(DEBUG)
|
||||
mouse src/mouse.c $(SDL) $(DEBUG)
|
||||
rect src/rect.c $(SDL) $(DEBUG)
|
||||
rwobject src/rwobject.c $(SDL) $(DEBUG)
|
||||
surface src/surface.c src/alphablit.c src/surface_fill.c $(SDL) $(DEBUG)
|
||||
surflock src/surflock.c $(SDL) $(DEBUG)
|
||||
time src/time.c $(SDL) $(DEBUG)
|
||||
joystick src/joystick.c $(SDL) $(DEBUG)
|
||||
draw src/draw.c $(SDL) $(DEBUG)
|
||||
image src/image.c $(SDL) $(DEBUG)
|
||||
overlay src/overlay.c $(SDL) $(DEBUG)
|
||||
transform src/transform.c src/rotozoom.c src/scale2x.c src/scale_mmx.c $(SDL) $(DEBUG)
|
||||
mask src/mask.c src/bitmask.c $(SDL) $(DEBUG)
|
||||
bufferproxy src/bufferproxy.c $(SDL) $(DEBUG)
|
||||
pixelarray src/pixelarray.c $(SDL) $(DEBUG)
|
||||
_arraysurfarray src/_arraysurfarray.c $(SDL) $(DEBUG)
|
||||
|
||||
|
BIN
build/exe.win-amd64-3.7/lib/distutils/text_file.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/distutils/util.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/email/__init__.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/email/_encoded_words.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/email/_header_value_parser.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/email/_parseaddr.pyc
Normal file
BIN
build/exe.win-amd64-3.7/lib/email/_policybase.pyc
Normal file
216
build/exe.win-amd64-3.7/lib/email/architecture.rst
Normal file
@ -0,0 +1,216 @@
|
||||
:mod:`email` Package Architecture
|
||||
=================================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The email package consists of three major components:
|
||||
|
||||
Model
|
||||
An object structure that represents an email message, and provides an
|
||||
API for creating, querying, and modifying a message.
|
||||
|
||||
Parser
|
||||
Takes a sequence of characters or bytes and produces a model of the
|
||||
email message represented by those characters or bytes.
|
||||
|
||||
Generator
|
||||
Takes a model and turns it into a sequence of characters or bytes. The
|
||||
sequence can either be intended for human consumption (a printable
|
||||
unicode string) or bytes suitable for transmission over the wire. In
|
||||
the latter case all data is properly encoded using the content transfer
|
||||
encodings specified by the relevant RFCs.
|
||||
|
||||
Conceptually the package is organized around the model. The model provides both
|
||||
"external" APIs intended for use by application programs using the library,
|
||||
and "internal" APIs intended for use by the Parser and Generator components.
|
||||
This division is intentionally a bit fuzzy; the API described by this
|
||||
documentation is all a public, stable API. This allows for an application
|
||||
with special needs to implement its own parser and/or generator.
|
||||
|
||||
In addition to the three major functional components, there is a third key
|
||||
component to the architecture:
|
||||
|
||||
Policy
|
||||
An object that specifies various behavioral settings and carries
|
||||
implementations of various behavior-controlling methods.
|
||||
|
||||
The Policy framework provides a simple and convenient way to control the
|
||||
behavior of the library, making it possible for the library to be used in a
|
||||
very flexible fashion while leveraging the common code required to parse,
|
||||
represent, and generate message-like objects. For example, in addition to the
|
||||
default :rfc:`5322` email message policy, we also have a policy that manages
|
||||
HTTP headers in a fashion compliant with :rfc:`2616`. Individual policy
|
||||
controls, such as the maximum line length produced by the generator, can also
|
||||
be controlled individually to meet specialized application requirements.
|
||||
|
||||
|
||||
The Model
|
||||
---------
|
||||
|
||||
The message model is implemented by the :class:`~email.message.Message` class.
|
||||
The model divides a message into the two fundamental parts discussed by the
|
||||
RFC: the header section and the body. The `Message` object acts as a
|
||||
pseudo-dictionary of named headers. Its dictionary interface provides
|
||||
convenient access to individual headers by name. However, all headers are kept
|
||||
internally in an ordered list, so that the information about the order of the
|
||||
headers in the original message is preserved.
|
||||
|
||||
The `Message` object also has a `payload` that holds the body. A `payload` can
|
||||
be one of two things: data, or a list of `Message` objects. The latter is used
|
||||
to represent a multipart MIME message. Lists can be nested arbitrarily deeply
|
||||
in order to represent the message, with all terminal leaves having non-list
|
||||
data payloads.
|
||||
|
||||
|
||||
Message Lifecycle
|
||||
-----------------
|
||||
|
||||
The general lifecycle of a message is:
|
||||
|
||||
Creation
|
||||
A `Message` object can be created by a Parser, or it can be
|
||||
instantiated as an empty message by an application.
|
||||
|
||||
Manipulation
|
||||
The application may examine one or more headers, and/or the
|
||||
payload, and it may modify one or more headers and/or
|
||||
the payload. This may be done on the top level `Message`
|
||||
object, or on any sub-object.
|
||||
|
||||
Finalization
|
||||
The Model is converted into a unicode or binary stream,
|
||||
or the model is discarded.
|
||||
|
||||
|
||||
|
||||
Header Policy Control During Lifecycle
|
||||
--------------------------------------
|
||||
|
||||
One of the major controls exerted by the Policy is the management of headers
|
||||
during the `Message` lifecycle. Most applications don't need to be aware of
|
||||
this.
|
||||
|
||||
A header enters the model in one of two ways: via a Parser, or by being set to
|
||||
a specific value by an application program after the Model already exists.
|
||||
Similarly, a header exits the model in one of two ways: by being serialized by
|
||||
a Generator, or by being retrieved from a Model by an application program. The
|
||||
Policy object provides hooks for all four of these pathways.
|
||||
|
||||
The model storage for headers is a list of (name, value) tuples.
|
||||
|
||||
The Parser identifies headers during parsing, and passes them to the
|
||||
:meth:`~email.policy.Policy.header_source_parse` method of the Policy. The
|
||||
result of that method is the (name, value) tuple to be stored in the model.
|
||||
|
||||
When an application program supplies a header value (for example, through the
|
||||
`Message` object `__setitem__` interface), the name and the value are passed to
|
||||
the :meth:`~email.policy.Policy.header_store_parse` method of the Policy, which
|
||||
returns the (name, value) tuple to be stored in the model.
|
||||
|
||||
When an application program retrieves a header (through any of the dict or list
|
||||
interfaces of `Message`), the name and value are passed to the
|
||||
:meth:`~email.policy.Policy.header_fetch_parse` method of the Policy to
|
||||
obtain the value returned to the application.
|
||||
|
||||
When a Generator requests a header during serialization, the name and value are
|
||||
passed to the :meth:`~email.policy.Policy.fold` method of the Policy, which
|
||||
returns a string containing line breaks in the appropriate places. The
|
||||
:meth:`~email.policy.Policy.cte_type` Policy control determines whether or
|
||||
not Content Transfer Encoding is performed on the data in the header. There is
|
||||
also a :meth:`~email.policy.Policy.binary_fold` method for use by generators
|
||||
that produce binary output, which returns the folded header as binary data,
|
||||
possibly folded at different places than the corresponding string would be.
|
||||
|
||||
|
||||
Handling Binary Data
|
||||
--------------------
|
||||
|
||||
In an ideal world all message data would conform to the RFCs, meaning that the
|
||||
parser could decode the message into the idealized unicode message that the
|
||||
sender originally wrote. In the real world, the email package must also be
|
||||
able to deal with badly formatted messages, including messages containing
|
||||
non-ASCII characters that either have no indicated character set or are not
|
||||
valid characters in the indicated character set.
|
||||
|
||||
Since email messages are *primarily* text data, and operations on message data
|
||||
are primarily text operations (except for binary payloads of course), the model
|
||||
stores all text data as unicode strings. Un-decodable binary inside text
|
||||
data is handled by using the `surrogateescape` error handler of the ASCII
|
||||
codec. As with the binary filenames the error handler was introduced to
|
||||
handle, this allows the email package to "carry" the binary data received
|
||||
during parsing along until the output stage, at which time it is regenerated
|
||||
in its original form.
|
||||
|
||||
This carried binary data is almost entirely an implementation detail. The one
|
||||
place where it is visible in the API is in the "internal" API. A Parser must
|
||||
do the `surrogateescape` encoding of binary input data, and pass that data to
|
||||
the appropriate Policy method. The "internal" interface used by the Generator
|
||||
to access header values preserves the `surrogateescaped` bytes. All other
|
||||
interfaces convert the binary data either back into bytes or into a safe form
|
||||
(losing information in some cases).
|
||||
|
||||
|
||||
Backward Compatibility
|
||||
----------------------
|
||||
|
||||
The :class:`~email.policy.Policy.Compat32` Policy provides backward
|
||||
compatibility with version 5.1 of the email package. It does this via the
|
||||
following implementation of the four+1 Policy methods described above:
|
||||
|
||||
header_source_parse
|
||||
Splits the first line on the colon to obtain the name, discards any spaces
|
||||
after the colon, and joins the remainder of the line with all of the
|
||||
remaining lines, preserving the linesep characters to obtain the value.
|
||||
Trailing carriage return and/or linefeed characters are stripped from the
|
||||
resulting value string.
|
||||
|
||||
header_store_parse
|
||||
Returns the name and value exactly as received from the application.
|
||||
|
||||
header_fetch_parse
|
||||
If the value contains any `surrogateescaped` binary data, return the value
|
||||
as a :class:`~email.header.Header` object, using the character set
|
||||
`unknown-8bit`. Otherwise just returns the value.
|
||||
|
||||
fold
|
||||
Uses :class:`~email.header.Header`'s folding to fold headers in the
|
||||
same way the email5.1 generator did.
|
||||
|
||||
binary_fold
|
||||
Same as fold, but encodes to 'ascii'.
|
||||
|
||||
|
||||
New Algorithm
|
||||
-------------
|
||||
|
||||
header_source_parse
|
||||
Same as legacy behavior.
|
||||
|
||||
header_store_parse
|
||||
Same as legacy behavior.
|
||||
|
||||
header_fetch_parse
|
||||
If the value is already a header object, returns it. Otherwise, parses the
|
||||
value using the new parser, and returns the resulting object as the value.
|
||||
`surrogateescaped` bytes get turned into unicode unknown character code
|
||||
points.
|
||||
|
||||
fold
|
||||
Uses the new header folding algorithm, respecting the policy settings.
|
||||
surrogateescaped bytes are encoded using the ``unknown-8bit`` charset for
|
||||
``cte_type=7bit`` or ``8bit``. Returns a string.
|
||||
|
||||
At some point there will also be a ``cte_type=unicode``, and for that
|
||||
policy fold will serialize the idealized unicode message with RFC-like
|
||||
folding, converting any surrogateescaped bytes into the unicode
|
||||
unknown character glyph.
|
||||
|
||||
binary_fold
|
||||
Uses the new header folding algorithm, respecting the policy settings.
|
||||
surrogateescaped bytes are encoded using the `unknown-8bit` charset for
|
||||
``cte_type=7bit``, and get turned back into bytes for ``cte_type=8bit``.
|
||||
Returns bytes.
|
||||
|
||||
At some point there will also be a ``cte_type=unicode``, and for that
|
||||
policy binary_fold will serialize the message according to :rfc:``5335``.
|