{"id":15651328,"url":"https://github.com/borzunov/dontasq","last_synced_at":"2025-09-13T06:37:58.303Z","repository":{"id":57423624,"uuid":"43461490","full_name":"borzunov/dontasq","owner":"borzunov","description":"⚡🐍 Extends built-in Python collections with LINQ-style methods","archived":false,"fork":false,"pushed_at":"2018-12-11T07:00:16.000Z","size":9,"stargazers_count":32,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-26T18:11:32.334Z","etag":null,"topics":["asq","functional-programming","linq","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/borzunov.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-30T21:52:32.000Z","updated_at":"2024-11-28T16:31:42.000Z","dependencies_parsed_at":"2022-08-29T22:51:48.130Z","dependency_job_id":null,"html_url":"https://github.com/borzunov/dontasq","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/borzunov%2Fdontasq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/borzunov%2Fdontasq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/borzunov%2Fdontasq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/borzunov%2Fdontasq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/borzunov","download_url":"https://codeload.github.com/borzunov/dontasq/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231756278,"owners_count":18421881,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asq","functional-programming","linq","python"],"created_at":"2024-10-03T12:37:58.562Z","updated_at":"2024-12-29T15:58:19.887Z","avatar_url":"https://github.com/borzunov.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"=======\ndontasq\n=======\n\nExtend built-in Python collections with LINQ-for-objects style methods\n\nDescription\n-----------\n\nThe library extends built-in Python collections with methods from `Robert Smallshire`_'s asq_. Adding methods to built-ins isn't officially allowed, but it's possible to do this in CPython (both 2.x and 3.x) using a hack described in the corresponding section below.\n\n.. _Robert Smallshire: https://github.com/rob-smallshire\n.. _asq: https://github.com/rob-smallshire/asq\n\nFor example:\n\n.. code:: python\n\n    \u003e\u003e\u003e import dontasq\n    \u003e\u003e\u003e\n    \u003e\u003e\u003e [1, 2, 3].select_many(lambda x: (x, x ** 2)).to_tuple()\n    (1, 1, 2, 4, 3, 9)\n    \u003e\u003e\u003e 'oh brave new world'.split() \\\n    ...                     .where(lambda word: len(word) \u003e= 5) \\\n    ...                     .select(str.capitalize) \\\n    ...                     .to_list()\n    ['Brave', 'World']\n\nIn some cases, this style helps to write functional-esque code that is more clear than code with ``map``, ``filter`` and generator expressions: there's no confusion with brackets, and methods are applied in the natural order.\n\n**Warning!** ``dontasq`` uses undocumented CPython features. It's not guaranteed that this features will be maintained in the future Python versions.\n\nDetails\n-------\n\nDuring import, ``dontasq`` looks for classes in the built-ins namespace, ``collections`` and ``itertools`` modules. If a class is an iterable and is not a metaclass, the library will append all public methods of ``asq.queryables.Queryable`` to it in such a way that a method call:\n\n.. code:: python\n\n    \u003e\u003e\u003e instance.select(lambda x: x * 2)\n\nWill be equal to:\n\n.. code:: python\n\n    \u003e\u003e\u003e Queryable(instance).select(lambda x: x * 2)\n\nFor example, the methods will be added to ``list``, ``str``, ``collections.OrderedDict``, and ``itertools.count``. You can find a list of all ``Queryable`` methods and their description in `asq documentation`_.\n\n.. _asq documentation: https://asq.readthedocs.io/en/latest/reference/queryables.html#asq.queryables.Queryable\n\nIf a class already contains an attribute with a coinciding name (e.g. ``str.join`` and ``list.count``), this attribute won't be replaced.\n\nOf course, you're able to import other ``asq`` modules when using ``dontasq``:\n\n.. code:: python\n\n    \u003e\u003e\u003e import dontasq\n    \u003e\u003e\u003e from asq.predicates import *\n    \u003e\u003e\u003e\n    \u003e\u003e\u003e words = ['banana', 'receive', 'believe', 'ticket', 'deceive']\n    \u003e\u003e\u003e words.where(contains_('ei')).to_list()\n    ['receive', 'deceive']\n\nIf you want to patch classes from another library, you can use methods ``dontasq.patch_type`` and ``dontasq.patch_module``:\n\n.. code:: python\n\n    \u003e\u003e\u003e import bintrees\n    \u003e\u003e\u003e import dontasq\n    \u003e\u003e\u003e\n    \u003e\u003e\u003e dontasq.patch_type(bintrees.AVLTree)\n    \u003e\u003e\u003e\n    \u003e\u003e\u003e dictionary = {1: 'Anton', 2: 'James', 3: 'Olivia'}\n    \u003e\u003e\u003e bintrees.AVLTree(dictionary).select(lambda x: x * 2).to_list()\n    [2, 4, 6]\n\nYou can find other examples in `\"tests\" directory`_.\n\n.. _\"tests\" directory: https://github.com/borzunov/dontasq/tree/master/tests\n\nAdding methods to built-ins\n---------------------------\n\nThe following approach is found in `this question`_ on StackOverflow.\n\n.. _this question: https://stackoverflow.com/questions/25440694/whats-the-purpose-of-dictproxy\n\nOfficially, you can get only a protected (read-only) instance of built-ins' ``__dict__``. The trick is that in CPython this instance contains a reference to an original (modifiable) dictionary that can be tracked with `gc.get_referents`_ function.\n\n.. _gc.get_referents: https://docs.python.org/3/library/gc.html#gc.get_referents\n\nFor example, we can add ``select`` method to built-in ``list`` (unlike ``dontasq``, it's non-lazy in this example):\n\n.. code:: python\n\n  \u003e\u003e\u003e import gc\n  \u003e\u003e\u003e gc.get_referents(vars(list))[0]['select'] = lambda self, func: list(map(func, self))\n  \u003e\u003e\u003e\n  \u003e\u003e\u003e [1, 2, 3].select(lambda x: x * 2)\n  [2, 4, 6]\n\nAnother possible way is to use forbiddenfruit_ library that interacts with ``ctypes.pythonapi`` module. The both approaches stably work on both Python 2 and 3, but restricted to CPython only.\n\n.. _forbiddenfruit: https://github.com/clarete/forbiddenfruit\n\nInstallation\n------------\n\nYou can install the library using pip::\n\n    sudo pip install dontasq\n\nOr install a previously downloaded and extracted package::\n\n    sudo python setup.py install\n\nAuthors\n-------\n\nCopyright (c) 2015 Alexander Borzunov\n\nThe library name suggested by `Robert Smallshire`_ (an author of `asq`_).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fborzunov%2Fdontasq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fborzunov%2Fdontasq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fborzunov%2Fdontasq/lists"}