pygolang:master commitshttps://lab.nexedi.com/kirr/pygolang/-/commits/master2024-02-17T23:06:31+03:00https://lab.nexedi.com/kirr/pygolang/-/commit/6dd420daa85715b6f620fbfe344be32b6620e29atox += CPython 3.122024-02-17T23:06:31+03:00Kirill Smelkovkirr@nexedi.com
Tests now pass with that version.
/reviewed-by <a href="/jerome" data-user="9" data-reference-type="user" data-container="body" data-placement="top" data-html="true" class="gfm gfm-project_member" title="Jérome Perrin">@jerome</a>
/reviewed-on <a href="https://lab.nexedi.com/nexedi/pygolang/-/merge_requests/23" data-original="https://lab.nexedi.com/nexedi/pygolang/-/merge_requests/23" data-link="false" data-link-reference="true" data-project="1156" data-merge-request="7532" data-project-path="nexedi/pygolang" data-iid="23" data-mr-title="Add support for CPython 3.12" data-reference-type="merge_request" data-container="body" data-placement="top" data-html="true" title="" class="gfm gfm-merge_request">nexedi/pygolang!23</a>https://lab.nexedi.com/kirr/pygolang/-/commit/f8761f73240080a38aadcd6f78ca901ffec356adgpython: Fix -V when underlying python is not exactly release2024-02-17T23:06:22+03:00Kirill Smelkovkirr@nexedi.com
When python is built from git checkout, not exactly on any tag state, it
adds a "+" sign as suffix to its version, for example:
(py312.venv) kirr@deca:~/src/tools/go/pygolang$ python -V
Python 3.12.2+
(py312.venv) kirr@deca:~/src/tools/go/pygolang$ python
Python 3.12.2+ (heads/3.12:0e4f73b8e45, Feb 15 2024, 10:52:08) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
but our handler for -V was trying to construct the version from
sys.version_info where there is no information about that "extra" part:
In [2]: sys.version_info
Out[2]: sys.version_info(major=3, minor=12, micro=2, releaselevel='final', serial=0) # no +
In [4]: platform.python_version()
Out[4]: '3.12.2+'
as the result test_pymain_ver is failing:
=================== FAILURES ===================
______________ test_pymain_ver[] _______________
runtime = ''
@gpython_only
def test_pymain_ver(runtime):
from golang import b
from gpython import _version_info_str as V
import gevent
vok = 'GPython %s' % golang.__version__
if runtime != 'threads':
vok += ' [gevent %s]' % gevent.__version__
else:
vok += ' [threads]'
if is_cpython:
vok += ' / CPython %s' % platform.python_version()
elif is_pypy:
vok += ' / PyPy %s / Python %s' % (V(sys.pypy_version_info), V(sys.version_info))
else:
vok = sys.version
vok += '\n'
ret, out, err = _pyrun(['-V'], stdout=PIPE, stderr=PIPE, env=gpyenv(runtime))
> assert (ret, out, b(err)) == (0, b'', b(vok))
E AssertionError: assert (0, b'', b'GPython 0.1 [gevent 24.2.1] / CPython 3.12.2\n') == (0, b'', b'GPython 0.1 [gevent 24.2.1] / CPython 3.12.2+\n')
E At index 2 diff: b'GPython 0.1 [gevent 24.2.1] / CPython 3.12.2\n' != b'GPython 0.1 [gevent 24.2.1] / CPython 3.12.2+\n'
E Full diff:
E - (0, b'', b'GPython 0.1 [gevent 24.2.1] / CPython 3.12.2+\n')
E ? -
E + (0, b'', b'GPython 0.1 [gevent 24.2.1] / CPython 3.12.2\n')
gpython/gpython_test.py:341: AssertionError
-> Fix it by handling -V with platform.python_version() directly.
/reviewed-by <a href="/jerome" data-user="9" data-reference-type="user" data-container="body" data-placement="top" data-html="true" class="gfm gfm-project_member" title="Jérome Perrin">@jerome</a>
/reviewed-on <a href="https://lab.nexedi.com/nexedi/pygolang/-/merge_requests/23" data-original="https://lab.nexedi.com/nexedi/pygolang/-/merge_requests/23" data-link="false" data-link-reference="true" data-project="1156" data-merge-request="7532" data-project-path="nexedi/pygolang" data-iid="23" data-mr-title="Add support for CPython 3.12" data-reference-type="merge_request" data-container="body" data-placement="top" data-html="true" title="" class="gfm gfm-merge_request">!23</a>https://lab.nexedi.com/kirr/pygolang/-/commit/74a9838c1eefbf47bb8dc9c7d5c01ad667baeaa8golang: tests: Fix for Pytest ≥ 7.42024-02-17T23:06:13+03:00Kirill Smelkovkirr@nexedi.com
Pytest 7.4 changed format of output tracebacks. Similarly to IPython adding
test support for later versions would add maintenance cost on pygolang
side, but testing this is actually not needed, since we activate
Pytest-related patch only on py2 and for py2 the latest pytest version
is pytest 4.6.11.
-> So simply skip this test if we see we have Pytest ≥ 7.4.
Skip it only on py3 just in case.
For the reference here is how diff in between running
golang_test_defer_excchain.py on Pytest 7.3 and Pytest 7.4 looks:
diff --git a/a b/b
index 45680b99..47c29cea 100644
--- a/a
+++ b/b
@@ -1,5 +1,5 @@
============================= test session starts ==============================
-platform linux -- Python 3.12.2+, pytest-7.3.2, pluggy-1.4.0
+platform linux -- Python 3.12.2+, pytest-7.4.0, pluggy-1.4.0
rootdir: /home/kirr/src/tools/go/pygolang-master
collected 1 item
@@ -7,22 +7,16 @@ golang/testprog/golang_test_defer_excchain.py F [100%]
=================================== FAILURES ===================================
_____________________________________ main _____________________________________
-golang/__init__.py:106: in _
- return f(*argv, **kw)
golang/testprog/golang_test_defer_excchain.py:42: in main
raise RuntimeError("err")
E RuntimeError: err
During handling of the above exception, another exception occurred:
-golang/__init__.py:183: in __exit__
- d()
golang/testprog/golang_test_defer_excchain.py:31: in d1
raise RuntimeError("d1: aaa")
E RuntimeError: d1: aaa
During handling of the above exception, another exception occurred:
-golang/__init__.py:183: in __exit__
- d()
golang/testprog/golang_test_defer_excchain.py:33: in d2
1/0
E ZeroDivisionError: division by zero
/reviewed-by <a href="/jerome" data-user="9" data-reference-type="user" data-container="body" data-placement="top" data-html="true" class="gfm gfm-project_member" title="Jérome Perrin">@jerome</a>
/reviewed-on <a href="https://lab.nexedi.com/nexedi/pygolang/-/merge_requests/23" data-original="https://lab.nexedi.com/nexedi/pygolang/-/merge_requests/23" data-link="false" data-link-reference="true" data-project="1156" data-merge-request="7532" data-project-path="nexedi/pygolang" data-iid="23" data-mr-title="Add support for CPython 3.12" data-reference-type="merge_request" data-container="body" data-placement="top" data-html="true" title="" class="gfm gfm-merge_request">nexedi/pygolang!23</a>https://lab.nexedi.com/kirr/pygolang/-/commit/68f384a946dcab318ae4c3d2e876540ddb432e40*: Replace imp with importlib on py32024-02-17T23:05:14+03:00Kirill Smelkovkirr@nexedi.com
@Qubitium notes (<a href="https://github.com/navytux/pygolang/issues/1" rel="nofollow noreferrer noopener" target="_blank">https://github.com/navytux/pygolang/issues/1</a>):
Python 3.12 no longer support the imp module (fully deprecated) with note to use importlib as replacement.
Please support python 3.12 by migrating from imp code to importlib. Thanks.
and indeed, even trying to build pygolang fails on py3.12:
(py312.venv) kirr@deca:~/src/tools/go/pygolang-master$ python setup.py build_ext -i
Traceback (most recent call last):
File "/home/kirr/src/tools/go/pygolang-master/setup.py", line 40, in <module>
exec(readfile('trun'), trun)
File "<string>", line 41, in <module>
ModuleNotFoundError: No module named 'imp'
-> Rework the code to use importlib instead, but keep using imp on py2
where there is practically no importlib functionality.
/reported-by @Qubitium (github)
/reviewed-by <a href="/jerome" data-user="9" data-reference-type="user" data-container="body" data-placement="top" data-html="true" class="gfm gfm-project_member" title="Jérome Perrin">@jerome</a>
/reviewed-on <a href="https://lab.nexedi.com/nexedi/pygolang/-/merge_requests/23" data-original="https://lab.nexedi.com/nexedi/pygolang/-/merge_requests/23" data-link="false" data-link-reference="true" data-project="1156" data-merge-request="7532" data-project-path="nexedi/pygolang" data-iid="23" data-mr-title="Add support for CPython 3.12" data-reference-type="merge_request" data-container="body" data-placement="top" data-html="true" title="" class="gfm gfm-merge_request">!23</a>https://lab.nexedi.com/kirr/pygolang/-/commit/6446a0be11c3e8e0df16bbabf11ecab72cae24bapyx.build: Fix build after Cython 3 release2023-08-16T23:01:11+03:00Kirill Smelkovkirr@nexedi.com
Unfortunately the best Cython release ever[1] breaks build for Pygolang[2], and
people on the net also report that there are other problems - both build
failures and popped up performance problems due to changed semantic[3,4,...].
Fix it all on Pygolang side by, for now, not delving into being Cython 3
beta-testers and relying on field-proven Cython 2.
/reported-by <a href="/levin.zimmermann" data-user="5555" data-reference-type="user" data-container="body" data-placement="top" data-html="true" class="gfm gfm-project_member" title="Levin Zimmermann">@levin.zimmermann</a>
[1] <a href="https://groups.google.com/g/cython-users/c/o41CrcRkVvo" rel="nofollow noreferrer noopener" target="_blank">https://groups.google.com/g/cython-users/c/o41CrcRkVvo</a>
[2] <a href="https://lab.nexedi.com/nexedi/wendelin.core/merge_requests/16#note_188623" data-original="https://lab.nexedi.com/nexedi/wendelin.core/merge_requests/16#note_188623" data-link="false" data-link-reference="true" data-project="21" data-merge-request="6886" data-project-path="nexedi/wendelin.core" data-iid="16" data-mr-title="wcfs: v↑ go dependencies" data-reference-type="merge_request" data-container="body" data-placement="top" data-html="true" title="" class="gfm gfm-merge_request">wendelin.core!16 (comment 188623)</a>
[3] <a href="https://news.ycombinator.com/item?id=36778617" rel="nofollow noreferrer noopener" target="_blank">https://news.ycombinator.com/item?id=36778617</a>
[4] <a href="https://github.com/cython/cython/issues/5540" rel="nofollow noreferrer noopener" target="_blank">https://github.com/cython/cython/issues/5540</a>https://lab.nexedi.com/kirr/pygolang/-/commit/31fc69512bbc92f3bf700f2a1dc29dde88302413pyx.build: v↑ setuptools_dso (2.7 -> 2.8)2023-05-03T13:24:44+03:00Kirill Smelkovkirr@nexedi.com
This fixes linking to editable pygolang install on Windows.
See <a href="https://github.com/mdavidsaver/setuptools_dso/commit/fca6f29e" rel="nofollow noreferrer noopener" target="_blank">https://github.com/mdavidsaver/setuptools_dso/commit/fca6f29e</a> and
<a href="https://github.com/mdavidsaver/setuptools_dso/pull/25" rel="nofollow noreferrer noopener" target="_blank">https://github.com/mdavidsaver/setuptools_dso/pull/25</a> for details.
Without this fix e.g. test_pyx_build was also failing:
platform win32 -- Python 3.10.11, pytest-7.3.1, pluggy-1.0.0 -- Z:\home\kirr\src\tools\go\pygo-win\1.wenv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: Z:\home\kirr\src\tools\go\pygo-win\pygolang
collecting 3 items
collected 3 items
golang/pyx/build_test.py::test_pyx_build running build_ext
skipping 'pyxuser\test.cpp' Cython extension (up-to-date)
building 'pyxuser.test' extension
Z:\home\kirr\src\tools\go\pygo-win\BuildTools\vc\tools\msvc\14.35.32215\bin\Hostx64\x64\cl.exe /c /nologo /O2 /W3 /GL /DNDEBUG /MD -IZ:\home\kir
r\src\tools\go\pygo-win\pygolang -IZ:\home\kirr\src\tools\go\pygo-win\pygolang\golang\_compat\windows -IZ:\home\kirr\src\tools\go\pygo-win\1.wen
v\include\site\python3.10 -IZ:\home\kirr\src\tools\go\pygo-win\1.wenv\include "-IC:\Program Files\Python310\include" "-IC:\Program Files\Python3
10\Include" -Iz:\home\kirr\src\tools\go\pygo-win\BuildTools\vc\tools\msvc\14.35.32215\include -Iz:\home\kirr\src\tools\go\pygo-win\BuildTools\ki
ts\10\include\10.0.22000.0\shared -Iz:\home\kirr\src\tools\go\pygo-win\BuildTools\kits\10\include\10.0.22000.0\ucrt -Iz:\home\kirr\src\tools\go\
pygo-win\BuildTools\kits\10\include\10.0.22000.0\um -Iz:\home\kirr\src\tools\go\pygo-win\BuildTools\kits\10\include\10.0.22000.0\winrt /EHsc /Tp
pyxuser\test.cpp /Fobuild\temp.win-amd64-cpython-310\Release\pyxuser\test.obj /std:c++20 /EHc- /EHsr
cl : Command line warning D9025 : overriding '/EHc' with '/EHc-'
test.cpp
...
Z:\home\kirr\src\tools\go\pygo-win\BuildTools\vc\tools\msvc\14.35.32215\bin\Hostx64\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EM
BED,ID=2 /MANIFESTUAC:NO /LIBPATH:Z:\home\kirr\src\tools\go\pygo-win\pygolang\golang\runtime "/LIBPATH:C:\Program Files\Python310\libs" "/LIBPAT
H:C:\Program Files\Python310" /LIBPATH:z:\home\kirr\src\tools\go\pygo-win\BuildTools\vc\tools\msvc\14.35.32215\lib\x64 /LIBPATH:z:\home\kirr\src
\tools\go\pygo-win\BuildTools\kits\10\lib\10.0.22000.0\ucrt\x64 /LIBPATH:z:\home\kirr\src\tools\go\pygo-win\BuildTools\kits\10\lib\10.0.22000.0\
um\x64 libgolang.lib /EXPORT:PyInit_test build\temp.win-amd64-cpython-310\Release\pyxuser\test.obj /OUT:build\lib.win-amd64-cpython-310\pyxuser\
test.cp310-win_amd64.pyd /IMPLIB:build\temp.win-amd64-cpython-310\Release\pyxuser\test.cp310-win_amd64.lib
LINK : fatal error LNK1181: cannot open input file 'libgolang.lib' <-- NOTE
error: command 'Z:\\home\\kirr\\src\\tools\\go\\pygo-win\\BuildTools\\vc\\tools\\msvc\\14.35.32215\\bin\\Hostx64\\x64\\link.exe' failed with exi
t code 1181
FAILED
========================== FAILURES ===========================
_______________________ test_pyx_build ________________________
def test_pyx_build():
pyxuser = testprog + "/golang_pyx_user"
> pyrun(["setup.py", "build_ext", "-i"], cwd=pyxuser)
golang\pyx\build_test.py:31:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
argv = ['setup.py', 'build_ext', '-i'], stdin = None, stdout = None, stderr = None
kw = {'cwd': 'Z:\\home\\kirr\\src\\tools\\go\\pygo-win\\pygolang\\golang\\pyx/testprog/golang_pyx_user'}, retcode = 1
def pyrun(argv, stdin=None, stdout=None, stderr=None, **kw):
retcode, stdout, stderr = _pyrun(argv, stdin=stdin, stdout=stdout, stderr=stderr, **kw)
if retcode:
> raise RuntimeError(' '.join(argv) + '\n' + (stderr and str(stderr) or '(failed)'))
E RuntimeError: setup.py build_ext -i
E (failed)
golang\golang_test.py:1771: RuntimeErrorhttps://lab.nexedi.com/kirr/pygolang/-/commit/55d39d4dd62a5b0fc9aa134d13eeab8a0e4b5fa1Windows support2023-04-27T21:16:26+03:00Kirill Smelkovkirr@nexedi.com
Pygolang stopped to work on Windows in 2019 starting from <a href="/levin.zimmermann/pygolang/-/commit/8fa3c15b25107d9827307749474dc8e3341c6f65" data-original="8fa3c15b" data-link="false" data-link-reference="false" data-project="1649" data-commit="8fa3c15b25107d9827307749474dc8e3341c6f65" data-reference-type="commit" data-container="body" data-placement="top" data-html="true" title="Start using Cython and providing Cython/nogil API" class="gfm gfm-commit has-tooltip">8fa3c15b</a> (Start using
Cython and providing Cython/nogil API). Restore it now.https://lab.nexedi.com/kirr/pygolang/-/commit/d1e92fa2d2ab507a878ced0370505d23ecabc32dsetup: Add classifiers to indicate Pygolang works on all Linux / macOS and Wi...2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
Linux and macOS was working before. And we just added Windows support in
the previous patches.https://lab.nexedi.com/kirr/pygolang/-/commit/3c10a0a33e7ca9515c69c57494bde505e5d72208libgolang/gevent: Fix io_read deadlock and io_read/io_write potential data co...2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
When underlying pygfobj is FileObjectThread its .readinto() leads to
deadlock because it is no cooperative(*). This manifests as
test_pyx_os_pipe_cpp hang when run by gpython on windows.
-> Workaround this by reading first into intermediate buffer and then
copying data to buffer that user provided.
After this the deadlock is gone but test_pyx_os_pipe_cpp starts to fail
and crash randomly. That's because similarly to channels we need to
care and not access a buffer if it is located on stack and owning
greenlet is inactive. Because when a greenlet is inactive, its stack is
reused by another active greenlet and writing/reading to on-stack memory
accesses that second greenlet stack, corrupting it on write.
-> do the same what we do in chan operations: use intermediate on-heap
buffer to protect original user's buffer to be accesses because it might
be located on stack. That's what actually happens in
test_pyx_os_pipe_cpp where two goroutines read and write to each other
via pipe and using on-stack located buffers. And becuase on windows
pipes, like regular files, are wrapped with FileObjectThread, when
reading greenlet becomes suspended waiting for read reasul, it will be
another greenlet to run on its stack, write to another end of a pipe,
wakeup IO thread, which will write the data to requested buffer on G1
stack and oops - it was G2 there.
(*) see <a href="https://github.com/gevent/gevent/pull/1948" rel="nofollow noreferrer noopener" target="_blank">https://github.com/gevent/gevent/pull/1948</a> for detailshttps://lab.nexedi.com/kirr/pygolang/-/commit/d950525601861ceed4310b21be061dfd0c82946cgpython: tests: Don't assume path delimiter is /2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
Because on Windows it is \ and using / for it to scan in path fails and
leads to test_pymain_opt failure:
E Full diff:
E [
E 'sys.flags.debug: 0',
E 'sys.flags.optimize: 0',
E '__debug__: True',
E 'assert: True',
E 'docstrings: True',
E 'import mod.py: '
E - 'C:\\users\\kirr\\Temp\\modpy_imports_fromvmgs8go4\\__pycache__/mod.cpython-310.pyc',
E ? ^^ ----
E + 'C:\\users\\kirr\\Temp\\modpy_imports_from850gb81s\\__pycache__/mod.cpython-310.pyc',
E ? ^^^ +++
E ]
Here the difference is because gpython/testprog/print_opt.py failed to
detect tmpd prefix and strip it.https://lab.nexedi.com/kirr/pygolang/-/commit/161629e668011f952a233fdfb79ea629176d1d85gpython: tests: Prepare expected repr properly2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
In several places we were preparing repr of a string as '%s' which works
ok most of the time but leads to failure if string contains '\'
characters e.g. if it represents a path and we are running on windows:
def test_pymain():
from golang import b
....
# -m <module>
_ = pyout(['-m', 'hello', 'abc', 'def'], cwd=testdata)
# realpath rewrites e.g. `local/lib -> lib` if local/lib is symlink
hellopy = realpath(join(testdata, 'hello.py'))
> assert _ == b"hello\nworld\n['%s', 'abc', 'def']\n" % b(hellopy)
E assert b"hello\nworld\n['Z:\\\\home\\\\kirr\\\\src\\\\tools\\\\go\\\\pygo-win\\\\pygolang\\\\gpython\\\\testdata\\\\hello.py', 'abc', 'def'
]\n" == b"hello\nworld\n['Z:\\home\\kirr\\src\\tools\\go\\pygo-win\\pygolang\\gpython\\testdata\\hello.py', 'abc', 'def']\n"
E At index 17 diff: b'\\' != b'h'
E Full diff:
E (
E - b"hello\nworld\n['Z:\\home\\kirr\\src\\tools\\go\\pygo-win\\pygolang\\gpytho"
E ? ------------
E + b"hello\nworld\n['Z:\\\\home\\\\kirr\\\\src\\\\tools\\\\go\\\\pygo-win\\\\pygo"
E ? ++ ++ ++ ++ ++ ++ ++
E - b"n\\testdata\\hello.py', 'abc', 'def']\n",
E + b"lang\\\\gpython\\\\testdata\\\\hello.py', 'abc', 'def']\n",
E ? ++ ++++++++++++++ ++
E )
gpython\gpython_test.py:183: AssertionError
-> Fix it by preparing repr via repr(...) properly.https://lab.nexedi.com/kirr/pygolang/-/commit/f23a9ef54aff54397307c4e99d0d174e9a15fbddgpython: Fix gevent activation on Windows2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
On Windows if geventmp is present gpython startup fails:
(1.wenv) Z:\home\kirr\src\tools\go\pygo-win\pygolang>gpython
Traceback (most recent call last):
File "C:\Program Files\Python310\lib\runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Program Files\Python310\lib\runpy.py", line 86, in _run_code
exec(code, run_globals)
File "Z:\home\kirr\src\tools\go\pygo-win\1.wenv\Scripts\gpython.exe\__main__.py", line 7, in <module>
File "Z:\home\kirr\src\tools\go\pygo-win\pygolang\gpython\__init__.py", line 450, in main
pymain(argv, init)
File "Z:\home\kirr\src\tools\go\pygo-win\pygolang\gpython\__init__.py", line 223, in pymain
init()
File "Z:\home\kirr\src\tools\go\pygo-win\pygolang\gpython\__init__.py", line 428, in init
_ = monkey.patch_all(thread=patch_thread) # XXX sys=True ?
File "Z:\home\kirr\src\tools\go\pygo-win\1.wenv\lib\site-packages\gevent\monkey.py", line 1255, in patch_all
_notify_patch(events.GeventWillPatchAllEvent(modules_to_patch, kwargs), _warnings)
File "Z:\home\kirr\src\tools\go\pygo-win\1.wenv\lib\site-packages\gevent\monkey.py", line 190, in _notify_patch
notify_and_call_entry_points(event)
File "Z:\home\kirr\src\tools\go\pygo-win\1.wenv\lib\site-packages\gevent\events.py", line 105, in notify_and_call_entry_points
subscriber(event)
File "Z:\home\kirr\src\tools\go\pygo-win\1.wenv\lib\site-packages\geventmp\monkey.py", line 160, in _patch_mp
_patch_module("_mp.3._mp_util", _patch_module=True, _package_prefix='geventmp.')
File "Z:\home\kirr\src\tools\go\pygo-win\1.wenv\lib\site-packages\geventmp\monkey.py", line 121, in _patch_module
gevent_module = import_module(_package_prefix + name)
File "C:\Program Files\Python310\lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 883, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "Z:\home\kirr\src\tools\go\pygo-win\1.wenv\lib\site-packages\geventmp\_mp\3\_mp_util.py", line 16, in <module>
from gevent.os import _watch_child
ImportError: cannot import name '_watch_child' from 'gevent.os' (Z:\home\kirr\src\tools\go\pygo-win\1.wenv\lib\site-packages\gevent\os.py)
That happens because geventmp does not support windows actually.
-> Fix it by requiring geventmp to be present only on non-windows.
Adjust related comment as <a href="https://github.com/karellen/geventmp/pull/2" rel="nofollow noreferrer noopener" target="_blank">https://github.com/karellen/geventmp/pull/2</a> has been merged long ago.https://lab.nexedi.com/kirr/pygolang/-/commit/377e44cb74ad846fa391e7eb15cd6cf185bc95acgpython: Fix startup on Windows when installed by pip2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
On windows setuptools install gpython.exe and gpython-script.py while
pip/distlib install gpython.exe with gpython-script sometimes embedded
into gpython.exe itself with argv[0] pointing to 'gpython' without .exe
suffix. This leads to gpython startup failure:
(1.wenv) Z:\home\kirr\src\tools\go\pygo-win\pygolang>gpython
Traceback (most recent call last):
File "C:\Program Files\Python310\lib\runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Program Files\Python310\lib\runpy.py", line 86, in _run_code
exec(code, run_globals)
File "Z:\home\kirr\src\tools\go\pygo-win\1.wenv\Scripts\gpython.exe\__main__.py", line 7, in <module>
File "Z:\home\kirr\src\tools\go\pygo-win\pygolang\gpython\__init__.py", line 437, in main
pymain(argv, init)
File "Z:\home\kirr\src\tools\go\pygo-win\pygolang\gpython\__init__.py", line 79, in pymain
if not _is_buildout_script(exe):
File "Z:\home\kirr\src\tools\go\pygo-win\pygolang\gpython\__init__.py", line 442, in _is_buildout_script
with open(path, 'rb') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'Z:\\home\\kirr\\src\\tools\\go\\pygo-win\\1.wenv\\Scripts\\gpython'
(1.wenv) Z:\home\kirr\src\tools\go\pygo-win\pygolang>dir ../1.wenv/scripts/gpython*
Directory of Z:\home\kirr\src\tools\go\pygo-win\1.wenv\scripts
26.04.2023 14:17 108,404 gpython.exe
1 file 108,404 bytes
0 directories 88,508,866,560 bytes free
-> Adjust pymain to handle this case accordingly.https://lab.nexedi.com/kirr/pygolang/-/commit/2f632a3e1979cab3b99721a63ec5ed94a246ea8aos/signal: tests: Adjust exit code expectation for Windows2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
On windows upon terminating signal reception exict code of the process
is always 3 instead of -signo. And so test_signal_all was failing as
def test_signal_all():
retcode, out, _ = _pyrun([dir_testprog + "/signal_test_all.py"], stdout=PIPE)
assert b"ok (notify)" in out
assert b"ok (ignore)" in out
assert b"terminating ..." in out
> assert retcode == -syscall.SIGTERM.signo
E assert 3 == -15
E + where 15 = os.Signal(15).signo
E + where os.Signal(15) = syscall.SIGTERMhttps://lab.nexedi.com/kirr/pygolang/-/commit/c1d5b67baf5bfbb2b601a32091710e4852c296a8os/signal: Adjust signal_test_all.py to support Windows2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
- There is no e.g. signal.SIGKILL on windows:
golang/os/signal_test.py::test_signal_all Traceback (most recent call last):
File "Z:\home\kirr\src\tools\go\pygo-win\pygolang\golang\os\testprog\signal_test_all.py", line 82, in <module>
main()
File "Z:\home\kirr\src\tools\go\pygo-win\pygolang\golang\os\testprog\signal_test_all.py", line 39, in main
allsigv.remove(syscall.SIGKILL) # SIGKILL/SIGSTOP cannot be caught
AttributeError: module 'golang.syscall' has no attribute 'SIGKILL'. Did you mean: 'SIGILL'?
-> filter-out signals conditionally depending on their presence.
- Need to also filter-out SIGILL/SIGABRT because upon reception MSVC
runtime terminates process.https://lab.nexedi.com/kirr/pygolang/-/commit/ca4af748192b5ba750de85d321ac1b83aa13f308os/signal: tests: use raise instead of kill(self)2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
Because on Windows os.kill unconditionally terminates target process,
even if own self, instead of sending it any kind of signal.https://lab.nexedi.com/kirr/pygolang/-/commit/75d4091034c6d8e11e349779d5d0b6b22761abafos/signal: tests: Use SIGTERM/SIGINT on Windows2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
We use SIGUSR1/SIGUSR2 mainly in this test, but those signals are not
available on Windows:
@func
def test_signal():
# Notify/Stop with wrong chan dtype -> panic
_ = panics("pychan: channel type mismatch")
> with _: signal.Notify(chan(2), syscall.SIGUSR1)
E AttributeError: module 'golang.syscall' has no attribute 'SIGUSR1'
-> Use SIGTERM/SIGINT if SIGUSR1/SIGUSR2 are not available.
Don't want to use SIGTERM/SIGINT unconditionally because those signals are
better to leave for the job control so that e.g. nxdtest can properly kill
spawned pygolang tests.https://lab.nexedi.com/kirr/pygolang/-/commit/a5349f5d7e53b877db3ab4f2da7c5787e5d460d1*.py: Open files in binary mode and decode to UTF-8 explicitly if needed2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
On Windows in text mode files are opened with encoding=locale.getdefaultlocale()
which is CP125X instead of UTF-8 even if $PYTHONIOENCODING=UTF-8. This
way e.g. test_strings_print fail as:
E Failed: not equal:
E Expected:
E print(qq(b)): "привет αβγ b"
E print(qq(u)): "привет αβγ u"
E Got:
E print(qq(b)): "привет αβγ b"
E print(qq(u)): "привет αβγ u"
where "Expected" was read from golang/testprog/golang_test_str.txt and
decoded wrongly.
-> Fix it by always opening files for reading in binary mode and
utf8-decoding manually, if needed, everywhere.https://lab.nexedi.com/kirr/pygolang/-/commit/8d723b3438f763dfe9af853aae7cb49c37c8c754golang: tests: Spawn subprocess python with $PYTHONIOENCODING set to encoding...2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.comgolang: tests: Spawn subprocess python with $PYTHONIOENCODING set to encoding of stdin/stdout/stderr
We need to do it because on Windows `python x.py | ...` runs with stdio
encoding set to cp125X even if just `python x.py` runs with stdio
encoding=UTF-8.
(1.wenv) Z:\home\kirr\src\tools\go\pygo-win\pygolang\golang\testprog>python golang_test_str.py
print(qq(b)): "привет b"
print(qq(u)): "привет u"
(1.wenv) Z:\home\kirr\src\tools\go\pygo-win\pygolang\golang\testprog>python golang_test_str.py |more
print(qq(b)): "яЁштхЄ b"
print(qq(u)): "яЁштхЄ u"
(1.wenv) Z:\home\kirr\src\tools\go\pygo-win\pygolang\golang\testprog>python golang_test_str.py >aaa.txt
(1.wenv) Z:\home\kirr\src\tools\go\pygo-win\pygolang\golang\testprog>type aaa.txt
print(qq(b)): "яЁштхЄ b"
print(qq(u)): "яЁштхЄ u"
Which leads to the following test_strings_print failure:
E Failed: not equal:
E Expected:
E print(qq(b)): "привет b"
E print(qq(u)): "привет u"
E Got:
E print(qq(b)): "������ b"
E print(qq(u)): "������ u"
We also change golang_test_str.py to print not only russian and english
letters, but also greek ones. This is to make sure that stdout IO encoding would
not go cp125X unnoticed because then printing will fail with UnicodeEncodeError.
Note: in the above example both got and expected are wrong. Via
$PYTHONIOENCODING we only fix "got" and we will fix "expected" in the followup
patch. After current patch test_strings_print result is
E Failed: not equal:
E Expected:
E print(qq(b)): "привет αβγ b"
E print(qq(u)): "привет αβγ u"
E Got:
E print(qq(b)): "привет αβγ b"
E print(qq(u)): "привет αβγ u"
https://lab.nexedi.com/kirr/pygolang/-/commit/ee55e19db6d65853b2c295e87032c9551e59a66bgolang: tests: Adjust golang_test_defer_excchain.txt-pytest golden to support...2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
Apparently on Windows pytest detects terminal width differently than on
Linux/macOS and the test fails as
E Failed: not equal:
E Differences (unified diff with -expected +actual):
E @@ -1,5 +1,12 @@
E -...
E -_____________________________________ main _____________________________________
E -../__init__.py:...: in _
E +============================= test session starts =============================
E +platform win32 -- Python 3.10.11, pytest-7.3.1, pluggy-1.0.0
E +rootdir: PYGOLANG
E +collected 1 item
E +<BLANKLINE>
E +golang_test_defer_excchain.py F [100%]
E +<BLANKLINE>
E +================================== FAILURES ===================================
E +____________________________________ main _____________________________________
E +../__init__.py:106: in _
E return f(*argv, **kw)
E golang_test_defer_excchain.py:42: in main
E @@ -8,6 +15,6 @@
E <BLANKLINE>
E During handling of the above exception, another exception occurred:
E -../__init__.py:...: in __exit__
E - ...
E +../__init__.py:183: in __exit__
E + d()
E golang_test_defer_excchain.py:31: in d1
E raise RuntimeError("d1: aaa")
E @@ -15,9 +22,9 @@
E <BLANKLINE>
E During handling of the above exception, another exception occurred:
E -../__init__.py:...: in __exit__
E - ...
E +../__init__.py:183: in __exit__
E + d()
E golang_test_defer_excchain.py:33: in d2
E 1/0
E -E ZeroDivisionError: ...
E +E ZeroDivisionError: division by zero
E <BLANKLINE>
E During handling of the above exception, another exception occurred:
E @@ -25,3 +32,5 @@
E raise RuntimeError("d3: bbb")
E E RuntimeError: d3: bbb
E -=========================== ...
E +=========================== short test summary info ===========================
E +FAILED golang_test_defer_excchain.py::main - RuntimeError: d3: bbb
E +============================== 1 failed in 1.45s ==============================
-> Fix it by not requesting header to be of particular width.https://lab.nexedi.com/kirr/pygolang/-/commit/17c1d2fa6887934269ae83d2d2c4151ed3528ce8golang: tests: Normalize \r\n to \n in doctests on windows2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
On windows print emits \r\n instead of just \n. Here is how e.g.
test_defer_excchain_dump fails without normalization:
E Failed: not equal:
E Differences (unified diff with -expected +actual):
E @@ -1,42 +1,43 @@
E -Traceback (most recent call last):
E - File "PYGOLANG/golang/__init__.py", line ..., in _
E - return f(*argv, **kw)
E - File "PYGOLANG/golang/testprog/golang_test_defer_excchain.py", line 42, in main
E - raise RuntimeError("err")
E -RuntimeError: err
E -<BLANKLINE>
E -During handling of the above exception, another exception occurred:
E -<BLANKLINE>
E -Traceback (most recent call last):
E - File "PYGOLANG/golang/__init__.py", line ..., in __exit__
E - ...
E - File "PYGOLANG/golang/testprog/golang_test_defer_excchain.py", line 31, in d1
E - raise RuntimeError("d1: aaa")
E -RuntimeError: d1: aaa
E -<BLANKLINE>
E -During handling of the above exception, another exception occurred:
E -<BLANKLINE>
E -Traceback (most recent call last):
E - File "PYGOLANG/golang/__init__.py", line ..., in __exit__
E - ...
E - File "PYGOLANG/golang/testprog/golang_test_defer_excchain.py", line 33, in d2
E - 1/0
E -ZeroDivisionError: ...
E -<BLANKLINE>
E -During handling of the above exception, another exception occurred:
E -<BLANKLINE>
E -Traceback (most recent call last):
E - ... "PYGOLANG/golang/testprog/golang_test_defer_excchain.py", line 45, in <module>
E - main()
E - ...
E - File "PYGOLANG/golang/__init__.py", line ..., in _
E - with __goframe__:
E - File "PYGOLANG/golang/__init__.py", line ..., in __exit__
E - ...
E - File "PYGOLANG/golang/__init__.py", line ..., in __exit__
E - ...
E - File "PYGOLANG/golang/__init__.py", line ..., in __exit__
E - ...
E - File "PYGOLANG/golang/testprog/golang_test_defer_excchain.py", line 35, in d3
E - raise RuntimeError("d3: bbb")
E -RuntimeError: d3: bbb
E +Traceback (most recent call last):
E + File "PYGOLANG/golang/__init__.py", line 106, in _
E + return f(*argv, **kw)
E + File "PYGOLANG/golang/testprog/golang_test_defer_excchain.py", line 42, in main
E + raise RuntimeError("err")
E +RuntimeError: err
E +
E +During handling of the above exception, another exception occurred:
E +
E +Traceback (most recent call last):
E + File "PYGOLANG/golang/__init__.py", line 183, in __exit__
E + d()
E + File "PYGOLANG/golang/testprog/golang_test_defer_excchain.py", line 31, in d1
E + raise RuntimeError("d1: aaa")
E +RuntimeError: d1: aaa
E +
E +During handling of the above exception, another exception occurred:
E +
E +Traceback (most recent call last):
E + File "PYGOLANG/golang/__init__.py", line 183, in __exit__
E + d()
E + File "PYGOLANG/golang/testprog/golang_test_defer_excchain.py", line 33, in d2
E + 1/0
E +ZeroDivisionError: division by zero
E +
E +During handling of the above exception, another exception occurred:
E +
E +Traceback (most recent call last):
E + File "PYGOLANG/golang/testprog/golang_test_defer_excchain.py", line 45, in <module>
E + main()
E + File "Z:\home\kirr\src\tools\go\pygo-win\1.wenv\lib\site-packages/decorator.py", line 232, in fun
E + return caller(func, *(extras + args), **kw)
E + File "PYGOLANG/golang/__init__.py", line 105, in _
E + with __goframe__:
E + File "PYGOLANG/golang/__init__.py", line 182, in __exit__
E + with __goframe__:
E + File "PYGOLANG/golang/__init__.py", line 182, in __exit__
E + with __goframe__:
E + File "PYGOLANG/golang/__init__.py", line 183, in __exit__
E + d()
E + File "PYGOLANG/golang/testprog/golang_test_defer_excchain.py", line 35, in d3
E + raise RuntimeError("d3: bbb")
E +RuntimeError: d3: bbbhttps://lab.nexedi.com/kirr/pygolang/-/commit/06935819f2464dfa90267026f0c0e72ce238ee54golang: tests: Normalize paths to use / delimiter in doctests's got2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
Else on Windows e.g. test_defer_excchain_traceback fails as
E Failed: not equal:
E Differences (unified diff with -expected +actual):
E @@ -1,8 +1,8 @@
E Traceback (most recent call last):
E - File "PYGOLANG/golang/golang_test.py", line ..., in test_defer_excchain_traceback
E + File "PYGOLANG\golang\golang_test.py", line 1524, in test_defer_excchain_traceback
E alpha()
E - File "PYGOLANG/golang/golang_test.py", line ..., in alpha
E + File "PYGOLANG\golang\golang_test.py", line 1521, in alpha
E beta()
E - File "PYGOLANG/golang/golang_test.py", line ..., in beta
E + File "PYGOLANG\golang\golang_test.py", line 1520, in beta
E raise RuntimeError("gamma")
E RuntimeError: gammahttps://lab.nexedi.com/kirr/pygolang/-/commit/a5ce817503b35ed9aa998591118dfcb734b2c3c6golang: Prepare path for libgolang.dll before importing _golang2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
Else it fails to import on Windows:
collecting ... 05c8:err:module:import_dll Library libgolang.dll (which is needed by L"Z:\\home\\kirr\\src\\tools\\go\\pygo-win\\pygolang\\golang\\_golang.cp310-win_amd64.pyd") not found
collected 0 items / 1 error
=========================================================== ERRORS ===========================================================
___________________________________________ ERROR collecting golang/golang_test.py ___________________________________
ImportError while importing test module 'Z:\home\kirr\src\tools\go\pygo-win\pygolang\golang\golang_test.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
C:\Program Files\Python310\lib\importlib\__init__.py:126: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
golang\__init__.py:45: in <module>
from golang._golang import _pysys_exc_clear as _sys_exc_clear
E ImportError: DLL load failed while importing _golang: Модуль не найден.
We need to increase required setuptools_dso version because dylink_prepare_dso
and generation of *_dsoinfo.py modules was done after setuptools_dso 2.https://lab.nexedi.com/kirr/pygolang/-/commit/0b97e0a82b336cc9b74330474359e1d409961cb0.gitignore += *.lib *.exp2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
On Windows this files are generated when linking alongside *.dll files
if there are exported symbols.
See also <a href="https://github.com/mdavidsaver/setuptools_dso/pull/25" rel="nofollow noreferrer noopener" target="_blank">https://github.com/mdavidsaver/setuptools_dso/pull/25</a>.https://lab.nexedi.com/kirr/pygolang/-/commit/fbed01b0ecf6eed8f82c6b21d77a7bc3158a9be7setup: We need to link libpyxruntime DSO to py runtime2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
Libpyxruntime by definition contains python-specific code and we already
compile it with include path having python includes in it. However on
windows pyconfig.h contains
#pragma comment(lib,"python3.lib")
which instructs the linker to automatically link to that library. And
without proper library path the link fails:
Z:\home\kirr\src\tools\go\pygo-win\BuildTools\vc\tools\msvc\14.35.32215\bin\Hostx64\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:build\lib.win-amd64-cpython-31
0\golang\runtime /LIBPATH:z:\home\kirr\src\tools\go\pygo-win\BuildTools\vc\tools\msvc\14.35.32215\lib\x64 /LIBPATH:z:\home\kirr\src\tools\go\pygo-win\BuildTools\kits\10\lib\10.0.22000.0\ucrt\x64 /LIBPATH:z:\h
ome\kirr\src\tools\go\pygo-win\BuildTools\kits\10\lib\10.0.22000.0\um\x64 libgolang.lib build\temp.win-amd64-cpython-310\Release\golang/runtime/libpyxruntime.obj /OUT:build\lib.win-amd64-cpython-310\golang\ru
ntime\libpyxruntime.dll /IMPLIB:build\lib.win-amd64-cpython-310\golang\runtime\libpyxruntime.lib
LINK : fatal error LNK1104: cannot open file 'python310.lib'
-> Fix it by providing proper library path for python.dll .
We need to do it ourselves only for libpyxruntime dso because for py
extensions this is automatically done by distutils out of the box.https://lab.nexedi.com/kirr/pygolang/-/commit/437bbd5650f6405eed715edc937af0befae0551blibgolang/gevent: Adjust to support Windows2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
On Windows rthere is no fcntl
golang/runtime\_runtime_gevent.cpp(4811): error C3861: 'S_ISBLK': identifier not found
golang/runtime\_runtime_gevent.cpp(4823): error C2039: 'Fcntl': is not a member of 'golang::internal::syscall'
.\golang/runtime/internal/syscall.h(36): note: see declaration of 'golang::internal::syscall'
golang/runtime\_runtime_gevent.cpp(4823): error C2065: 'F_GETFL': undeclared identifier
golang/runtime\_runtime_gevent.cpp(4823): error C3861: 'Fcntl': identifier not found
golang/runtime\_runtime_gevent.cpp(4870): error C2065: 'O_ACCMODE': undeclared identifier
golang/runtime\_runtime_gevent.cpp(4889): error C2039: 'Fcntl': is not a member of 'golang::internal::syscall'
.\golang/runtime/internal/syscall.h(36): note: see declaration of 'golang::internal::syscall'
golang/runtime\_runtime_gevent.cpp(4889): error C2065: 'F_SETFL': undeclared identifier
golang/runtime\_runtime_gevent.cpp(4889): error C2065: 'O_NONBLOCK': undeclared identifier
golang/runtime\_runtime_gevent.cpp(4889): error C3861: 'Fcntl': identifier not found
and even if there would be gevent does not provide cooperative version
of FileObject for non-POSIX platforms.
-> Always use FileObjectThread on windows even for pipes.https://lab.nexedi.com/kirr/pygolang/-/commit/45473979581a50c4dbf448ac47f4398d0bbf5f6cos/signal: Use windows-specific code to turn wakeup pipe into nonblocking mode2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
There is no fcntl on windows. Named pipes can be set into nonblocking
mode via SetNamedPipeHandleState(PIPE_NOWAIT).https://lab.nexedi.com/kirr/pygolang/-/commit/acc6c3f189d0bb3b1297a19e57b27bd4730223acos/signal: Internally emulate sigaction via signal2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
On MSVC there is no sigaction and we have to use signal. Fortunately
our sigaction usage in os/signal can be practically emulated because we
do not use all features of sigaction and because on MSVC there is
SIG_GET signal extension to query current signal handler without
resetting it.
Because the emulation is limited we keep it in os/signal.cpp instead of
adjusting syscall::Sigaction .https://lab.nexedi.com/kirr/pygolang/-/commit/b15fa8186bb9463dd8b2f402a7ca3379f0c34828os/signal: Factor call to sys::Sigaction into sys_sigaction internal helper2023-04-27T21:08:51+03:00Kirill Smelkovkirr@nexedi.com
On MSVC we will need to use signal(2), because there is no sigaction,
and sigaction will be partly emulated through that. Move signal setting
code into common place as a preparatory step.https://lab.nexedi.com/kirr/pygolang/-/commit/d3bf3b7d74c7c8b15b0cbf8d1ebc6937d74df5e6internal/syscall: Initial adjust to support MSVC2023-04-27T21:08:48+03:00Kirill Smelkovkirr@nexedi.com
- there is no strerror_r, but strerror_s instead
- fcntl is not supported
- we need to explicitly tell open to open files in binary mode
- pipes are created via _pipe and explicitly in binary mode
- there is no sigaction.https://lab.nexedi.com/kirr/pygolang/-/commit/63b5c1d9fe8196354242bfc248279adc9789b4c8internal/syscall: Adjust Pipe to take flags2023-04-27T21:06:22+03:00Kirill Smelkovkirr@nexedi.com
This way e.g. O_CLOEXEC can be passed in at pipe creation time removing
potential race in between pipe+fcntl vs exec in the middle. It will also
help in windows porting in follow-up patches becuase there is no fcntl
on Windows, but pipe with O_CLOEXEC semantic can be created directly
with flags=_O_NOINHERIT.https://lab.nexedi.com/kirr/pygolang/-/commit/534033a56d4d1a43efe8a5840a436b5dfb7aa781internal/atomic: Adjust to support MSVC2023-04-27T16:22:18+03:00Kirill Smelkovkirr@nexedi.com
There is no fork on windows and that we do not need to install atfork
handler at all.
golang/runtime/internal/atomic.cpp(23): fatal error C1083: Cannot open include file: 'pthread.h': No such file or directoryhttps://lab.nexedi.com/kirr/pygolang/-/commit/5098decb6dc1daf810b970c0af29ebc7162ee3aefmt: Adjust to support MSVC2023-04-27T16:17:23+03:00Kirill Smelkovkirr@nexedi.com
- there is no __attribute__ on that compiler
- sadly va_start is rejected to work on reference:
z:\home\kirr\src\tools\go\pygo-win\BuildTools\vc\tools\msvc\14.35.32215\include\vadefs.h(194): error C2338: static_assert failed: 'va_start argument must not have reference type and must not be parenthesized'
golang/fmt.cpp(53): note: see reference to class template instantiation '__vcrt_assert_va_start_is_not_reference<const golang::string &>' being compiled
-> change format from string& to be string in sprintf.
Probably it should be ok in practice from performance point of view because
string contains only pointer to data, not the data itself.https://lab.nexedi.com/kirr/pygolang/-/commit/22a597a0305b478983921920d44111a3cd226c68os: Adjust to support MSVC2023-04-27T16:11:24+03:00Kirill Smelkovkirr@nexedi.com
- There is no S_IRUSR & friends -> use _S_IREAD & co.
- Tthere is no sys_siglist -> kind-of define it ourselves for all documented signals.https://lab.nexedi.com/kirr/pygolang/-/commit/715fa60bea7c3c7f70a10e32f2fdfaf2287c5488libgolang: Use custom list_entry on MSVC2023-04-27T16:04:09+03:00Kirill Smelkovkirr@nexedi.com
list_entry, as provided by linux/list.h, uses statement expressions(*) which
are not supported by MSVC:
#define list_entry(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
golang/runtime/libgolang.cpp(439): error C2059: syntax error: '{'
golang/runtime/libgolang.cpp(439): error C2143: syntax error: missing ';' before '{'
golang/runtime/libgolang.cpp(439): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
golang/runtime/libgolang.cpp(439): error C2440: 'initializing': cannot convert from 'list_head' to 'int'
golang/runtime/libgolang.cpp(439): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
golang/runtime/libgolang.cpp(439): error C2143: syntax error: missing ';' before '*'
golang/runtime/libgolang.cpp(439): error C2065: '__mptr': undeclared identifier
golang/runtime/libgolang.cpp(439): error C2059: syntax error: ')'
-> work it around by defining list_entry with C++ lambda.
(*) <a href="https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html" rel="nofollow noreferrer noopener" target="_blank">https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html</a>https://lab.nexedi.com/kirr/pygolang/-/commit/1845b93d6b9b0face511eae3954d779dae158bdblibgolang: random_shuffle -> shuffle2023-04-27T15:59:01+03:00Kirill Smelkovkirr@nexedi.com
There is no std::random_shuffle on `MSVC /std:c++20` because it was removed in C++17:
golang/runtime/libgolang.cpp(946): error C2039: 'random_shuffle': is not a member of 'std'
z:\home\kirr\src\tools\go\pygo-win\BuildTools\vc\tools\msvc\14.35.32215\include\random(34): note: see declaration of 'std'
golang/runtime/libgolang.cpp(946): error C3861: 'random_shuffle': identifier not found
<a href="https://en.cppreference.com/w/cpp/algorithm/random_shuffle" rel="nofollow noreferrer noopener" target="_blank">https://en.cppreference.com/w/cpp/algorithm/random_shuffle</a>https://lab.nexedi.com/kirr/pygolang/-/commit/35ed249202011aea3eec72f73149662b2cc34168libgolang: Provide custom bzero, mode_t and unistd.h on MSVC2023-04-27T15:53:58+03:00Kirill Smelkovkirr@nexedi.com
We need unistd.h because e.g. `cimport posix.stat` forces inclusion of unistd.h
even if we use part of posix.stat that is available everywhere.
We use bzero in libgolang.cpp - provide it in similar way via compat
strings.h because on windows there is only string.h (no "s" in the end).
We also use mode_t in several places - provide it via typedef in
libgolang.h directly, because fcntl.h is present on MSVC.https://lab.nexedi.com/kirr/pygolang/-/commit/5f107215c43d8f376b8cca6e292c4277df172d06pyx.build: Adjust compile flags if we are on Windows/MSVC2023-04-27T15:35:04+03:00Kirill Smelkovkirr@nexedi.com
MSVC does not accept -std=c++11 but instead accepts /std:c++11. We cannot
use that however because with /std:c++11 compilation fails with
.\golang/libgolang.h(280): error C7555: use of designated initializers requires at least '/std:c++20'
.\golang/libgolang.h(294): error C7555: use of designated initializers requires at least '/std:c++20'
.\golang/libgolang.h(308): error C7555: use of designated initializers requires at least '/std:c++20'
for
276 // _selsend creates `_chansend(ch, ptx)` case for _chanselect.
277 static inline
278 _selcase _selsend(_chan *ch, const void *ptx) {
279 _selcase _ = {
280 .ch = ch, <-- NOTE
281 .op = _CHANSEND,
282 .flags = (enum _selflags)0,
283 .user = 0xff,
284 };
and similar places.
-> Use /std:c++20 instead as MSVC advices (WOW designated initializers are C99
and it took 21 years for C++ to catch up).
We also need to adjust exception handling mode into "fully conformant" instead
of "assume extern C cannot throw" setuptools default so that `panic` and other
extern C libgolang functions generate exceptions that could be caught
instead of crashing programs.
For C vs C++ flags we also need to adjust our build_ext, because the way
setuptools/distutils organize compilation for MSVC is different from
UNIX compilers.https://lab.nexedi.com/kirr/pygolang/-/commit/b5bd136c1688f69643c456b4d7d4d767e05262c8setup: Reuse golang.pyx.build to build DSOs2023-04-27T10:37:45+03:00Kirill Smelkovkirr@nexedi.com
We already reuse golang.pyx.build in setup.py to build Extensions, but
DSOs were built via setuptools_dso directly so far. To support Windows
we will soon need to adjust compilation flags for both Extensions and
DSOs. It makes sense to first concentrate build recipes in one place
before doing that.
-> Move/factor DSOs build flags into golang.pyx.build and reuse that
from setup.https://lab.nexedi.com/kirr/pygolang/-/commit/0ffef2d8432a0e32a8dae831cc7117c2de9ee9f8*: Fix dll export annotation everywhere2023-04-27T10:21:53+03:00Kirill Smelkovkirr@nexedi.com
We already try to annotate functions exported from DSOs as such.
However so far we were testing only on Linux and macOS where
-fvisibility=hidden is not the default, and thus linker forgives us
annotation mistakes. But on Windows the default is to have hidden
visibility out of the box and so the linker becomes strict about this.
-> Fix all issues caught there.
For example here is how it breaks if ~_interface() is not annotated properly:
building 'golang.runtime.libpyxruntime' DSO as build\lib.win-amd64-cpython-310\golang\runtime\libpyxruntime.dll
...
Z:\home\kirr\src\tools\go\pygo-win\BuildTools\vc\tools\msvc\14.35.32215\bin\Hostx64\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO "/LIBPATH:C:\Program Files\Python310\li
bs" /LIBPATH:build\lib.win-amd64-cpython-310\golang\runtime /LIBPATH:z:\home\kirr\src\tools\go\pygo-win\BuildTools\vc\tools\msvc\14.35.32215\lib\x64 /LIBPATH:z:\home\kirr\src\tools\go\pygo-win\BuildTools\kits
\10\lib\10.0.22000.0\ucrt\x64 /LIBPATH:z:\home\kirr\src\tools\go\pygo-win\BuildTools\kits\10\lib\10.0.22000.0\um\x64 libgolang.lib build\temp.win-amd64-cpython-310\Release\golang/runtime/libpyxruntime.obj /OU
T:build\lib.win-amd64-cpython-310\golang\runtime\libpyxruntime.dll /IMPLIB:build\lib.win-amd64-cpython-310\golang\runtime\libpyxruntime.lib
Creating library build\lib.win-amd64-cpython-310\golang\runtime\libpyxruntime.lib and object build\lib.win-amd64-cpython-310\golang\runtime\libpyxruntime.exp
libpyxruntime.obj : error LNK2001: unresolved external symbol "protected: __cdecl golang::_interface::~_interface(void)" (??1_interface@golang@@IEAA@XZ)
build\lib.win-amd64-cpython-310\golang\runtime\libpyxruntime.dll : fatal error LNK1120: 1 unresolved externals
error: command 'Z:\\home\\kirr\\src\\tools\\go\\pygo-win\\BuildTools\\vc\\tools\\msvc\\14.35.32215\\bin\\Hostx64\\x64\\link.exe' failed with exit code 1120