{"id":6213,"library":"pytools","title":"Pytools","description":"Pytools is a comprehensive collection of utilities designed to augment the Python standard library, offering a diverse set of tools for various programming needs. It includes functionalities for mathematical operations, persistent key-value stores, graph algorithms, and object array handling. Maintained by Andreas Kloeckner, it serves primarily as a dependency for his other software packages but provides valuable utilities for direct use. The library is actively developed, with frequent releases, currently at version 2026.1.","status":"active","version":"2026.1","language":"python","source_language":"en","source_url":"https://github.com/inducer/pytools/","tags":["utility","tools","development","math","data-structures","algorithms"],"install":[{"cmd":"pip install pytools","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Required for functionalities interacting with NumPy object arrays.","package":"numpy","optional":true}],"imports":[{"note":"For various memoization strategies like memoize_method.","symbol":"memoize","correct":"from pytools import memoize"},{"note":"To use the persistent key-value store.","symbol":"PersistentDict","correct":"from pytools.persistent_dict import PersistentDict"},{"note":"For in-memory relational database table functionality.","symbol":"DataTable","correct":"from pytools.datatable import DataTable"},{"note":"For the lexer functionality.","symbol":"lex","correct":"from pytools import lex"}],"quickstart":{"code":"import time\nfrom pytools import memoize\n\nclass MyService:\n    def __init__(self):\n        self.compute_calls = 0\n\n    @memoize.memoize_method\n    def expensive_computation(self, data_id):\n        self.compute_calls += 1\n        time.sleep(0.1) # Simulate a time-consuming operation\n        return f\"Result for {data_id} (computed on call {self.compute_calls})\"\n\nservice = MyService()\nprint(service.expensive_computation(\"user_profile_123\"))\nprint(service.expensive_computation(\"user_profile_123\")) # This call will use the cached result\nprint(service.expensive_computation(\"product_data_abc\"))\n","lang":"python","description":"This example demonstrates how to use `pytools.memoize.memoize_method` to cache the results of an expensive method, preventing redundant computations for the same inputs. Subsequent calls with identical arguments will return the cached value instantly."},"warnings":[{"fix":"Review release notes for specific migration paths or alternatives if using older versions of the `Tag` system.","message":"The `Tag` constructor was removed around `v2024.1.8`, breaking compatibility for code relying on it. Some releases were yanked due to this change.","severity":"breaking","affected_versions":"<2024.1.8"},{"fix":"Migrate logging-related imports and usage to `logpyle` by installing it separately (`pip install logpyle`) and updating import paths.","message":"The logging functionality previously under `pytools.log` has been spun out into a separate, dedicated project called `logpyle`.","severity":"deprecated","affected_versions":">=2024.1.x"},{"fix":"Consult the official documentation (e.g., for specific submodule APIs) rather than expecting intuitive top-level functions for all tasks.","message":"Pytools primarily serves as an internal dependency for the author's other scientific computing projects. While it offers useful general-purpose utilities, its design and sometimes opaque naming conventions might require users to delve into its documentation to find specific tools.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure your project's environment uses Python 3.10 or a more recent compatible version.","message":"Pytools requires Python 3.10 or higher. Older Python versions are not supported.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'2026.1':76 'activ':68 'algorithm':38,84 'andrea':45 'array':41 'augment':11 'collect':6 'comprehens':5 'current':73 'data':82 'data-structur':81 'depend':52 'design':9 'develop':69,79 'direct':63 'divers':18 'frequent':71 'function':28 'graph':37 'handl':42 'includ':27 'key':34 'key-valu':33 'kloeckner':46 'librari':15,66 'maintain':43 'math':80 'mathemat':30 'need':25 'object':40 'offer':16 'oper':31 'packag':57 'persist':32 'primarili':49 'program':24 'provid':59 'python':13 'pytool':1,2 'releas':72 'serv':48 'set':19 'softwar':56 'standard':14 'store':36 'structur':83 'tool':21,78 'use':64 'util':8,61,77 'valu':35 'valuabl':60 'various':23 'version':75","created_at":"2026-04-14T18:46:53.248716+00:00","updated_at":"2026-04-16T20:32:51.859160+00:00","problems":[{"fix":"Install the library using pip:\n```bash\npip install pytools\n```","cause":"The `pytools` library is not installed in the Python environment where the code is being executed.","error":"ModuleNotFoundError: No module named 'pytools'"},{"fix":"Import `gcd` from `pytools.arithmetic` or access it as `pytools.arithmetic.gcd`:\n```python\nimport pytools.arithmetic\nresult = pytools.arithmetic.gcd(10, 15)\n# Or\nfrom pytools.arithmetic import gcd\nresult = gcd(10, 15)\n```","cause":"The `gcd` function is located within the `pytools.arithmetic` submodule, not directly exposed at the top level of the `pytools` package.","error":"AttributeError: module 'pytools' has no attribute 'gcd'"},{"fix":"To 'modify' a `frozendict`, create a new one with the desired changes, typically by merging it with another dictionary or reconstructing it:\n```python\nfrom pytools.immutable_collection import frozendict\nd = frozendict({\"a\": 1, \"b\": 2})\n\n# To add/change an item (returns a new frozendict)\nnew_d = d.update({\"c\": 3})\nprint(new_d) # frozendict({'a': 1, 'b': 2, 'c': 3})\n\n# To 'remove' an item (construct a new frozendict)\nnew_d_without_b = frozendict({k: v for k, v in d.items() if k != 'b'})\nprint(new_d_without_b) # frozendict({'a': 1})\n```","cause":"`frozendict` from `pytools.immutable_collection` is an immutable dictionary, meaning its contents cannot be modified after creation.","error":"TypeError: 'frozendict' object does not support item assignment"},{"fix":"Ensure the directory where the persistent dictionary file is stored has appropriate write permissions for the executing user, or choose a different, writable path for the data file:\n```python\nfrom pytools import persistent_dict\n# Option 1: Ensure '/tmp/' is writable\nd = persistent_dict(\"/tmp/mypersistentdict.dat\")\n\n# Option 2: Use a user-specific writable directory\nimport os\nuser_data_dir = os.path.join(os.path.expanduser('~'), '.pytools_data')\nos.makedirs(user_data_dir, exist_ok=True)\nd = persistent_dict(os.path.join(user_data_dir, \"mypersistentdict.dat\"))\n```","cause":"The Python process lacks the necessary write permissions for the directory where `pytools.persistent_dict` attempts to create or access its data file.","error":"IOError: [Errno 13] Permission denied: '/path/to/your/pytools-persistent.dat'"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"2026.1.1","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/inducer/pytools","docs":"https://documen.tician.de/pytools/","changelog":null,"pypi":"https://pypi.org/project/pytools/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["data","database"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-06-28","next_check":"2026-07-28","install_tag":null}}