Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

INTERNAL ERROR: Black produced different code on the second pass of the formatter. #1902

Closed
Viech opened this issue Jan 4, 2021 · 2 comments
Labels
C: unstable formatting Formatting changed on the second pass R: duplicate This issue or pull request already exists T: bug Something isn't working

Comments

@Viech
Copy link

Viech commented Jan 4, 2021

File is found here, formatting with black -l 80, version is 20.8b1.

Mode(target_versions=set(), line_length=80, string_normalization=True, experimental_string_processing=False, is_pyi=False)
--- source
+++ first pass
@@ -27,92 +27,92 @@
 _API_START = api_start(globals())
 # -------------------------------
 
 
 # Solution status strings, as verified by PICOS.
-VS_UNKNOWN           = "unverified"
+VS_UNKNOWN = "unverified"
 """PICOS failed to verify the solution."""
 
-VS_DETACHED          = "detached"
+VS_DETACHED = "detached"
 """The solution is not attached to a problem (it was given by the user)."""
 
-VS_EMPTY             = "empty"
+VS_EMPTY = "empty"
 """The solution is empty; there are neither primals nor duals."""
 
-VS_DETACHED_EMPTY    = "detached empty"
+VS_DETACHED_EMPTY = "detached empty"
 """The solution is both detached and empty."""
 
-VS_OUTDATED          = "outdated"
+VS_OUTDATED = "outdated"
 """The solution does not fit the problem formulation any more.
 
 Variables or constraints were removed from the problem."""
 
-VS_INCOMPLETE        = "incomplete"
+VS_INCOMPLETE = "incomplete"
 """The primal (dual) solution does not concern all variables (constraints)."""
 
-VS_FEASIBLE          = "feasible"
+VS_FEASIBLE = "feasible"
 """The solution is primal feasible; there is no dual solution."""
 
-VS_INFEASIBLE        = "infeasible"
+VS_INFEASIBLE = "infeasible"
 """The solution is primal infeasible; there is no dual solution."""
 
-VS_PRIMAL_FEASIBLE   = "primal feasible"
+VS_PRIMAL_FEASIBLE = "primal feasible"
 """The solution is primal feasible; a dual solution was not verified."""
 
 VS_PRIMAL_INFEASIBLE = "primal infeasible"
 """The solution is primal infeasible; a dual solution was not verified."""
 
 
 # Primal or dual solution (or search) status strings, as claimed by the solver.
-SS_UNKNOWN           = "unknown"
+SS_UNKNOWN = "unknown"
 """The solver did not make a clear claim about the solution status."""
 
-SS_EMPTY             = "empty"
+SS_EMPTY = "empty"
 """The solver claims not to have produced a solution."""
 
-SS_OPTIMAL           = "optimal"
+SS_OPTIMAL = "optimal"
 """The solution is optimal."""
 
-SS_FEASIBLE          = "feasible"
+SS_FEASIBLE = "feasible"
 """The solution is feasible."""
 
-SS_INFEASIBLE        = "infeasible"
+SS_INFEASIBLE = "infeasible"
 """No feasible solution exists.
 
 In the case of a primal solution, the problem is infeasible. In the case of a
 dual solution, the problem is unbounded.
 """
 
-SS_PREMATURE         = "premature"
+SS_PREMATURE = "premature"
 """The search was prematurely terminated due to some limit."""
 
-SS_FAILURE           = "failure"
+SS_FAILURE = "failure"
 """The search was termined due to a solver failure."""
 
 
 # Problem status strings, as claimed by the solver.
-PS_UNKNOWN           = "unknown"
+PS_UNKNOWN = "unknown"
 """The solver did not make a clear claim about the problem status."""
 
-PS_FEASIBLE          = "feasible"
+PS_FEASIBLE = "feasible"
 """The problem is primal (and dual) feasible and bounded."""
 
-PS_INFEASIBLE        = "infeasible"
+PS_INFEASIBLE = "infeasible"
 """The problem is primal infeasible (and dual unbounded or infeasible)."""
 
-PS_UNBOUNDED         = "unbounded"
+PS_UNBOUNDED = "unbounded"
 """The problem is primal unbounded (and dual infeasible)."""
 
-PS_INF_OR_UNB        = "infeasible or unbounded"
+PS_INF_OR_UNB = "infeasible or unbounded"
 """The problem is primal infeasible or unbounded.
 
 Being unbounded is usually infered from being dual infeasible."""
 
-PS_UNSTABLE          = "unstable"
+PS_UNSTABLE = "unstable"
 """The problem was found numerically unstable or otherwise hard to handle."""
 
-PS_ILLPOSED          = "illposed"
+PS_ILLPOSED = "illposed"
 """The problem was found to be in a state that is not amenable to solution."""
 
 
 def _check_type(argument, *types):
     """Enforce the type of a method or function argument."""
@@ -120,13 +120,16 @@
         if type_ is None:
             type_ = type(None)
         if isinstance(argument, type_):
             return
 
-    raise TypeError("An argument is of type '{}' but must be instance of {}."
-        .format(type(argument).__name__, " or ".join("'{}'".format(t.__name__)
-            for t in types)))
+    raise TypeError(
+        "An argument is of type '{}' but must be instance of {}.".format(
+            type(argument).__name__,
+            " or ".join("'{}'".format(t.__name__) for t in types),
+        )
+    )
 
 
 # TODO: Make all public fields use snake_case, ensure backwards compatibility.
 class Solution:
     """Assignment of primal and dual values to variables and constraints.
@@ -154,14 +157,24 @@
     '0.83 ms'
     >>> C2 = P.add_constraint(x >= 3); s
     <infeasible primal solution (was feasible and claimed optimal) from cvxopt>
     """
 
-    def __init__(self, primals, duals=None, problem=None, solver="user",
-            primalStatus=SS_UNKNOWN, dualStatus=SS_UNKNOWN,
-            problemStatus=PS_UNKNOWN, searchTime=0.0, info=None,
-            vectorizedPrimals=False, reportedValue=None):
+    def __init__(
+        self,
+        primals,
+        duals=None,
+        problem=None,
+        solver="user",
+        primalStatus=SS_UNKNOWN,
+        dualStatus=SS_UNKNOWN,
+        problemStatus=PS_UNKNOWN,
+        searchTime=0.0,
+        info=None,
+        vectorizedPrimals=False,
+        reportedValue=None,
+    ):
         """Create a solution to an optimization problem.
 
         :param dict(picos.expressions.BaseVariable, object) primals:
             A mapping of variables to their primal solution value.
         :param dict(picos.constraints.Constraint, object) duals:
@@ -187,11 +200,11 @@
         :param float reportedValue:
             Objective value of the solution as reported by the solver.
         """
         from ..expressions import BaseVariable
         from ..constraints import Constraint
-        from .problem      import Problem
+        from .problem import Problem
 
         if primals is None:
             primals = {}
 
         if duals is None:
@@ -213,92 +226,110 @@
         _check_type(vectorizedPrimals, bool)
         _check_type(reportedValue, None, float)
 
         for variable, _ in primals.items():
             if not isinstance(variable, BaseVariable):
-                raise TypeError("They keys in the primals argument of "
-                    "Solution.__init__ must be variables.")
+                raise TypeError(
+                    "They keys in the primals argument of "
+                    "Solution.__init__ must be variables."
+                )
 
         for constraint, _ in duals.items():
             if not isinstance(constraint, Constraint):
-                raise TypeError("They keys in the duals argument of "
-                    "Solution.__init__ must be constraints.")
+                raise TypeError(
+                    "They keys in the duals argument of "
+                    "Solution.__init__ must be constraints."
+                )
 
         # Derive a "claimed status" from the claimed primal and dual states.
         if primals and duals:
             if primalStatus == dualStatus:
                 claimedStatus = primalStatus
             else:
                 claimedStatus = "primal {} and dual {}".format(
-                    primalStatus, dualStatus)
+                    primalStatus, dualStatus
+                )
         elif primals:
             # Do not warn about correctingdualStatus, because the solver might
             # have produced primals but PICOS did not read them.
-            dualStatus    = SS_EMPTY
+            dualStatus = SS_EMPTY
             claimedStatus = primalStatus
         elif duals:
             # Do not warn about correcting primalStatus, because the solver
             # might have produced duals but PICOS did not read them.
-            primalStatus  = SS_EMPTY
+            primalStatus = SS_EMPTY
             claimedStatus = dualStatus
         else:
-            primalStatus  = SS_EMPTY
-            dualStatus    = SS_EMPTY
+            primalStatus = SS_EMPTY
+            dualStatus = SS_EMPTY
             claimedStatus = SS_EMPTY
 
         # Infeasible problem implies infeasible primal.
-        if problemStatus == PS_INFEASIBLE \
-        and primalStatus not in (SS_INFEASIBLE, SS_EMPTY):
+        if problemStatus == PS_INFEASIBLE and primalStatus not in (
+            SS_INFEASIBLE,
+            SS_EMPTY,
+        ):
             warnings.warn(
                 "{} claims that a problem is infeasible but does not say the "
-                "same about the nonempty primal solution. Correcting this.".
-                format(solver), RuntimeWarning)
+                "same about the nonempty primal solution. Correcting this.".format(
+                    solver
+                ),
+                RuntimeWarning,
+            )
             primalStatus = SS_INFEASIBLE
 
         # Unbounded problem implies infeasible dual.
-        if problemStatus == PS_UNBOUNDED \
-        and dualStatus not in (SS_INFEASIBLE, SS_EMPTY):
+        if problemStatus == PS_UNBOUNDED and dualStatus not in (
+            SS_INFEASIBLE,
+            SS_EMPTY,
+        ):
             warnings.warn(
                 "{} claims that a problem is unbounded but does not say that "
-                "the nonempty dual solution is infeasible. Correcting this.".
-                format(solver), RuntimeWarning)
+                "the nonempty dual solution is infeasible. Correcting this.".format(
+                    solver
+                ),
+                RuntimeWarning,
+            )
             dualStatus = SS_INFEASIBLE
 
         # Optimal solution implies feasible problem.
         if claimedStatus == SS_OPTIMAL and problemStatus != PS_FEASIBLE:
             warnings.warn(
                 "{} claims to have found an optimal solution but does not say "
-                " that the problem is feasible. Correcting this."
-                .format(solver), RuntimeWarning)
+                " that the problem is feasible. Correcting this.".format(
+                    solver
+                ),
+                RuntimeWarning,
+            )
             problemStatus = PS_FEASIBLE
 
-        self.problem       = problem
+        self.problem = problem
         """The problem that was solved to produce the solution."""
 
-        self.solver        = solver
+        self.solver = solver
         """The solver that produced the solution."""
 
-        self.searchTime    = searchTime
+        self.searchTime = searchTime
         """Time in seconds that the solution search took."""
 
-        self.primals       = primals
+        self.primals = primals
         """The primal solution values returned by the solver."""
 
-        self.duals         = duals
+        self.duals = duals
         """The dual solution values returned by the solver."""
 
-        self.info          = info
+        self.info = info
         """Additional information provided by the solver."""
 
-        self.lastStatus    = VS_UNKNOWN
+        self.lastStatus = VS_UNKNOWN
         """The solution status as verified by PICOS when the solution was
         applied to the problem."""
 
-        self.primalStatus  = primalStatus
+        self.primalStatus = primalStatus
         """The primal solution status as claimed by the solver."""
 
-        self.dualStatus    = dualStatus
+        self.dualStatus = dualStatus
         """The dual solution status as claimed by the solver."""
 
         self.claimedStatus = claimedStatus
         """The primal and dual solution status as claimed by the solver."""
 
@@ -373,11 +404,12 @@
             that problem instead.
         """
         if not self.problem:
             raise RuntimeError(
                 "Cannot compute the objective value of a detached solution. "
-                "Use attach_to to assign the solution to a problem.")
+                "Use attach_to to assign the solution to a problem."
+            )
 
         problemCopy = self.problem.copy()
 
         self.apply(toProblem=problemCopy)
 
@@ -388,13 +420,13 @@
         """The objective value as reported by the solver, or :obj:`None`."""
         return self.reportedValue
 
     def __str__(self):
         verifiedStatus = self.status
-        lastStatus     = self.lastStatus
-        claimedStatus  = self.claimedStatus
-        problemStatus  = self.problemStatus
+        lastStatus = self.lastStatus
+        claimedStatus = self.claimedStatus
+        problemStatus = self.problemStatus
 
         if self.primals and self.duals:
             solutionType = "solution pair"
         elif self.primals:
             solutionType = "primal solution"
@@ -402,45 +434,55 @@
             solutionType = "dual solution"
         else:
             solutionType = "solution"  # "(detached) empty solution"
 
         # Print the last status if it is known and differs from the current one.
-        printLastStatus = lastStatus != VS_UNKNOWN and \
-            verifiedStatus != lastStatus
+        printLastStatus = (
+            lastStatus != VS_UNKNOWN and verifiedStatus != lastStatus
+        )
 
         # Print the claimed status only if it differs from the initial verified
         # one is not implied by a problem status that will be printed.
-        printClaimedStatus = \
-            claimedStatus not in (verifiedStatus, SS_UNKNOWN) and \
-            problemStatus not in (PS_INFEASIBLE, PS_UNBOUNDED)
+        printClaimedStatus = claimedStatus not in (
+            verifiedStatus,
+            SS_UNKNOWN,
+        ) and problemStatus not in (PS_INFEASIBLE, PS_UNBOUNDED)
 
         # Print the problem status only if it is interesting.
-        printProblemStatus = \
-            problemStatus not in (PS_UNKNOWN, PS_FEASIBLE)
+        printProblemStatus = problemStatus not in (PS_UNKNOWN, PS_FEASIBLE)
 
         if printLastStatus and printClaimedStatus:
             unverifiedStatus = " (was {} and claimed {})".format(
-                lastStatus, claimedStatus)
+                lastStatus, claimedStatus
+            )
         elif printLastStatus:
             unverifiedStatus = " (was {})".format(lastStatus)
         elif printClaimedStatus:
             unverifiedStatus = " (claimed {})".format(claimedStatus)
         else:
             unverifiedStatus = ""
 
         if printProblemStatus:
-            unverifiedStatus += \
-                " for a problem claimed {}".format(problemStatus)
-
-        return "{} {}{} from {}".format(verifiedStatus, solutionType,
-            unverifiedStatus, self.solver)
+            unverifiedStatus += " for a problem claimed {}".format(
+                problemStatus
+            )
+
+        return "{} {}{} from {}".format(
+            verifiedStatus, solutionType, unverifiedStatus, self.solver
+        )
 
     def __repr__(self):
         return glyphs.repr1(self.__str__())
 
-    def apply(self, primals=True, duals=True, clearOnNone=True, toProblem=None,
-              snapshotStatus=False):
+    def apply(
+        self,
+        primals=True,
+        duals=True,
+        clearOnNone=True,
+        toProblem=None,
+        snapshotStatus=False,
+    ):
         """Apply the solution to the involved variables and constraints.
 
         :param bool primals: Whether to apply the primal solution.
         :param bool duals: Whether to apply the dual solution.
         :param bool clearOnNone: Whether to clear the value of a variable or
@@ -460,24 +502,26 @@
                     for variable, primal in self.primals.items():
                         thePrimals[toProblem.variables[variable.name]] = primal
                 except KeyError:
                     raise RuntimeError(
                         "Cannot apply solution to specified problem as not all "
-                        "variables for which primal values exist were found.")
+                        "variables for which primal values exist were found."
+                    )
 
             if duals:
                 theDuals = {}
                 try:
                     for constraint, dual in self.duals.items():
                         theDuals[toProblem.constraints[constraint.id]] = dual
                 except KeyError:
                     raise RuntimeError(
                         "Cannot apply solution to specified problem as not all "
-                        "constraints for which dual values exist were found.")
+                        "constraints for which dual values exist were found."
+                    )
         else:
             thePrimals = self.primals
-            theDuals   = self.duals
+            theDuals = self.duals
 
         if primals:
             for variable, primal in thePrimals.items():
                 if primal is None and not clearOnNone:
                     continue
--- first pass
+++ second pass
@@ -440,14 +440,18 @@
             lastStatus != VS_UNKNOWN and verifiedStatus != lastStatus
         )
 
         # Print the claimed status only if it differs from the initial verified
         # one is not implied by a problem status that will be printed.
-        printClaimedStatus = claimedStatus not in (
-            verifiedStatus,
-            SS_UNKNOWN,
-        ) and problemStatus not in (PS_INFEASIBLE, PS_UNBOUNDED)
+        printClaimedStatus = (
+            claimedStatus
+            not in (
+                verifiedStatus,
+                SS_UNKNOWN,
+            )
+            and problemStatus not in (PS_INFEASIBLE, PS_UNBOUNDED)
+        )
 
         # Print the problem status only if it is interesting.
         printProblemStatus = problemStatus not in (PS_UNKNOWN, PS_FEASIBLE)
 
         if printLastStatus and printClaimedStatus:
@Viech Viech added the T: bug Something isn't working label Jan 4, 2021
@ichard26 ichard26 added the C: unstable formatting Formatting changed on the second pass label Jan 4, 2021
@mvolfik
Copy link

mvolfik commented Feb 22, 2021

MCVE:

def f():
    def f():
        printClaimedStatus = \
            claimedStatus not in (verifiedStatus, SS_UNKNOWN) and \
            problemStatus not in (PS_INFEASIBLE, PS_UNBOUNDED)

Likely a duplicate of #1629 , as this file works after applying #1958

@ichard26 ichard26 added the R: duplicate This issue or pull request already exists label Apr 25, 2021
@ichard26
Copy link
Collaborator

Hello!

All reproduction cases in this issue format without error on master. The fixing commit was 8672af3 from PR GH-2126. I'll be marking this issue as a duplicate of GH-1629 since that's what GH-2126 aimed to fix and it's highly likely this issue falls under GH-1629.

Since we use the issue tracker as a reflection of what's on master, I'll be closing this issue. If you have any issues, especially with the new (but stable) output, please open a new issue. Oh and the fix should be available in a published release soon, see GH-2125 for more info.

Thank you for reporting!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C: unstable formatting Formatting changed on the second pass R: duplicate This issue or pull request already exists T: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants