{"id":1013,"library":"ppft","title":"ppft: Parallel Python Framework","description":"ppft is a friendly fork of Parallel Python (pp), designed to provide distributed and parallel Python capabilities on Symmetric Multi-Processing (SMP) systems and clusters. It offers an easier installation process and enhanced serialization through the optional `dill` library. Currently at version 1.7.8, ppft maintains an active development and release cadence, with recent updates focused on Python 3 compatibility and dropping support for older Python versions.","status":"active","version":"1.7.8","language":"python","source_language":"en","source_url":"https://github.com/uqfoundation/ppft","tags":["parallel processing","distributed computing","fork","serialization","pp"],"install":[{"cmd":"pip install ppft","lang":"bash","label":"Basic Installation"},{"cmd":"pip install ppft[dill]","lang":"bash","label":"With Enhanced Serialization"}],"dependencies":[{"reason":"Optional, for enhanced serialization of complex Python objects.","package":"dill","optional":true},{"reason":"Required for building and installation.","package":"setuptools","optional":false}],"imports":[{"note":"ppft installs and is accessed via the `pp` module, maintaining compatibility with the original Parallel Python library. Directly importing from `ppft` is not the intended mechanism for core functionalities.","wrong":"from ppft import Server","symbol":"Server","correct":"import pp\njob_server = pp.Server()"},{"note":"The primary way to interact with ppft is by importing the `pp` module.","symbol":"pp","correct":"import pp"}],"quickstart":{"code":"import pp\nimport math\n\ndef my_function(a, b):\n    return math.sqrt(a**2 + b**2)\n\n# Create a job server\n# The number of workers can be specified, e.g., pp.Server(4)\njob_server = pp.Server()\n\n# Submit jobs\njobs = []\nfor i in range(10):\n    jobs.append(job_server.submit(my_function, (i, i+1), ())) # func, args, modules\n\n# Retrieve results\nresults = [job() for job in jobs]\nprint(f\"Calculated results: {results}\")\n\n# Destroy the job server\njob_server.destroy()","lang":"python","description":"This quickstart demonstrates how to create a local `pp.Server`, submit a simple function for parallel execution, and collect the results. The server automatically manages worker processes."},"warnings":[{"fix":"Upgrade your Python environment to 3.9 or higher. For future compatibility, target Python 3.10+.","message":"Python 2.x support was dropped in early versions, and Python 3.x minimum requirements have increased incrementally. Version 1.7.8 requires Python >=3.9, and upcoming versions (e.g., 1.7.9.dev0 documentation) indicate a requirement of Python >=3.10. Ensure your Python environment meets the specific version's requirements.","severity":"breaking","affected_versions":"All versions >=1.7.6.8 (Python 3.8 dropped), >=1.7.8 (Python 3.9 dropped)."},{"fix":"Before installing ppft, uninstall any existing 'pp' installations: `pip uninstall pp`.","message":"ppft installs itself as the 'pp' module. If the original 'Parallel Python' (pp) library is already installed in your environment, 'import pp' may point to the original library instead of the ppft fork. This can lead to unexpected behavior or missing features.","severity":"gotcha","affected_versions":"All versions where the original 'pp' library might be present."},{"fix":"Install ppft using `pip install ppft[dill]` to include the `dill` library for improved serialization.","message":"For enhanced serialization of complex Python objects (e.g., lambdas, nested functions, objects with custom serialization), it is highly recommended to install ppft with the optional 'dill' dependency. Without it, some objects might fail to serialize correctly for parallel execution.","severity":"gotcha","affected_versions":"All versions."}],"env_vars":null,"last_verified":"2026-05-12T22:36:06.837Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"fix":"Use `import pp` to access the library's functionalities. For example, `job_server = pp.Server()`.","cause":"ppft installs itself as the 'pp' module, and core functionalities are accessed via `import pp`. Directly importing from `ppft` is not the intended mechanism for using the library's core features.","error":"import ppft"},{"fix":"Ensure ppft is installed in your active Python environment using `pip install ppft`. If you have the original 'Parallel Python' (pp) library installed, uninstall it first (`pip uninstall pp`) to avoid conflicts, then install `ppft`.","cause":"This error occurs when the Python interpreter cannot find the 'pp' module, which is how ppft is imported. This can be due to ppft not being installed, being installed in a different Python environment, or issues with the Python path.","error":"ModuleNotFoundError: No module named 'pp'"},{"fix":"Ensure your Python version meets ppft's requirements (version 1.7.8 requires Python >=3.9; newer versions may require >=3.10). If the issue persists, consider installing ppft with the optional 'dill' dependency (`pip install ppft[dill]`) for enhanced serialization, as dill can handle more complex Python objects than the default pickle module.","cause":"This specific AttributeError indicates a serialization issue, often encountered when using ppft with newer Python versions (e.g., Python 3.13) where there might be incompatibilities with how objects are pickled or unpickled across processes.","error":"AttributeError: Can't get attribute 'PartialSum' on <module 'ppft.__main__' from '...'>"},{"fix":"Install ppft with the optional `dill` dependency using `pip install ppft[dill]`. `dill` provides enhanced serialization capabilities that can handle a wider range of Python objects and functions, resolving many pickling issues.","cause":"ppft, like other parallel processing libraries, relies on serialization (pickling) to pass functions and objects between processes. This error occurs when a function or object you are trying to pass for parallel execution cannot be serialized by the default `pickle` module, often due to closures, lambda functions, or objects with complex states.","error":"TypeError: cannot pickle 'function' object"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.7.8","cli_name":"","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":2.1,"disk_size":"18.2M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":2.1,"disk_size":"18.2M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"dill","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.18,"mem_mb":7,"disk_size":"19.0M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"dill","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.19,"mem_mb":7,"disk_size":"19.0M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.03,"mem_mb":2.1,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":2.1,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"dill","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.12,"mem_mb":7.1,"disk_size":"20M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"dill","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.13,"mem_mb":7.1,"disk_size":"20M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":2.6,"disk_size":"20.0M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":2.6,"disk_size":"20.0M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"dill","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":7.6,"disk_size":"21.1M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"dill","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.27,"mem_mb":7.6,"disk_size":"21.1M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.6,"import_time_s":0.08,"mem_mb":2.6,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":2.6,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"dill","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.7,"import_time_s":0.22,"mem_mb":7.6,"disk_size":"22M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"dill","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.21,"mem_mb":7.6,"disk_size":"22M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":2.6,"disk_size":"11.9M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":2.6,"disk_size":"11.9M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"dill","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.21,"mem_mb":7.6,"disk_size":"12.9M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"dill","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.26,"mem_mb":7.6,"disk_size":"12.9M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.4,"import_time_s":0.08,"mem_mb":2.6,"disk_size":"12M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":2.6,"disk_size":"12M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"dill","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.23,"mem_mb":7.7,"disk_size":"13M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"dill","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":7.7,"disk_size":"13M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":3.6,"disk_size":"11.7M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":2.8,"disk_size":"11.6M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"dill","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.22,"mem_mb":8.1,"disk_size":"12.7M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"dill","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":8.1,"disk_size":"12.6M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.4,"import_time_s":0.09,"mem_mb":3.4,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":2.6,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"dill","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.21,"mem_mb":8.2,"disk_size":"13M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"dill","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":8.2,"disk_size":"13M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":2,"disk_size":"17.7M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.05,"mem_mb":2,"disk_size":"17.7M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"dill","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":6.9,"disk_size":"18.5M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"dill","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.17,"mem_mb":6.9,"disk_size":"18.5M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.7,"import_time_s":0.04,"mem_mb":2,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":2,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"dill","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.9,"import_time_s":0.14,"mem_mb":6.9,"disk_size":"19M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"dill","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.16,"mem_mb":6.9,"disk_size":"19M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":null,"tag_description":null,"results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}