Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Dense LinearExpression.to_constraint('==') keeps sign '==': repr raises KeyError, differs from sparse '='

Abierto Apto para principiantes
#1,054 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
78/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python
Área
backend, testing

Línea de trabajo

Empieza con LinearExpression.to_constraint y compara cómo maneja los signos en los backends denso y disperso; el issue señala linopy/constants.py y el caso SIGN_EQ de test/test_store_conformance.py como referencias útiles. Comprueba cómo gestiona la ruta densa "==" y ejecuta la prueba de conformidad. El trabajo estará terminado cuando las restricciones densas almacenen "=", su representación funcione y se pueda eliminar el xfail de SIGN_EQ.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

bug

[!NOTE]
The following content was generated by AI.

Version Checks
  • I have confirmed this bug exists on the current master branch of Linopy (95f6bfa4).
Issue Description

LinearExpression.to_constraint("==", rhs) stores the sign verbatim as "==" on the dense backend, while the sparse (CSR) backend normalizes it to "=". linopy's canonical equality sign is EQUAL = "=" (linopy/constants.py; "==" is only in SIGNS_alternative), so the dense backend is the wrong one. Consequences on dense:

  • repr() of the constraint raises KeyError: '==' (SIGNS_pretty only knows "=").
  • The un-normalized "==" is carried into the model by m.add_constraints(con).

x == 1, (1*x) == 1 and m.add_constraints(1*x, "==", 1) are fine on both backends; only the to_constraint path skips sign normalization.

Found while building the dense/sparse conformance suite for #1019 (test/test_store_conformance.py, the case marked SIGN_EQ, currently a strict xfail on sparse).

Reproducible Example
from linopy import Model

for sparse in (False, True):
    m = Model(sparse=sparse)
    x = m.add_variables(name="x")
    con = (1 * x).to_constraint("==", 1)
    m.add_constraints(con, name="c")
    print(f"sparse={sparse}: sign={con.sign.item()!r}, stored={m.constraints['c'].sign.item()!r}")
    try:
        print(repr(con))
    except KeyError as e:
        print(f"repr -> KeyError: {e}")

Output:

sparse=False: sign='==', stored='=='
repr -> KeyError: '=='
sparse=True: sign='=', stored='='
Constraint (unassigned)
-----------------------
+1 x = 1.0
Traceback of the dense repr (without try/except)
  File "linopy/constraints.py", line 581, in __repr__
    f"{header_string}\n{'-' * len(header_string)}\n{expr} {SIGNS_pretty[self.sign.item()]} {self.rhs.item()}"
                                                           ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
KeyError: '=='
Expected Behavior

Dense to_constraint("==", ...) normalizes the sign to "=", as sparse already does and as x == 1 / add_constraints(lhs, "==", rhs) do, so repr works and both backends agree. The xfail in the conformance suite can then be dropped.

Lenguaje dominante
Python
Estrellas
262
Forks
89
Merge medio
2 d 5 h
PR fusionados (30 d)
36

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de PyPSA/linopy

Todos los issues de PyPSA/linopy

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.