[MediaWiki-commits] [Gerrit] Simplify getattr/setattr magic - change (thumbor/proxy-engine)

2015-12-16 Thread jenkins-bot (Code Review)
jenkins-bot has submitted this change and it was merged.

Change subject: Simplify getattr/setattr magic
..


Simplify getattr/setattr magic

By whitelisting local attributes, code is a lot less verbose

Bug: T120566
Change-Id: I7b49b76d48896f8708665e3ef6abac6e224e1504
---
M wikimedia_thumbor_proxy_engine/__init__.py
1 file changed, 44 insertions(+), 31 deletions(-)

Approvals:
  Ori.livneh: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/wikimedia_thumbor_proxy_engine/__init__.py 
b/wikimedia_thumbor_proxy_engine/__init__.py
index 5c30b80..dc52da4 100644
--- a/wikimedia_thumbor_proxy_engine/__init__.py
+++ b/wikimedia_thumbor_proxy_engine/__init__.py
@@ -22,8 +22,13 @@
 def __init__(self, context):
 engines = context.config.PROXY_ENGINE_ENGINES
 
-object.__setattr__(self, 'context', context)
-object.__setattr__(self, 'engines', engines)
+# Create an object that will store local values
+# Setting it this way avoids hitting the __setattr__
+# proxying
+super(Engine, self).__setattr__('lcl', {})
+
+self.lcl['context'] = context
+self.lcl['engines'] = engines
 
 for engine in engines:
 self.init_engine(context, engine)
@@ -31,17 +36,17 @@
 def init_engine(self, context, module):
 mod = importlib.import_module(module)
 klass = getattr(mod, 'Engine')
-object.__setattr__(self, module, klass(context))
+
+self.lcl[module] = klass(context)
 
 def select_engine(self):
-buffer = object.__getattribute__(self, 'buffer')
-extension = object.__getattribute__(self, 'extension')
-engines = object.__getattribute__(self, 'engines')
-
-for enginename in engines:
-engine = object.__getattribute__(self, enginename)
+for enginename in self.lcl['engines']:
+engine = self.lcl[enginename]
 try:
-if engine.should_run(extension, buffer):
+if engine.should_run(
+self.lcl['extension'],
+self.lcl['buffer']
+):
 return enginename
 
 # Not implementing should_run means that the engine
@@ -51,39 +56,40 @@
 except AttributeError:
 return enginename
 
-raise Exception('Unable to find a suitable engine, tried %r' % engines)
+raise Exception(
+'Unable to find a suitable engine, tried %r' % self.lcl['engines']
+)
 
 # This is our entry point for the proxy, it's the first call to the engine
 def load(self, buffer, extension):
-object.__setattr__(self, 'start', datetime.datetime.now())
+self.lcl['start'] = datetime.datetime.now()
 
 # buffer and extension are needed by select_engine
-object.__setattr__(self, 'extension', extension)
-object.__setattr__(self, 'buffer', buffer)
+self.lcl['extension'] = extension
+self.lcl['buffer'] = buffer
 
 # Now that we'll select the right engine, let's initialize it
-context = object.__getattribute__(self, 'context')
-engine = getattr(self, 'select_engine')()
-context.request_handler.set_header('Engine', engine)
+self.lcl['context'].request_handler.set_header(
+'Engine',
+self.select_engine()
+)
 
-super(Engine, self).__init__(context)
+super(Engine, self).__init__(self.lcl['context'])
 super(Engine, self).load(buffer, extension)
 
 def __getattr__(self, name):
-engine = getattr(self, 'select_engine')()
-
-return getattr(object.__getattribute__(self, engine), name)
+return getattr(self.lcl[self.select_engine()], name)
 
 def __delattr__(self, name):
-engine = self.select_engine()
-return delattr(object.__getattribute__(self, engine), name)
+return delattr(self.lcl[self.select_engine()], name)
 
 def __setattr__(self, name, value):
-engine = self.select_engine()
-return setattr(object.__getattribute__(self, engine), name, value)
+return setattr(self.lcl[self.select_engine()], name, value)
 
 # The following have to be redefined because their fallbacks in BaseEngine
 # don't have the right amount of parameters
+# They call __getattr__ because the calls still need to be proxied
+# (otherwise they would just loop back to their own definition right here)
 def create_image(self, buffer):
 return self.__getattr__('create_image')(buffer)
 
@@ -99,13 +105,20 @@
 ret = self.__getattr__('read')(extension, quality)
 
 finish = datetime.datetime.now()
-start = object.__getattribute__(self, 'start')
-context = object.__getattribute__(self, 'context')
-engine = getattr(self, 'select_engine')()
-duration = (finish - start).total_seconds() 

[MediaWiki-commits] [Gerrit] Simplify getattr/setattr magic - change (thumbor/proxy-engine)

2015-12-06 Thread Gilles (Code Review)
Gilles has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/257189

Change subject: Simplify getattr/setattr magic
..

Simplify getattr/setattr magic

By whitelisting local attributes, code is a lot less verbose

Bug: T120566
Change-Id: I7b49b76d48896f8708665e3ef6abac6e224e1504
---
M wikimedia_thumbor_proxy_engine/__init__.py
1 file changed, 57 insertions(+), 37 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/thumbor/proxy-engine 
refs/changes/89/257189/1

diff --git a/wikimedia_thumbor_proxy_engine/__init__.py 
b/wikimedia_thumbor_proxy_engine/__init__.py
index 5c30b80..01e4b75 100644
--- a/wikimedia_thumbor_proxy_engine/__init__.py
+++ b/wikimedia_thumbor_proxy_engine/__init__.py
@@ -17,13 +17,22 @@
 
 from thumbor.engines import BaseEngine
 
+# These attributes aren't to be proxied, they are local to the class
+LOCAL_ATTRIBUTES = [
+'buffer',
+'context',
+'engines',
+'extension',
+'start'
+]
+
 
 class Engine(BaseEngine):
 def __init__(self, context):
 engines = context.config.PROXY_ENGINE_ENGINES
 
-object.__setattr__(self, 'context', context)
-object.__setattr__(self, 'engines', engines)
+self.context = context
+self.engines = engines
 
 for engine in engines:
 self.init_engine(context, engine)
@@ -31,17 +40,15 @@
 def init_engine(self, context, module):
 mod = importlib.import_module(module)
 klass = getattr(mod, 'Engine')
-object.__setattr__(self, module, klass(context))
+LOCAL_ATTRIBUTES.append(module)
+
+setattr(self, module, klass(context))
 
 def select_engine(self):
-buffer = object.__getattribute__(self, 'buffer')
-extension = object.__getattribute__(self, 'extension')
-engines = object.__getattribute__(self, 'engines')
-
-for enginename in engines:
-engine = object.__getattribute__(self, enginename)
+for enginename in self.engines:
+engine = getattr(self, enginename)
 try:
-if engine.should_run(extension, buffer):
+if engine.should_run(self.extension, self.buffer):
 return enginename
 
 # Not implementing should_run means that the engine
@@ -51,72 +58,85 @@
 except AttributeError:
 return enginename
 
-raise Exception('Unable to find a suitable engine, tried %r' % engines)
+raise Exception(
+'Unable to find a suitable engine, tried %r' % self.engines
+)
 
 # This is our entry point for the proxy, it's the first call to the engine
 def load(self, buffer, extension):
-object.__setattr__(self, 'start', datetime.datetime.now())
+self.start = datetime.datetime.now()
 
 # buffer and extension are needed by select_engine
-object.__setattr__(self, 'extension', extension)
-object.__setattr__(self, 'buffer', buffer)
+self.extension = extension
+self.buffer = buffer
 
 # Now that we'll select the right engine, let's initialize it
-context = object.__getattribute__(self, 'context')
-engine = getattr(self, 'select_engine')()
-context.request_handler.set_header('Engine', engine)
+self.context.request_handler.set_header('Engine', self.select_engine())
 
-super(Engine, self).__init__(context)
+super(Engine, self).__init__(self.context)
 super(Engine, self).load(buffer, extension)
 
 def __getattr__(self, name):
-engine = getattr(self, 'select_engine')()
+# These attributes need to be local to the proxy
+if (name in LOCAL_ATTRIBUTES):
+return super(Engine, self).__getattr__(name)
 
-return getattr(object.__getattribute__(self, engine), name)
+# Any other attributes are to be proxied
+return self.proxy(name)
+
+def proxy(self, name):
+return getattr(getattr(self, self.select_engine()), name)
 
 def __delattr__(self, name):
-engine = self.select_engine()
-return delattr(object.__getattribute__(self, engine), name)
+# These attributes need to be local to the proxy
+if (name in LOCAL_ATTRIBUTES):
+return super(Engine, self).__delattr__(name)
+
+# Any other attributes are to be proxied
+return delattr(getattr(self, self.select_engine()), name)
 
 def __setattr__(self, name, value):
-engine = self.select_engine()
-return setattr(object.__getattribute__(self, engine), name, value)
+# These attributes need to be local to the proxy
+if (name in LOCAL_ATTRIBUTES):
+return super(Engine, self).__setattr__(name, value)
+
+# Any other attributes are to be proxied
+return setattr(getattr(self, self.select_engine()), name, value)
 
 # The following have to be redefined