Files
edx-platform/common/djangoapps/monkey_patch/__init__.py
stv 86633df3db Monkey patch 'django.utils.translation'
Modify Django's translation library, such that the gettext family of
functions return an empty string when attempting to translate a
falsey value. This overrides the default behavior [0]:
> It is convention with GNU gettext to include meta-data as the
> translation for the empty string.

This patch provides a holistic solution to replace the current piecemeal
approach [1][2].

Affected Methods:
    - gettext
    - ugettext

[0] https://docs.python.org/2.7/library/gettext.html#the-gnutranslations-class
[1] bad803e451
[2] https://github.com/edx/edx-platform/pull/4653
2014-08-27 15:27:34 -07:00

81 lines
2.7 KiB
Python

"""
Monkey-patch the edX platform
Here be dragons (and simians!)
* USE WITH CAUTION *
No, but seriously, you probably never really want to make changes here.
This module contains methods to monkey-patch [0] the edx-platform.
Patches are to be applied as early as possible in the callstack
(currently lms/startup.py and cms/startup.py). Consequently, changes
made here will affect the entire platform.
That said, if you've decided you really need to monkey-patch the
platform (and you've convinced enough people that this is best
solution), kindly follow these guidelines:
- Reference django_utils_translation.py for a sample implementation.
- Name your module by replacing periods with underscores for the
module to be patched:
- patching 'django.utils.translation'
becomes 'django_utils_translation'
- patching 'your.module'
becomes 'your_module'
- Implement argumentless function wrappers in
monkey_patch.your_module for the following:
- is_patched
- patch
- unpatch
- Add the following code where needed (typically cms/startup.py and
lms/startup.py):
```
from monkey_patch import your_module
your_module.patch()
```
- Write tests! All code should be tested anyway, but with code that
patches the platform runtime, we must be extra sure there are no
unintended consequences.
[0] http://en.wikipedia.org/wiki/Monkey_patch
"""
# Use this key to store a reference to the unpatched copy
__BACKUP_ATTRIBUTE_NAME = '__monkey_patch'
def is_patched(module, attribute_name):
"""
Check if an attribute has been monkey-patched
"""
attribute = getattr(module, attribute_name)
return hasattr(attribute, __BACKUP_ATTRIBUTE_NAME)
def patch(module, attribute_name, attribute_replacement):
"""
Monkey-patch an attribute
A backup of the original attribute is preserved in the patched
attribute (see: __BACKUP_ATTRIBUTE_NAME).
"""
attribute = getattr(module, attribute_name)
setattr(attribute_replacement, __BACKUP_ATTRIBUTE_NAME, attribute)
setattr(module, attribute_name, attribute_replacement)
return is_patched(module, attribute_name)
def unpatch(module, attribute_name):
"""
Un-monkey-patch an attribute
Restore a backup of the original attribute from the patched
attribute, iff it exists (see: __BACKUP_ATTRIBUTE_NAME).
Return boolean whether or not the attribute could be unpatched
"""
was_patched = False
attribute = getattr(module, attribute_name)
if hasattr(attribute, __BACKUP_ATTRIBUTE_NAME):
attribute_old = getattr(attribute, __BACKUP_ATTRIBUTE_NAME)
setattr(module, attribute_name, attribute_old)
was_patched = True
return was_patched