Note
This is a packaging fork of python-constraint 1.4.0, maintained by the ComPWA project. It is published as compwa-python-constraint, but preserves the public constraint import package and the behavior of the upstream 1.4.0 solver.
The upstream 1.4.0 release on
PyPI provides only a
.tar.bz2 source distribution.
PEP 625 standardized source distributions
as gzip-compressed .tar.gz archives. In version 0.12.0,
uv stopped accepting legacy source-distribution formats,
including .tar.bz2, and recommends rebuilding affected packages as .tar.gz
archives.
This fork makes that packaging-only update so projects can continue using the
1.4.0 implementation with current Python packaging tools. Its declarative
pyproject.toml build produces:
- a pure-Python
py3-none-anywheel, which installers can use without a local build step; and - a standards-compliant
.tar.gzsource distribution as a fallback.
The distribution is versioned as 1.4.0.post1 to identify it as a downstream
packaging revision. Solver changes continue to belong in the
upstream project.
The Python constraint module offers solvers for Constraint Satisfaction Problems (CSPs) over finite domains in simple and pure Python. A CSP can be represented in terms of variables, their possible domains, and constraints between them.
>>> from constraint import *
>>> problem = Problem()
>>> problem.addVariable("a", [1, 2, 3])
>>> problem.addVariable("b", [4, 5, 6])
>>> problem.getSolutions()
[{'a': 3, 'b': 6}, {'a': 3, 'b': 5}, {'a': 3, 'b': 4},
{'a': 2, 'b': 6}, {'a': 2, 'b': 5}, {'a': 2, 'b': 4},
{'a': 1, 'b': 6}, {'a': 1, 'b': 5}, {'a': 1, 'b': 4}]
>>> problem.addConstraint(lambda a, b: a * 2 == b, ("a", "b"))
>>> problem.getSolutions()
[{'a': 3, 'b': 6}, {'a': 2, 'b': 4}]
>>> problem = Problem()
>>> problem.addVariables(["a", "b"], [1, 2, 3])
>>> problem.addConstraint(AllDifferentConstraint())
>>> problem.getSolutions()
[{'a': 3, 'b': 2}, {'a': 3, 'b': 1}, {'a': 2, 'b': 3},
{'a': 2, 'b': 1}, {'a': 1, 'b': 2}, {'a': 1, 'b': 3}]>>> problem = Problem()
>>> numpieces = 8
>>> cols = range(numpieces)
>>> rows = range(numpieces)
>>> problem.addVariables(cols, rows)
>>> for col1 in cols:
... for col2 in cols:
... if col1 < col2:
... problem.addConstraint(
... lambda row1, row2: row1 != row2,
... (col1, col2),
... )
>>> solutions = problem.getSolutions()>>> problem = Problem()
>>> problem.addVariables(range(16), range(1, 17))
>>> problem.addConstraint(AllDifferentConstraint(), range(16))
>>> problem.addConstraint(ExactSumConstraint(34), [0, 5, 10, 15])
>>> problem.addConstraint(ExactSumConstraint(34), [3, 6, 9, 12])
>>> for row in range(4):
... problem.addConstraint(
... ExactSumConstraint(34),
... [row * 4 + i for i in range(4)],
... )
>>> for col in range(4):
... problem.addConstraint(
... ExactSumConstraint(34),
... [col + 4 * i for i in range(4)],
... )
>>> solutions = problem.getSolutions()The following solvers are available:
- Backtracking solver
- Recursive backtracking solver
- Minimum conflicts solver
Predefined constraint types include:
FunctionConstraintAllDifferentConstraintAllEqualConstraintExactSumConstraintMaxSumConstraintMinSumConstraintInSetConstraintNotInSetConstraintSomeInSetConstraintSomeNotInSetConstraint
python -m pip install compwa-python-constraintThe distribution name is compwa-python-constraint, while the import remains
unchanged:
from constraint import Problempython-constraint was written by Gustavo Niemeyer and is maintained at
python-constraint/python-constraint.
Please report solver bugs and propose behavioral changes
upstream.
For packaging issues specific to this fork, use the ComPWA issue tracker.