SlideShare a Scribd company logo
1 of 50
Download to read offline
Hear no evil, see no evil,
patch no evil: Or, how to
monkey-patch safely.
Graham Dumpleton
@GrahamDumpleton
PyCon Australia - August 2016
Decorators are useful!
Decorators are easy to
implement?
Are you sure?
Typical decorator.
def function_wrapper(wrapped):
def _wrapper(*args, **kwargs):
return wrapped(*args, **kwargs)
return _wrapper
@function_wrapper
def function():
pass
This breaks
introspection.
__name__ and __doc__
attributes are not
preserved.
Doesn’t @functools.wraps() help?
import functools
def function_wrapper(wrapped):
@functools.wraps(wrapped)
def _wrapper(*args, **kwargs):
return wrapped(*args, **kwargs)
return _wrapper
@function_wrapper
def function():
pass
No, it doesn’t solve all
problems.
Still issues with: introspection,
wrapping decorators
implemented using descriptors,
and more.
http://blog.dscpl.com.au
Quick Link: Decorators and monkey patching.
Complicated details removed ….
Get all the details at:
Please try not to
implement decorators
yourself.
What is the solution?
Use ‘wrapt’.
Basic decorator.
import wrapt
@wrapt.decorator
def pass_through(wrapped, instance, args, kwargs):
return wrapped(*args, **kwargs)
@pass_through
def function():
pass
Universal decorator.
import wrapt
import inspect
@wrapt.decorator
def universal(wrapped, instance, args, kwargs):
if instance is None:
if inspect.isclass(wrapped):
# Decorator was applied to a class.
return wrapped(*args, **kwargs)
else:
# Decorator was applied to a function or staticmethod.
return wrapped(*args, **kwargs)
else:
if inspect.isclass(instance):
# Decorator was applied to a classmethod.
return wrapped(*args, **kwargs)
else:
# Decorator was applied to an instancemethod.
return wrapped(*args, **kwargs)
Bonus feature of wrapt
if using multithreading.
Synchronise function calls.
from wrapt import synchronized
@synchronized # lock bound to function1
def function1():
pass
@synchronized # lock bound to function2
def function2():
pass
Methods of classes as well.
from wrapt import synchronized
class Class(object):
@synchronized # lock bound to instance of Class
def function_im(self):
pass
@synchronized # lock bound to Class
@classmethod
def function_cm(cls):
pass
@synchronized # lock bound to function_sm
@staticmethod
def function_sm():
pass
Synchronise block of code.
from wrapt import synchronized
class Object(object):
@synchronized
def function_im_1(self):
pass
def function_im_2(self):
with synchronized(self):
pass
def function_im_3(self):
with synchronized(Object):
pass
Don’t trust me when I say
you should use wrapt?
Potential candidate for being
included in the Python
standard library.
So it must be awesome.
Primary purpose of the
wrapt package wasn’t as
way to build decorators.
Primary reason for
existence of wrapt was to
help with monkey patching.
Decorators rely on similar
principles to monkey
patching.
Before decorators.
# python 2.4+
@function_wrapper
def function():
pass
# python 2.3
def function():
pass
function = function_wrapper(function)
Decorators are applied
when code is defined.
Monkey patching is
performed after the fact,
… and can’t use the
decorator syntax
Why monkey patch?
• Fix bugs in code you can’t modify.
• Replace/mock out code for testing.
• Add instrumentation for monitoring.
Monkey patching with wrapt.
# example.py
class Example(object):
def name(self):
return 'name'
# patches.py
import wrapt
def wrapper(wrapped, instance, args, kwargs):
return wrapped(*args, **kwargs)
from example import Example
wrapt.wrap_function_wrapper(Example, 'name', wrapper)
Don’t patch it yourself.
# patches.py
import wrapt
@wrapt.decorator
def wrapper(wrapped, instance, args, kwargs):
return wrapped(*args, **kwargs)
from example import Example
# DON’T DO THIS.
Example.name = wrapper(Example.name)
Direct patching of
methods breaks in
certain corner cases.
Let wrapt apply the
wrapper for you.
Avoiding imports.
# patches.py
import wrapt
@wrapt.patch_function_wrapper('example', 'Example.name')
def wrapper(wrapped, instance, args, kwargs):
return wrapped(*args, **kwargs)
What about testing,
where we do not want
permanent patches?
Mock alternative.
# example.py
class Storage(object):
def lookup(self, key):
return 'value'
def clear(self):
pass
# tests.py
import wrapt
@wrapt.transient_function_wrapper('example', 'Storage.lookup')
def validate_storage_lookup(wrapped, instance, args, kwargs):
assert len(args) == 1 and not kwargs
return wrapped(*args, **kwargs)
@validate_storage_lookup
def test_method():
storage = Storage()
result = storage.lookup('key')
storage.clear()
What if we need to
intercept access to single
instance of an object?
Transparent object proxy.
# tests.py
import wrapt
class StorageProxy(wrapt.ObjectProxy):
def lookup(self, key):
assert isinstance(key, str)
return self.__wrapped__.lookup(key)
def test_method():
storage = StorageProxy(Storage())
result = storage.lookup(‘key')
storage.clear()
Beware though of
ordering problems when
applying monkey patches.
Import from module.
# example.py
def function():
pass
# module.py
from example import function
# patches.py
import wrapt
@wrapt.patch_function_wrapper('example', 'function')
def wrapper(wrapped, instance, args, kwargs):
return wrapped(*args, **kwargs)
Plus importing and patching
of modules that the
application doesn’t need.
Post import hooks (PEP 369).
# patches.py
import wrapt
def wrapper(wrapped, instance, args, kwargs):
return wrapped(*args, **kwargs)
@wrapt.when_imported('example')
def apply_patches(module):
wrapt.wrap_function_wrapper(module, 'Example.name', wrapper)
Better, but still requires
patches module to be
imported before anything
else in the main
application script.
Need a way to trigger
monkey patches without
modifying application code.
The autowrapt package.
pip install autowrapt
Bundle patches as module.
from setuptools import setup
PATCHES = [
'wsgiref.simple_server = wrapt_wsgiref_debugging:apply_patches'
]
setup(
name = 'wrapt_wsgiref_debugging',
version = '0.1',
py_modules = ['wrapt_wsgiref_debugging'],
entry_points = {‘wrapt_wsgiref_debugging': PATCHES}
)
Patch to time functions.
from __future__ import print_function
from wrapt import wrap_function_wrapper
from timeit import default_timer
def timed_function(wrapped, instance, args, kwargs):
start = default_timer()
print('start', wrapped.__name__)
try:
return wrapped(*args, **kwargs)
finally:
duration = default_timer() - start
print('finish %s %.3fms' % (
wrapped.__name__, duration*1000.0))
def apply_patches(module):
print('patching', module.__name__)
wrap_function_wrapper(module,
'WSGIRequestHandler.handle', timed_function)
Enabling patches.
$ AUTOWRAPT_BOOTSTRAP=wrapt_wsgiref_debugging
$ export AUTOWRAPT_BOOTSTRAP
$ python app.py
patching wsgiref.simple_server
start handle
127.0.0.1 - - [14/Jul/2016 10:18:46] "GET / HTTP/1.1" 200 12
finish handle 1.018ms
Packaging of patches means
they could technically be
shared via PyPi.
Eg: instrumentation for
monitoring.
Reasons to use wrapt.
• Create better decorators.
• Awesome thread synchronisation decorator.
• Safer mechanisms for monkey patching.
Graham.Dumpleton@gmail.com
@GrahamDumpleton
wrapt.readthedocs.io
blog.dscpl.com.au

More Related Content

What's hot

From Message to Cluster: A Realworld Introduction to Kafka Capacity Planning
From Message to Cluster: A Realworld Introduction to Kafka Capacity PlanningFrom Message to Cluster: A Realworld Introduction to Kafka Capacity Planning
From Message to Cluster: A Realworld Introduction to Kafka Capacity Planningconfluent
 
ksqlDB - Stream Processing simplified!
ksqlDB - Stream Processing simplified!ksqlDB - Stream Processing simplified!
ksqlDB - Stream Processing simplified!Guido Schmutz
 
Asynchronous Python A Gentle Introduction
Asynchronous Python A Gentle IntroductionAsynchronous Python A Gentle Introduction
Asynchronous Python A Gentle IntroductionPyData
 
An Introduction to Apache Kafka
An Introduction to Apache KafkaAn Introduction to Apache Kafka
An Introduction to Apache KafkaAmir Sedighi
 
Using Grafana with InfluxDB 2.0 and Flux Lang by Jacob Lisi
Using Grafana with InfluxDB 2.0 and Flux Lang by Jacob LisiUsing Grafana with InfluxDB 2.0 and Flux Lang by Jacob Lisi
Using Grafana with InfluxDB 2.0 and Flux Lang by Jacob LisiInfluxData
 
Monitoring and alerting as code with Terraform and New Relic
Monitoring and alerting as code with Terraform and New RelicMonitoring and alerting as code with Terraform and New Relic
Monitoring and alerting as code with Terraform and New RelicRichard Bullington-McGuire
 
From Paper to Power using Azure Form Recognizer (Azure Sydney UG 2020)
From Paper to Power using Azure Form Recognizer (Azure Sydney UG 2020)From Paper to Power using Azure Form Recognizer (Azure Sydney UG 2020)
From Paper to Power using Azure Form Recognizer (Azure Sydney UG 2020)Jernej Kavka (JK)
 
Kafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presentedKafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presentedSumant Tambe
 
Timeseries - data visualization in Grafana
Timeseries - data visualization in GrafanaTimeseries - data visualization in Grafana
Timeseries - data visualization in GrafanaOCoderFest
 
Infrastructure-as-Code with Pulumi - Better than all the others (like Ansible)?
Infrastructure-as-Code with Pulumi- Better than all the others (like Ansible)?Infrastructure-as-Code with Pulumi- Better than all the others (like Ansible)?
Infrastructure-as-Code with Pulumi - Better than all the others (like Ansible)?Jonas Hecht
 
Python, the Language of Science and Engineering for Engineers
Python, the Language of Science and Engineering for EngineersPython, the Language of Science and Engineering for Engineers
Python, the Language of Science and Engineering for EngineersBoey Pak Cheong
 
Docker, Containers and the Future of Application Delivery
Docker, Containers and the Future of Application DeliveryDocker, Containers and the Future of Application Delivery
Docker, Containers and the Future of Application DeliveryDocker, Inc.
 
Introduction to using google colab
Introduction to using google colabIntroduction to using google colab
Introduction to using google colabali alemi
 

What's hot (20)

From Message to Cluster: A Realworld Introduction to Kafka Capacity Planning
From Message to Cluster: A Realworld Introduction to Kafka Capacity PlanningFrom Message to Cluster: A Realworld Introduction to Kafka Capacity Planning
From Message to Cluster: A Realworld Introduction to Kafka Capacity Planning
 
ksqlDB - Stream Processing simplified!
ksqlDB - Stream Processing simplified!ksqlDB - Stream Processing simplified!
ksqlDB - Stream Processing simplified!
 
Asynchronous Python A Gentle Introduction
Asynchronous Python A Gentle IntroductionAsynchronous Python A Gentle Introduction
Asynchronous Python A Gentle Introduction
 
An Introduction to Apache Kafka
An Introduction to Apache KafkaAn Introduction to Apache Kafka
An Introduction to Apache Kafka
 
Using Grafana with InfluxDB 2.0 and Flux Lang by Jacob Lisi
Using Grafana with InfluxDB 2.0 and Flux Lang by Jacob LisiUsing Grafana with InfluxDB 2.0 and Flux Lang by Jacob Lisi
Using Grafana with InfluxDB 2.0 and Flux Lang by Jacob Lisi
 
Monitoring and alerting as code with Terraform and New Relic
Monitoring and alerting as code with Terraform and New RelicMonitoring and alerting as code with Terraform and New Relic
Monitoring and alerting as code with Terraform and New Relic
 
From Paper to Power using Azure Form Recognizer (Azure Sydney UG 2020)
From Paper to Power using Azure Form Recognizer (Azure Sydney UG 2020)From Paper to Power using Azure Form Recognizer (Azure Sydney UG 2020)
From Paper to Power using Azure Form Recognizer (Azure Sydney UG 2020)
 
Basics of python
Basics of pythonBasics of python
Basics of python
 
Scrum Ceremonies
Scrum CeremoniesScrum Ceremonies
Scrum Ceremonies
 
Kafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presentedKafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presented
 
How to implement Slack
How to implement SlackHow to implement Slack
How to implement Slack
 
Timeseries - data visualization in Grafana
Timeseries - data visualization in GrafanaTimeseries - data visualization in Grafana
Timeseries - data visualization in Grafana
 
Infrastructure-as-Code with Pulumi - Better than all the others (like Ansible)?
Infrastructure-as-Code with Pulumi- Better than all the others (like Ansible)?Infrastructure-as-Code with Pulumi- Better than all the others (like Ansible)?
Infrastructure-as-Code with Pulumi - Better than all the others (like Ansible)?
 
Extreme programming
Extreme programmingExtreme programming
Extreme programming
 
Python
PythonPython
Python
 
Python, the Language of Science and Engineering for Engineers
Python, the Language of Science and Engineering for EngineersPython, the Language of Science and Engineering for Engineers
Python, the Language of Science and Engineering for Engineers
 
Docker, Containers and the Future of Application Delivery
Docker, Containers and the Future of Application DeliveryDocker, Containers and the Future of Application Delivery
Docker, Containers and the Future of Application Delivery
 
Introduction to using google colab
Introduction to using google colabIntroduction to using google colab
Introduction to using google colab
 
Introduction to DevOps
Introduction to DevOpsIntroduction to DevOps
Introduction to DevOps
 
Introduction to Apache Beam
Introduction to Apache BeamIntroduction to Apache Beam
Introduction to Apache Beam
 

Viewers also liked

Jupyterの機能を拡張してみた
Jupyterの機能を拡張してみたJupyterの機能を拡張してみた
Jupyterの機能を拡張してみたtaka400k
 
Data analytics in the cloud with Jupyter notebooks.
Data analytics in the cloud with Jupyter notebooks.Data analytics in the cloud with Jupyter notebooks.
Data analytics in the cloud with Jupyter notebooks.Graham Dumpleton
 
HadoopCon 2016 - 用 Jupyter Notebook Hold 住一個上線 Spark Machine Learning 專案實戰
HadoopCon 2016  - 用 Jupyter Notebook Hold 住一個上線 Spark  Machine Learning 專案實戰HadoopCon 2016  - 用 Jupyter Notebook Hold 住一個上線 Spark  Machine Learning 專案實戰
HadoopCon 2016 - 用 Jupyter Notebook Hold 住一個上線 Spark Machine Learning 專案實戰Wayne Chen
 
Introduction to IPython & Jupyter Notebooks
Introduction to IPython & Jupyter NotebooksIntroduction to IPython & Jupyter Notebooks
Introduction to IPython & Jupyter NotebooksEueung Mulyana
 
[數學、邏輯與人生] 05 數,三聲數
[數學、邏輯與人生] 05 數,三聲數[數學、邏輯與人生] 05 數,三聲數
[數學、邏輯與人生] 05 數,三聲數Yen-lung Tsai
 
Jupyter, A Platform for Data Science at Scale
Jupyter, A Platform for Data Science at ScaleJupyter, A Platform for Data Science at Scale
Jupyter, A Platform for Data Science at ScaleMatthias Bussonnier
 
D3 in Jupyter : PyData NYC 2015
D3 in Jupyter : PyData NYC 2015D3 in Jupyter : PyData NYC 2015
D3 in Jupyter : PyData NYC 2015Brian Coffey
 
Data science apps: beyond notebooks
Data science apps: beyond notebooksData science apps: beyond notebooks
Data science apps: beyond notebooksNatalino Busa
 
Jupyter NotebookとChainerで楽々Deep Learning
Jupyter NotebookとChainerで楽々Deep LearningJupyter NotebookとChainerで楽々Deep Learning
Jupyter NotebookとChainerで楽々Deep LearningJun-ya Norimatsu
 
Jupyter for Education: Beyond Gutenberg and Erasmus
Jupyter for Education: Beyond Gutenberg and ErasmusJupyter for Education: Beyond Gutenberg and Erasmus
Jupyter for Education: Beyond Gutenberg and ErasmusPaco Nathan
 
Jupyter Kernel: How to Speak in Another Language
Jupyter Kernel: How to Speak in Another LanguageJupyter Kernel: How to Speak in Another Language
Jupyter Kernel: How to Speak in Another LanguageWey-Han Liaw
 
APACHE TOREE: A JUPYTER KERNEL FOR SPARK by Marius van Niekerk
APACHE TOREE: A JUPYTER KERNEL FOR SPARK by Marius van NiekerkAPACHE TOREE: A JUPYTER KERNEL FOR SPARK by Marius van Niekerk
APACHE TOREE: A JUPYTER KERNEL FOR SPARK by Marius van NiekerkSpark Summit
 
QGIS第三講—地圖展示與匯出
QGIS第三講—地圖展示與匯出QGIS第三講—地圖展示與匯出
QGIS第三講—地圖展示與匯出Chengtao Lin
 
Jupyter 簡介—互動式的筆記本系統
Jupyter 簡介—互動式的筆記本系統Jupyter 簡介—互動式的筆記本系統
Jupyter 簡介—互動式的筆記本系統Chengtao Lin
 

Viewers also liked (16)

Jupyterの機能を拡張してみた
Jupyterの機能を拡張してみたJupyterの機能を拡張してみた
Jupyterの機能を拡張してみた
 
Data analytics in the cloud with Jupyter notebooks.
Data analytics in the cloud with Jupyter notebooks.Data analytics in the cloud with Jupyter notebooks.
Data analytics in the cloud with Jupyter notebooks.
 
Days on Jupyter
Days on JupyterDays on Jupyter
Days on Jupyter
 
HadoopCon 2016 - 用 Jupyter Notebook Hold 住一個上線 Spark Machine Learning 專案實戰
HadoopCon 2016  - 用 Jupyter Notebook Hold 住一個上線 Spark  Machine Learning 專案實戰HadoopCon 2016  - 用 Jupyter Notebook Hold 住一個上線 Spark  Machine Learning 專案實戰
HadoopCon 2016 - 用 Jupyter Notebook Hold 住一個上線 Spark Machine Learning 專案實戰
 
Introduction to IPython & Jupyter Notebooks
Introduction to IPython & Jupyter NotebooksIntroduction to IPython & Jupyter Notebooks
Introduction to IPython & Jupyter Notebooks
 
[數學、邏輯與人生] 05 數,三聲數
[數學、邏輯與人生] 05 數,三聲數[數學、邏輯與人生] 05 數,三聲數
[數學、邏輯與人生] 05 數,三聲數
 
Jupyter, A Platform for Data Science at Scale
Jupyter, A Platform for Data Science at ScaleJupyter, A Platform for Data Science at Scale
Jupyter, A Platform for Data Science at Scale
 
D3 in Jupyter : PyData NYC 2015
D3 in Jupyter : PyData NYC 2015D3 in Jupyter : PyData NYC 2015
D3 in Jupyter : PyData NYC 2015
 
Data science apps: beyond notebooks
Data science apps: beyond notebooksData science apps: beyond notebooks
Data science apps: beyond notebooks
 
Jupyter NotebookとChainerで楽々Deep Learning
Jupyter NotebookとChainerで楽々Deep LearningJupyter NotebookとChainerで楽々Deep Learning
Jupyter NotebookとChainerで楽々Deep Learning
 
Jupyter for Education: Beyond Gutenberg and Erasmus
Jupyter for Education: Beyond Gutenberg and ErasmusJupyter for Education: Beyond Gutenberg and Erasmus
Jupyter for Education: Beyond Gutenberg and Erasmus
 
Clean Code in Jupyter notebook
Clean Code in Jupyter notebookClean Code in Jupyter notebook
Clean Code in Jupyter notebook
 
Jupyter Kernel: How to Speak in Another Language
Jupyter Kernel: How to Speak in Another LanguageJupyter Kernel: How to Speak in Another Language
Jupyter Kernel: How to Speak in Another Language
 
APACHE TOREE: A JUPYTER KERNEL FOR SPARK by Marius van Niekerk
APACHE TOREE: A JUPYTER KERNEL FOR SPARK by Marius van NiekerkAPACHE TOREE: A JUPYTER KERNEL FOR SPARK by Marius van Niekerk
APACHE TOREE: A JUPYTER KERNEL FOR SPARK by Marius van Niekerk
 
QGIS第三講—地圖展示與匯出
QGIS第三講—地圖展示與匯出QGIS第三講—地圖展示與匯出
QGIS第三講—地圖展示與匯出
 
Jupyter 簡介—互動式的筆記本系統
Jupyter 簡介—互動式的筆記本系統Jupyter 簡介—互動式的筆記本系統
Jupyter 簡介—互動式的筆記本系統
 

Similar to Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.

PyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating DecoratorsPyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating DecoratorsGraham Dumpleton
 
Python mocking intro
Python mocking introPython mocking intro
Python mocking introHans Jones
 
What's New In Python 2.5
What's New In Python 2.5What's New In Python 2.5
What's New In Python 2.5Richard Jones
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014Matthias Noback
 
Functions and Modules.pptx
Functions and Modules.pptxFunctions and Modules.pptx
Functions and Modules.pptxAshwini Raut
 
iPhone Seminar Part 2
iPhone Seminar Part 2iPhone Seminar Part 2
iPhone Seminar Part 2NAILBITER
 
DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicGraham Dumpleton
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicNew Relic
 
Control structures functions and modules in python programming
Control structures functions and modules in python programmingControl structures functions and modules in python programming
Control structures functions and modules in python programmingSrinivas Narasegouda
 
Metaprogramming Rails
Metaprogramming RailsMetaprogramming Rails
Metaprogramming RailsJustus Eapen
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumMatthias Noback
 
Effective testing with pytest
Effective testing with pytestEffective testing with pytest
Effective testing with pytestHector Canto
 
python interview prep question , 52 questions
python interview prep question , 52 questionspython interview prep question , 52 questions
python interview prep question , 52 questionsgokul174578
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 

Similar to Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely. (20)

PyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating DecoratorsPyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating Decorators
 
Andy On Closures
Andy On ClosuresAndy On Closures
Andy On Closures
 
Python mocking intro
Python mocking introPython mocking intro
Python mocking intro
 
Python and You Series
Python and You SeriesPython and You Series
Python and You Series
 
Advance python
Advance pythonAdvance python
Advance python
 
обзор Python
обзор Pythonобзор Python
обзор Python
 
What's New In Python 2.5
What's New In Python 2.5What's New In Python 2.5
What's New In Python 2.5
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 
Functions and Modules.pptx
Functions and Modules.pptxFunctions and Modules.pptx
Functions and Modules.pptx
 
iPhone Seminar Part 2
iPhone Seminar Part 2iPhone Seminar Part 2
iPhone Seminar Part 2
 
DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New Relic
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New Relic
 
Control structures functions and modules in python programming
Control structures functions and modules in python programmingControl structures functions and modules in python programming
Control structures functions and modules in python programming
 
Django Good Practices
Django Good PracticesDjango Good Practices
Django Good Practices
 
Metaprogramming Rails
Metaprogramming RailsMetaprogramming Rails
Metaprogramming Rails
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup Belgium
 
Effective testing with pytest
Effective testing with pytestEffective testing with pytest
Effective testing with pytest
 
python interview prep question , 52 questions
python interview prep question , 52 questionspython interview prep question , 52 questions
python interview prep question , 52 questions
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 

More from Graham Dumpleton

Implementing a decorator for thread synchronisation.
Implementing a decorator for thread synchronisation.Implementing a decorator for thread synchronisation.
Implementing a decorator for thread synchronisation.Graham Dumpleton
 
“warpdrive”, making Python web application deployment magically easy.
“warpdrive”, making Python web application deployment magically easy.“warpdrive”, making Python web application deployment magically easy.
“warpdrive”, making Python web application deployment magically easy.Graham Dumpleton
 
OpenShift, Docker, Kubernetes: The next generation of PaaS
OpenShift, Docker, Kubernetes: The next generation of PaaSOpenShift, Docker, Kubernetes: The next generation of PaaS
OpenShift, Docker, Kubernetes: The next generation of PaaSGraham Dumpleton
 
Automated Image Builds in OpenShift and Kubernetes
Automated Image Builds in OpenShift and KubernetesAutomated Image Builds in OpenShift and Kubernetes
Automated Image Builds in OpenShift and KubernetesGraham Dumpleton
 
PyCon HK 2015 - Monitoring the performance of python web applications
PyCon HK 2015 -  Monitoring the performance of python web applicationsPyCon HK 2015 -  Monitoring the performance of python web applications
PyCon HK 2015 - Monitoring the performance of python web applicationsGraham Dumpleton
 
PyCon AU 2015 - Using benchmarks to understand how wsgi servers work
PyCon AU 2015  - Using benchmarks to understand how wsgi servers workPyCon AU 2015  - Using benchmarks to understand how wsgi servers work
PyCon AU 2015 - Using benchmarks to understand how wsgi servers workGraham Dumpleton
 
PyCon US 2013 Making Apache suck less for hosting Python web applications
PyCon US 2013 Making Apache suck less for hosting Python web applicationsPyCon US 2013 Making Apache suck less for hosting Python web applications
PyCon US 2013 Making Apache suck less for hosting Python web applicationsGraham Dumpleton
 
PyCon AU 2010 - Getting Started With Apache/mod_wsgi.
PyCon AU 2010 - Getting Started With Apache/mod_wsgi.PyCon AU 2010 - Getting Started With Apache/mod_wsgi.
PyCon AU 2010 - Getting Started With Apache/mod_wsgi.Graham Dumpleton
 
PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2Graham Dumpleton
 
PyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsPyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsGraham Dumpleton
 
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance TuningPyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance TuningGraham Dumpleton
 

More from Graham Dumpleton (12)

Implementing a decorator for thread synchronisation.
Implementing a decorator for thread synchronisation.Implementing a decorator for thread synchronisation.
Implementing a decorator for thread synchronisation.
 
Not Tom Eastman
Not Tom EastmanNot Tom Eastman
Not Tom Eastman
 
“warpdrive”, making Python web application deployment magically easy.
“warpdrive”, making Python web application deployment magically easy.“warpdrive”, making Python web application deployment magically easy.
“warpdrive”, making Python web application deployment magically easy.
 
OpenShift, Docker, Kubernetes: The next generation of PaaS
OpenShift, Docker, Kubernetes: The next generation of PaaSOpenShift, Docker, Kubernetes: The next generation of PaaS
OpenShift, Docker, Kubernetes: The next generation of PaaS
 
Automated Image Builds in OpenShift and Kubernetes
Automated Image Builds in OpenShift and KubernetesAutomated Image Builds in OpenShift and Kubernetes
Automated Image Builds in OpenShift and Kubernetes
 
PyCon HK 2015 - Monitoring the performance of python web applications
PyCon HK 2015 -  Monitoring the performance of python web applicationsPyCon HK 2015 -  Monitoring the performance of python web applications
PyCon HK 2015 - Monitoring the performance of python web applications
 
PyCon AU 2015 - Using benchmarks to understand how wsgi servers work
PyCon AU 2015  - Using benchmarks to understand how wsgi servers workPyCon AU 2015  - Using benchmarks to understand how wsgi servers work
PyCon AU 2015 - Using benchmarks to understand how wsgi servers work
 
PyCon US 2013 Making Apache suck less for hosting Python web applications
PyCon US 2013 Making Apache suck less for hosting Python web applicationsPyCon US 2013 Making Apache suck less for hosting Python web applications
PyCon US 2013 Making Apache suck less for hosting Python web applications
 
PyCon AU 2010 - Getting Started With Apache/mod_wsgi.
PyCon AU 2010 - Getting Started With Apache/mod_wsgi.PyCon AU 2010 - Getting Started With Apache/mod_wsgi.
PyCon AU 2010 - Getting Started With Apache/mod_wsgi.
 
PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2
 
PyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsPyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web Applications
 
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance TuningPyCon US 2012 - Web Server Bottlenecks and Performance Tuning
PyCon US 2012 - Web Server Bottlenecks and Performance Tuning
 

Recently uploaded

Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...Lisi Hocke
 
Transformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksTransformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksJinanKordab
 
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024MulesoftMunichMeetup
 
The Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationThe Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationElement34
 
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...Andrea Goulet
 
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
^Clinic ^%[+27788225528*Abortion Pills For Sale In hararekasambamuno
 
Encryption Recap: A Refresher on Key Concepts
Encryption Recap: A Refresher on Key ConceptsEncryption Recap: A Refresher on Key Concepts
Encryption Recap: A Refresher on Key Conceptsthomashtkim
 
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...naitiksharma1124
 
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdfThe Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdfkalichargn70th171
 
Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?Maxim Salnikov
 
Workshop - Architecting Innovative Graph Applications- GraphSummit Milan
Workshop -  Architecting Innovative Graph Applications- GraphSummit MilanWorkshop -  Architecting Innovative Graph Applications- GraphSummit Milan
Workshop - Architecting Innovative Graph Applications- GraphSummit MilanNeo4j
 
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
Auto Affiliate  AI Earns First Commission in 3 Hours..pdfAuto Affiliate  AI Earns First Commission in 3 Hours..pdf
Auto Affiliate AI Earns First Commission in 3 Hours..pdfSelfMade bd
 
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024SimonedeGijt
 
^Clinic ^%[+27788225528*Abortion Pills For Sale In soweto
^Clinic ^%[+27788225528*Abortion Pills For Sale In soweto^Clinic ^%[+27788225528*Abortion Pills For Sale In soweto
^Clinic ^%[+27788225528*Abortion Pills For Sale In sowetokasambamuno
 
Microsoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdfMicrosoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdfMarkus Moeller
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletAndrea Goulet
 
BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AIAGATSoftware
 
A Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfA Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfICS
 
Weeding your micro service landscape.pdf
Weeding your micro service landscape.pdfWeeding your micro service landscape.pdf
Weeding your micro service landscape.pdftimtebeek1
 

Recently uploaded (20)

Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
 
Transformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksTransformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with Links
 
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
 
The Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationThe Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test Automation
 
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
 
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
 
Encryption Recap: A Refresher on Key Concepts
Encryption Recap: A Refresher on Key ConceptsEncryption Recap: A Refresher on Key Concepts
Encryption Recap: A Refresher on Key Concepts
 
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
 
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdfThe Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
The Evolution of Web App Testing_ An Ultimate Guide to Future Trends.pdf
 
Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?
 
Workshop - Architecting Innovative Graph Applications- GraphSummit Milan
Workshop -  Architecting Innovative Graph Applications- GraphSummit MilanWorkshop -  Architecting Innovative Graph Applications- GraphSummit Milan
Workshop - Architecting Innovative Graph Applications- GraphSummit Milan
 
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
Auto Affiliate  AI Earns First Commission in 3 Hours..pdfAuto Affiliate  AI Earns First Commission in 3 Hours..pdf
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
 
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
 
^Clinic ^%[+27788225528*Abortion Pills For Sale In soweto
^Clinic ^%[+27788225528*Abortion Pills For Sale In soweto^Clinic ^%[+27788225528*Abortion Pills For Sale In soweto
^Clinic ^%[+27788225528*Abortion Pills For Sale In soweto
 
Microsoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdfMicrosoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdf
 
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea Goulet
 
BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AI
 
A Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfA Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdf
 
Weeding your micro service landscape.pdf
Weeding your micro service landscape.pdfWeeding your micro service landscape.pdf
Weeding your micro service landscape.pdf
 

Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.

  • 1. Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely. Graham Dumpleton @GrahamDumpleton PyCon Australia - August 2016
  • 3. Decorators are easy to implement?
  • 5. Typical decorator. def function_wrapper(wrapped): def _wrapper(*args, **kwargs): return wrapped(*args, **kwargs) return _wrapper @function_wrapper def function(): pass
  • 7. __name__ and __doc__ attributes are not preserved.
  • 8. Doesn’t @functools.wraps() help? import functools def function_wrapper(wrapped): @functools.wraps(wrapped) def _wrapper(*args, **kwargs): return wrapped(*args, **kwargs) return _wrapper @function_wrapper def function(): pass
  • 9. No, it doesn’t solve all problems.
  • 10. Still issues with: introspection, wrapping decorators implemented using descriptors, and more.
  • 11. http://blog.dscpl.com.au Quick Link: Decorators and monkey patching. Complicated details removed …. Get all the details at:
  • 12. Please try not to implement decorators yourself.
  • 13. What is the solution?
  • 15. Basic decorator. import wrapt @wrapt.decorator def pass_through(wrapped, instance, args, kwargs): return wrapped(*args, **kwargs) @pass_through def function(): pass
  • 16. Universal decorator. import wrapt import inspect @wrapt.decorator def universal(wrapped, instance, args, kwargs): if instance is None: if inspect.isclass(wrapped): # Decorator was applied to a class. return wrapped(*args, **kwargs) else: # Decorator was applied to a function or staticmethod. return wrapped(*args, **kwargs) else: if inspect.isclass(instance): # Decorator was applied to a classmethod. return wrapped(*args, **kwargs) else: # Decorator was applied to an instancemethod. return wrapped(*args, **kwargs)
  • 17. Bonus feature of wrapt if using multithreading.
  • 18. Synchronise function calls. from wrapt import synchronized @synchronized # lock bound to function1 def function1(): pass @synchronized # lock bound to function2 def function2(): pass
  • 19. Methods of classes as well. from wrapt import synchronized class Class(object): @synchronized # lock bound to instance of Class def function_im(self): pass @synchronized # lock bound to Class @classmethod def function_cm(cls): pass @synchronized # lock bound to function_sm @staticmethod def function_sm(): pass
  • 20. Synchronise block of code. from wrapt import synchronized class Object(object): @synchronized def function_im_1(self): pass def function_im_2(self): with synchronized(self): pass def function_im_3(self): with synchronized(Object): pass
  • 21. Don’t trust me when I say you should use wrapt?
  • 22. Potential candidate for being included in the Python standard library. So it must be awesome.
  • 23. Primary purpose of the wrapt package wasn’t as way to build decorators.
  • 24. Primary reason for existence of wrapt was to help with monkey patching.
  • 25. Decorators rely on similar principles to monkey patching.
  • 26. Before decorators. # python 2.4+ @function_wrapper def function(): pass # python 2.3 def function(): pass function = function_wrapper(function)
  • 27. Decorators are applied when code is defined.
  • 28. Monkey patching is performed after the fact, … and can’t use the decorator syntax
  • 29. Why monkey patch? • Fix bugs in code you can’t modify. • Replace/mock out code for testing. • Add instrumentation for monitoring.
  • 30. Monkey patching with wrapt. # example.py class Example(object): def name(self): return 'name' # patches.py import wrapt def wrapper(wrapped, instance, args, kwargs): return wrapped(*args, **kwargs) from example import Example wrapt.wrap_function_wrapper(Example, 'name', wrapper)
  • 31. Don’t patch it yourself. # patches.py import wrapt @wrapt.decorator def wrapper(wrapped, instance, args, kwargs): return wrapped(*args, **kwargs) from example import Example # DON’T DO THIS. Example.name = wrapper(Example.name)
  • 32. Direct patching of methods breaks in certain corner cases. Let wrapt apply the wrapper for you.
  • 33. Avoiding imports. # patches.py import wrapt @wrapt.patch_function_wrapper('example', 'Example.name') def wrapper(wrapped, instance, args, kwargs): return wrapped(*args, **kwargs)
  • 34. What about testing, where we do not want permanent patches?
  • 35. Mock alternative. # example.py class Storage(object): def lookup(self, key): return 'value' def clear(self): pass # tests.py import wrapt @wrapt.transient_function_wrapper('example', 'Storage.lookup') def validate_storage_lookup(wrapped, instance, args, kwargs): assert len(args) == 1 and not kwargs return wrapped(*args, **kwargs) @validate_storage_lookup def test_method(): storage = Storage() result = storage.lookup('key') storage.clear()
  • 36. What if we need to intercept access to single instance of an object?
  • 37. Transparent object proxy. # tests.py import wrapt class StorageProxy(wrapt.ObjectProxy): def lookup(self, key): assert isinstance(key, str) return self.__wrapped__.lookup(key) def test_method(): storage = StorageProxy(Storage()) result = storage.lookup(‘key') storage.clear()
  • 38. Beware though of ordering problems when applying monkey patches.
  • 39. Import from module. # example.py def function(): pass # module.py from example import function # patches.py import wrapt @wrapt.patch_function_wrapper('example', 'function') def wrapper(wrapped, instance, args, kwargs): return wrapped(*args, **kwargs)
  • 40. Plus importing and patching of modules that the application doesn’t need.
  • 41. Post import hooks (PEP 369). # patches.py import wrapt def wrapper(wrapped, instance, args, kwargs): return wrapped(*args, **kwargs) @wrapt.when_imported('example') def apply_patches(module): wrapt.wrap_function_wrapper(module, 'Example.name', wrapper)
  • 42. Better, but still requires patches module to be imported before anything else in the main application script.
  • 43. Need a way to trigger monkey patches without modifying application code.
  • 44. The autowrapt package. pip install autowrapt
  • 45. Bundle patches as module. from setuptools import setup PATCHES = [ 'wsgiref.simple_server = wrapt_wsgiref_debugging:apply_patches' ] setup( name = 'wrapt_wsgiref_debugging', version = '0.1', py_modules = ['wrapt_wsgiref_debugging'], entry_points = {‘wrapt_wsgiref_debugging': PATCHES} )
  • 46. Patch to time functions. from __future__ import print_function from wrapt import wrap_function_wrapper from timeit import default_timer def timed_function(wrapped, instance, args, kwargs): start = default_timer() print('start', wrapped.__name__) try: return wrapped(*args, **kwargs) finally: duration = default_timer() - start print('finish %s %.3fms' % ( wrapped.__name__, duration*1000.0)) def apply_patches(module): print('patching', module.__name__) wrap_function_wrapper(module, 'WSGIRequestHandler.handle', timed_function)
  • 47. Enabling patches. $ AUTOWRAPT_BOOTSTRAP=wrapt_wsgiref_debugging $ export AUTOWRAPT_BOOTSTRAP $ python app.py patching wsgiref.simple_server start handle 127.0.0.1 - - [14/Jul/2016 10:18:46] "GET / HTTP/1.1" 200 12 finish handle 1.018ms
  • 48. Packaging of patches means they could technically be shared via PyPi. Eg: instrumentation for monitoring.
  • 49. Reasons to use wrapt. • Create better decorators. • Awesome thread synchronisation decorator. • Safer mechanisms for monkey patching.