nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: scala-steward-org/scala-steward
Pull request #2247 (2021-09-22 20:11:58)

Improved content parser for .mill-version file
Fix sugested by Frank Thomas.



Patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/edit/UpdateHeuristic.scala b/modules/core/src/main/scala/org/scalasteward/core/edit/UpdateHeuristic.scala
index 66d93bc6..ce6c3a8b 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/edit/UpdateHeuristic.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/edit/UpdateHeuristic.scala
@@ -215,7 +215,7 @@ object UpdateHeuristic {
         defaultReplaceVersion(_ => List("version"))(update)
       case update: Update.Single if MillAlg.isMillMainUpdate(update) =>
         // this is intended to update the `.mill-version`
-        content => if (content === update.currentVersion) Some(update.nextVersion) else None
+        content => if (content.trim() === update.currentVersion) Some(update.nextVersion) else None
       case _ =>
         _ => None
     }


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/edit/EditAlgTest.scala b/modules/core/src/test/scala/org/scalasteward/core/edit/EditAlgTest.scala
index 4a6a16b6..f0f24b51 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/edit/EditAlgTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/edit/EditAlgTest.scala
@@ -258,7 +258,7 @@ class EditAlgTest extends FunSuite {
       newerVersions = Nel.of("0.9.9")
     )
     val original = Map(
-      ".mill-version" -> """0.9.5""",
+      ".mill-version" -> "0.9.5 \n ",
       ".travis.yml" -> """- TEST_MILL_VERSION=0.9.5"""
     )
     val expected = Map(
Repository: scala-steward-org/scala-steward
Pull request #2356 (2021-11-15 14:50:17)

Improve formatting of UnexpectedResponse.getMessage
This lists each header of the response on its own line instead of
having them all on one line.


Patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/util/HttpJsonClient.scala b/modules/core/src/main/scala/org/scalasteward/core/util/HttpJsonClient.scala
index 7794d681..f6c13ec4 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/util/HttpJsonClient.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/util/HttpJsonClient.scala
@@ -133,5 +133,10 @@ final case class UnexpectedResponse(
 ) extends RuntimeException
     with NoStackTrace {
   override def getMessage: String =
-    s"uri: $uri\nmethod: $method\nstatus: $status\nheaders: $headers\nbody: $body"
+    s"""|uri: $uri
+        |method: $method
+        |status: $status
+        |headers:
+        |${headers.headers.map(h => s"  ${h.show}").mkString("\n")}
+        |body: $body""".stripMargin
 }


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/util/UnexpectedResponseTest.scala b/modules/core/src/test/scala/org/scalasteward/core/util/UnexpectedResponseTest.scala
new file mode 100644
index 00000000..11ee5245
--- /dev/null
+++ b/modules/core/src/test/scala/org/scalasteward/core/util/UnexpectedResponseTest.scala
@@ -0,0 +1,29 @@
+package org.scalasteward.core.util
+
+import munit.FunSuite
+import org.http4s.{Header, Headers, Method, Status, Uri}
+import org.typelevel.ci.CIString
+
+class UnexpectedResponseTest extends FunSuite {
+  test("getMessage") {
+    val unexpected = UnexpectedResponse(
+      Uri.unsafeFromString("https://api.github.com/repos/foo/bar/pulls"),
+      Method.POST,
+      Headers(
+        Header.Raw(CIString("access-control-allow-origin"), "*"),
+        Header.Raw(CIString("content-type"), "application/json; charset=utf-8")
+      ),
+      Status.Forbidden,
+      """{ message: "nope" }"""
+    )
+    val expected =
+      """|uri: https://api.github.com/repos/foo/bar/pulls
+         |method: POST
+         |status: 403 Forbidden
+         |headers:
+         |  access-control-allow-origin: *
+         |  content-type: application/json; charset=utf-8
+         |body: { message: "nope" }""".stripMargin
+    assertEquals(unexpected.getMessage, expected)
+  }
+}
Repository: scala-steward-org/scala-steward
Pull request #2385 (2021-11-29 18:19:51)

Fix: `process.slurp` ignores the timeout


Patch:
diff --git a/.scalafmt.conf b/.scalafmt.conf
index fff12fe9..528d0d67 100644
--- a/.scalafmt.conf
+++ b/.scalafmt.conf
@@ -1,4 +1,4 @@
-version = 3.1.2
+version = 3.2.0
 runner.dialect = scala213
 assumeStandardLibraryStripMargin = true
 align.openParenCallSite = false
diff --git a/modules/core/src/main/scala/org/scalasteward/core/io/process.scala b/modules/core/src/main/scala/org/scalasteward/core/io/process.scala
index 5228d32d..48083a94 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/io/process.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/io/process.scala
@@ -42,13 +42,10 @@ object process {
   )(implicit F: Async[F]): F[List[String]] =
     createProcess(args).flatMap { process =>
       F.delay(new ListBuffer[String]).flatMap { buffer =>
-        val readOut = {
-          val out = readInputStream[F](process.getInputStream)
-          out
-            .evalMap(line => F.delay(appendBounded(buffer, line, maxBufferSize)) >> log(line))
-            .compile
-            .drain
-        }
+        val readOut = readInputStream[F](process.getInputStream)
+          .evalMap(line => F.delay(appendBounded(buffer, line, maxBufferSize)) >> log(line))
+          .compile
+          .drain
 
         val result = readOut >> F.blocking(process.waitFor()) >>= { exitValue =>
           if (exitValue === 0) F.pure(buffer.toList)
@@ -63,7 +60,7 @@ object process {
           F.raiseError[List[String]](new TimeoutException(makeMessage(msg, buffer.toList)))
         }
 
-        F.timeoutTo(result, timeout, fallback)
+        F.timeoutAndForget(result, timeout).recoverWith { case _: TimeoutException => fallback }
       }
     }
 


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/io/processTest.scala b/modules/core/src/test/scala/org/scalasteward/core/io/processTest.scala
index 693d26f8..1274c694 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/io/processTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/io/processTest.scala
@@ -4,7 +4,8 @@ import cats.effect.IO
 import cats.effect.unsafe.implicits.global
 import munit.FunSuite
 import org.scalasteward.core.io.process.Args
-import org.scalasteward.core.util.Nel
+import org.scalasteward.core.util.{DateTimeAlg, Nel}
+import scala.concurrent.TimeoutException
 import scala.concurrent.duration._
 
 class processTest extends FunSuite {
@@ -38,6 +39,13 @@ class processTest extends FunSuite {
   }
 
   test("sleep 1: fail") {
-    assert(slurp2(Nel.of("sleep", "1"), 500.milliseconds).attempt.unsafeRunSync().isLeft)
+    val timeout = 500.milliseconds
+    val sleep = timeout * 2
+    val p = slurp2(Nel.of("sleep", sleep.toSeconds.toInt.toString), timeout).attempt
+    val (Left(t), fd) = DateTimeAlg.create[IO].timed(p).unsafeRunSync()
+
+    assert(clue(t).isInstanceOf[TimeoutException])
+    assert(clue(fd) > timeout)
+    assert(clue(fd) < sleep)
   }
 }
Repository: scala-steward-org/scala-steward
Pull request #2386 (2021-11-30 04:42:34)

Move `UpdateState` into its own file
It has nothing to do with `NewPullRequestData`.


Patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/vcs/data/NewPullRequestData.scala b/modules/core/src/main/scala/org/scalasteward/core/vcs/data/NewPullRequestData.scala
index 75900374..d2fd33c4 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/vcs/data/NewPullRequestData.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/vcs/data/NewPullRequestData.scala
@@ -28,13 +28,6 @@ import org.scalasteward.core.git.Branch
 import org.scalasteward.core.repoconfig.RepoConfigAlg
 import org.scalasteward.core.util.{Details, Nel}
 
-final case class UpdateState(
-    state: PullRequestState
-)
-object UpdateState {
-  implicit val updateStateEncoder: Encoder[UpdateState] = deriveEncoder
-}
-
 final case class NewPullRequestData(
     title: String,
     body: String,


Test patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/vcs/data/UpdateState.scala b/modules/core/src/main/scala/org/scalasteward/core/vcs/data/UpdateState.scala
new file mode 100644
index 00000000..4a797d1a
--- /dev/null
+++ b/modules/core/src/main/scala/org/scalasteward/core/vcs/data/UpdateState.scala
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2018-2021 Scala Steward contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.scalasteward.core.vcs.data
+
+import io.circe.Encoder
+import io.circe.generic.semiauto.deriveEncoder
+
+final case class UpdateState(
+    state: PullRequestState
+)
+
+object UpdateState {
+  implicit val updateStateEncoder: Encoder[UpdateState] = deriveEncoder
+}
Repository: scala-steward-org/scala-steward
Pull request #2517 (2022-02-08 11:52:11)

Limit precision for human readability
Context: https://github.com/scala-steward-org/scala-steward/pull/2515#discussion_r801344269

This also helps adding new time-related test in PR #2515


Patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/util/dateTime.scala b/modules/core/src/main/scala/org/scalasteward/core/util/dateTime.scala
index 4c0f3e31..ffe198e3 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/util/dateTime.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/util/dateTime.scala
@@ -42,7 +42,7 @@ object dateTime {
         case MICROSECONDS => "µs"
         case NANOSECONDS  => "ns"
       }
-    splitDuration(d).map(d1 => d1.length.toString + symbol(d1.unit)).mkString(" ")
+    splitDuration(d).map(d1 => d1.length.toString + symbol(d1.unit)).take(3).mkString(" ")
   }
 
   def splitDuration(d: FiniteDuration): List[FiniteDuration] = {


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/util/dateTimeTest.scala b/modules/core/src/test/scala/org/scalasteward/core/util/dateTimeTest.scala
index d312f440..29fb773b 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/util/dateTimeTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/util/dateTimeTest.scala
@@ -29,7 +29,7 @@ class dateTimeTest extends ScalaCheckSuite {
 
   test("showDuration: example 1") {
     val d = 2.days + 20.hours + 37.minutes + 3.seconds + 586.millis + 491.micros + 264.nanos
-    assertEquals(showDuration(d), "2d 20h 37m 3s 586ms 491µs 264ns")
+    assertEquals(showDuration(d), "2d 20h 37m")
   }
 
   test("showDuration: example 2") {
Repository: scala-steward-org/scala-steward
Pull request #2655 (2022-07-04 19:54:55)

Add command to the commit message of post-update hooks
This adds the executed command of post-update hooks to their commit
message. It makes it obvious what Scala Steward did and is helpful for
users who want to reproduce the changes themselves.


Patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/HookExecutor.scala b/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/HookExecutor.scala
index 470aacb3..b5effcf3 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/HookExecutor.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/edit/hooks/HookExecutor.scala
@@ -65,7 +65,9 @@ final class HookExecutor[F[_]](implicit
       result <- logger.attemptWarn.log("Post-update hook failed") {
         processAlg.execMaybeSandboxed(hook.useSandbox)(hook.command, repoDir)
       }
-      commitMessage = hook.commitMessage(update)
+      commitMessage = hook
+        .commitMessage(update)
+        .withParagraph(s"Executed command: ${hook.command.mkString_(" ")}")
       maybeHookCommit <- gitAlg.commitAllIfDirty(repo, commitMessage)
       maybeBlameIgnoreCommit <-
         maybeHookCommit.flatTraverse(addToGitBlameIgnoreRevs(repo, repoDir, hook, _, commitMessage))
diff --git a/modules/core/src/main/scala/org/scalasteward/core/git/CommitMsg.scala b/modules/core/src/main/scala/org/scalasteward/core/git/CommitMsg.scala
index bc543ab4..80b4ba36 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/git/CommitMsg.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/git/CommitMsg.scala
@@ -29,6 +29,9 @@ final case class CommitMsg(
   def toNel: Nel[String] =
     Nel(title, body ++ trailers)
 
+  def withParagraph(paragraph: String): CommitMsg =
+    copy(body = body :+ paragraph)
+
   private def trailers: Option[String] = {
     val lines = coAuthoredBy.map(author => s"Co-authored-by: ${author.show}")
     Nel.fromList(lines).map(_.mkString_("\n"))


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/edit/hooks/HookExecutorTest.scala b/modules/core/src/test/scala/org/scalasteward/core/edit/hooks/HookExecutorTest.scala
index 30218ce9..bd1f5c35 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/edit/hooks/HookExecutorTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/edit/hooks/HookExecutorTest.scala
@@ -64,7 +64,9 @@ class HookExecutorTest extends CatsEffectSuite {
           "--all",
           "--no-gpg-sign",
           "-m",
-          "Reformat with scalafmt 2.7.5"
+          "Reformat with scalafmt 2.7.5",
+          "-m",
+          s"Executed command: $scalafmtBinary ${opts.nonInteractive}"
         ),
         Cmd(gitCmd(repoDir), "rev-parse", "--verify", "HEAD"),
         Cmd("read", gitBlameIgnoreRevs.pathAsString),
Repository: scala-steward-org/scala-steward
Pull request #2707 (2022-09-06 10:49:18)

Ignore common prefix weight for snapshots ordering
This is a bug fix to match the documented behavior in #2635 

> This also implies, that it will be allowed for snapshot versions to be updated to snapshots of different series.

For this to work reliably we need to eliminate weight of common prefix in allowPrereleases mode upgrading from Snapshot to Snapshot.

This is crucial, because in many projects (which publishes only snapshots for some reasons like continuous builds) there is no point to merge snapshots one by one sequentially.

Tests for these cases added.


Patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/data/Version.scala b/modules/core/src/main/scala/org/scalasteward/core/data/Version.scala
index 19bdaaaa..77f6b72c 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/data/Version.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/data/Version.scala
@@ -40,11 +40,15 @@ final case class Version(value: String) {
   def selectNext(versions: List[Version], allowPreReleases: Boolean = false): Option[Version] = {
     val cutoff = alnumComponentsWithoutPreRelease.length - 1
     val newerVersionsByCommonPrefix =
-      versions
-        .filter(_ > this)
-        .groupBy(_.alnumComponents.zip(alnumComponents).take(cutoff).takeWhile { case (c1, c2) =>
-          c1 === c2
-        })
+      if (this.isPreRelease && allowPreReleases) {
+        versions.groupBy(_ => List.empty)
+      } else {
+        versions
+          .filter(_ > this)
+          .groupBy(_.alnumComponents.zip(alnumComponents).take(cutoff).takeWhile { case (c1, c2) =>
+            c1 === c2
+          })
+      }
 
     newerVersionsByCommonPrefix.toList
       .sortBy { case (commonPrefix, _) => commonPrefix.length }


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/data/VersionTest.scala b/modules/core/src/test/scala/org/scalasteward/core/data/VersionTest.scala
index 5f2f09b3..12f31408 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/data/VersionTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/data/VersionTest.scala
@@ -253,6 +253,16 @@ class VersionTest extends DisciplineSuite {
         List("0.22.0+99-a0087dd-SNAPSHOT"),
         Some("0.22.0+99-a0087dd-SNAPSHOT")
       ),
+      (
+        "0.21.6+75-6ad94f6f-SNAPSHOT",
+        List("0.21.6+78-a0457da-SNAPSHOT", "0.21.7+81-a0ff7dd-SNAPSHOT"),
+        Some("0.21.7+81-a0ff7dd-SNAPSHOT")
+      ),
+      (
+        "0.21.6+75-6ad94f6f-SNAPSHOT",
+        List("0.21.7+81-a0ff7dd-SNAPSHOT", "0.22.0+99-a0087dd-SNAPSHOT"),
+        Some("0.22.0+99-a0087dd-SNAPSHOT")
+      ),
       ("0.1.1", List("0.2.1-485fdf3b"), None),
       ("0.1.1-RC1", List("0.2.1-485fdf3b"), None),
       ("0.1.1-ALPHA", List("0.2.1-SNAPSHOT"), None),
Repository: scala-steward-org/scala-steward
Pull request #2804 (2022-11-30 06:41:52)

Scalafix artifactId patterns must match whole artifactIds
Closes https://github.com/scala-steward-org/scala-steward/issues/2682.


Patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsFinder.scala b/modules/core/src/main/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsFinder.scala
index 8a91b972..9792e8c8 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsFinder.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsFinder.scala
@@ -17,6 +17,7 @@
 package org.scalasteward.core.edit.scalafix
 
 import cats.syntax.all._
+import java.util.regex.Pattern
 import org.scalasteward.core.data.Update
 import org.scalasteward.core.edit.scalafix.ScalafixMigration.ExecutionOrder
 
@@ -26,7 +27,8 @@ final class ScalafixMigrationsFinder(migrations: List[ScalafixMigration]) {
       .filter { migration =>
         update.groupId === migration.groupId &&
         migration.artifactIds.exists { re =>
-          update.artifactIds.exists(artifactId => re.r.findFirstIn(artifactId.name).isDefined)
+          val pattern = Pattern.compile(re)
+          update.artifactIds.exists(artifactId => pattern.matcher(artifactId.name).matches())
         } &&
         update.currentVersion < migration.newVersion &&
         update.nextVersion >= migration.newVersion


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsFinderTest.scala b/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsFinderTest.scala
index a5ead078..829751cf 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsFinderTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/edit/scalafix/ScalafixMigrationsFinderTest.scala
@@ -9,7 +9,7 @@ import org.scalasteward.core.util.Nel
 class ScalafixMigrationsFinderTest extends FunSuite {
   test("findMigrations") {
     val update = ("org.typelevel".g % "cats-core".a % "2.1.0" %> "2.2.0").single
-    val migrations = scalafixMigrationsFinder.findMigrations(update)
+    val obtained = scalafixMigrationsFinder.findMigrations(update)
     val expected = (
       List(
         ScalafixMigration(
@@ -25,6 +25,13 @@ class ScalafixMigrationsFinderTest extends FunSuite {
       ),
       List()
     )
-    assertEquals(migrations, expected)
+    assertEquals(obtained, expected)
+  }
+
+  test("findMigrations: pattern must match whole artifactId") {
+    val update = ("org.typelevel".g % "log4cats-core".a % "2.1.1" %> "2.4.0").single
+    val obtained = scalafixMigrationsFinder.findMigrations(update)
+    val expected = (List(), List())
+    assertEquals(obtained, expected)
   }
 }
Repository: scala-steward-org/scala-steward
Pull request #2870 (2022-12-31 17:24:13)

Issue #2866: add FEAT to pre-release identifiers
Taking a quick first pass. Happy to iterate based on feedback.


Patch:
diff --git a/modules/core/src/main/scala/org/scalasteward/core/data/Version.scala b/modules/core/src/main/scala/org/scalasteward/core/data/Version.scala
index 77f6b72c..76ac0c6e 100644
--- a/modules/core/src/main/scala/org/scalasteward/core/data/Version.scala
+++ b/modules/core/src/main/scala/org/scalasteward/core/data/Version.scala
@@ -162,10 +162,11 @@ object Version {
     }
     final case class Alpha(value: String) extends Component {
       def isPreReleaseIdent: Boolean = order < 0
-      def isSnapshotIdent: Boolean = order <= -6
+      def isSnapshotIdent: Boolean = order <= -7
       def order: Int =
         value.toUpperCase match {
-          case "SNAP" | "SNAPSHOT" | "NIGHTLY" => -6
+          case "SNAP" | "SNAPSHOT" | "NIGHTLY" => -7
+          case "FEAT" | "FEATURE"              => -6
           case "ALPHA" | "PREVIEW"             => -5
           case "BETA" | "B"                    => -4
           case "EA" /* early access */         => -3


Test patch:
diff --git a/modules/core/src/test/scala/org/scalasteward/core/data/VersionTest.scala b/modules/core/src/test/scala/org/scalasteward/core/data/VersionTest.scala
index 12f31408..505bbdd3 100644
--- a/modules/core/src/test/scala/org/scalasteward/core/data/VersionTest.scala
+++ b/modules/core/src/test/scala/org/scalasteward/core/data/VersionTest.scala
@@ -225,7 +225,10 @@ class VersionTest extends DisciplineSuite {
       ("0.1.1", List("0.2.1-485fdf3b"), None),
       ("0.1.1-ALPHA", List("0.2.1-485fdf3b"), None),
       ("0.1.1-ALPHA", List("0.2.1-BETA"), None),
-      ("0.1.1", List("0.2.1-BETA"), None)
+      ("0.1.1", List("0.2.1-BETA"), None),
+      ("0.1.1", List("0.2.0-FEAT"), None),
+      ("0.1.1-FEAT", List("0.2.0"), Some("0.2.0")),
+      ("0.1.1-FEAT+3dfde9d7", List("0.2.0"), Some("0.2.0"))
     )
 
     val rnd = new Random()
@@ -277,7 +280,9 @@ class VersionTest extends DisciplineSuite {
       ("0.1.1-3dfde9d7", List("0.1.2"), Some("0.1.2")),
       ("0.1.1", List("0.1.2"), Some("0.1.2")),
       ("0.1.1-RC1", List("0.1.2"), Some("0.1.2")),
-      ("0.1.1-ALPHA", List("0.1.2"), Some("0.1.2"))
+      ("0.1.1-ALPHA", List("0.1.2"), Some("0.1.2")),
+      ("0.1.1", List("0.1.2-FEAT"), Some("0.1.2-FEAT")),
+      ("0.1.1", List("0.1.2-FEAT+3dfde9d7"), None)
     )
 
     val rnd = new Random()
Repository: rigetticomputing/pyquil
Pull request #89 (2017-07-25 18:03:06)

__len__ method added for PauliSum (to match PauliTerm)


Patch:
diff --git a/pyquil/paulis.py b/pyquil/paulis.py
index d61464a..2892785 100644
--- a/pyquil/paulis.py
+++ b/pyquil/paulis.py
@@ -282,6 +282,12 @@ class PauliSum(object):
     def __str__(self):
         return " + ".join([str(term) for term in self.terms])
 
+    def __len__(self):
+        """
+        The length of the PauliSum is the number of PauliTerms in the sum.
+        """
+        return len(self.terms)
+
     def __getitem__(self, item):
         """
         :param int item: The index of the term in the sum to return


Test patch:
diff --git a/pyquil/tests/test_paulis.py b/pyquil/tests/test_paulis.py
index 25db2fc..ac4d66c 100644
--- a/pyquil/tests/test_paulis.py
+++ b/pyquil/tests/test_paulis.py
@@ -129,6 +129,11 @@ def test_len():
     assert len(term) == 2
 
 
+def test_sum_len():
+    pauli_sum = PauliTerm("Z", 0, 1.0) + PauliTerm("Z", 1, 1.0)
+    assert len(pauli_sum) == 2
+
+
 def test_enumerate():
     term = PauliTerm("Z", 0, 1.0) * PauliTerm("Z", 1, 1.0) * PauliTerm("X", 5, 5)
     position_op_pairs = [(0, "Z"), (1, "Z"), (5, "X")]