Repository: sympy/sympy

Issue:
Wigner3j has problems with Half Integers 
I was trying to find the result of this operation and am getting this error for half integers
```
>>> w3j = Wigner3j(0,0,1/2,1/2,1/2,-1/2)    
>>> w3j.doit()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "D:\Orgs\sympy\sympy\physics\quantum\cg.py", line 158, in doit 
    return wigner_3j(self.j1, self.j2, self.j3, self.m1, self.m2, self.m3)
  File "D:\Orgs\sympy\sympy\physics\wigner.py", line 199, in wigner_3j
    raise ValueError("j values must be integer or half integer")      
ValueError: j values must be integer or half integer
>>> w3j = Wigner3j(0.5,0.5,0.5,0.5,0.5,0.5)
>>> w3j.doit()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "D:\Orgs\sympy\sympy\physics\quantum\cg.py", line 158, in doit 
    return wigner_3j(self.j1, self.j2, self.j3, self.m1, self.m2, self.m3)
  File "D:\Orgs\sympy\sympy\physics\wigner.py", line 199, in wigner_3j    raise ValueError("j values must be integer or half integer")      
ValueError: j values must be integer or half integer
```
It is working fine for integer values but gives an error of values with half integers . 

Discussion:

Patch:
diff --git a/.mailmap b/.mailmap
index 20b4d5efc5..3271762121 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1378,6 +1378,7 @@ Sushant Hiray <hiraysushant@gmail.com>
 Susumu Ishizuka <susumu.ishizuka@kii.com>
 Swapnil Agarwal <swapnilag29@gmail.com>
 Szymon Mieszczak <szymon.mieszczak@gmail.com>
+T-vaccari <05-gesto-follemente@icloud.com>
 Takafumi Arakaki <aka.tkf@gmail.com>
 Takumasa Nakamura <n.takumasa@gmail.com>
 Tanay Agrawal <tanay_agrawal@hotmail.com>
diff --git a/pyproject.toml b/pyproject.toml
index 4b8fe24101..14730f023a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -34,7 +34,6 @@ select = [
     "E",
     "F",
     "PIE810",
-    "PLE",
     "SIM101",
 ]
 
diff --git a/sympy/logic/algorithms/dpll2.py b/sympy/logic/algorithms/dpll2.py
index 75115e01ef..4a88a35be5 100644
--- a/sympy/logic/algorithms/dpll2.py
+++ b/sympy/logic/algorithms/dpll2.py
@@ -120,8 +120,8 @@ def __init__(self, clauses, variables, var_settings, symbols=None,
 
         if 'simple' == clause_learning:
             self.add_learned_clause = self._simple_add_learned_clause
-            self.compute_conflict = self._simple_compute_conflict
-            self.update_functions.append(self._simple_clean_clauses)
+            self.compute_conflict = self.simple_compute_conflict
+            self.update_functions.append(self.simple_clean_clauses)
         elif 'none' == clause_learning:
             self.add_learned_clause = lambda x: None
             self.compute_conflict = lambda: None
diff --git a/sympy/parsing/latex/lark/latex_parser.py b/sympy/parsing/latex/lark/latex_parser.py
index bd14f7e162..cdc765450a 100644
--- a/sympy/parsing/latex/lark/latex_parser.py
+++ b/sympy/parsing/latex/lark/latex_parser.py
@@ -76,21 +76,21 @@ def doparse(self, s: str):
 
         if not self.transform_expr:
             # exit early and return the parse tree
-            _lark.logger.debug("expression = %s", s)
+            _lark.logger.debug("expression =", s)
             _lark.logger.debug(parse_tree)
             _lark.logger.debug(parse_tree.pretty())
             return parse_tree
 
         if self.print_debug_output:
             # print this stuff before attempting to run the transformer
-            _lark.logger.debug("expression = %s", s)
+            _lark.logger.debug("expression =", s)
             # print the `parse_tree` variable
             _lark.logger.debug(parse_tree.pretty())
 
         sympy_expression = self.transformer.transform(parse_tree)
 
         if self.print_debug_output:
-            _lark.logger.debug("SymPy expression = %s", sympy_expression)
+            _lark.logger.debug("SymPy expression =", sympy_expression)
 
         return sympy_expression
 
diff --git a/sympy/physics/wigner.py b/sympy/physics/wigner.py
index e49360df15..346ef8707e 100644
--- a/sympy/physics/wigner.py
+++ b/sympy/physics/wigner.py
@@ -56,7 +56,7 @@
 from sympy.core.add import Add
 from sympy.core.numbers import int_valued
 from sympy.core.function import Function
-from sympy.core.numbers import (I, Integer, pi)
+from sympy.core.numbers import (Float, I, Integer, pi, Rational, equal_valued)
 from sympy.core.singleton import S
 from sympy.core.symbol import Dummy
 from sympy.core.sympify import sympify
@@ -108,6 +108,21 @@ def _calc_factlist(nn):
     return _Factlist[:int(nn) + 1]
 
 
+def _Integer_or_halfInteger(value):
+    if isinstance(value, int):
+        return Integer(value)
+    elif isinstance(value, (float, Float)):
+        if isinstance(value, float) and value.is_integer():
+            return Integer(int(value))
+        elif (equal_valued((v:=2*value), (i:=int(v)))):
+            return Rational(i, 2)
+    elif isinstance(value, Integer):
+        return value
+    elif isinstance(value, Rational) and value.q == 2:
+        return value
+    raise ValueError("expecting integer or half-integer, got %s" % value)
+
+
 def wigner_3j(j_1, j_2, j_3, m_1, m_2, m_3):
     r"""
     Calculate the Wigner 3j symbol `\operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,m_3)`.
@@ -194,16 +209,12 @@ def wigner_3j(j_1, j_2, j_3, m_1, m_2, m_3):
 
     - Jens Rasch (2009-03-24): initial version
     """
-    if int(j_1 * 2) != j_1 * 2 or int(j_2 * 2) != j_2 * 2 or \
-            int(j_3 * 2) != j_3 * 2:
-        raise ValueError("j values must be integer or half integer")
-    if int(m_1 * 2) != m_1 * 2 or int(m_2 * 2) != m_2 * 2 or \
-            int(m_3 * 2) != m_3 * 2:
-        raise ValueError("m values must be integer or half integer")
+
+    j_1, j_2, j_3, m_1, m_2, m_3 = map(_Integer_or_halfInteger,
+                                       [j_1, j_2, j_3, m_1, m_2, m_3])
+
     if m_1 + m_2 + m_3 != 0:
         return S.Zero
-    prefid = Integer((-1) ** int(j_1 - j_2 - m_3))
-    m_3 = -m_3
     a1 = j_1 + j_2 - j_3
     if a1 < 0:
         return S.Zero
@@ -216,6 +227,8 @@ def wigner_3j(j_1, j_2, j_3, m_1, m_2, m_3):
     if (abs(m_1) > j_1) or (abs(m_2) > j_2) or (abs(m_3) > j_3):
         return S.Zero
 
+    prefid = Integer((-1) ** int(j_1 - j_2 - m_3))
+    m_3 = -m_3
     maxfact = max(j_1 + j_2 + j_3 + 1, j_1 + abs(m_1), j_2 + abs(m_2),
                   j_3 + abs(m_3))
     _calc_factlist(int(maxfact))
@@ -337,6 +350,8 @@ def _big_delta_coeff(aa, bb, cc, prec=None):
         1/2*sqrt(1/6)
     """
 
+    # the triangle test will only pass if a) all 3 values are ints or
+    # b) 1 is an int and the other two are half-ints
     if not int_valued(aa + bb - cc):
         raise ValueError("j values must be integer or half integer and fulfill the triangle relation")
     if not int_valued(aa + cc - bb):
diff --git a/sympy/polys/domains/gmpyfinitefield.py b/sympy/polys/domains/gmpyfinitefield.py
index 2e8315a29e..a417e8170f 100644
--- a/sympy/polys/domains/gmpyfinitefield.py
+++ b/sympy/polys/domains/gmpyfinitefield.py
@@ -13,4 +13,4 @@ class GMPYFiniteField(FiniteField):
     alias = 'FF_gmpy'
 
     def __init__(self, mod, symmetric=True):
-        super().__init__(mod, GMPYIntegerRing(), symmetric)
+        return super().__init__(mod, GMPYIntegerRing(), symmetric)
diff --git a/sympy/polys/domains/pythonfinitefield.py b/sympy/polys/domains/pythonfinitefield.py
index 44baa4f6d1..526669717f 100644
--- a/sympy/polys/domains/pythonfinitefield.py
+++ b/sympy/polys/domains/pythonfinitefield.py
@@ -13,4 +13,4 @@ class PythonFiniteField(FiniteField):
     alias = 'FF_python'
 
     def __init__(self, mod, symmetric=True):
-        super().__init__(mod, PythonIntegerRing(), symmetric)
+        return super().__init__(mod, PythonIntegerRing(), symmetric)


Test patch:
diff --git a/sympy/physics/quantum/tests/test_cg.py b/sympy/physics/quantum/tests/test_cg.py
index 7f04d386d7..e5ff16265f 100644
--- a/sympy/physics/quantum/tests/test_cg.py
+++ b/sympy/physics/quantum/tests/test_cg.py
@@ -171,6 +171,8 @@ def test_cg_simp_sum():
 
 def test_doit():
     assert Wigner3j(S.Half, Rational(-1, 2), S.Half, S.Half, 0, 0).doit() == -sqrt(2)/2
+    assert Wigner3j(1/2,1/2,1/2,1/2,1/2,1/2).doit() == 0
+    assert Wigner3j(9/2,9/2,9/2,9/2,9/2,9/2).doit() ==  0
     assert Wigner6j(1, 2, 3, 2, 1, 2).doit() == sqrt(21)/105
     assert Wigner6j(3, 1, 2, 2, 2, 1).doit() == sqrt(21) / 105
     assert Wigner9j(