100% found this document useful (5 votes)
77 views

Instant Download Expert Twisted: Event-Driven and Asynchronous Programming With Python 1st Edition Mark Williams PDF All Chapter

Mark

Uploaded by

nduluesrzic
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (5 votes)
77 views

Instant Download Expert Twisted: Event-Driven and Asynchronous Programming With Python 1st Edition Mark Williams PDF All Chapter

Mark

Uploaded by

nduluesrzic
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 62

Download the full version of the textbook now at textbookfull.

com

Expert Twisted: Event-Driven and Asynchronous


Programming with Python 1st Edition Mark
Williams

https://textbookfull.com/product/expert-twisted-
event-driven-and-asynchronous-programming-with-
python-1st-edition-mark-williams/

Explore and download more textbook at https://textbookfull.com


Recommended digital products (PDF, EPUB, MOBI) that
you can download immediately if you are interested.

Expert Twisted: Event-Driven and Asynchronous Programming


with Python 1st Edition Mark Williams

https://textbookfull.com/product/expert-twisted-event-driven-and-
asynchronous-programming-with-python-1st-edition-mark-williams-2/

textbookfull.com

Reactive Programming with RxJava Creating Asynchronous


Event Based Applications 1st Edition Tomasz Nurkiewicz Ben
Christensen
https://textbookfull.com/product/reactive-programming-with-rxjava-
creating-asynchronous-event-based-applications-1st-edition-tomasz-
nurkiewicz-ben-christensen/
textbookfull.com

Using Asyncio in Python Understanding Python s


Asynchronous Programming Features Caleb Hattingh

https://textbookfull.com/product/using-asyncio-in-python-
understanding-python-s-asynchronous-programming-features-caleb-
hattingh/
textbookfull.com

We Are an African People: Independent Education, Black


Power, and the Radical Imagination 1st Edition Russell
Rickford
https://textbookfull.com/product/we-are-an-african-people-independent-
education-black-power-and-the-radical-imagination-1st-edition-russell-
rickford/
textbookfull.com
Rare Metal Technology 2019 Gisele Azimi

https://textbookfull.com/product/rare-metal-technology-2019-gisele-
azimi/

textbookfull.com

The Complete Guidebook to Yosemite National Park Steven P.


Medley

https://textbookfull.com/product/the-complete-guidebook-to-yosemite-
national-park-steven-p-medley/

textbookfull.com

Essentials of Negotiation, 6e - Test Bank 6th Edition Roy


J. Lewicki

https://textbookfull.com/product/essentials-of-negotiation-6e-test-
bank-6th-edition-roy-j-lewicki/

textbookfull.com

Sex Hormones Exercise and Women Scientific and Clinical


Aspects 1st Edition Anthony C. Hackney (Eds.)

https://textbookfull.com/product/sex-hormones-exercise-and-women-
scientific-and-clinical-aspects-1st-edition-anthony-c-hackney-eds/

textbookfull.com

Drug Abuse and Antisocial Behavior: A Biosocial Life


Course Approach 1st Edition Christopher P. Salas-Wright

https://textbookfull.com/product/drug-abuse-and-antisocial-behavior-a-
biosocial-life-course-approach-1st-edition-christopher-p-salas-wright/

textbookfull.com
Advances in Computers Volume 108 1st Edition Atif Memon

https://textbookfull.com/product/advances-in-computers-volume-108-1st-
edition-atif-memon/

textbookfull.com
Expert Twisted
Event-Driven and Asynchronous
Programming with Python

Mark Williams
Cory Benfield
Brian Warner
Moshe Zadka
Dustin Mitchell
Kevin Samuel
Pierre Tardy
Expert Twisted
Event-Driven and Asynchronous
Programming with Python

Mark Williams
Cory Benfield
Brian Warner
Moshe Zadka
Dustin Mitchell
Kevin Samuel
Pierre Tardy
Expert Twisted
Mark Williams Cory Benfield
Pasadena, CA, USA London, UK

Brian Warner Moshe Zadka


New York, USA New York, USA

Dustin Mitchell Kevin Samuel


New York, USA Nice, France

Pierre Tardy
Toulouse, France

ISBN-13 (pbk): 978-1-4842-3741-0 ISBN-13 (electronic): 978-1-4842-3742-7


https://doi.org/10.1007/978-1-4842-3742-7
Library of Congress Control Number: 2018965166
Copyright © 2019 by Mark Williams, Cory Benfield, Brian Warner, Moshe Zadka,
Dustin Mitchell, Kevin Samuel, Pierre Tardy
This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the
material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilms or in any other physical way, and transmission or information
storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now
known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with
every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an
editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not
identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to
proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication,
neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or
omissions that may be made. The publisher makes no warranty, express or implied, with respect to the
material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Jonathan Gennick
Development Editor: James Markham
Coordinating Editor: Jill Balzano
Cover image designed by Freepik (www.freepik.com)
Distributed to the book trade worldwide by Springer Science+Business Media New York, 233 Spring Street,
6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail orders-ny@springer-
sbm.com, or visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole member
(owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a
Delaware corporation.
For information on translations, please e-mail [email protected], or visit http://www.apress.com/
rights-permissions.
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and
licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales
web page at http://www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to
readers on GitHub via the book’s product page, located at www.apress.com/9781484237410. For more
detailed information, please visit http://www.apress.com/source-code.
Printed on acid-free paper
Dedicated to AZ, NZ, and TS: Twisted prevails,
and we're looking forward to the next
generation of maintainers.
—Moshe Zadka
Table of Contents
About the Authors�������������������������������������������������������������������������������������������������� xiii

About the Technical Reviewers�������������������������������������������������������������������������������xv


Acknowledgments�������������������������������������������������������������������������������������������������xvii

Introduction������������������������������������������������������������������������������������������������������������xix

Part 1: Foundations���������������������������������������������������������������������������������������� 1
Chapter 1: An Introduction to Event-­Driven Programming with Twisted����������������� 3
A Note About Python Versions������������������������������������������������������������������������������������������������������� 4
What Is Event-Driven Programming?�������������������������������������������������������������������������������������������� 4
Multiple Events����������������������������������������������������������������������������������������������������������������������������� 5
Application(tkinter.Tk()).mainloop()����������������������������������������������������������������������������������������������� 6
Multiplexing and Demultiplexing��������������������������������������������������������������������������������������������������� 7
The select Multiplexer������������������������������������������������������������������������������������������������������������������� 9
Its History, Its Siblings, and Its Purpose���������������������������������������������������������������������������������� 9
select and Sockets������������������������������������������������������������������������������������������������������������������ 9
The How and Why of Socket Events�������������������������������������������������������������������������������������� 11
Handling Events��������������������������������������������������������������������������������������������������������������������� 12
An Event Loop with select����������������������������������������������������������������������������������������������������� 13
Event-Driven Clients and Servers������������������������������������������������������������������������������������������ 15
Non-blocking I/O������������������������������������������������������������������������������������������������������������������������� 18
Knowing When to Stop���������������������������������������������������������������������������������������������������������� 18
Tracking State������������������������������������������������������������������������������������������������������������������������ 19
State Makes Programs Complex������������������������������������������������������������������������������������������� 23
Managing Complexity with Transports and Protocols����������������������������������������������������������������� 23
Reactors: Working with Transports���������������������������������������������������������������������������������������� 24

v
Table of Contents

Transports: Working with Protocols�������������������������������������������������������������������������������������������� 25


Playing Ping-Pong with Protocols and Transports����������������������������������������������������������������� 26
Clients and Servers with Protocols and Transports��������������������������������������������������������������� 31
Twisted and Reactors, Protocols, and Transports������������������������������������������������������������������ 33
The Value of Event-Driven Programming������������������������������������������������������������������������������������ 33
Twisted and the Real World��������������������������������������������������������������������������������������������������������� 36
Events in Time����������������������������������������������������������������������������������������������������������������������������� 41
Repeated Events with LoopingCall���������������������������������������������������������������������������������������� 44
Event Interfaces with zope.interface������������������������������������������������������������������������������������������� 46
Flow Control in Event-Driven Programs�������������������������������������������������������������������������������������� 49
Flow Control in Twisted with Producers and Consumers������������������������������������������������������������ 50
Push Producers��������������������������������������������������������������������������������������������������������������������� 51
Consumers���������������������������������������������������������������������������������������������������������������������������� 54
Pull Producers����������������������������������������������������������������������������������������������������������������������� 57
Summary������������������������������������������������������������������������������������������������������������������������������������ 57

Chapter 2: An Introduction to Asynchronous Programming with Twisted������������� 59


Event Handlers and Composition������������������������������������������������������������������������������������������������ 59
What Is Asynchronous Programming?���������������������������������������������������������������������������������������� 63
Placeholders for Future Values��������������������������������������������������������������������������������������������������� 63
Asynchronous Exception Handling���������������������������������������������������������������������������������������������� 66
An Introduction to Twisted’s Deferred����������������������������������������������������������������������������������������� 71
Callbacks������������������������������������������������������������������������������������������������������������������������������� 71
Errbacks and Failures������������������������������������������������������������������������������������������������������������ 73
Composing Deferreds������������������������������������������������������������������������������������������������������������ 76
Generators and InlineCallbacks�������������������������������������������������������������������������������������������������� 80
yield��������������������������������������������������������������������������������������������������������������������������������������� 80
send��������������������������������������������������������������������������������������������������������������������������������������� 81
throw������������������������������������������������������������������������������������������������������������������������������������� 84
Asynchronous Programming with inlineCallbacks���������������������������������������������������������������� 85

vi
Table of Contents

Coroutines in Python������������������������������������������������������������������������������������������������������������������� 88
Coroutines with yield from���������������������������������������������������������������������������������������������������� 88
Coroutines async and await�������������������������������������������������������������������������������������������������� 90
Awaiting Deferreds��������������������������������������������������������������������������������������������������������������������� 95
Coroutines to Deferreds with ensureDeferred���������������������������������������������������������������������������� 97
Multiplexing Deferreds���������������������������������������������������������������������������������������������������������������� 99
Testing Deferreds���������������������������������������������������������������������������������������������������������������������� 102
Summary���������������������������������������������������������������������������������������������������������������������������������� 106

Chapter 3: Applications with treq and Klein��������������������������������������������������������� 109


Why Libraries?�������������������������������������������������������������������������������������������������������������������������� 109
Feed Aggregation���������������������������������������������������������������������������������������������������������������������� 110
Introducing treq������������������������������������������������������������������������������������������������������������������������ 111
Introducing Klein����������������������������������������������������������������������������������������������������������������������� 115
Klein and Deferreds������������������������������������������������������������������������������������������������������������� 117
Klein Templates with Plating����������������������������������������������������������������������������������������������� 118
A First Draft of Feed Aggregation���������������������������������������������������������������������������������������������� 121
Test-Driven Development with Klein and treq�������������������������������������������������������������������������� 128
Running Test on an Installable Project�������������������������������������������������������������������������������� 128
Testing Klein with StubTreq������������������������������������������������������������������������������������������������� 131
Testing treq with Klein��������������������������������������������������������������������������������������������������������� 140
Logging with twisted.logger������������������������������������������������������������������������������������������������ 143
Running Twisted Applications with twist����������������������������������������������������������������������������� 149
Summary���������������������������������������������������������������������������������������������������������������������������������� 154

Part 2: Projects������������������������������������������������������������������������������������������� 155


Chapter 4: Twisted in Docker�������������������������������������������������������������������������������� 157
Intro to Docker�������������������������������������������������������������������������������������������������������������������������� 157
Containers��������������������������������������������������������������������������������������������������������������������������� 157
Container Images���������������������������������������������������������������������������������������������������������������� 158
Runc and Containerd����������������������������������������������������������������������������������������������������������� 159

vii
Table of Contents

Client����������������������������������������������������������������������������������������������������������������������������������� 159
Registry������������������������������������������������������������������������������������������������������������������������������� 160
Build������������������������������������������������������������������������������������������������������������������������������������ 160
Multi-stage Build����������������������������������������������������������������������������������������������������������������� 161
Python on Docker���������������������������������������������������������������������������������������������������������������������� 163
Deployment Options������������������������������������������������������������������������������������������������������������ 163
Full env�������������������������������������������������������������������������������������������������������������������������������� 163
Virtualenv���������������������������������������������������������������������������������������������������������������������������� 169
Pex��������������������������������������������������������������������������������������������������������������������������������������� 170
Build Options����������������������������������������������������������������������������������������������������������������������� 172
One Big Bag������������������������������������������������������������������������������������������������������������������������� 172
Copying Wheels Between Stages���������������������������������������������������������������������������������������� 172
Copying Environment Between Stages������������������������������������������������������������������������������� 173
Copying the Pex Executable Between Stages��������������������������������������������������������������������� 173
Automation with Dockerpy�������������������������������������������������������������������������������������������������� 173
Twisted on Docker�������������������������������������������������������������������������������������������������������������������� 174
ENTRYPOINT and PID 1�������������������������������������������������������������������������������������������������������� 174
Custom Plugins�������������������������������������������������������������������������������������������������������������������� 174
NColony������������������������������������������������������������������������������������������������������������������������������� 175
Summary���������������������������������������������������������������������������������������������������������������������������������� 178

Chapter 5: Using Twisted as a WSGI Server���������������������������������������������������������� 179


Introduction to WSGI����������������������������������������������������������������������������������������������������������������� 179
PEP�������������������������������������������������������������������������������������������������������������������������������������� 180
Raw Example����������������������������������������������������������������������������������������������������������������������� 181
Reference Implementation�������������������������������������������������������������������������������������������������� 183
WebOb Example������������������������������������������������������������������������������������������������������������������ 185
Pyramid Example����������������������������������������������������������������������������������������������������������������� 186
Getting Started�������������������������������������������������������������������������������������������������������������������������� 187
WSGI Server������������������������������������������������������������������������������������������������������������������������ 188
Finding Code������������������������������������������������������������������������������������������������������������������������ 191

viii
Table of Contents

Default Path������������������������������������������������������������������������������������������������������������������������� 191


PYTHONPATH����������������������������������������������������������������������������������������������������������������������� 192
setup.py������������������������������������������������������������������������������������������������������������������������������� 192
Why Twisted������������������������������������������������������������������������������������������������������������������������ 192
Production vs. Development������������������������������������������������������������������������������������������������ 192
TLS�������������������������������������������������������������������������������������������������������������������������������������� 194
Server Name Indication������������������������������������������������������������������������������������������������������� 195
Static Files��������������������������������������������������������������������������������������������������������������������������� 197
Resource Model������������������������������������������������������������������������������������������������������������������� 197
Pure Static��������������������������������������������������������������������������������������������������������������������������� 198
Combining Static Files with WSGI��������������������������������������������������������������������������������������� 200
Built-In Scheduled Tasks����������������������������������������������������������������������������������������������������� 203
Control Channels����������������������������������������������������������������������������������������������������������������� 206
Strategies for Using Multiple Cores������������������������������������������������������������������������������������������ 208
Load Balancer���������������������������������������������������������������������������������������������������������������������� 208
Opening Socket in Shared Mode����������������������������������������������������������������������������������������� 210
Other Options����������������������������������������������������������������������������������������������������������������������� 213
Dynamic Configuration�������������������������������������������������������������������������������������������������������������� 214
A/B Testable Pyramid App���������������������������������������������������������������������������������������������������� 214
Custom Plugin with AMP����������������������������������������������������������������������������������������������������� 216
Control Program������������������������������������������������������������������������������������������������������������������ 219
Summary���������������������������������������������������������������������������������������������������������������������������������� 221

Chapter 6: Tahoe-LAFS: The Least-­Authority File System������������������������������������ 223


How Tahoe-LAFS Works������������������������������������������������������������������������������������������������������������ 224
System Architecture������������������������������������������������������������������������������������������������������������������ 227
How It Uses Twisted������������������������������������������������������������������������������������������������������������������ 229
Problems We’ve Run Into���������������������������������������������������������������������������������������������������������� 230
Daemonization Tools������������������������������������������������������������������������������������������������������������ 231
Internal FileNode Interfaces������������������������������������������������������������������������������������������������������ 232
Front-End Protocol Integration�������������������������������������������������������������������������������������������������� 233

ix
Table of Contents

The Web Front End�������������������������������������������������������������������������������������������������������������������� 234


File Types, Content-Type, /name/����������������������������������������������������������������������������������������� 237
Saving to Disk���������������������������������������������������������������������������������������������������������������������� 238
Range Headers�������������������������������������������������������������������������������������������������������������������� 238
Error Conversion on the Return Side����������������������������������������������������������������������������������� 240
Rendering UI Elements: Nevow Templates�������������������������������������������������������������������������� 241
The FTP Front End��������������������������������������������������������������������������������������������������������������������� 242
The SFTP Front End������������������������������������������������������������������������������������������������������������������� 248
Backward-Incompatible Twisted APIs��������������������������������������������������������������������������������������� 248
Summary���������������������������������������������������������������������������������������������������������������������������������� 251
References�������������������������������������������������������������������������������������������������������������������������������� 251

Chapter 7: Magic Wormhole��������������������������������������������������������������������������������� 253


What It Looks Like��������������������������������������������������������������������������������������������������������������������� 254
How It Works����������������������������������������������������������������������������������������������������������������������������� 255
Network Protocols, Transfer Latency, Client Compatibility�������������������������������������������������������� 257
Network Protocols and Client Compatibility������������������������������������������������������������������������ 258
Server Architecture������������������������������������������������������������������������������������������������������������������� 260
Persistent Database������������������������������������������������������������������������������������������������������������ 262
Transit Client: Cancelable Deferreds����������������������������������������������������������������������������������������� 262
Transit Relay Server������������������������������������������������������������������������������������������������������������������ 265
Wormhole Client Architecture��������������������������������������������������������������������������������������������������� 267
Deferreds vs State Machines, One-Shot Observer�������������������������������������������������������������������� 268
One-Shot Observers������������������������������������������������������������������������������������������������������������������ 271
Promises/Futures vs. Deferreds������������������������������������������������������������������������������������������������ 272
Eventual-Send, Synchronous Testing���������������������������������������������������������������������������������������� 275
Asynchronous Testing with Deferreds��������������������������������������������������������������������������������������� 277
Synchronous Testing with Deferreds���������������������������������������������������������������������������������������� 278
Synchronous Testing and Eventual Send����������������������������������������������������������������������������� 281
Summary���������������������������������������������������������������������������������������������������������������������������������� 283
References�������������������������������������������������������������������������������������������������������������������������������� 283

x
Visit https://textbookfull.com
now to explore a rich
collection of eBooks, textbook
and enjoy exciting offers!
Table of Contents

Chapter 8: Push Data to Browsers and Micro-services with WebSocket������������� 285


Why WebSocket?���������������������������������������������������������������������������������������������������������������������� 285
WebSocket and Twisted������������������������������������������������������������������������������������������������������������ 286
Raw WebSocket, from Python to Python����������������������������������������������������������������������������������� 288
Raw WebSocket, Between Python and JavaScript�������������������������������������������������������������������� 292
More Powerful WebSocket with WAMP������������������������������������������������������������������������������������� 294
Summary���������������������������������������������������������������������������������������������������������������������������������� 303

Chapter 9: Applications with asyncio and Twisted����������������������������������������������� 305


Core Concepts��������������������������������������������������������������������������������������������������������������������������� 305
Promises����������������������������������������������������������������������������������������������������������������������������������� 306
Event Loops������������������������������������������������������������������������������������������������������������������������� 307
Guidelines��������������������������������������������������������������������������������������������������������������������������������� 308
Case Study: A Proxy with aiohttp and treq�������������������������������������������������������������������������������� 312
Summary���������������������������������������������������������������������������������������������������������������������������������� 316

Chapter 10: Buildbot and Twisted������������������������������������������������������������������������� 317


History of Buildbot�������������������������������������������������������������������������������������������������������������������� 317
The Evolution of Buildbot’s Async Python���������������������������������������������������������������������������� 318
Migrating Synchronous APIs������������������������������������������������������������������������������������������������ 321
Async Build Steps���������������������������������������������������������������������������������������������������������������� 322
Buildbot’s Code������������������������������������������������������������������������������������������������������������������������� 323
Async Utilities���������������������������������������������������������������������������������������������������������������������� 323
Debounce���������������������������������������������������������������������������������������������������������������������������� 323
Async Services�������������������������������������������������������������������������������������������������������������������� 324
LRU Cache��������������������������������������������������������������������������������������������������������������������������� 326
Eventual������������������������������������������������������������������������������������������������������������������������������� 327
Interfacing with Synchronous Code������������������������������������������������������������������������������������� 327
SQLAlchemy������������������������������������������������������������������������������������������������������������������������ 328
requests������������������������������������������������������������������������������������������������������������������������������� 329
Docker��������������������������������������������������������������������������������������������������������������������������������� 332
Concurrent Access to Shared Resources���������������������������������������������������������������������������� 333
xi
Table of Contents

Yield as a Concurrency Barrier�������������������������������������������������������������������������������������������� 333


Thread-Pool Functions Should Not Mutate State���������������������������������������������������������������� 334
DeferredLocks��������������������������������������������������������������������������������������������������������������������� 336
Testing��������������������������������������������������������������������������������������������������������������������������������� 336
Fakes����������������������������������������������������������������������������������������������������������������������������������� 338
Summary���������������������������������������������������������������������������������������������������������������������������������� 338

Chapter 11: Twisted and HTTP/2�������������������������������������������������������������������������� 339


Introduction������������������������������������������������������������������������������������������������������������������������������� 339
Design Goals����������������������������������������������������������������������������������������������������������������������������� 341
Seamless Integration����������������������������������������������������������������������������������������������������������� 341
Most-Optimized Behavior by Default����������������������������������������������������������������������������������� 343
Separating Concerns and Reusing Code����������������������������������������������������������������������������� 343
Implementation Concerns��������������������������������������������������������������������������������������������������������� 344
What Is a Connection Anyway? The Value of Standard Interfaces��������������������������������������� 345
Multiplexing and Priority����������������������������������������������������������������������������������������������������� 348
Backpressure���������������������������������������������������������������������������������������������������������������������� 355
Backpressure in Twisted����������������������������������������������������������������������������������������������������� 356
Backpressure in HTTP/2������������������������������������������������������������������������������������������������������ 359
Current Status and Future Expansion��������������������������������������������������������������������������������������� 362
Summary���������������������������������������������������������������������������������������������������������������������������������� 363

Chapter 12: Twisted and Django Channels����������������������������������������������������������� 365


Introduction������������������������������������������������������������������������������������������������������������������������������� 365
Channels Building Blocks���������������������������������������������������������������������������������������������������������� 367
Message Brokers and Queues�������������������������������������������������������������������������������������������������� 368
Distributed Multi-Layer Systems in Twisted����������������������������������������������������������������������������� 369
Current Status and Future Expansion��������������������������������������������������������������������������������������� 371
Summary���������������������������������������������������������������������������������������������������������������������������������� 371

Index��������������������������������������������������������������������������������������������������������������������� 373

xii
About the Authors
Mark Williams works on Twisted. At eBay and PayPal, he worked on high-performance
Python web services (over a billion requests a day!), application and information
security, and porting enterprise, Java-only libraries to Python.

Cory Benfield is an open source Python developer heavily involved in the Python HTTP
community. He's a Requests core contributor, a urllib3 core contributor, and the lead
maintainer of the Hyper Project, a collection of HTTP and HTTP/2 tools for Python. For
his sins, he also helps out with the Python Cryptographic Authority on PyOpenSSL.

Brian Warner is a security engineer and software developer, having worked at Mozilla
on Firefox Sync, the Add-On SDK, and Persona. He is co-founder of the Tahoe-LAFS
distributed secure filesystem, and develops secure storage and communication tools.

Moshe Zadka has been part of the open source community since 1995, made his first
core Python contributions in 1998, and is a founding member of the Twisted open
source project. He also loves to teach Twisted and Python, having given tutorials at
several conferences as well as regularly blogging.

Dustin Mitchell has contributed to Buildbot and is a member of the TaskCluster team
at Mozilla, having also worked on the Release Engineering, Release Operations, and
Infrastructure teams.

Kevin Samuel has been a Dev and trainer since Python 2.4 and has been putting
his skills to work in East Europe, North America, Asia, and West Africa. He has been
working closely with the Crossbar.io team and is an active member of the French Python
community.

Pierre Tardy is a continuous integration specialist with Renault Software Labs, and he is
currently the lead committer for Buildbot.

xiii
About the Technical Reviewers
Julian Berman is a New York-based software developer and
open source contributor. He is the author of the jsonschema
Python library, an occasional contributor to the Twisted
ecosystem, and an active member of the Python community.

Shawn Shojaie lives in the clement chaparral of California's Bay Area, where he works
as a back-end software engineer. He has worked at Intel, NetApp, and now SimpleLegal,
where he happily builds web-based applications for legal services. He spends weekdays
writing Django and tuning PostgreSQL, and his weekends contributing to open source
projects like django-pylint, occasionally editing technical essays. Find out more at him at
shawnshojaie.com.
Tom Most is a software engineer in the telecommunications industry. He is a Twisted
committer with 10 years of experience of applying Twisted to web services, client
libraries, and command-line applications. He is the maintainer of Afkak, the Twisted
Kafka client. He can be found online at freecog.net and reached at [email protected].

xv
Acknowledgments
Thanks to my wife, Jennifer Zadka, without whose support I could not have done it.

Thanks to my parents, Yaacov and Pnina Zadka, who taught me how to learn.

Thanks to my advisor, Yael Karshon, for teaching me how to write.

Thanks to Mahmoud Hashemi, for inspiration and encouragement.

Thanks to Mark Williams, for always being there for me.

Thanks to Glyph Lefkowitz, for teaching me things about Python, about programming,
and about being a good person.

—Moshe Zadka

Thanks to Mahmoud Hashemi and David Karapetyan for their feedback. Thanks to
Annie for putting up with me while I wrote

—Mark Williams

xvii
Introduction
Twisted has recently celebrated its sweet sixteen birthday. It has been around for a
while; and in that time, it grew to be a powerful library. In that time, some interesting
applications have been built on top of it. In that time, many of us learned a lot about how
to use Twisted well, how to think about networking code, and how to architect event-­
based programs.
After going through the introductory materials that we have on the Twisted site,
a common thing to hear is “What now? How can I learn more about Twisted?” The
usual way we answered that question is with a question: “What do you want to do with
Twisted?” This book shows how to do interesting things with Twisted.
Each of the contributors to this book has done slightly different things with Twisted
and learned different lessons. We are excited to present all of these lessons, with the
goals of making them common knowledge in the community.
Enjoy!

xix
PART 1

Foundations
CHAPTER 1

An Introduction to
Event-­Driven
Programming with Twisted
Twisted is a powerful, well-tested, and mature concurrent networking library and
framework. As we’ll see in this book, many projects and individuals have used it to great
effect for more than a decade.
At the same time, Twisted is large, complicated, and old. Its lexicon teems with
strange names, like “reactor,” “protocol,” “endpoint,” and “Deferred.” These describe a
philosophy and architecture that have baffled both newcomers and old hands with years
of Python experience.
Two fundamental programming paradigms inform Twisted’s pantheon of APIs:
event-driven programming and asynchronous programming. The rise of JavaScript
and the introduction of asyncio into the Python standard library have brought both
further into the mainstream, but neither paradigm dominates Python programming
so completely that merely knowing the language makes them familiar. They remain
specialized topics reserved for intermediate or advanced programmers.
This chapter and the next introduce the motivations behind event-driven and
asynchronous programming, and then show how Twisted employs these paradigms.
They lay the foundation for later chapters that explore real-world Twisted programs.
We’ll begin by exploring the nature of event-driven programming outside of the
context of Twisted. Once we have a sense of what defines event-driven programming,
we’ll see how Twisted provides software abstractions that help developers write clear
and effective event-driven programs. We’ll also stop along the way to learn about
some of the unique parts of those abstractions, like interfaces, and explore how they’re
documented on Twisted’s website.

3
© Mark Williams, Cory Benfield, Brian Warner, Moshe Zadka, Dustin Mitchell, Kevin Samuel, Pierre Tardy 2019
M. Williams et al., Expert Twisted, https://doi.org/10.1007/978-1-4842-3742-7_1
Chapter 1 An Introduction to Event-­Driven Programming with Twisted

By the end of this chapter you’ll know Twisted terminology: protocols, transports,
reactors, consumers, and producers. These concepts form the foundation of Twisted’s
approach to event-driven programming, and knowing them is essential to writing useful
software with Twisted.

A Note About Python Versions


Twisted itself supports Python 2 and 3, so all code examples in this chapter are written
to work on both Python 2 and 3. Python 3 is the future, but part of Twisted’s strength is
its rich history of protocol implementations; for that reason, it’s important that you’re
comfortable with code that runs on Python 2, even if you never write it.

What Is Event-Driven Programming?


An event is something that causes an event-driven program to perform an action.
This broad definition allows many programs to be understood as event-driven;
consider, for example, a simple program that prints either Hello or World!
depending on user input:

import sys
line = sys.stdin.readline().strip()
if line == "h":
     print("Hello")
else:
     print("World")

The availability of a line of input over standard input is an event. Our program
pauses on sys.stdin.readline(), which asks the operating system to allow the user to
input a complete line. Until one is received, our program can make no progress. When
the operating system receives input, and Python’s internals determine it’s a line, sys.
stdin.readline() resumes our program by returning that data to it. This resumption
is the event that drives our program forward. Even this simple program, then, can be
understood as an event-driven one.

4
Chapter 1 An Introduction to Event-­Driven Programming with Twisted

Multiple Events
A program that receives a single event and then exits doesn’t benefit from an event-­
driven approach. Programs in which more than one thing can happen at a time,
however, are more naturally organized around events. A graphical user interface implies
just such a program: at any moment, a user might click a button, select an item from a
menu, scroll through a text widget, and so on.
Here’s a version of our previous program with a Tkinter GUI:

from six.moves import tkinter


from six.moves.tkinter import scrolledtext

class Application(tkinter.Frame):
    def __init__ (self, root):
        super(Application,self). __init__ (root)
        self.pack()
        self.helloButton = tkinter.Button(self,
                                      text="Say Hello",
                                      command=self.sayHello)
        self.worldButton = tkinter.Button(self,
                                        text="Say World",
                                        command=self.sayWorld)
         self.output = scrolledtext.ScrolledText(master=self)
         self.helloButton.pack(side="top")
        self.worldButton.pack(side="top")
         self.output.pack(side="top")
    def outputLine(self, text):
        self.output.insert(tkinter.INSERT, text+ '\n')
    def sayHello(self):
        self.outputLine("Hello")
    def sayWorld(self):
        self.outputLine("World")

5
Visit https://textbookfull.com
now to explore a rich
collection of eBooks, textbook
and enjoy exciting offers!
Chapter 1 An Introduction to Event-­Driven Programming with Twisted

Application(tkinter.Tk()).mainloop()
This version of our program presents the user with two buttons, either of which can
generate an independent click event. This differs from our previous program, where only
sys.stdin.readline could generate the single “line ready” event.
We cope with the possible occurrence of either button’s event by associating event
handlers with each one. Tkinter buttons accept a callable command to invoke when they
are clicked. When the button labeled “Say Hello” generates a click event, that event
drives our program to call Application.sayHello as shown in Figure 1-1. This, in turn,
outputs a line consisting of Hello to a scrollable text widget. The same process applies to
the button labeled “Say Hello” and Application.sayWorld.

Figure 1-1. Our Tkinter GUI application after a series of clicks of “Say Hello” and
“Say World”

tkinter.Frame’s mainloop method, which our Application class inherits, waits


until a button bound to it generates an event and then runs the associated event handler.
After each event handler has run, tkinter.Frame.mainloop again begins waiting for new
events. A loop that monitors event sources and dispatches their associated handlers is
typical of event-driven programs, and is known as an event loop.

6
Chapter 1 An Introduction to Event-­Driven Programming with Twisted

These concepts are the core of event-driven programming:

1. Events represent that something has occurred and to which the


program should react. In both our examples, events correspond
naturally to program input, but as we’ll see, they can represent
anything that causes our program to perform some action.

2. Event handlers constitute the program’s reactions to events.


Sometimes an event’s handler just consists of a sequence of
code, as in our sys.stdin.readline example, but more often
it’s encapsulated by a function or method, as in our tkinter
example.

3. An event loop waits for events and invokes the event handler
associated with each. Not all event-driven programs have an event
loop; our sys.stdin.readline example did not because it only
responds to a single event. However, most resemble our tkinter
example in that they process many events before finally exiting.
These kinds of programs use an event loop.

Multiplexing and Demultiplexing


The way event loops wait for events affects the way we write event-driven programs, so
we must take a closer look at them. Consider our tkinter example and its two buttons;
the event loop inside mainloop must wait until the user has clicked at least one button.
A naive implementation might look like this:

def mainloop(self):
    while self.running:
         ready = [button for button in self.buttons if button.hasEvent()]
         if ready:
            self.dispatchButtonEventHandlers(ready)

mainloop continually polls each button for a new event, dispatching event handlers
only for those that have an event ready. When no events are ready, the program makes
no progress because no action has been taken that requires a response. An event-driven
program must suspend its execution during these periods of inactivity.

7
Chapter 1 An Introduction to Event-­Driven Programming with Twisted

The while loop in our mainloop example suspends its program until one of the
buttons has been clicked and sayHello or sayWorld should run. Unless the user is
supernaturally fast with a mouse, this loop spends most of its time checking buttons that
haven’t been clicked. This is known as a busy wait because the program is actively busy
waiting.
A busy wait like this pauses a program’s overall execution until one of its event
sources reports an event, and so it suffices as a mechanism to pause an event loop.
The inner list comprehension that powers our implementation’s busy wait asks
a critical question: Has anything happened? The answer comes from the ready
variable, which contains all buttons that have been clicked in a single place. The
truthiness of ready decides the answer to the event loop’s question: when ready is
empty and thus falsey, no buttons have been clicked and so nothing has happened.
When it’s truthy, however, at least one has been clicked, and so something has
happened.
The list comprehension that constructs ready coalesces many separate inputs
into one. This is known as multiplexing, while the inverse process of separating
different inputs out from a single coalesced input is known as demultiplexing.
The list comprehension multiplexes our buttons into ready while the
dispatchButtonEventHandlers method demultiplexes them out by invoking each
event’s handler.
We can now refine our understanding of event loops by precisely describing how
they wait for events:

• An event loop waits for events by multiplexing their sources into a


single input. When that input indicates that events have occurred, the
event loop demultiplexes it into its constituent inputs and invokes the
event handler associated with each.
Our mainloop multiplexer wastes most of its time polling buttons that haven’t
been clicked. Not all multiplexers are so inefficient. tkinter.Frame.mainloop’s
actual implementation employs a similar multiplexer that polls all widgets unless the
operating system provides more efficient primitives. To improve its efficiency, mainloop’s
multiplexer exploits the insight that computers can check a GUI’s widgets faster than a
person can interact with them, and inserts a sleep call that pauses the entire program
for several milliseconds. This allows the program to spend part of its busy-wait loop
passively rather than actively do nothing, saving CPU time and energy at the expense of
negligible latency.

8
Chapter 1 An Introduction to Event-­Driven Programming with Twisted

While Twisted can integrate with graphical user interfaces, and in fact has special
support for tkinter, it is at its heart a networking engine. Sockets, not buttons, are the
fundamental object in networking, and operating systems expose efficient primitives for
multiplexing socket events. Twisted’s event loop uses these primitives to wait for events.
To understand Twisted’s approach to event-driven programming, we must understand
the interaction between these sockets and these multiplexing networking primitives.

The select Multiplexer


Its History, Its Siblings, and Its Purpose
Almost all modern operating systems support the select multiplexer. select gets its
name from its ability to take a list of sockets and “select” only those that have events
ready to be handled.
select was born in 1983, when computers were capable of far less. Consequently, its
interface prevents it from operating at maximum efficiency, especially when multiplexing
a large number of sockets. Each operating system family provides its own, more efficient
multiplexer, such as BSD’s kqueue and Linux’s epoll, but no two interoperate. Luckily
their principles are similar enough to select that we can generalize their behavior from
select’s. We’ll use select to explore how these socket multiplexers behave.

select and Sockets


The code that follows omits error handling and will break on many edge cases that occur
in practice. It is intended only as a teaching tool. Do not use it in real applications.
Use Twisted instead. Twisted strives to correctly handle errors and edge cases; that’s
part of why its implementation is so complicated.
With that disclaimer out of the way, let’s begin an interactive Python session and
create sockets for select to multiplex:

>>> import socket


>>> listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> listener.bind(('127.0.0.1', 0))
>>> listener.listen(1)
>>> client = socket.create_connection(listener.getsockname())
>>> server, _ = listener.accept()

9
Chapter 1 An Introduction to Event-­Driven Programming with Twisted

A full explanation of the socket API is beyond the scope of this book. Indeed, we
expect that the parts we discuss will lead you to prefer Twisted! The preceding code,
however, contains more fundamental concepts than irrelevant details:

1. listener - This socket can accept incoming connections. It is an


internet (socket.AF_INET) and TCP (socket.SOCK_STREAM) socket
accessible by clients on the internal, local-only network interface
(which conventionally has an address of 127.0.0.1) and on a port
randomly assigned by the operating system (0). This listener can
perform the setup necessary for one incoming connection and
enqueue it until we’re reading for it (listen(1)).

2. client - This socket is an outgoing connection. Python’s socket.


create_connection function accepts a (host, port) tuple
representing the listening socket to which to connect and returns
a socket connected to it. Because our listening socket is in the
same process and named listener, we can retrieve its host and
port with the listener.getsockname().

3. server - The server’s incoming connection. Once client has


connected to our host and port, we must accept the connection
from listener’s queue of length 1. listener.accept returns a
(socket, address) tuple; we only need the socket, so we discard
the address. A real program might log the address or use it to track
connection metrics. The listening queue, which we set to 1 via the
socket’s listen method, holds this socket for us before we call
accept and allows create_connection to return.

client and server are two ends of the same TCP connection. An established TCP
connection has no concept of “client” and “server”; our client socket has the same
privileges to read, write, or close the connection as our server:

>>> data = b"xyz"


>>> client.sendall(data)
>>> server.recv(1024) == data
True
>>> server.sendall(data)
>>> client.recv(1024) == data
True
10
Random documents with unrelated
content Scribd suggests to you:
That it was she, the which for helpe did seeke.
Tho looking vp vnto the cry to lest,
They saw that Carle from farre, with hand vnblest
Hayling that mayden by the yellow heare,
That all her garments from her snowy brest,
And from her head her lockes he nigh did teare,
Ne would he spare for pitty, nor refraine for feare.

Which haynous sight when Calidore beheld, xviii


Eftsoones he loosd that Squire, and so him left,
With hearts dismay and inward dolour queld,
For to pursue that villaine, which had reft
That piteous spoile by so iniurious theft.
Whom ouertaking, loude to him he cryde;
Leaue faytor quickely that misgotten weft
To him, that hath it better iustifyde,
And turne thee soone to him, of whom thou art defyde.

Who hearkning to that voice, him selfe vpreard, xix


And seeing him so fiercely towardes make,
Against him stoutly ran, as nought afeard,
But rather more enrag’d for those words sake;
And with sterne count’naunce thus vnto him spake.
Art thou the caytiue, that defyest me,
And for this Mayd, whose party thou doest take,
Wilt giue thy beard, though it but little bee?
Yet shall it not her lockes for raunsome fro me free.

With that he fiercely at him flew, and layd xx


On hideous strokes with most importune might,
That oft he made him stagger as vnstayd,
And oft recuile to shunne his sharpe despight.
But Calidore, that was well skild in fight,
Him long forbore, and still his spirite spar’d,
Lying in waite, how him he damadge might.
But when he felt him shrinke, and come to ward,
He greater grew, and gan to driue at him more hard.

Like as a water streame, whose swelling sourse xxi


Shall driue a Mill, within strong bancks is pent,
And long restrayned of his ready course;
So soone as passage is vnto him lent,
Breakes forth, and makes his way more violent.
Such was the fury of Sir Calidore,
When once he felt his foeman to relent;
He fiercely him pursu’d, and pressed sore,
Who as he still decayd, so he encreased more.

The heauy burden of whose dreadfull might xxii


When as the Carle no longer could sustaine,
His heart gan faint, and streight he tooke his flight
Toward the Castle, where if need constraine,
His hope of refuge vsed to remaine.
Whom Calidore perceiuing fast to flie,
He him pursu’d and chaced through the plaine,
That he for dread of death gan loude to crie
Vnto the ward, to open to him hastilie.

They from the wall him seeing so aghast, xxiii


The gate soone opened to receiue him in,
But Calidore did follow him so fast,
That euen in the Porch he him did win,
And cleft his head asunder to his chin.
The carkasse[406] tumbling downe within the dore,
Did choke the entraunce with a lumpe of sin,
That it could not be shut, whilest Calidore
Did enter in, and slew the Porter on the flore.

With that the rest, the which the Castle kept, xxiv
About him flockt, and hard at him did lay;
But he them all from him full lightly swept,
As doth a Steare, in heat of sommers day,[407]
With his long taile the bryzes brush away.
Thence passing forth, into the hall he came,
Where of the Lady selfe in sad dismay
He was ymett, who with vncomely shame
Gan him salute, and fowle vpbrayd with faulty blame.

False traytor Knight, (sayd she) no Knight at all, xxv


But scorne of armes that hast with guilty hand
Murdred my men, and slaine my Seneschall;
Now comest thou to rob my house vnmand,
And spoile my selfe, that can not thee withstand?
Yet doubt thou not, but that some better Knight
Then thou, that shall thy treason vnderstand,
Will it auenge, and pay thee with thy right:
And if none do, yet shame shal thee with shame requight.[408]

Much was the Knight abashed at that word; xxvi


Yet answerd thus; Not vnto me the shame,
But to the shamefull doer it afford.
Bloud is no blemish; for it is no blame
To punish those, that doe deserue the same;
But they that breake bands of ciuilitie,
And wicked customes make, those doe defame
Both noble armes and gentle curtesie.
No greater shame to man then inhumanitie.

Then doe your selfe, for dread of shame, forgoe xxvii


This euill manner, which ye here maintaine,
And doe in stead thereof mild curt’sie showe
To all, that passe. That shall you glory gaine
More then his loue, which thus ye seeke t’obtaine.
Wherewith all full of wrath, she thus replyde;
Vile recreant, know that I doe much disdaine
Thy courteous lore, that doest my loue deride,
Who scornes thy ydle scoffe, and bids thee be defyde.
To take defiaunce at a Ladies word xxviii
(Quoth he) I hold it no indignity;
But were he here, that would it with his sword
Abett, perhaps he mote it deare aby.
Cowherd (quoth she) were not, that thou wouldst fly,
Ere he[409] doe come, he should be soone in place.
If I doe so, (sayd he) then liberty
I leaue to you, for aye me to disgrace
With all those shames, that erst ye spake me to deface.

With that a Dwarfe she cald to her in hast, xxix


And taking from her hand a ring of gould,
A priuy token, which betweene them past,
Bad him to flie with all the speed he could,
To Crudor, and desire him that he would
Vouchsafe to reskue her against a Knight,
Who through strong powre had now her self in hould,
Hauing late slaine her Seneschall in fight,
And all her people murdred with outragious might.

The Dwarfe his way did hast, and went all night; xxx
But Calidore did with her there abyde
The comming of that so much threatned Knight,
Where that discourteous Dame with scornfull pryde,
And fowle entreaty him indignifyde,
That yron heart it hardly could sustaine:
Yet he, that could his wrath full wisely guyde,
Did well endure her womanish disdaine,
And did him selfe from fraile impatience refraine.

The morrow next, before the lampe of light[410] xxxi


Aboue the earth vpreard his flaming head,
The Dwarfe, which bore that message to her knight,
Brought aunswere backe, that ere he tasted bread,
He would her succour, and aliue or dead
Her foe deliuer vp into her hand:
Therefore he wild her doe away all dread;
And that of him she mote assured stand,
He sent to her his basenet, as a faithfull band.

Thereof full blyth the Lady streight became, xxxii


And gan t’augment her bitternesse much more:
Yet no whit more appalled for the same,
Ne ought dismayed was Sir Calidore,
But rather did more chearefull seeme therefore.
And hauing soone his armes about him dight,
Did issue forth, to meete his foe afore;
Where long he stayed not, when as a Knight
He spide come pricking on with al his powre and might.

Well weend he streight, that he should be the same, xxxiii


Which tooke in hand her quarrell to maintaine;
Ne stayd to aske if it were he by name,
But coucht his speare, and ran at him amaine.
They bene ymett in middest of the plaine,
With so fell fury, and dispiteous forse,
That neither could the others stroke sustaine,
But rudely rowld to ground both man and horse,
Neither of other taking pitty nor remorse.

But Calidore vprose againe full light, xxxiv


Whiles yet his foe lay fast in sencelesse sound,
Yet would he not him hurt, although he might:
For shame he weend a sleeping wight to wound.
But when Briana saw that drery stound,
There where she stood vppon the Castle wall,
She deem’d him sure to haue bene dead on ground,
And made such piteous mourning therewithall,
That from the battlements she ready seem’d to fall.

Nathlesse at length him selfe he did vpreare xxxv


In lustlesse wise, as if against his will,
Ere he had slept his fill, he wakened were,
And gan to stretch his limbs; which feeling ill
Of his late fall, a while he rested still:
But when he saw his foe before in vew,
He shooke off luskishnesse, and courage chill
Kindling a fresh, gan battell to renew,
To proue if better foote then horsebacke would ensew.

There then began a fearefull cruell fray xxxvi


Betwixt them two, for maystery of might.
For both were wondrous practicke in that play,
And passing well expert in single fight,
And both inflam’d with furious despight:
Which as it still encreast, so still increast
Their cruell strokes and terrible affright;
Ne once for ruth their rigour they releast,
Ne once to breath[411] a while their angers tempest ceast.

Thus long they trac’d and trauerst to and fro, xxxvii


And tryde all waies, how each mote entrance make
Into the life of his malignant foe;
They hew’d their helmes, and plates asunder brake,
As they had potshares bene; for nought mote slake
Their greedy vengeaunces, but goary blood,
That at the last like to a purple lake
Of bloudy gore congeal’d about them stood,
Which from their riuen sides forth gushed like a flood.

At length it chaunst, that both their hands on hie[412] xxxviii


At once did heaue, with all their powre and might,
Thinking the vtmost of their force to trie,
And proue the finall fortune of the fight:
But Calidore, that was more quicke of sight,
And nimbler handed, then his enemie,
Preuented him before his stroke could light,
And on the helmet smote him formerlie,
That made him stoupe to ground with meeke humilitie.

And ere he could recouer foot againe, xxxix


He following that faire aduantage fast,
His stroke redoubled with such might and maine,
That him vpon the ground he groueling cast;
And leaping to him light, would haue vnlast
His Helme, to make vnto his vengeance way.
Who seeing, in what daunger he was plast,
Cryde out, Ah mercie Sir, doe me not slay,
But saue my life, which lot before your foot doth lay.

With that his mortall hand a while he stayd, xl


And hauing somewhat calm’d his wrathfull heat
With goodly patience, thus he to him sayd;
And is the boast of that proud Ladies threat,
That menaced me from the field to beat,
Now brought to this? By this now may ye learne,
Strangers no more so rudely to intreat,
But put away proud looke, and vsage sterne,
The which shal nought to you but foule dishonor yearne[413].

For nothing is more blamefull to a knight, xli


That court’sie doth as well as armes professe,
How euer strong and fortunate in fight,
Then the reproch of pride and cruelnesse.
In vaine he seeketh others to suppresse,
Who hath not learnd him selfe first to subdew:
All flesh is frayle, and full of ficklenesse,
Subiect to fortunes chance, still chaunging new;
What haps to day to me, to morrow may to you.

Who will not mercie vnto others shew, xlii


How can he mercy euer hope to haue?
To pay each with his owne is right and dew.
Yet since[414] ye mercie now doe need to craue,
I will it graunt, your hopelesse life to saue;
With these conditions, which I will propound:
First, that ye better shall your selfe behaue
Vnto all errant knights, whereso on ground;
Next that ye Ladies ayde in euery stead and stound.

The wretched man, that all this while did dwell xliii
In dread of death, his heasts did gladly heare,
And promist to performe his precept well,
And whatsoeuer else he would requere.
So suffring him to rise, he made him sweare
By his owne sword, and by the crosse thereon,
To take Briana for his louing fere,
Withouten dowre or composition;
But to release his former foule condition.

All which accepting, and with faithfull oth xliv


Bynding himselfe most firmely to obay,
He vp arose, how euer liefe or loth,
And swore to him true fealtie for aye.
Then forth he cald from sorrowfull dismay
The sad Briana, which all this beheld:
Who comming forth yet full of late affray,
Sir Calidore vpcheard, and to her teld
All this accord, to which he Crudor had compeld.

Whereof she now more glad, then sory earst, xlv


All ouercome with infinite affect,
For his exceeding courtesie, that pearst
Her stubborne hart with inward deepe effect,
Before his feet her selfe she did proiect,
And him adoring as her liues deare Lord,
With all due thankes, and dutifull respect,
Her selfe acknowledg’d bound for that accord,
By which he had to her both life and loue restord.
So all returning to the Castle glad, xlvi
Most ioyfully she them did entertaine,
Where goodly glee and feast to them she made,
To shew her thankefull mind and meaning faine,
By all the meanes she mote it best explaine:
And after all, vnto Sir Calidore
She freely gaue that Castle for his paine,
And her selfe bound to him for euermore;
So wondrously now chaung’d, from that she was afore.

But Calidore himselfe would not retaine xlvii


Nor land nor fee, for hyre of his good deede,
But gaue them streight vnto that Squire againe,
Whom from her Seneschall he lately freed,
And to his damzell as their rightfull meed,
For recompence of all their former wrong:
There he remaind with them right well agreed,
Till of his wounds he wexed hole and strong,
And then to his first quest he passed forth along.

FOOTNOTES:
[401] vii 6 replide) 1596
[402] ix i leaue 1596
[403] x 8 withall, 1596 withall; 1609
[404] xiii 9 pay 1596
[405] xvi 6 vnable 1609
[406] xxiii 6 carkarsse 1596
[407] xxiv 4 day. 1596
[408] xxv 9 requight 1596
[409] xxviii 6 Ere he] Ere thou 1596
[410] xxxi 1 light, 1596
[411] xxxvi 9 breathe 1609
[412] xxxviii 1 hie, 1596
[413] xl 9 earne 1609
[414] xlii 4 sith 1609
Cant. II.

Calidore sees young Tristram slay


A proud discourteous knight,
He makes him Squire, and of him learnes
his state and present plight.

What vertue is so fitting for a knight, i


Or for a Ladie, whom a knight should loue,
As Curtesie, to beare themselues aright
To all of each degree, as doth behoue?
For whether they be placed high aboue,
Or low beneath, yet ought they well to know
Their good, that none them rightly may reproue
Of rudenesse, for not yeelding what they owe:
Great skill it is such duties timely to bestow.

Thereto great helpe dame Nature selfe doth lend: ii


For some so goodly gratious are by kind,
That euery action doth them much commend,
And in the eyes of men great liking find;
Which others, that haue greater skill in mind,
Though they enforce themselues, cannot attaine.
For euerie thing, to which one is inclin’d,
Doth best become, and greatest grace doth gaine:
Yet praise likewise deserue good thewes, enforst with paine.

That well in courteous Calidore appeares, iii


Whose euery deed and word[415], that he did say,
Was like enchantment, that through both the eyes[416],
And both the eares[417] did steale the hart away.
He now againe is on his former way,
To follow his first quest, when as he spyde
A tall young man from thence not farre away,
Fighting on foot, as well he him descryde,
Against an armed knight, that did on horsebacke ryde.

And them beside a Ladie faire he saw, iv


Standing alone on foot, in foule array:
To whom himselfe he hastily did draw,
To weet the cause of so vncomely fray,
And to depart them, if so be he may.
But ere he came in place, that youth had kild
That armed knight, that low on ground he lay;
Which when he saw, his hart was inly child
With great amazement, and his thought with wonder fild.

Him stedfastly he markt, and saw to bee v


A goodly youth of amiable grace,
Yet but a slender slip, that scarse did see
Yet seuenteene yeares, but tall and faire of face
That sure he deem’d him borne of noble race.
All in a woodmans iacket he was clad
Of Lincolne[418] greene, belayd with siluer lace;
And on his head an hood with aglets sprad,
And by his side his hunters horne he hanging had.

Buskins he wore of costliest cordwayne, vi


Pinckt vpon gold, and paled part per part,
As then the guize was for each gentle swayne;
In his right hand he held a trembling dart,
Whose fellow he before had sent apart;
And in his left he held a sharpe borespeare,
With which he wont to launch[419] the saluage hart
Of many a Lyon, and of many a Beare
That first vnto his hand in chase did happen neare.

Whom Calidore a while well hauing vewed, vii


At length bespake; What[420] meanes this, gentle swaine?
Why hath thy hand too bold it selfe embrewed
In blood of knight, the which by thee is slaine,
By thee no knight; which armes impugneth plaine?
Certes (said he) loth were I to haue broken
The law of armes; yet breake it should againe,
Rather then let my selfe of wight be stroken,
So long as these two armes were able to be wroken.

For not I him[421], as this his Ladie here viii


May witnesse well, did offer first to wrong,
Ne surely thus vnarm’d I likely were;
But he me first, through pride and puissance strong
Assayld, not knowing what to armes doth long.
Perdie great blame, (then said Sir Calidore)
For armed knight a wight vnarm’d to wrong.
But then aread, thou gentle chyld, wherefore
Betwixt you two began this strife and sterne vprore.

That shall I sooth (said he) to you declare, ix


I whose vnryper yeares are yet vnfit
For thing of weight, or worke of greater care,
Doe spend my dayes, and bend my carelesse wit
To saluage chace, where I thereon may hit
In all this forrest, and wyld wooddie raine:
Where, as this day I was enraunging[422] it,
I chaunst to meete this knight, who there lyes slaine,
Together with this Ladie, passing on the plaine.

The knight, as ye did see, on horsebacke was, x


And this his Ladie, (that him ill became,)
On her faire feet by his horse side did pas
Through thicke and thin, vnfit for any Dame.
Yet not content, more to increase his shame,
When so she lagged, as she needs mote so,
He with his speare, that was to him great blame,
Would thumpe her forward, and inforce to goe,
Weeping to him in vaine, and making piteous woe.

Which when I saw, as they me passed by, xi


Much was I moued in indignant mind,
And gan to blame him for such cruelty
Towards a Ladie, whom with vsage kind
He rather should haue taken vp behind.
Wherewith he wroth, and full of proud disdaine,
Tooke in foule scorne, that I such fault did find,
And me in lieu thereof reuil’d againe,
Threatning to chastize me, as doth t’a chyld pertaine.

Which I no lesse disdayning, backe returned xii


His scornefull taunts vnto his teeth againe,
That he streight way with haughtie choler burned,
And with his speare strooke me one stroke or twaine;
Which I enforst to beare though to my paine,
Cast to requite, and with a slender dart,
Fellow of this I beare, throwne not in vaine,
Strooke him, as seemeth, vnderneath the hart,
That through the wound his spirit shortly did depart.

Much did Sir Calidore admyre his speach xiii


Tempred so well, but more admyr’d the stroke
That through the mayles had made so strong a breach
Into his hart, and had so sternely wroke
His wrath on him, that first occasion broke.
Yet rested not, but further gan inquire
Of that same Ladie, whether what he spoke,
Were soothly so, and that th’vnrighteous ire
Of her owne knight, had giuen him his owne due hire.

Of all which, when as she could nought deny, xiv


But cleard that stripling of th’imputed blame,
Sayd[423] then Sir Calidore; Neither[424] will I
Him charge with guilt, but rather doe quite clame:
For what he spake, for you he spake it, Dame:
And what he did, he did him selfe to saue:
Against both which that knight wrought knightlesse shame.
For knights and all men this by nature haue,
Towards all womenkind them kindly to behaue.

But sith that he is gone irreuocable, xv


Please it you Ladie, to vs to aread,
What cause could make him so dishonourable,
To driue you so on foot vnfit to tread,
And lackey by him, gainst all womanhead?
Certes Sir knight (sayd she) full loth I were
To rayse a lyuing blame against the dead:
But since[425] it me concernes, my selfe to clere,
I will the truth discouer, as it chaunst whylere.

This day, as he and I together roade xvi


Vpon our way, to which we weren bent,
We chaunst to come foreby a couert glade
Within a wood, whereas a Ladie gent
Sate with a knight in ioyous iolliment[426]
Of their franke loues, free from all gealous spyes:
Faire was the Ladie sure, that mote content
An hart, not carried with too curious eyes,
And vnto him did shew all louely courtesyes.

Whom when my knight did see so louely faire, xvii


He inly gan her louer to enuy,
And wish, that he part of his spoyle might share.
Whereto when as my presence he did spy
To be a let, he bad me by and by
For to alight: but when as I was loth,
My loues owne part to leaue so suddenly,
He with strong hand down from his steed me throw’th,
And with presumpteous powre against that knight streight go’th.

Vnarm’d all was the knight, as then more meete xviii


For Ladies seruice, and for loues delight,
Then fearing any foeman there to meete:
Whereof he taking oddes, streight bids him dight
Himselfe to yeeld his loue, or else to fight.
Whereat the other starting vp dismayd,
Yet boldly answer’d, as he rightly might;
To leaue his loue he should be ill apayd,
In which he had good right gaynst all, that it gainesayd.

Yet since he was not presently in plight xix


Her to defend, or his to iustifie,
He him requested, as he was a knight,
To lend him day his better right to trie,
Or stay till he his armes, which were thereby,
Might lightly fetch. But he was fierce and whot[427],
Ne time would giue, nor any termes aby,
But at him flew, and with his speare him smot;
From which to thinke to saue himselfe, it booted not.

Meane while his Ladie, which this outrage saw, xx


Whilest they together for the quarrey stroue,
Into the couert did her selfe withdraw,
And closely hid her selfe within the groue.
My knight hers soone, as seemes, to daunger droue
And left sore wounded: but when her he mist,
He woxe halfe mad, and in that rage gan roue
And range through all the wood, where so he wist
She hidden was, and sought her so long, as him list.

But when as her he by no meanes could find, xxi


After long search and chauff, he turned backe
Vnto the place, where me he left behind:
There gan he me to curse and ban, for lacke
Of that faire bootie, and with bitter wracke
To wreake on me the guilt of his owne wrong.
Of all which I yet glad to beare the packe,
Stroue to appease him, and perswaded long:
But still his passion grew more violent and strong.

Then as it were t’auenge his wrath on mee, xxii


When forward we should fare, he flat refused
To take me vp (as this young man did see)
Vpon his steed, for no iust cause accused,
But forst to trot on foot, and foule misused,
Pounching[428] me with the butt end of his speare,
In vaine complayning, to be so abused.
For he regarded neither playnt nor teare,
But more enforst my paine, the more my plaints to heare.

So passed we, till this young man vs met, xxiii


And being moou’d with pittie of my plight,
Spake, as was meet, for ease of my regret:
Whereof befell, what now is in your sight.
Now sure (then said Sir Calidore) and right
Me seemes, that him befell by his owne fault:
Who euer thinkes through confidence of might,
Or through support of count’nance proud and hault
To wrong the weaker, oft falles in his owne assault.
Then turning backe vnto that gentle boy, xxiv
Which had himselfe so stoutly well acquit;
Seeing his face so louely sterne and coy,
And hearing th’answeres of his pregnant wit,
He praysd it much, and much admyred it;
That sure he weend him borne of noble blood,
With whom those graces did so goodly fit:
And when he long had him beholding stood,
He burst into these words, as to him seemed good.

Faire gentle swayne, and yet as stout as fayre, xxv


That in these woods amongst the Nymphs dost wonne,
Which daily may to thy sweete lookes repayre,
As they are wont vnto Latonaes sonne,
After his chace on woodie Cynthus donne:
Well may I certes such an one thee read,
As by thy worth thou worthily hast wonne,
Or surely borne of some Heroicke sead,
That in thy face appeares and gratious goodlyhead.

But should it not displease thee it to tell; xxvi


(Vnlesse thou in these woods thy selfe conceale,
For loue amongst the woodie Gods to dwell;)
I would thy selfe require thee to reueale,
For deare affection and vnfayned zeale,
Which to thy noble personage I beare,
And wish thee grow in worship and great weale.
For since the day that armes I first did reare,
I neuer saw in any greater hope appeare.

To whom then thus the noble youth; May[429] be xxvii


Sir knight, that by discouering my estate,
Harme may arise vnweeting vnto me;
Nathelesse, sith ye so courteous seemed late,
To you I will not feare it to relate.
Then wote ye that I am a Briton borne,
Sonne of a King, how euer thorough fate
Or fortune I my countrie haue forlorne,
And lost the crowne, which should my head by right adorne.

And Tristram is my name, the onely heire xxviii


Of good king Meliogras which did rayne
In Cornewale, till that he through liues despeire
Vntimely dyde, before I did attaine
Ripe yeares of reason, my right to maintaine.
After whose death, his brother seeing mee
An infant, weake a kingdome to sustaine,
Vpon him tooke the roiall high degree,
And sent me, where him list, instructed for to bee.

The widow Queene my mother, which then hight xxix


Faire Emiline, conceiuing then great feare
Of my fraile safetie, resting in the might
Of him, that did the kingly Scepter beare,
Whose gealous dread induring not a peare,
Is wont to cut off all, that doubt may breed,
Thought best away me to remoue somewhere
Into some forrein land, where as no need
Of dreaded daunger might his doubtfull humor feed.

So taking counsell of a wise man red, xxx


She was by him aduiz’d, to send me quight
Out of the countrie, wherein I was bred,
The which the fertile Lionesse is hight,
Into the land of Faerie, where no wight
Should weet of me, nor worke me any wrong[430].
To whose wise read she hearkning, sent me streight
Into this land, where I haue wond thus long,
Since I was ten yeares old, now growen to stature strong.

All which my daies I haue not lewdly spent, xxxi


Nor spilt the blossome of my tender yeares
In ydlesse, but as was conuenient,
Haue trayned bene with many noble feres
In gentle thewes, and such like seemely leres.
Mongst which my most delight hath alwaies been,
To hunt the saluage chace amongst my peres,
Of all that raungeth in the forrest greene;
Of which none is to me vnknowne, that eu’r was seene.

Ne is there hauke, which mantleth her on pearch, xxxii


Whether high towring, or accoasting low,
But I the measure of her flight doe search,
And all her pray, and all her diet know.
Such be our ioyes, which in these forrests grow:
Onely the vse of armes, which most I ioy,
And fitteth most for noble swayne to know,
I haue not tasted yet, yet past a boy,
And being now high time these strong ioynts to imploy.

Therefore, good Sir, sith now occasion fit xxxiii


Doth fall, whose like hereafter seldome[431] may,
Let me this craue, vnworthy though of it,
That ye will make me Squire without delay,
That from henceforth in batteilous array
I may beare armes, and learne to vse them right;
The rather since[432] that fortune hath this day
Giuen to me the spoile of this dead knight,
These goodly gilden armes, which I haue won in fight.

All which when well Sir Calidore had heard, xxxiv


Him much more now, then earst he gan admire,
For the rare hope which in his yeares appear’d,
And thus replide; Faire[433] chyld, the high desire
To loue of armes, which in you doth aspire,
I may not certes without blame denie;
But rather wish, that some more noble hire,
(Though none more noble then is cheualrie,)
I had, you to reward with greater dignitie.

There him he causd to kneele, and made to sweare xxxv


Faith to his knight, and truth to Ladies all,
And neuer to be recreant, for feare
Of perill, or of ought that might befall:
So he him dubbed, and his Squire did call.
Full glad and ioyous then young Tristram grew,
Like as a flowre, whose silken leaues small,
Long shut vp in the bud from heauens vew,
At length breakes forth, and brode displayes his smyling hew.

Thus when they long had treated to and fro, xxxvi


And Calidore betooke him to depart,
Chyld Tristram prayd, that he with him might goe
On his aduenture, vowing not to start,
But wayt on him in euery place and part.
Whereat Sir Calidore did much delight,
And greatly ioy’d at his so noble hart,
In hope he sure would proue a doughtie knight:
Yet for the time this answere he to him behight.

Glad would I surely be, thou courteous Squire, xxxvii


To haue thy presence in my present quest,
That mote thy kindled courage set on fire,
And flame forth honour in thy noble brest:
But I am bound by vow, which I profest
To my dread[434] Soueraine, when I it assayd,
That in atchieuement of her high behest,
I should no creature ioyne vnto mine ayde,
For thy I may not graunt, that ye so greatly prayde.

But since this Ladie is all desolate, xxxviii


And needeth safegard now vpon her way,
Ye may doe well in this her needfull state
To succour her, from daunger of dismay;
That thankfull guerdon may to you repay.
The noble ympe of such new seruice fayne,
It gladly did accept, as he did say.
So taking courteous leaue, they parted twayne,
And Calidore forth passed to his former payne.

But Tristram then despoyling that dead knight xxxix


Of all those goodly implements[435] of prayse,
Long fed his greedie eyes with the faire sight
Of the bright mettall, shyning like Sunne rayes;
Handling and turning them a thousand wayes.
And after hauing them vpon him dight,
He tooke that Ladie, and her vp did rayse
Vpon the steed of her owne late dead knight,
So with her marched forth, as she did him behight.

There to their fortune leaue we them awhile, xl


And turne we backe to good Sir Calidore;
Who ere he thence had traueild many a mile,
Came to the place, whereas ye heard afore
This knight, whom Tristram slew, had wounded sore
Another knight in his despiteous pryde;
There he that knight found lying on the flore,
With many wounds full perilous and wyde,
That all his garments, and the grasse in vermeill dyde.

And there beside him sate vpon the ground xli


His wofull Ladie, piteously complayning
With loud laments that most vnluckie stound,
And her sad selfe with carefull hand constrayning
To wype his wounds, and ease their bitter payning.
Which sorie sight when Calidore did vew
With heauie eyne, from teares vneath refrayning,
His mightie hart their mournefull case can rew,
And for their better comfort to them nigher drew.
Then speaking to the Ladie, thus he sayd: xlii
Ye dolefull Dame, let not your griefe empeach
To tell, what cruell hand hath thus arayd
This knight vnarm’d, with so vnknightly breach
Of armes, that if I yet him nigh may reach,
I may auenge him of so foule despight.
The Ladie hearing his so courteous speach,
Gan reare her eyes as to the chearefull light,
And from her sory hart few heauie words forth sight.

In which she shew’d, how that discourteous knight xliii


(Whom Tristram slew) them in that shadow found,
Ioying together in vnblam’d delight,
And him vnarm’d, as now he lay on ground,
Charg’d with his speare and mortally did wound,
Withouten cause, but onely her to reaue
From him, to whom she was for euer bound:
Yet when she fled into that couert greaue,
He her not finding, both them thus nigh dead did leaue.

When Calidore this ruefull storie had xliv


Well vnderstood, he gan of her demand,
What manner wight he was, and how yclad,
Which had this outrage wrought with wicked hand.
She then, like as she best could vnderstand,
Him thus describ’d, to be of stature large,
Clad all in gilden armes, with azure band
Quartred athwart, and bearing in his targe
A Ladie on rough waues, row’d in a sommer barge.

Then gan Sir Calidore to ghesse streight way xlv


By many signes, which she described had,
That this was he, whom Tristram earst did slay,
And to her said; Dame be no longer sad:
For he, that hath your Knight so ill bestad,
Is now him selfe in much more wretched plight;
These eyes him saw vpon the cold earth sprad,
The meede of his desert for that despight,
Which to your selfe he wrought, and to your loued knight.

Therefore faire Lady lay aside this griefe, xlvi


Which ye haue gathered to your gentle hart,
For that displeasure; and thinke what reliefe
Were best deuise for this your louers smart,
And how ye may him hence, and to what part
Conuay to be recur’d. She thankt him deare,
Both for that newes he did to her impart,
And for the courteous care, which he did beare
Both to her loue, and to her selfe in that sad dreare.

Yet could she not deuise by any wit, xlvii


How thence she might conuay him to some place.
For him to trouble she it thought vnfit,
That was a straunger to her wretched case;
And him to beare, she thought it thing too base.
Which when as he perceiu’d, he thus bespake;
Faire Lady let it not you seeme disgrace,
To beare this burden on your dainty backe;
My selfe will beare a part, coportion of your packe.

So off he did his shield, and downeward layd xlviii


Vpon the ground, like to an hollow beare;
And powring balme, which he had long puruayd,
Into his wounds, him vp thereon did reare,
And twixt them both with parted paines did beare,
Twixt life and death, not knowing what was donne.
Thence they him carried to a Castle neare,
In which a worthy auncient Knight did wonne:
Where what ensu’d, shall in next Canto be begonne.

FOOTNOTES:
[415] iii 2 deed and word] act and deed 1596
[416] 3 eyes] eares edd.
[417] 4 eares] eyes edd.
[418] v 7 lincolne 1596
[419] vi 7 launce 1609
[420] vii 2 what 1596
[421] viii 1 him 1596
[422] ix 7 enranging 1609
[423] xiv 3 Sayd] Staid 1609
[424] neither 1596, 1609
[425] xv 8 since] sith 1609
[426] xvi 5 iolliment, 1596
[427] xix 6 hot 1609
[428] xxii 6 Punching 1609
[429] xxvii 1 may 1596
[430] xxx 6 wrong 1596
[431] xxxiii 2 sildome 1609
[432] 7 since] sith 1609
[433] xxxiv 4 faire 1596
[434] xxxvii 6 drad 1609
[435] xxxix 2 implements] ornaments 1609
Cant. III.

Calidore brings Priscilla home,


Pursues the Blatant Beast:
Saues Serena whilest Calepine
By Turpine is opprest.

True is, that whilome that good Poet sayd, i


The gentle minde by gentle deeds is knowne.
For a man by nothing is so well bewrayd,
As by his manners, in which plaine is showne
Of what degree and what race he is growne.
For seldome seene, a trotting Stalion get
An ambling Colt, that is his proper owne:
So seldome seene, that one in basenesse set
Doth noble courage shew, with curteous manners met.

But euermore contrary hath bene tryde, ii


That gentle bloud will gentle manners breed;
As well may be in Calidore descryde,
By late ensample of that courteous deed,
Done to that wounded Knight in his great need,
Whom on his backe he bore, till he him brought
Vnto the Castle where they had decreed.
There of the Knight, the which that Castle ought,
To make abode that night he greatly was besought.

He was to weete a man of full ripe yeares, iii


That in his youth had beene of mickle might,
And borne great sway in armes amongst his peares:
But now weake age had dimd his candle light.
Yet was he courteous still to euery wight,
And loued all that did to armes incline,
And was the father of that wounded Knight,
Whom Calidore thus carried on his chine,
And Aldus was his name, and his sonnes Aladine.

Who when he saw his sonne so ill bedight, iv


With bleeding wounds, brought home vpon a Beare,
By a faire Lady, and a straunger Knight,
Was inly touched with compassion deare,
And deare affection of so dolefull[436] dreare,
That he these words burst forth; Ah sory boy,
Is this the hope that to my hoary heare
Thou brings? aie me, is this the timely ioy,
Which I expected long, now turnd to sad annoy?

Such is the weakenesse of all mortall hope; v


So tickle is the state of earthly things,
That ere they come vnto their aymed scope,
They fall too short of our fraile reckonings,
And bring vs bale and bitter sorrowings,
In stead of comfort, which we should embrace:
This is the state of Keasars and of Kings.
Let none therefore, that is in meaner place,
Too greatly grieue at any his vnlucky case.

So well and wisely did that good old Knight vi


Temper his griefe, and turned it to cheare,
To cheare his guests, whom he had stayd that night,
And make their welcome to them well appeare:
That to Sir Calidore was easie geare;
But that faire Lady would be cheard for nought,
But sigh’d and sorrow’d for her louer deare,
And inly did afflict her pensiue thought,
With thinking to what case her name should now be brought.

For she was daughter to a noble Lord, vii


Which dwelt thereby, who sought her to affy
To a great pere; but she did disaccord,
Ne could her liking to his loue apply,
But lou’d this fresh young Knight, who dwelt her ny,
The lusty Aladine, though meaner borne,
And of lesse liuelood and hability,
Yet full of valour, the which did adorne
His meanesse much, and make her th’others riches scorne.

So hauing both found fit occasion, viii


They met together in that luckelesse glade;
Where that proud Knight in his presumption
The gentle Aladine did earst inuade,
Being vnarm’d, and set in secret shade.
Whereof she now bethinking, gan t’aduize,
How great a hazard she at earst had made
Of her good fame, and further gan deuize,
How she the blame might salue with coloured disguize.

But Calidore with all good courtesie ix


Fain’d her to frolicke, and to put away
The pensiue fit of her melancholie;
And that old Knight by all meanes did assay,
To make them both as merry as he may.
So they the euening past, till time of rest,
When Calidore in seemly good array
Vnto his bowre was brought, and there vndrest,
Did sleepe all night through weary trauell of his quest.
But faire Priscilla (so that Lady hight) x
Would to no[437] bed, nor take no kindely sleepe,
But by her wounded loue did watch all night,
And all the night for bitter anguish weepe,
And with her teares his wounds did wash and steepe.
So well she washt them, and so well she wacht him,
That of the deadly swound, in which full deepe
He drenched was, she at the length dispacht him,
And droue away the stound, which mortally attacht him.

The morrow next, when day gan to vplooke, xi


He also gan vplooke with drery eye,
Like one that out of deadly dreame awooke:
Where when he saw his faire Priscilla by,
He deepely sigh’d[438], and groaned inwardly,
To thinke of this ill state, in which she stood,
To which she for his sake had weetingly
Now brought her selfe, and blam’d her noble blood:
For first, next after life, he tendered her good.

Which she perceiuing, did with plenteous teares xii


His care more then her owne compassionate,
Forgetfull of her owne, to minde his feares:
So both conspiring, gan to intimate
Each others griefe with zeale affectionate,
And twixt them twaine with equall care to cast,
How to saue whole her hazarded estate;
For which the onely helpe now left them last
Seem’d to be Calidore: all other helpes were past.

Him they did deeme, as sure to them he seemed, xiii


A courteous Knight, and full of faithfull trust:
Therefore to him their cause they best esteemed
Whole to commit, and to his dealing iust.
Earely, so soone as Titans beames forth brust
Through the thicke clouds, in which they steeped lay
All night in darkenesse, duld with yron rust,[439]
Calidore rising vp as fresh as day,
Gan freshly him addresse vnto his former way.

But first him seemed fit, that wounded Knight xiv


To visite, after this nights perillous passe,
And to salute him, if he were in plight,
And eke that Lady his faire louely lasse.
There he him found much better then he was,
And moued speach to him of things of course,
The anguish of his paine to ouerpasse:
Mongst which he namely did to him discourse,
Of former daies mishap, his sorrowes wicked sourse.

Of which occasion Aldine taking hold, xv


Gan breake to him the fortunes of his loue,
And all his disaduentures to vnfold;
That Calidore it dearly deepe did moue.
In th’end his kyndly courtesie to proue,
He him by all the bands of loue besought,
And as it mote a faithfull friend behoue,
To safeconduct his loue, and not for ought
To leaue, till to her fathers house he had her brought.

Sir Calidore his faith thereto did plight, xvi


It to performe: so after little stay,
That she her selfe had to the iourney dight,
He passed forth with her in faire array,
Fearelesse, who ought did thinke, or ought did say,
Sith his own thought he knew most cleare from wite.
So as they past together on their way,
He can deuize this counter-cast of slight,
To giue faire colour to that Ladies cause in sight.

Streight to the carkasse of that Knight he went, xvii


The cause of all this euill, who was slaine

You might also like