Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/wimglenn/monkey-magic
Monkeypatch built-in types
https://github.com/wimglenn/monkey-magic
Last synced: 10 days ago
JSON representation
Monkeypatch built-in types
- Host: GitHub
- URL: https://github.com/wimglenn/monkey-magic
- Owner: wimglenn
- License: mit
- Created: 2023-07-29T04:02:38.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-11-16T18:12:24.000Z (about 1 year ago)
- Last Synced: 2024-12-20T14:53:20.161Z (20 days ago)
- Language: Python
- Size: 8.79 KB
- Stars: 3
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.rst
- License: LICENSE
Awesome Lists containing this project
README
Monkey Magic
============Monkeypatch built-in types in Python.
Installation
------------.. code-block:: bash
pip install monkey-magic
Usage
-----Suppose you define a function ``href`` that you want to contribute as a "method" on ``str``:
.. code-block:: python
def href(self: str) -> str:
"""make a url string into a hyperlink"""
return f'{self}'Applying and then using it would look like this:
>>> from monkey_magic import monkeypatch
>>> monkeypatch(str, href)
>>> url = "www.example.com"
>>> url.href()
'www.example.com'This patch affects all strings, globally, including literals. It will work regardless of whether the patch was applied before or after a string instance was created.
.. skip: next
.. code-block::
>>> help(str.href)
Help on function href:href(self: str) -> str
make a url string into a hyperlink>>> "href" in dir(str)
True
>>> "hello".href>>> "hello".href()
'hello'More Examples
-------------Adding some pre-existing function:
>>> hi = """\
... hello
... world
... """
>>> import textwrap
>>> monkeypatch(str, textwrap.dedent)
>>> hi.dedent()
'hello\nworld\n'Want to use a different name than the function's name?
.. code-block:: python
import math
def func(n):
if n == 2 or n == 3:
return True
if n == 1 or n % 2 == 0:
return False
else:
return all(n % i for i in range(3, int(1 + math.sqrt(n)), 2))>>> monkeypatch(int, func, name="is_prime")
>>> 7 .is_prime()
True
>>> 8 .is_prime()
FalseContributing the unicode name function
>>> import unicodedata
>>> monkeypatch(str, unicodedata.name)
>>> "a".name()
'LATIN SMALL LETTER A'
>>> "💩".name()
'PILE OF POO'Would you prefer that as a property instead of a method?
>>> monkeypatch(str, property(unicodedata.name), name="pname")
>>> "a".pname
'LATIN SMALL LETTER A'
>>> "🔥".pname
'FIRE'To apply the same patch on a bunch of types:
.. code-block:: python
@property
def first(self):
return next(iter(self))>>> monkeypatch((str, bytes, tuple, list, dict), first)
>>> [1, 2].first
1
>>> (3, 4, 5).first
3
>>> "potato".first
'p'
>>> b"cafef00d".first
99
>>> {"k1": "v1", "k2": "v2"}.first
'k1'Why does ``list.sort`` exist but ``dict.sort`` doesn't?
.. code-block:: python
def sort(self, key=None, reverse=False):
d_sort = {k: d[k] for k in sorted(self, key=key, reverse=reverse)}
self.clear()
self.update(d_sort)>>> monkeypatch(dict, sort)
>>> d = {1: 1, 0: 0, 2: 2}
>>> d.sort()
>>> print(d)
{0: 0, 1: 1, 2: 2}
>>> d.sort(reverse=True)
>>> print(d)
{2: 2, 1: 1, 0: 0}
>>> d.sort(key=lambda k: k % 2)
>>> print(d)
{2: 2, 0: 0, 1: 1}Just want an attribute, not a callable? That's fine.
>>> monkeypatch(list, 42, "number")
>>> [].number
42
>>> [1, 2].number
42FAQ
---... Why should I use this? Why not just use a function?
You should not use this. Just use a function.... Where are the tests?
This ``README.rst`` is the test. The code-blocks in this document are actually `executed `_.... Does this work in PyPy?
The code uses implementation details of CPython. It will not work in PyPy.... How to undo a patch?
I don't know. When I try, Python segfaults. If you know how, `send me a PR `_.... Did people really ask you these questions?
Nope. I just made them up.