Last active
August 21, 2017 09:48
-
-
Save ttsiodras/88f0afc712b4bfc3fe16 to your computer and use it in GitHub Desktop.
I just did something that depending on your viewpoint on coding, is either an insult to God and humanity, or absolutely brilliant.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# I inherited a large code base, where hundreds of code paths end up | |
# calling "common_function_called_in_gazillion_places". | |
# | |
# And the need arose for this function to access the HTTP request's | |
# headers... | |
# | |
# What to do? Refactor all the places leading up to here? In a dynamically | |
# typed language, with no compiler to tell us the places to refactor? | |
# | |
# NO - let's hack the universe instead. | |
def get_the_request(): | |
""" | |
Look up the call stack to see if one of our callers has "self.request" | |
(i.e. the Pyramid request) and if so, return it | |
""" | |
for f in inspect.stack(): | |
if 'self' in f[0].f_locals: | |
self = f[0].f_locals['self'] | |
if hasattr(self, 'request'): | |
return self.request | |
else: | |
return None | |
def common_function_called_in_gazillion_places( variables, action ): | |
... | |
# Get the request from our callers, and extract the IP from it | |
request = get_the_request() | |
if request is not None: | |
ip_addr = request.remote_addr | |
if 'X-Forwarded-For' in request.headers: | |
ip_addr = request.headers['X-Forwarded-For'] | |
if ip_addr not in ['127.0.0.1', 'localhost'] and \ | |
isinstance(ip_addr, (str,unicode)): | |
event_data['context'] = {'ip': ip_addr} | |
.... | |
# TADA!!! | |
# | |
# OK, now I can burn in programmer Hell - for all eternity. |
@ttsiodras I had to do something similar in 2009 for a trac extension, for the same exact reason, so definitely absolutely brilliant, ;) . https://gist.github.com/seanjensengrey/84beab9d6f907c0dc433
Frame hacks are what make Python, Python. See http://farmdev.com/src/secrets/framehack/
Another option would be to put in a fixme into function_called_everywhere
that logs all the invocation points.
def fixme(msg):
print >>sys.stderr,"fixme:" + sys._getframe().f_code.co_filename + ":" + \
sys._getframe().f_back.f_code.co_name + ":" + \
str(sys._getframe().f_back.f_lineno) + ":" + msg
Effectively what you have done is enable dynamic scope for a lexically scoped language. One could also think of dynamic scope as a form of execution context or lightweight dependency injection.
@bertjwregeer Thanks - good to know!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ttsiodras you could probably implement this method as the author has, but add some logging to it, then attempt a find/replace, then periodically check your logs. You should be able to find any calls you missed and replace them over time while retaining some form of backwards compatibility.