Repository: dimagi/jsonobject (language: python)

Issue:
unable to compile jsonobject-0.9.10 for python 3.10
I'm not able to install `jsonobject-0.9.10` at Windows 10 😞 for `Python 3.10` (Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32). I've tried it from venv (`py -3.10 -m venv venv`). Just note, there is no problem at Python 3.9.

```
(venv) c:\temp>python -m pip install jsonobject
Collecting jsonobject
  Using cached jsonobject-0.9.10.tar.gz (394 kB)
Requirement already satisfied: six in .\venv\lib\site-packages (from jsonobject) (1.16.0)
Building wheels for collected packages: jsonobject
  Building wheel for jsonobject (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: 'C:\temp\venv\Scripts\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\user\\AppData\\Local\\Temp\\pip-install-6vbuiurz\\jsonobject_9ef8c7da9549402ba95a3094cde2fe11\\setup.py'"'"'; __file__='"'"'C:\\Users\\user\\AppData\\Local\\Temp\\pip-install-6vbuiurz\\jsonobject_9ef8c7da9549402ba95a3094cde2fe11\\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d 'C:\Users\user\AppData\Local\Temp\pip-wheel-1yolk631'
       cwd: C:\Users\user\AppData\Local\Temp\pip-install-6vbuiurz\jsonobject_9ef8c7da9549402ba95a3094cde2fe11\
  Complete output (35 lines):
  You are running without Cython installed. It is highly recommended to run
    pip install cython>=0.29.21,<1.0.0
  before you continue
  Warning: 'classifiers' should be a list, got type 'tuple'
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build\lib.win-amd64-3.10
  creating build\lib.win-amd64-3.10\jsonobject
  copying jsonobject\exceptions.py -> build\lib.win-amd64-3.10\jsonobject
  copying jsonobject\__init__.py -> build\lib.win-amd64-3.10\jsonobject
  running build_ext
  building 'jsonobject.api' extension
  creating build\temp.win-amd64-3.10
  creating build\temp.win-amd64-3.10\Release
  creating build\temp.win-amd64-3.10\Release\jsonobject
  C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\temp\venv\include -IC:\Python310\include -IC:\Python310\Include -IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\include -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\winrt -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\cppwinrt /Tcjsonobject/api.c /Fobuild\temp.win-amd64-3.10\Release\jsonobject/api.obj
  api.c
  C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\temp\venv\libs /LIBPATH:C:\Python310\libs /LIBPATH:C:\Python310 /LIBPATH:C:\temp\venv\PCbuild\amd64 /LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\lib\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\ucrt\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\um\x64 /EXPORT:PyInit_api build\temp.win-amd64-3.10\Release\jsonobject/api.obj /OUT:build\lib.win-amd64-3.10\jsonobject\api.cp310-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.10\Release\jsonobject\api.cp310-win_amd64.lib
     Creating library build\temp.win-amd64-3.10\Release\jsonobject\api.cp310-win_amd64.lib and object build\temp.win-amd64-3.10\Release\jsonobject\api.cp310-win_amd64.exp
  Generating code
  Finished generating code
  building 'jsonobject.base' extension
  C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\temp\venv\include -IC:\Python310\include -IC:\Python310\Include -IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\include -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\winrt -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\cppwinrt /Tcjsonobject/base.c /Fobuild\temp.win-amd64-3.10\Release\jsonobject/base.obj
  base.c
  jsonobject/base.c(17142): warning C4013: '_PyGen_Send' undefined; assuming extern returning int
  jsonobject/base.c(17142): warning C4047: '=': 'PyObject *' differs in levels of indirection from 'int'
  jsonobject/base.c(17147): warning C4047: '=': 'PyObject *' differs in levels of indirection from 'int'
  jsonobject/base.c(17231): warning C4047: '=': 'PyObject *' differs in levels of indirection from 'int'
  C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\temp\venv\libs /LIBPATH:C:\Python310\libs /LIBPATH:C:\Python310 /LIBPATH:C:\temp\venv\PCbuild\amd64 /LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\lib\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\ucrt\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\um\x64 /EXPORT:PyInit_base build\temp.win-amd64-3.10\Release\jsonobject/base.obj /OUT:build\lib.win-amd64-3.10\jsonobject\base.cp310-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.10\Release\jsonobject\base.cp310-win_amd64.lib
     Creating library build\temp.win-amd64-3.10\Release\jsonobject\base.cp310-win_amd64.lib and object build\temp.win-amd64-3.10\Release\jsonobject\base.cp310-win_amd64.exp
  base.obj : error LNK2001: unresolved external symbol _PyGen_Send
  build\lib.win-amd64-3.10\jsonobject\base.cp310-win_amd64.pyd : fatal error LNK1120: 1 unresolved externals
  error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\bin\\HostX86\\x64\\link.exe' failed with exit code 1120
  ----------------------------------------
  ERROR: Failed building wheel for jsonobject
  Running setup.py clean for jsonobject
Failed to build jsonobject
Installing collected packages: jsonobject
    Running setup.py install for jsonobject ... error
    ERROR: Command errored out with exit status 1:
     command: 'C:\temp\venv\Scripts\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\user\\AppData\\Local\\Temp\\pip-install-6vbuiurz\\jsonobject_9ef8c7da9549402ba95a3094cde2fe11\\setup.py'"'"'; __file__='"'"'C:\\Users\\user\\AppData\\Local\\Temp\\pip-install-6vbuiurz\\jsonobject_9ef8c7da9549402ba95a3094cde2fe11\\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\user\AppData\Local\Temp\pip-record-9ltgm6kh\install-record.txt' --single-version-externally-managed --compile --install-headers 'C:\temp\venv\include\site\python3.10\jsonobject'
         cwd: C:\Users\user\AppData\Local\Temp\pip-install-6vbuiurz\jsonobject_9ef8c7da9549402ba95a3094cde2fe11\
    Complete output (35 lines):
    You are running without Cython installed. It is highly recommended to run
      pip install cython>=0.29.21,<1.0.0
    before you continue
    Warning: 'classifiers' should be a list, got type 'tuple'
    running install
    running build
    running build_py
    creating build
    creating build\lib.win-amd64-3.10
    creating build\lib.win-amd64-3.10\jsonobject
    copying jsonobject\exceptions.py -> build\lib.win-amd64-3.10\jsonobject
    copying jsonobject\__init__.py -> build\lib.win-amd64-3.10\jsonobject
    running build_ext
    building 'jsonobject.api' extension
    creating build\temp.win-amd64-3.10
    creating build\temp.win-amd64-3.10\Release
    creating build\temp.win-amd64-3.10\Release\jsonobject
    C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\temp\venv\include -IC:\Python310\include -IC:\Python310\Include -IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\include -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\winrt -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\cppwinrt /Tcjsonobject/api.c /Fobuild\temp.win-amd64-3.10\Release\jsonobject/api.obj
    api.c
    C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\temp\venv\libs /LIBPATH:C:\Python310\libs /LIBPATH:C:\Python310 /LIBPATH:C:\temp\venv\PCbuild\amd64 /LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\lib\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\ucrt\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\um\x64 /EXPORT:PyInit_api build\temp.win-amd64-3.10\Release\jsonobject/api.obj /OUT:build\lib.win-amd64-3.10\jsonobject\api.cp310-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.10\Release\jsonobject\api.cp310-win_amd64.lib
       Creating library build\temp.win-amd64-3.10\Release\jsonobject\api.cp310-win_amd64.lib and object build\temp.win-amd64-3.10\Release\jsonobject\api.cp310-win_amd64.exp
    Generating code
    Finished generating code
    building 'jsonobject.base' extension
    C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\temp\venv\include -IC:\Python310\include -IC:\Python310\Include -IC:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\include -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\winrt -IC:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\cppwinrt /Tcjsonobject/base.c /Fobuild\temp.win-amd64-3.10\Release\jsonobject/base.obj
    base.c
    jsonobject/base.c(17142): warning C4013: '_PyGen_Send' undefined; assuming extern returning int
    jsonobject/base.c(17142): warning C4047: '=': 'PyObject *' differs in levels of indirection from 'int'
    jsonobject/base.c(17147): warning C4047: '=': 'PyObject *' differs in levels of indirection from 'int'
    jsonobject/base.c(17231): warning C4047: '=': 'PyObject *' differs in levels of indirection from 'int'
    C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\temp\venv\libs /LIBPATH:C:\Python310\libs /LIBPATH:C:\Python310 /LIBPATH:C:\temp\venv\PCbuild\amd64 /LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.28.29333\lib\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\ucrt\x64 /LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\um\x64 /EXPORT:PyInit_base build\temp.win-amd64-3.10\Release\jsonobject/base.obj /OUT:build\lib.win-amd64-3.10\jsonobject\base.cp310-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.10\Release\jsonobject\base.cp310-win_amd64.lib
       Creating library build\temp.win-amd64-3.10\Release\jsonobject\base.cp310-win_amd64.lib and object build\temp.win-amd64-3.10\Release\jsonobject\base.cp310-win_amd64.exp
    base.obj : error LNK2001: unresolved external symbol _PyGen_Send
    build\lib.win-amd64-3.10\jsonobject\base.cp310-win_amd64.pyd : fatal error LNK1120: 1 unresolved externals
    error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\bin\\HostX86\\x64\\link.exe' failed with exit code 1120
    ----------------------------------------
ERROR: Command errored out with exit status 1: 'C:\temp\venv\Scripts\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\user\\AppData\\Local\\Temp\\pip-install-6vbuiurz\\jsonobject_9ef8c7da9549402ba95a3094cde2fe11\\setup.py'"'"'; __file__='"'"'C:\\Users\\user\\AppData\\Local\\Temp\\pip-install-6vbuiurz\\jsonobject_9ef8c7da9549402ba95a3094cde2fe11\\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\user\AppData\Local\Temp\pip-record-9ltgm6kh\install-record.txt' --single-version-externally-managed --compile --install-headers 'C:\temp\venv\include\site\python3.10\jsonobject' Check the logs for full command output.
```



Discussion / hints:
I've also stumbled over this issue on ubuntu! The above error seems to be related to the fix from https://github.com/cython/cython/issues/3876, which has been released with cython 0.29.22.
Using the latest master of jsonobject, which contains #183, fixes the issue for me with python 3.10.

@czue could you release a new version with the newly compiled c files? But I haven't run any tests, so maybe #185 should be merged first, to run the tests against 3.10?



Fix patch:
diff --git a/setup.py b/setup.py
index a8a26b9..9f9d8bb 100644
--- a/setup.py
+++ b/setup.py
@@ -49,7 +49,6 @@
     packages=['jsonobject'],
     setup_requires=CYTHON_REQUIRES,
     install_requires=['six'],
-    tests_require=['unittest2'],
     ext_modules=extensions,
     test_suite='test',
     classifiers=(
@@ -62,6 +61,7 @@
         'Programming Language :: Python :: 3.7',
         'Programming Language :: Python :: 3.8',
         'Programming Language :: Python :: 3.9',
+        'Programming Language :: Python :: 3.10',
         'License :: OSI Approved :: BSD License',
     ),
 )


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index b2bb934..22b407a 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -15,7 +15,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        python-version: ["3.7", "3.8", "3.9"]
+        python-version: ["3.7", "3.8", "3.9", "3.10"]
 
     steps:
     - uses: actions/checkout@v2
diff --git a/test/test_couchdbkit.py b/test/test_couchdbkit.py
index 26eb622..eafd8ac 100644
--- a/test/test_couchdbkit.py
+++ b/test/test_couchdbkit.py
@@ -2,7 +2,7 @@
 from __future__ import unicode_literals
 import json
 import os
-from unittest2 import TestCase
+from unittest import TestCase
 from .couchdbkit.application import Application
 from io import open
 
diff --git a/test/test_stringconversions.py b/test/test_stringconversions.py
index 8da34be..5a74cb1 100644
--- a/test/test_stringconversions.py
+++ b/test/test_stringconversions.py
@@ -4,11 +4,11 @@
 import datetime
 from jsonobject.exceptions import BadValueError
 from jsonobject import JsonObject, ObjectProperty, DateTimeProperty
-import unittest2
+import unittest
 from jsonobject.base import get_settings
 
 
-class StringConversionsTest(unittest2.TestCase):
+class StringConversionsTest(unittest.TestCase):
 
     EXAMPLES = {
         'decimal': '1.2',
diff --git a/test/tests.py b/test/tests.py
index 5a891b6..c3d855a 100644
--- a/test/tests.py
+++ b/test/tests.py
@@ -2,7 +2,7 @@
 from __future__ import unicode_literals
 import six
 from copy import deepcopy
-import unittest2
+import unittest
 from jsonobject import *
 from jsonobject.exceptions import (
     BadValueError,
@@ -68,7 +68,7 @@ class ObjectWithDictProperty(JsonObject):
     mapping = DictProperty()
 
 
-class JsonObjectTestCase(unittest2.TestCase):
+class JsonObjectTestCase(unittest.TestCase):
     def _danny_data(self):
         return {
             'first_name': 'Danny',
@@ -434,7 +434,7 @@ class Foo(JsonObject):
         self.assertIsInstance(foo.bar, Bar)
 
 
-class PropertyInsideContainerTest(unittest2.TestCase):
+class PropertyInsideContainerTest(unittest.TestCase):
 
     def test_default_is_required(self):
         class Foo(JsonObject):
@@ -466,7 +466,7 @@ class Foo(JsonObject):
             Foo(container=[None])
 
 
-class LazyValidationTest(unittest2.TestCase):
+class LazyValidationTest(unittest.TestCase):
 
     def _validate_raises(self, foo):
         with self.assertRaises(BadValueError):
@@ -577,7 +577,7 @@ class Foo(JsonObject):
         self._validate_not_raises(foo)
 
 
-class PropertyTestCase(unittest2.TestCase):
+class PropertyTestCase(unittest.TestCase):
     def test_date(self):
         import datetime
         p = DateProperty()
@@ -755,12 +755,12 @@ def test_attribute_error(self):
         class Foo(JsonObject):
             pass
         foo = Foo()
-        
+
         with self.assertRaises(AttributeError):
             foo.hello
 
 
-class DynamicConversionTestCase(unittest2.TestCase):
+class DynamicConversionTestCase(unittest.TestCase):
     import datetime
 
     class Foo(JsonObject):
@@ -843,7 +843,7 @@ class User(JsonObject):
     tags = ListProperty(six.text_type)
 
 
-class TestExactDateTime(unittest2.TestCase):
+class TestExactDateTime(unittest.TestCase):
     def test_exact(self):
         class DateObj(JsonObject):
             date = DateTimeProperty(exact=True)
@@ -862,7 +862,7 @@ class DateObj(JsonObject):
         self.assertEqual(len(date_obj.to_json()['date']), 27)
 
 
-class IntegerTest(unittest2.TestCase):
+class IntegerTest(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         class Foo(JsonObject):
@@ -883,7 +883,7 @@ def test_set_zero(self):
         self.assertEqual(foo.to_json()['my_int'], 0)
 
 
-class TestReadmeExamples(unittest2.TestCase):
+class TestReadmeExamples(unittest.TestCase):
     def test(self):
         import datetime
         user1 = User(