ernie-research/MEnvData-SWE huggingface dataset:
Repository: sanic-org/sanic (Python)

Issue:
RecursionError on Sanic subclass initialisation
Discovered at https://github.com/sanic-org/sanic/issues/2071

version: latest sanic master (`8a2ea626c6d04a5eb1e28d071ffa56bf9ad98a12`)

description:

RecursionError occurs when initialising Sanic subclass

minimal code to reproduce:

```python
from sanic import Sanic


class Custom(Sanic):
    pass

custom = Custom("custom")
```


Potential fix: https://github.com/sanic-org/sanic/pull/2072


Discussion:

Patch:
diff --git a/sanic/base.py b/sanic/base.py
index 5170614950..368288c408 100644
--- a/sanic/base.py
+++ b/sanic/base.py
@@ -8,38 +8,19 @@
 from sanic.mixins.signals import SignalMixin
 
 
-class Base(type):
-    def __new__(cls, name, bases, attrs):
-        init = attrs.get("__init__")
-
-        def __init__(self, *args, **kwargs):
-            nonlocal init
-            nonlocal name
-
-            bases = [
-                b for base in type(self).__bases__ for b in base.__bases__
-            ]
-
-            for base in bases:
-                base.__init__(self, *args, **kwargs)
-
-            if init:
-                init(self, *args, **kwargs)
-
-        attrs["__init__"] = __init__
-        return type.__new__(cls, name, bases, attrs)
-
-
 class BaseSanic(
     RouteMixin,
     MiddlewareMixin,
     ListenerMixin,
     ExceptionMixin,
     SignalMixin,
-    metaclass=Base,
 ):
     __fake_slots__: Tuple[str, ...]
 
+    def __init__(self, *args, **kwargs) -> None:
+        for base in BaseSanic.__bases__:
+            base.__init__(self, *args, **kwargs)  # type: ignore
+
     def __str__(self) -> str:
         return f"<{self.__class__.__name__} {self.name}>"
 
diff --git a/sanic/blueprints.py b/sanic/blueprints.py
index f8b0323c00..85b60ddc18 100644
--- a/sanic/blueprints.py
+++ b/sanic/blueprints.py
@@ -73,6 +73,7 @@ def __init__(
         version: Optional[int] = None,
         strict_slashes: Optional[bool] = None,
     ):
+        super().__init__()
 
         self._apps: Set[Sanic] = set()
         self.ctx = SimpleNamespace()


Test patch:
diff --git a/tests/test_app.py b/tests/test_app.py
index bfe7900c23..f096496a47 100644
--- a/tests/test_app.py
+++ b/tests/test_app.py
@@ -405,3 +405,10 @@ def test_app_set_context(app):
 
     retrieved = Sanic.get_app(app.name)
     assert retrieved.ctx.foo == 1
+
+
+def test_subclass_initialisation():
+    class CustomSanic(Sanic):
+        pass
+
+    CustomSanic("test_subclass_initialisation")
Repository: sympy/sympy (Python)

Issue:
Ellipse with 0 h or v radius is Segment
```
>>> Ellipse((a, b),3,0)
Ellipse(Point2D(0, 0), 3, 0)
>>> _.equation()
x**2/9 + zoo*y**2 - 1
```
This could be
```
Segment((a-3,b),(a+3,b))
```
and similar for the case when hradius is 0. When both are zero, a Point should be obtained.


Discussion:
Possible side-effects would be `isinstance(Ellipse((a, b), 3, 0), Ellipse)` (wrt this issue) and `isinstance(Circle((1, 2), 0), Circle)` (wrt #15259) returning `False`.



Patch:
diff --git a/sympy/geometry/ellipse.py b/sympy/geometry/ellipse.py
index 93766e25d358..0c02cc480f05 100644
--- a/sympy/geometry/ellipse.py
+++ b/sympy/geometry/ellipse.py
@@ -26,7 +26,7 @@
 
 from .entity import GeometryEntity, GeometrySet
 from .point import Point, Point2D, Point3D
-from .line import Line, LinearEntity
+from .line import Line, LinearEntity, Segment
 from .util import idiff
 
 import random
@@ -147,6 +147,9 @@ def __new__(
         if hradius == vradius:
             return Circle(center, hradius, **kwargs)
 
+        if hradius == 0 or vradius == 0:
+            return Segment(Point(center[0] - hradius, center[1] - vradius), Point(center[0] + hradius, center[1] + vradius))
+
         return GeometryEntity.__new__(cls, center, hradius, vradius, **kwargs)
 
     def _svg(self, scale_factor=1., fill_color="#66cc99"):


Test patch:
diff --git a/sympy/geometry/tests/test_ellipse.py b/sympy/geometry/tests/test_ellipse.py
index 01756ff84232..fb89b7da9a4a 100644
--- a/sympy/geometry/tests/test_ellipse.py
+++ b/sympy/geometry/tests/test_ellipse.py
@@ -58,6 +58,10 @@ def test_ellipse_geom():
     assert c1.hradius == 1
     assert c1.vradius == 1
 
+    assert Ellipse((1, 1), 0, 0) == Point(1, 1)
+    assert Ellipse((1, 1), 1, 0) == Segment(Point(0, 1), Point(2, 1))
+    assert Ellipse((1, 1), 0, 1) == Segment(Point(1, 0), Point(1, 2))
+
     # Private Functions
     assert hash(c1) == hash(Circle(Point(1, 0), Point(0, 1), Point(0, -1)))
     assert c1 in e1
@@ -421,7 +425,7 @@ def test_circumference():
     assert Ellipse(Point(0, 0), 5, 4).circumference == 20 * elliptic_e(S(9) / 25)
 
     # degenerate ellipse
-    assert Ellipse(None, 1, None, 1).circumference == 4
+    assert Ellipse(None, 1, None, 1).length == 2
 
     # circle
     assert Ellipse(None, 1, None, 0).circumference == 2*pi
Repository: getsentry/responses (Python)

Issue:
Regression between 0.10.7 and 0.10.8
Minimal reproduction:
```
import responses
import requests


@responses.activate
def test_it():
    
    def request_callback(request):
        return (
            200,
            [('Content-Type', 'application/json')],
            b'foo',
        )

    responses.add_callback('GET', 'http://mockhost/.foo', callback=request_callback)
    resp = requests.get('http://mockhost/.foo')
    assert resp.headers['content-type'] == 'application/json'
```

This test succeeds on 0.10.7, and fails on 0.10.8.

This may be the root cause behind #292, but that ticket contains insufficient details to confirm this suspicion, so I created a new ticket instead.


Discussion:

Patch:
diff --git a/responses.py b/responses.py
index e841af9b..eff4033a 100644
--- a/responses.py
+++ b/responses.py
@@ -408,7 +408,14 @@ def get_response(self, request):
         # If the callback set a content-type remove the one
         # set in add_callback() so that we don't have multiple
         # content type values.
-        if "Content-Type" in r_headers:
+        has_content_type = False
+        if isinstance(r_headers, dict) and "Content-Type" in r_headers:
+            has_content_type = True
+        elif isinstance(r_headers, list):
+            has_content_type = any(
+                [h for h in r_headers if h and h[0].lower() == "content-type"]
+            )
+        if has_content_type:
             headers.pop("Content-Type", None)
 
         body = _handle_body(body)


Test patch:
diff --git a/test_responses.py b/test_responses.py
index f5720254..6f6482f8 100644
--- a/test_responses.py
+++ b/test_responses.py
@@ -499,6 +499,44 @@ def run():
     assert_reset()
 
 
+def test_callback_content_type_dict():
+    def request_callback(request):
+        return (
+            200,
+            {"Content-Type": "application/json"},
+            b"foo",
+        )
+
+    @responses.activate
+    def run():
+        responses.add_callback("GET", "http://mockhost/.foo", callback=request_callback)
+        resp = requests.get("http://mockhost/.foo")
+        assert resp.text == "foo"
+        assert resp.headers["content-type"] == "application/json"
+
+    run()
+    assert_reset()
+
+
+def test_callback_content_type_tuple():
+    def request_callback(request):
+        return (
+            200,
+            [("Content-Type", "application/json")],
+            b"foo",
+        )
+
+    @responses.activate
+    def run():
+        responses.add_callback("GET", "http://mockhost/.foo", callback=request_callback)
+        resp = requests.get("http://mockhost/.foo")
+        assert resp.text == "foo"
+        assert resp.headers["content-type"] == "application/json"
+
+    run()
+    assert_reset()
+
+
 def test_regular_expression_url():
     @responses.activate
     def run():
Repository: sympy/sympy (Python)

Issue:
regression: `factor(f, x, deep=True)` 
Consider the factorable expression f:
```
>>> g = (x+3)*(x+4)*(y+5)*(y+6)
>>> f = g.expand()

 2  2       2         2        2                        2              
x ⋅y  + 11⋅x ⋅y + 30⋅x  + 7⋅x⋅y  + 77⋅x⋅y + 210⋅x + 12⋅y  + 132⋅y + 360
```

Good:
```
>>> f.factor(x)
                ⎛ 2            ⎞
(x + 3)⋅(x + 4)⋅⎝y  + 11⋅y + 30⎠
```

Regression:
```
>>> f.factor(x, deep=True)
(x + 3)⋅(x + 4)⋅(y + 5)⋅(y + 6)
```
(I think this should do the same as above)

This is a regression from 1.3, bisected to 9b879cc1dd0acee7d2f741dadea22ebd4f010732

CC @normalhuman 


Discussion:
It would probably suffice to include the parameters in [`_try_factor`](https://github.com/sympy/sympy/blob/master/sympy/polys/polytools.py#L6322):

`fac = factor(expr)` -> `fac = factor(expr, *gens, **args)`

(as `deep` has been popped already).



Patch:
diff --git a/sympy/polys/polytools.py b/sympy/polys/polytools.py
index b892a8be0aeb..886627692851 100644
--- a/sympy/polys/polytools.py
+++ b/sympy/polys/polytools.py
@@ -6319,7 +6319,7 @@ def _try_factor(expr):
             """
             Factor, but avoid changing the expression when unable to.
             """
-            fac = factor(expr)
+            fac = factor(expr, *gens, **args)
             if fac.is_Mul or fac.is_Pow:
                 return fac
             return expr


Test patch:
diff --git a/sympy/polys/tests/test_polytools.py b/sympy/polys/tests/test_polytools.py
index 32ff08fc75a3..2a64eb377ffc 100644
--- a/sympy/polys/tests/test_polytools.py
+++ b/sympy/polys/tests/test_polytools.py
@@ -2471,6 +2471,11 @@ def test_factor():
         0.5*y + 1.0, evaluate = False)
     assert factor(expand((0.5*x+0.5)**2)) == 0.25*(1.0*x + 1.0)**2
 
+    eq = x**2*y**2 + 11*x**2*y + 30*x**2 + 7*x*y**2 + 77*x*y + 210*x + 12*y**2 + 132*y + 360
+    assert factor(eq, x) == (x + 3)*(x + 4)*(y**2 + 11*y + 30)
+    assert factor(eq, x, deep=True) == (x + 3)*(x + 4)*(y**2 + 11*y + 30)
+    assert factor(eq, y, deep=True) == (y + 5)*(y + 6)*(x**2 + 7*x + 12)
+
 
 def test_factor_large():
     f = (x**2 + 4*x + 4)**10000000*(x**2 + 1)*(x**2 + 2*x + 1)**1234567
Repository: sympy/sympy (Python)

Issue:
Incorrect result from minpoly(cos(pi/9))
I believe that sympy returns the incorrect answer for `minpoly(cos(pi/9))`.

sympy 1.8 and sympy gamma (as of 05/12/2021) return `8*x**3 - 6*x + 1`, but the correct answer is `8*x**3 - 6*x - 1` which I verified by hand and with [Wolfram Alpha](https://www.wolframalpha.com/input/?i=minpoly%28cos%28pi%2F9%29%29).

```py
In [1]: from sympy import *

In [2]: x=symbols("x")

In [3]: p=minpoly(cos(pi/9),x)

In [4]: p
Out[4]: 8*x**3 - 6*x + 1

In [5]: N(p.subs(x,cos(pi/9)))
Out[5]: 2.00000000000000

In [6]: p=8*x**3 - 6*x - 1

In [7]: N(p.subs(x,cos(pi/9)))
Out[7]: 0.e-124
```

I think the bug is [here](https://github.com/sympy/sympy/blob/82cc5a598f236b32b5f7adf530802503c121b080/sympy/polys/numberfields/minpoly.py#L440), the code should be `return 8*x**3 - 6*x - 1`


Discussion:
I agree that this is a typo. The documentation in the code refers to https://mathworld.wolfram.com/TrigonometryAngles.html (table between eq. 11 and eq. 12), which also states `8*x**3 - 6*x - 1`, yet the code reads `8*x**3 - 6*x + 1`

https://github.com/sympy/sympy/blob/82cc5a598f236b32b5f7adf530802503c121b080/sympy/polys/numberfields/minpoly.py#L428-L440
Yes, you're right, it should be `8*x**3 - 6*x - 1`, which is familiar from the proof of the impossibility of the trisection! Thanks for catching this!
Ok, if nobody else has started yet, I will try to work on this one. I just wanted to wait and see if it was sympy or me that had the wrong answer.
[Link to PR](https://github.com/sympy/sympy/pull/22610)



Patch:
diff --git a/sympy/polys/numberfields/minpoly.py b/sympy/polys/numberfields/minpoly.py
index 797a2af20521..1b62e1e6b5cd 100644
--- a/sympy/polys/numberfields/minpoly.py
+++ b/sympy/polys/numberfields/minpoly.py
@@ -437,7 +437,7 @@ def _minpoly_cos(ex, x):
                 if c.q == 7:
                     return 8*x**3 - 4*x**2 - 4*x + 1
                 if c.q == 9:
-                    return 8*x**3 - 6*x + 1
+                    return 8*x**3 - 6*x - 1
             elif c.p == 2:
                 q = sympify(c.q)
                 if q.is_prime:


Test patch:
diff --git a/sympy/polys/numberfields/tests/test_minpoly.py b/sympy/polys/numberfields/tests/test_minpoly.py
index ee202b914646..e61cfe615254 100644
--- a/sympy/polys/numberfields/tests/test_minpoly.py
+++ b/sympy/polys/numberfields/tests/test_minpoly.py
@@ -273,7 +273,7 @@ def test_minpoly_compose():
             2816*x**6 - 1232*x**4 + 220*x**2 - 11
     assert minimal_polynomial(sin(pi/21), x) == 4096*x**12 - 11264*x**10 + \
            11264*x**8 - 4992*x**6 + 960*x**4 - 64*x**2 + 1
-    assert minimal_polynomial(cos(pi/9), x) == 8*x**3 - 6*x + 1
+    assert minimal_polynomial(cos(pi/9), x) == 8*x**3 - 6*x - 1
 
     ex = 2**Rational(1, 3)*exp(2*I*pi/3)
     assert minimal_polynomial(ex, x) == x**3 - 2
Repository: Kludex/uvicorn (Python)

Issue:
Passing `reload_dirs` as a string instead of a list
@Roang-zero1 @euri10 @Kludex this PR introduced a regression and deleted the test for it (`test_reload_dir_is_set()`). Previously you could pass `reload_dirs` a string instead of a list. Now:
```python
Config('myapp:app', reload=True, reload_dirs='src')
```
prints:
```
WARNING:  Provided reload directories ['r', 'c', 's'] did not contain valid directories, watching current working directory.
```
https://github.com/encode/uvicorn/pull/820/files#diff-6982a5e270879281f9182303a9da9776148857b46325afb230e50ef8eb3264c9R294
(Of course, `set` expects an iterable... and strings are iterables of chars.)

_Originally posted by @HansBrende in https://github.com/encode/uvicorn/issues/820#issuecomment-977957988_


Discussion:
happy to take a PR on this @HansBrende 
Sure, why not.
@euri10 PR submitted ^



Patch:
diff --git a/uvicorn/config.py b/uvicorn/config.py
index 683a83079..59c94b412 100644
--- a/uvicorn/config.py
+++ b/uvicorn/config.py
@@ -180,7 +180,15 @@ def resolve_reload_patterns(
 
     directories = list(set(directories).difference(set(children)))
 
-    return (list(set(patterns)), directories)
+    return list(set(patterns)), directories
+
+
+def _normalize_dirs(dirs: Union[List[str], str, None]) -> List[str]:
+    if dirs is None:
+        return []
+    if isinstance(dirs, str):
+        return [dirs]
+    return list(set(dirs))
 
 
 class Config:
@@ -291,9 +299,9 @@ def __init__(
             )
 
         if self.should_reload:
-            reload_dirs = list(set(reload_dirs)) if reload_dirs else []
-            reload_includes = list(set(reload_includes)) if reload_includes else []
-            reload_excludes = list(set(reload_excludes)) if reload_excludes else []
+            reload_dirs = _normalize_dirs(reload_dirs)
+            reload_includes = _normalize_dirs(reload_includes)
+            reload_excludes = _normalize_dirs(reload_excludes)
 
             self.reload_includes, self.reload_dirs = resolve_reload_patterns(
                 reload_includes, reload_dirs


Test patch:
diff --git a/tests/test_config.py b/tests/test_config.py
index 7a04092d5..265d09b36 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -119,6 +119,10 @@ def test_reload_dir_is_set(
             == f"Will watch for changes in these directories: {[str(app_dir)]}"
         )
         assert config.reload_dirs == [app_dir]
+        config = Config(
+            app="tests.test_config:asgi_app", reload=True, reload_dirs=str(app_dir)
+        )
+        assert config.reload_dirs == [app_dir]
 
 
 def test_non_existant_reload_dir_is_not_set(
Repository: nvbn/thefuck (Python)

Issue:
git checkout new branch suggestion improvement
Currently if i do the following:

    > git checkout my-new-branch
     error: pathspec 'my-new-branch' did not match any file(s) known to git.
    > fuck
I get the following suggestion:

    > git branch my-new-branch && git checkout my-new-branch

This works fine, but what i more likely meant (and this does the same thing) is:

    > git checkout -b my-new-branch

This is much more succinct and should probably be the suggestion in my opinion.



Discussion:

Patch:
diff --git a/thefuck/rules/git_checkout.py b/thefuck/rules/git_checkout.py
index 934f0a497..65705f4f0 100644
--- a/thefuck/rules/git_checkout.py
+++ b/thefuck/rules/git_checkout.py
@@ -34,6 +34,8 @@ def get_new_command(command):
                                        fallback_to_first=False)
     if closest_branch:
         return replace_argument(command.script, missing_file, closest_branch)
+    elif command.script_parts[1] == 'checkout':
+        return replace_argument(command.script, 'checkout', 'checkout -b')
     else:
         return shell.and_('git branch {}', '{}').format(
             missing_file, command.script)


Test patch:
diff --git a/tests/rules/test_git_checkout.py b/tests/rules/test_git_checkout.py
index 355b6862e..a803f201e 100644
--- a/tests/rules/test_git_checkout.py
+++ b/tests/rules/test_git_checkout.py
@@ -52,7 +52,7 @@ def test_get_branches(branches, branch_list, git_branch):
 @pytest.mark.parametrize('branches, command, new_command', [
     (b'',
      Command('git checkout unknown', did_not_match('unknown')),
-     'git branch unknown && git checkout unknown'),
+     'git checkout -b unknown'),
     (b'',
      Command('git commit unknown', did_not_match('unknown')),
      'git branch unknown && git commit unknown'),
Repository: pypa/twine (Python)

Issue:
Improve `--verbose` suggestion
While responding to #671 (and other issues), I saw that the current suggestion is:

```
NOTE: Try --verbose to see response content.
```

Now that Twine has more useful verbose logging ([as of 3.3.0](https://twine.readthedocs.io/en/latest/changelog.html#twine-3-3-0-2020-12-23)), I think we might enable users to self-serve more effectively with a message like:

```
For more details, retry the upload with the --verbose option.
```



Discussion:
I'm +1 on this. It doesn't show the response content only but also files to be uploaded, etc.

Opened #807 for this.



Patch:
diff --git a/twine/utils.py b/twine/utils.py
index e5bdb4b5..48d3a34f 100644
--- a/twine/utils.py
+++ b/twine/utils.py
@@ -200,7 +200,9 @@ def check_status_code(response: requests.Response, verbose: bool) -> None:
         if response.text:
             logger.info("Content received from server:\n{}".format(response.text))
             if not verbose:
-                logger.warning("NOTE: Try --verbose to see response content.")
+                logger.warning(
+                    "For more details, retry the upload with the --verbose option."
+                )
         raise err
 
 


Test patch:
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 903155f9..cbcba7d5 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -285,7 +285,12 @@ def test_check_status_code_for_missing_status_code(
     if verbose:
         assert captured.out.count("Content received from server:\nForbidden\n") == 1
     else:
-        assert captured.out.count("NOTE: Try --verbose to see response content.\n") == 1
+        assert (
+            captured.out.count(
+                "For more details, retry the upload with the --verbose option.\n"
+            )
+            == 1
+        )
 
 
 @pytest.mark.parametrize(
Repository: getmoto/moto (Python)

Issue:
CloudFront: list_invalidations includes empty element if no invalidations
## How to reproduce the issue

```python
@mock_cloudfront
def test_list_invalidations__no_entries():
    client = boto3.client("cloudfront", region_name="us-west-1")

    resp = client.list_invalidations(
        DistributionId="SPAM",
    )

    resp.should.have.key("InvalidationList")
    resp["InvalidationList"].shouldnt.have.key("NextMarker")
    resp["InvalidationList"].should.have.key("MaxItems").equal(100)
    resp["InvalidationList"].should.have.key("IsTruncated").equal(False)
    resp["InvalidationList"].should.have.key("Quantity").equal(0)
    resp["InvalidationList"].shouldnt.have.key("Items")
```

### what you expected to happen

Test passes

### what actually happens

The final assertion fails.

## what version of Moto you're using

moto 4.0.7
boto3 1.24.90
botocore 1.27.90


Discussion:

Patch:
diff --git a/moto/cloudfront/responses.py b/moto/cloudfront/responses.py
index 89b223da00fc..b434b7c97996 100644
--- a/moto/cloudfront/responses.py
+++ b/moto/cloudfront/responses.py
@@ -622,6 +622,7 @@ def list_tags_for_resource(self) -> TYPE_RESPONSE:
 INVALIDATIONS_TEMPLATE = """<?xml version="1.0" encoding="UTF-8"?>
 <InvalidationList>
    <IsTruncated>false</IsTruncated>
+   {% if invalidations %}
    <Items>
       {% for invalidation in invalidations %}
       <InvalidationSummary>
@@ -631,6 +632,7 @@ def list_tags_for_resource(self) -> TYPE_RESPONSE:
       </InvalidationSummary>
       {% endfor %}
    </Items>
+   {% endif %}
    <Marker></Marker>
    <MaxItems>100</MaxItems>
    <Quantity>{{ invalidations|length }}</Quantity>


Test patch:
diff --git a/tests/test_cloudfront/test_cloudfront_invalidation.py b/tests/test_cloudfront/test_cloudfront_invalidation.py
index dfa3c067a333..b7c9600d3762 100644
--- a/tests/test_cloudfront/test_cloudfront_invalidation.py
+++ b/tests/test_cloudfront/test_cloudfront_invalidation.py
@@ -76,4 +76,4 @@ def test_list_invalidations__no_entries():
     resp["InvalidationList"].should.have.key("MaxItems").equal(100)
     resp["InvalidationList"].should.have.key("IsTruncated").equal(False)
     resp["InvalidationList"].should.have.key("Quantity").equal(0)
-    resp["InvalidationList"].should.have.key("Items").equals([])
+    resp["InvalidationList"].shouldnt.have.key("Items")
Repository: commitizen-tools/commitizen (Python)

Issue:
Allow lower case names for SemVer `--increment` 
### Description

The cz cli only accepts upper case increment names, but some tools work with lower case names for the same increment types. So, to keep things simpler in scripts, it'd be great to don't care about transforming to lower/upper case.

### Possible Solution

Since `decli` is mostly a declarative wrapper around `argparse`, maybe a simple `str.upper` can be used as the [`type`](https://docs.python.org/3/library/argparse.html#type) for `increment`.

This seems to work:

```python
# rps.py
import argparse

parser = argparse.ArgumentParser()
parser.add_argument(
    'move',
    choices=['ROCK', 'PAPER', 'SCISSORS'],
    type=str.upper,
)

args = parser.parse_args()
print(args.move)
```

```console
$ python rps.py rock     
ROCK
```

### Additional context

I can submit a PR if this is desirable.


Discussion:
Hey Edgar, that would be great! A PR is more than welcome 



Patch:
diff --git a/commitizen/cli.py b/commitizen/cli.py
index 90abc55453..0f2d52efc9 100644
--- a/commitizen/cli.py
+++ b/commitizen/cli.py
@@ -145,6 +145,7 @@
                         "name": ["--increment"],
                         "help": "manually specify the desired increment",
                         "choices": ["MAJOR", "MINOR", "PATCH"],
+                        "type": str.upper,
                     },
                     {
                         "name": ["--check-consistency", "-cc"],


Test patch:
diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py
index 1d1df88979..da15174c5d 100644
--- a/tests/commands/test_bump_command.py
+++ b/tests/commands/test_bump_command.py
@@ -109,6 +109,27 @@ def test_bump_major_increment(commit_msg, mocker):
     assert tag_exists is True
 
 
+@pytest.mark.usefixtures("tmp_commitizen_project")
+@pytest.mark.parametrize(
+    "commit_msg,increment,expected_tag",
+    [
+        ("feat: new file", "PATCH", "0.1.1"),
+        ("fix: username exception", "major", "1.0.0"),
+        ("refactor: remove ini configuration support", "patch", "0.1.1"),
+        ("BREAKING CHANGE: age is no longer supported", "minor", "0.2.0"),
+    ],
+)
+def test_bump_command_increment_option(commit_msg, increment, expected_tag, mocker):
+    create_file_and_commit(commit_msg)
+
+    testargs = ["cz", "bump", "--increment", increment, "--yes"]
+    mocker.patch.object(sys, "argv", testargs)
+    cli.main()
+
+    tag_exists = git.tag_exist(expected_tag)
+    assert tag_exists is True
+
+
 @pytest.mark.usefixtures("tmp_commitizen_project")
 def test_bump_command_prelease(mocker):
     # PRERELEASE
Repository: tobymao/sqlglot (Python)

Issue:
Double-quoted dates may not be recognized in MySQL dialect
per https://github.com/dbcli/mycli/pull/1075#discussion_r957254586

This expression 
```
python -c 'import sqlglot; print(sqlglot.parse_one("""SELECT "2021-01-01" + interval 1 month""", read="mysql").sql(dialect="mysql"))'
```
throws 
```
sqlglot.errors.ParseError: Invalid expression / Unexpected token. Line 1, Col: 21.
  SELECT "2021-01-01" + interval 1 month
```

whereas single-quoting the date is accepted.

This would seem to indicate that the string is being read in a strange way:
```
$ python -c 'import sqlglot; print(sqlglot.parse_one("""SELECT "2021-01-01" """, read="mysql").sql(dialect="mysql"))'
SELECT "2021 - 01 - 01 AS "
```

Thanks for an awesome project.


Discussion:
This should fix the issue: https://github.com/tobymao/sqlglot/pull/376

That will parse string literals with double quotes, but it will always generate SQL with single quotes. I think that's acceptable for your prettify use case. Let me know if otherwise.
Fix available in [v5.1.3](https://pypi.org/project/sqlglot/5.1.3/)
> That will parse string literals with double quotes, but it will always generate SQL with single quotes. I think that's acceptable for your prettify use case. Let me know if otherwise.

Perfect.



Patch:
diff --git a/sqlglot/dialects/mysql.py b/sqlglot/dialects/mysql.py
index cd4b2e3496..e4bb06c6f5 100644
--- a/sqlglot/dialects/mysql.py
+++ b/sqlglot/dialects/mysql.py
@@ -9,6 +9,7 @@
 from sqlglot.generator import Generator
 from sqlglot.helper import list_get
 from sqlglot.parser import Parser
+from sqlglot.tokens import Tokenizer
 
 
 def _date_trunc_sql(self, expression):
@@ -85,6 +86,9 @@ class MySQL(Dialect):
         "%u": "%W",
     }
 
+    class Tokenizer(Tokenizer):
+        QUOTES = ["'", '"']
+
     class Parser(Parser):
         STRICT_CAST = False
 


Test patch:
diff --git a/tests/dialects/test_mysql.py b/tests/dialects/test_mysql.py
index d63d6e588d..ae69e3562d 100644
--- a/tests/dialects/test_mysql.py
+++ b/tests/dialects/test_mysql.py
@@ -6,3 +6,11 @@ class TestMySQL(Validator):
 
     def test_identity(self):
         self.validate_identity("SELECT CAST(`a`.`b` AS INT) FROM foo")
+
+    def test_string_literals(self):
+        self.validate(
+            'SELECT "2021-01-01" + INTERVAL 1 MONTH',
+            "SELECT '2021-01-01' + INTERVAL 1 MONTH",
+            read="mysql",
+            write="mysql",
+        )
Repository: pypa/pipx (Python)

Issue:
Upgrading shared libraries messes up JSON output
**Describe the bug**
I have a script that parses the output of `pipx list --json` to list all installed packages. Today, it triggered the upgrading shared libraries logic. The upgrader wrote "upgrading shared libraries..." to stdout, which caused an error when attempting to parse the JSON output.

**How to reproduce**
Manually set `SHARED_LIBS_MAX_AGE_SEC = 0`. Then run `pipx list --json`.

**Expected behavior**
Stdout should contain valid JSON. Instead it contains `upgrading shared libraries...\n{ JSON output... }`



Discussion:

Patch:
diff --git a/docs/changelog.md b/docs/changelog.md
index 7450e740da..b608b04912 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -2,6 +2,7 @@ dev
 
 - Include machinery to build a manpage for pipx with [argparse-manpage](https://pypi.org/project/argparse-manpage/).
 - Add better handling for 'app not found' when a single app is present in the project, and an improved error message (#733)
+- Fixed animations sending output to stdout, which can break JSON output. (#769)
 
 0.17.0
 
diff --git a/src/pipx/animate.py b/src/pipx/animate.py
index 5814ec7e34..e9d8bb375a 100644
--- a/src/pipx/animate.py
+++ b/src/pipx/animate.py
@@ -36,7 +36,7 @@ def animate(
 
     if not do_animation or not _env_supports_animation():
         # No animation, just a single print of message
-        print(f"{message}...")
+        sys.stderr.write(f"{message}...\n")
         yield
         return
 


Test patch:
diff --git a/tests/test_animate.py b/tests/test_animate.py
index 4c612a27d5..b57816e28e 100644
--- a/tests/test_animate.py
+++ b/tests/test_animate.py
@@ -55,6 +55,7 @@ def check_animate_output(
 
 def test_delay_suppresses_output(capsys, monkeypatch):
     monkeypatch.setattr(pipx.animate, "stderr_is_tty", True)
+    monkeypatch.setenv("COLUMNS", "80")
 
     test_string = "asdf"
 
@@ -138,5 +139,5 @@ def test_env_no_animate(capsys, monkeypatch, env_columns, stderr_is_tty):
     time.sleep(extra_after_thread_time)
     captured = capsys.readouterr()
 
-    assert captured.out == expected_string
-    assert captured.err == ""
+    assert captured.out == ""
+    assert captured.err == expected_string
Repository: jax-ml/jax (Python)

Issue:
jvp of jnp.power(arr, scalar) fails
Repro:
```python
>>> import jax
>>> jax.jacrev(jax.jit(jax.lax.pow))(jax.numpy.arange(4.0), 2)
...
TypeError: select cases must have the same shapes, got [(4,), ()].
```
It looks like this was introduced by https://github.com/google/jax/pull/16419.


Discussion:

Patch:
diff --git a/jax/_src/lax/lax.py b/jax/_src/lax/lax.py
index 78d52cef4789..3dc7566adc62 100644
--- a/jax/_src/lax/lax.py
+++ b/jax/_src/lax/lax.py
@@ -1989,6 +1989,10 @@ def _pow_jvp_lhs(g, ans, x, y):
   y_dtype = dtypes.dtype(y)
   x, y = jax._src.numpy.util.promote_dtypes_numeric(x, y)  # TODO replace this
   if dtypes.issubdtype(y_dtype, np.integer):
+    if x.shape != y.shape:
+      shape = broadcast_shapes(x.shape, y.shape)
+      x = _maybe_broadcast(shape, x)
+      y = _maybe_broadcast(shape, y)
     jac = select(eq(y, _const(y, 0)), _ones(y),
                  mul(_replace_zero(y), pow(x, sub(y, _ones(y)))))
   else:


Test patch:
diff --git a/tests/lax_autodiff_test.py b/tests/lax_autodiff_test.py
index faa22afb1f3a..45aac19887fc 100644
--- a/tests/lax_autodiff_test.py
+++ b/tests/lax_autodiff_test.py
@@ -1140,6 +1140,14 @@ def f(x):
     with self.assertRaises(NotImplementedError):
       jax.jacrev(f)(x)
 
+  def testPowShapeMismatch(self):
+    # Regression test for https://github.com/google/jax/issues/17294
+    x = lax.iota('float32', 4)
+    y = 2
+    actual = jax.jacrev(jax.jit(jax.lax.pow))(x, y)  # no error
+    expected = jax.numpy.diag(y * x ** (y - 1))
+    self.assertArraysEqual(actual, expected)
+
 
 if __name__ == '__main__':
   absltest.main(testLoader=jtu.JaxTestLoader())
Repository: wagtail/wagtail (Python)

Issue:
`to_python` throws `AttributeError` on `TableBlock` when value is None
### Issue Summary

Similar to: https://github.com/wagtail/wagtail/issues/4822

After upgrading one of our sites to 6.0, attempting to update some of our pages' indices results in a server error.

```
  File "/venv/lib/python3.8/site-packages/wagtail/contrib/table_block/blocks.py", line 135, in to_python
    if not value.get("table_header_choice", ""):
AttributeError: 'NoneType' object has no attribute 'get'
```

This is because, in Wagtail 6.0, the following code has been added:
https://github.com/wagtail/wagtail/commit/fe1a306285da6c48b66506c589abc2c66b51668a#diff-f058d7a36746222950f678ed6b178205778e4e1e5b85f0299c2a7c3b9d6c8939R129

### Steps to Reproduce

1. Create a page with an empty TableBlock in its body
2. Before Wagtail 6.0, this should save and render OK
3. After upgrading to 6.0, editing the same page will throw an error.
4. Looking at the logs, you should see the error above

A workaround is to identify those pages and remove the empty TableBlocks, but this would prove to be a tedious task if there are many page instances.

A possible fix would be to check if the value is not None first:
```
if value and not value.get("table_header_choice", ""):
```


Discussion:
Thanks for the report! I can confirm this issue using the bakerydemo by creating a new Recipe page with an empty table block.
Thanks for the bug report and the quick fix @laymonage 



Patch:
diff --git a/wagtail/contrib/table_block/blocks.py b/wagtail/contrib/table_block/blocks.py
index 38066501f273..ace83383c559 100644
--- a/wagtail/contrib/table_block/blocks.py
+++ b/wagtail/contrib/table_block/blocks.py
@@ -132,7 +132,7 @@ def to_python(self, value):
         value for the header choice. I would really like to have this default to "" and force the
         editor to reaffirm they don't want any headers, but that would be a breaking change.
         """
-        if not value.get("table_header_choice", ""):
+        if value and not value.get("table_header_choice", ""):
             if value.get("first_row_is_table_header", False) and value.get(
                 "first_col_is_header", False
             ):


Test patch:
diff --git a/wagtail/contrib/table_block/tests.py b/wagtail/contrib/table_block/tests.py
index 51e9eff6dd37..98fb8ef074eb 100644
--- a/wagtail/contrib/table_block/tests.py
+++ b/wagtail/contrib/table_block/tests.py
@@ -439,6 +439,12 @@ def test_merge_cells_render(self):
         """
         self.assertHTMLEqual(result, expected)
 
+    def test_empty_table_block_to_python(self):
+        # Should not raise an error
+        # See https://github.com/wagtail/wagtail/issues/11816
+        block = TableBlock()
+        self.assertIsNone(block.to_python(None))
+
 
 class TestTableBlockForm(WagtailTestUtils, SimpleTestCase):
     def setUp(self):
Repository: python/cpython (Python)

Issue:
Improve error message when trying to call `issubclass()` against a Protocol that has non-method members
# Feature or enhancement

### Proposal:

The error message could tell the user what the non-method members in the protocol are.

### Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

### Links to previous discussion of this feature:

_No response_

<!-- gh-linked-prs -->
### Linked PRs
* gh-112344
<!-- /gh-linked-prs -->



Discussion:

Patch:
diff --git a/Lib/typing.py b/Lib/typing.py
index a96c7083eb785e..872aca82c4e779 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -1828,8 +1828,13 @@ def __subclasscheck__(cls, other):
                 not cls.__callable_proto_members_only__
                 and cls.__dict__.get("__subclasshook__") is _proto_hook
             ):
+                non_method_attrs = sorted(
+                    attr for attr in cls.__protocol_attrs__
+                    if not callable(getattr(cls, attr, None))
+                )
                 raise TypeError(
-                    "Protocols with non-method members don't support issubclass()"
+                    "Protocols with non-method members don't support issubclass()."
+                    f" Non-method members: {str(non_method_attrs)[1:-1]}."
                 )
             if not getattr(cls, '_is_runtime_protocol', False):
                 raise TypeError(
diff --git a/Misc/NEWS.d/next/Library/2023-11-23-17-25-27.gh-issue-112345.FFApHx.rst b/Misc/NEWS.d/next/Library/2023-11-23-17-25-27.gh-issue-112345.FFApHx.rst
new file mode 100644
index 00000000000000..b2b9894e6bef3a
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-11-23-17-25-27.gh-issue-112345.FFApHx.rst
@@ -0,0 +1,3 @@
+Improve error message when trying to call :func:`issubclass` against a
+:class:`typing.Protocol` that has non-method members.
+Patch by Randolf Scholz.


Test patch:
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 2b5f34b4b92e0c..31d7fda2f978da 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -4091,6 +4091,22 @@ def method(self) -> None: ...
         self.assertIsInstance(Foo(), ProtocolWithMixedMembers)
         self.assertNotIsInstance(42, ProtocolWithMixedMembers)
 
+    def test_protocol_issubclass_error_message(self):
+        class Vec2D(Protocol):
+            x: float
+            y: float
+
+            def square_norm(self) -> float:
+                return self.x ** 2 + self.y ** 2
+
+        self.assertEqual(Vec2D.__protocol_attrs__, {'x', 'y', 'square_norm'})
+        expected_error_message = (
+            "Protocols with non-method members don't support issubclass()."
+            " Non-method members: 'x', 'y'."
+        )
+        with self.assertRaisesRegex(TypeError, re.escape(expected_error_message)):
+            issubclass(int, Vec2D)
+
 
 class GenericTests(BaseTestCase):
Repository: python/cpython (Python)

Issue:
dis output is missing information for KW_NAMES
# Bug report

dis output is missing the constant value for KW_NAMES

This is due to a hardcoded check that the op is LOAD_CONST before grabbing the value.
This check comes after a check that the opcode is in dis.hasconst, so reasonably it can be removed to allow KW_NAMES and future opcodes that feature constants to work moving  forward.

I have drafted a simple pull request #99943 to fix this bug


<!-- gh-linked-prs -->
### Linked PRs
* gh-99943
* gh-103856
<!-- /gh-linked-prs -->



Discussion:
It seems that i have the same problem, is this pr still active?
@Lorisredstone The PR needs tests and there is nobody with free time to dig into the matter and add them.
Thank you @chilaxan and @jkchandalia.



Patch:
diff --git a/Lib/dis.py b/Lib/dis.py
index 6a7fcb8a1a0071..f2cb3d34df3aab 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -368,9 +368,8 @@ def _get_const_value(op, arg, co_consts):
     assert op in hasconst
 
     argval = UNKNOWN
-    if op == LOAD_CONST or op == RETURN_CONST:
-        if co_consts is not None:
-            argval = co_consts[arg]
+    if co_consts is not None:
+        argval = co_consts[arg]
     return argval
 
 def _get_const_info(op, arg, co_consts):
diff --git a/Misc/NEWS.d/next/Library/2023-04-25-22-59-06.gh-issue-99944.pst8iT.rst b/Misc/NEWS.d/next/Library/2023-04-25-22-59-06.gh-issue-99944.pst8iT.rst
new file mode 100644
index 00000000000000..80238a65e32a41
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-04-25-22-59-06.gh-issue-99944.pst8iT.rst
@@ -0,0 +1,1 @@
+Make :mod:`dis` display the value of oparg of :opcode:`KW_NAMES`.


Test patch:
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index 2d5c73c9adc920..3ba13a22ff880c 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -227,6 +227,26 @@ def bug42562():
        JUMP_FORWARD            -4 (to 0)
 """
 
+def func_w_kwargs(a, b, **c):
+    pass
+
+def wrap_func_w_kwargs():
+    func_w_kwargs(1, 2, c=5)
+
+dis_kw_names = """\
+%3d        RESUME                   0
+
+%3d        LOAD_GLOBAL              1 (NULL + func_w_kwargs)
+           LOAD_CONST               1 (1)
+           LOAD_CONST               2 (2)
+           LOAD_CONST               3 (5)
+           KW_NAMES                 4 (('c',))
+           CALL                     3
+           POP_TOP
+           RETURN_CONST             0 (None)
+""" % (wrap_func_w_kwargs.__code__.co_firstlineno,
+       wrap_func_w_kwargs.__code__.co_firstlineno + 1)
+
 _BIG_LINENO_FORMAT = """\
   1        RESUME                   0
 
@@ -911,6 +931,10 @@ def test_bug_46724(self):
         # Test that negative operargs are handled properly
         self.do_disassembly_test(bug46724, dis_bug46724)
 
+    def test_kw_names(self):
+        # Test that value is displayed for KW_NAMES
+        self.do_disassembly_test(wrap_func_w_kwargs, dis_kw_names)
+
     def test_big_linenos(self):
         def func(count):
             namespace = {}
Repository: python/cpython (Python)

Issue:
Do not shadow user arguments in generated `__new__` by `@warnings.deprecated`
# Bug report

### Bug description:

Follow comment https://github.com/python/cpython/pull/132055#discussion_r2029062118

```python
from warnings import deprecated


@deprecated("MyMeta will go away soon")
class MyMeta(type):
    def __new__(mcs, name, bases, attrs, cls=None):
        return super().__new__(mcs, name, bases, attrs)


class Foo(metaclass=MyMeta, cls='haha'):
    pass
```

Output:

```console
$ python3 test.py
Traceback (most recent call last):
  File "/Users/PanXuehai/Projects/cpython/test.py", line 10, in <module>
    class Foo(metaclass=MyMeta, cls='haha'):
        pass
TypeError: MyMeta.__new__() got multiple values for argument 'cls'
```

### CPython versions tested on:

3.13

### Operating systems tested on:

macOS

<!-- gh-linked-prs -->
### Linked PRs
* gh-132160
* gh-132163
<!-- /gh-linked-prs -->



Discussion:

Patch:
diff --git a/Lib/warnings.py b/Lib/warnings.py
index df844253ab4e6d..0307f89dafef5a 100644
--- a/Lib/warnings.py
+++ b/Lib/warnings.py
@@ -597,7 +597,7 @@ def __call__(self, arg, /):
             original_new = arg.__new__
 
             @functools.wraps(original_new)
-            def __new__(cls, *args, **kwargs):
+            def __new__(cls, /, *args, **kwargs):
                 if cls is arg:
                     warn(msg, category=category, stacklevel=stacklevel + 1)
                 if original_new is not object.__new__:
diff --git a/Misc/NEWS.d/next/Library/2025-04-06-16-12-49.gh-issue-132159.WvBfBm.rst b/Misc/NEWS.d/next/Library/2025-04-06-16-12-49.gh-issue-132159.WvBfBm.rst
new file mode 100644
index 00000000000000..8cec76e9b47405
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-04-06-16-12-49.gh-issue-132159.WvBfBm.rst
@@ -0,0 +1,1 @@
+Do not shadow user arguments in generated :meth:`!__new__` by decorator :class:`warnings.deprecated`. Patch by Xuehai Pan.


Test patch:
diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py
index 6f4c569d247601..de4280cd22f0c9 100644
--- a/Lib/test/test_warnings/__init__.py
+++ b/Lib/test/test_warnings/__init__.py
@@ -1653,6 +1653,25 @@ class Child(Base, Mixin):
         instance = Child(42)
         self.assertEqual(instance.a, 42)
 
+    def test_do_not_shadow_user_arguments(self):
+        new_called = False
+        new_called_cls = None
+
+        @deprecated("MyMeta will go away soon")
+        class MyMeta(type):
+            def __new__(mcs, name, bases, attrs, cls=None):
+                nonlocal new_called, new_called_cls
+                new_called = True
+                new_called_cls = cls
+                return super().__new__(mcs, name, bases, attrs)
+
+        with self.assertWarnsRegex(DeprecationWarning, "MyMeta will go away soon"):
+            class Foo(metaclass=MyMeta, cls='haha'):
+                pass
+
+        self.assertTrue(new_called)
+        self.assertEqual(new_called_cls, 'haha')
+
     def test_existing_init_subclass(self):
         @deprecated("C will go away soon")
         class C:
Repository: pydantic/pydantic (Python)

Issue:
Issue using annotated_types.Predicate
### Initial Checks

- [X] I confirm that I'm using Pydantic V2

### Description

Using `annotated_types.Predicate` gives unexpected result in 2.9.0. The below code fails but works in <2.9.0. Also replacing `PositiveInt` with `Annotated[int, Gt(0)]` (with `Gt` also from `annotated_types`) does work in 2.9.0.

### Example Code

```Python
from typing import TypeAlias
from typing import Annotated
from annotated_types import Predicate
from pydantic import BaseModel


def is_positive(value: int) -> bool:
    return value > 0


PositiveInt: TypeAlias = Annotated[int, Predicate(is_positive)]


class MyModel(BaseModel):
    foo: PositiveInt


m = MyModel.model_validate({'foo': 3})
assert m.foo == 3
```


### Python, Pydantic & OS Version

```Text
pydantic version: 2.9.0
        pydantic-core version: 2.23.2
          pydantic-core build: profile=release pgo=false
                 install path: /home/axel/venvs/psi/lib/python3.12/site-packages/pydantic
               python version: 3.12.3 (main, Jul 31 2024, 17:43:48) [GCC 13.2.0]
                     platform: Linux-6.8.0-41-generic-x86_64-with-glibc2.39
             related packages: mypy-1.11.0 typing_extensions-4.11.0
                       commit: unknown
```



Discussion:
@AckslD,

Thanks for reporting this. Indeed, a bug on our end. I've opened https://github.com/pydantic/pydantic/pull/10321 to fix this issue, and we'll roll out the fix in a beta release soon!



Patch:
diff --git a/pydantic/_internal/_known_annotated_metadata.py b/pydantic/_internal/_known_annotated_metadata.py
index efdb8924c7a..b34ece10d96 100644
--- a/pydantic/_internal/_known_annotated_metadata.py
+++ b/pydantic/_internal/_known_annotated_metadata.py
@@ -319,6 +319,8 @@ def val_func(v: Any) -> Any:
                             f'Not of {predicate_name} failed',  # type: ignore  # noqa: B023
                         )
 
+                return v
+
             schema = cs.no_info_after_validator_function(val_func, schema)
         else:
             # ignore any other unknown metadata


Test patch:
diff --git a/tests/test_annotated.py b/tests/test_annotated.py
index e0d3da79968..a4160dc7c81 100644
--- a/tests/test_annotated.py
+++ b/tests/test_annotated.py
@@ -385,6 +385,12 @@ def test_validate_float_inf_nan_python() -> None:
     ]
 
 
+def test_predicate_success_python() -> None:
+    ta = TypeAdapter(Annotated[int, Predicate(lambda x: x > 0)])
+
+    assert ta.validate_python(1) == 1
+
+
 def test_predicate_error_python() -> None:
     ta = TypeAdapter(Annotated[int, Predicate(lambda x: x > 0)])
Repository: quantumlib/Cirq (Python)

Issue:
equivalent measurements evaluate as unequal
**Description of the issue**

the default value of `MeasurementGate.invert_mask` is `()`, which should be equivalent to `invert_mask=(False, ...)`. However, specifying the latter results in a gate which evaluates as unequal to the default

it seems like this would be fixed by using `self.full_invert_mask()` instead of `self.invert_mask` in  `MeasurementGate._value_equality_values_`

**How to reproduce the issue**

```python
assert cirq.MeasurementGate(1) == cirq.MeasurementGate(1)  # ok
assert cirq.MeasurementGate(1) == cirq.MeasurementGate(1, invert_mask=())  # ok
assert cirq.MeasurementGate(1) == cirq.MeasurementGate(1, invert_mask=(False,))  # fails, but should be the same
```

**Cirq version**

```
1.2.0.dev20230427183358
```


Discussion:
Hi @tanujkhattar, I can take this up!

Hi @TarunSinghania ,
Are you working on this or is this fixed already? If not, can I take it up? I'm new to OpenSource and this seems like a good place to start.



Patch:
diff --git a/cirq-core/cirq/ops/measurement_gate.py b/cirq-core/cirq/ops/measurement_gate.py
index 8a589332988..971e0b01547 100644
--- a/cirq-core/cirq/ops/measurement_gate.py
+++ b/cirq-core/cirq/ops/measurement_gate.py
@@ -273,7 +273,7 @@ def _value_equality_values_(self) -> Any:
             (idxs, tuple(v for _, v in np.ndenumerate(cmap)))
             for idxs, cmap in self._confusion_map.items()
         )
-        return self.key, self.invert_mask, self._qid_shape, hashable_cmap
+        return self.key, self.full_invert_mask(), self._qid_shape, hashable_cmap
 
     def _json_dict_(self) -> Dict[str, Any]:
         other: Dict[str, Any] = {}


Test patch:
diff --git a/cirq-core/cirq/ops/measurement_gate_test.py b/cirq-core/cirq/ops/measurement_gate_test.py
index e4d594ffa24..41bb3f9b610 100644
--- a/cirq-core/cirq/ops/measurement_gate_test.py
+++ b/cirq-core/cirq/ops/measurement_gate_test.py
@@ -74,11 +74,11 @@ def test_measurement_eq():
     eq.make_equality_group(
         lambda: cirq.MeasurementGate(1, 'a'),
         lambda: cirq.MeasurementGate(1, 'a', invert_mask=()),
+        lambda: cirq.MeasurementGate(1, 'a', invert_mask=(False,)),
         lambda: cirq.MeasurementGate(1, 'a', qid_shape=(2,)),
         lambda: cirq.MeasurementGate(1, 'a', confusion_map={}),
     )
     eq.add_equality_group(cirq.MeasurementGate(1, 'a', invert_mask=(True,)))
-    eq.add_equality_group(cirq.MeasurementGate(1, 'a', invert_mask=(False,)))
     eq.add_equality_group(
         cirq.MeasurementGate(1, 'a', confusion_map={(0,): np.array([[0, 1], [1, 0]])})
     )