- 16 Apr, 2023 4 commits
-
-
Kirill Smelkov authored
Python changed traceback output a bit: - added '^^^^^^^' and '~~^~~' - changed lineno of frame corresponding to __exit__ to be at line of `with ...` -> Adjust to that by introducing a bit more generalized conditionals in assertDoc. Here is, for example, how test_defer_excchain_traceback was failing on py3.11: E Failed: not equal: E Differences (unified diff with -expected +actual): E @@ -1,6 +1,7 @@ E Traceback (most recent call last): E - File "PYGOLANG/golang/__init__.py", line ..., in _ E + File "PYGOLANG/golang/__init__.py", line 103, in _ E return f(*argv, **kw) E - File "PYGOLANG/golang/golang_test.py", line ..., in caller E + ^^^^^^^^^^^^^^ E + File "PYGOLANG/golang/golang_test.py", line 1550, in caller E raise RuntimeError("ccc") E RuntimeError: ccc E @@ -9,7 +10,7 @@ E <BLANKLINE> E Traceback (most recent call last): E - File "PYGOLANG/golang/__init__.py", line ..., in __exit__ E + File "PYGOLANG/golang/__init__.py", line 180, in __exit__ E d() E - File "PYGOLANG/golang/golang_test.py", line ..., in q2 E + File "PYGOLANG/golang/golang_test.py", line 1548, in q2 E raise RuntimeError("bbb") E RuntimeError: bbb E @@ -18,14 +19,16 @@ E <BLANKLINE> 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 1553, in test_defer_excchain_traceback E caller() E - ... E - File "PYGOLANG/golang/__init__.py", line ..., in _ E - return f(*argv, **kw) E - File "PYGOLANG/golang/__init__.py", line ..., in __exit__ E + File "/home/kirr/src/tools/go/py3.venv/lib/python3.11/site-packages/decorator.py", line 232, in fun E + return caller(func, *(extras + args), **kw) E + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ E + File "PYGOLANG/golang/__init__.py", line 102, in _ E + with __goframe__: E + File "PYGOLANG/golang/__init__.py", line 179, in __exit__ E + with __goframe__: E + File "PYGOLANG/golang/__init__.py", line 180, in __exit__ E d() E - File "PYGOLANG/golang/__init__.py", line ..., in __exit__ E - d() E - File "PYGOLANG/golang/golang_test.py", line ..., in q1 E + File "PYGOLANG/golang/golang_test.py", line 1545, in q1 E raise RuntimeError("aaa") E RuntimeError: aaa
-
Kirill Smelkov authored
IPython8 changed format of output tracebacks (see https://github.com/ipython/ipython/commit/02660f35 and further). Adding test support for later versions would add maintenance cost on pygolang side, but testing this is actually not needed, since we activate IPython-related patch only on py2 and for py2 the latest ipython version is ipython5. -> So simply skip this test if we see we have IPython ≥ 8. Skip it only on py3 just in case. For the reference here is how diff in between running golang_test_defer_excchain.py on IPython7 and IPython8 looks: diff --git a/golang/testprog/7 b/golang/testprog/8 index 5c31ed2..8fea57b 100644 --- a/golang/testprog/7 +++ b/golang/testprog/8 @@ -1,101 +1,91 @@ -[22;0t]0;IPython: golang/testprog--------------------------------------------------------------------------- +--------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) -~/src/tools/go/pygolang-master/golang/__init__.py in _(f, *argv, **kw) - 102 with __goframe__: ---> 103 return f(*argv, **kw) - 104 +File ~/src/tools/go/pygolang-master/golang/__init__.py:103, in _func.<locals>._(f, *argv, **kw) + 102 with __goframe__: +--> 103 return f(*argv, **kw) -~/src/tools/go/pygolang-master/golang/testprog/golang_test_defer_excchain.py in main() - 41 defer(d1) ----> 42 raise RuntimeError("err") - 43 +File ~/src/tools/go/pygolang-master/golang/testprog/golang_test_defer_excchain.py:42, in main() + 41 defer(d1) +---> 42 raise RuntimeError("err") RuntimeError: err During handling of the above exception, another exception occurred: RuntimeError Traceback (most recent call last) -~/src/tools/go/pygolang-master/golang/__init__.py in __exit__(__goframe__, exc_type, exc_val, exc_tb) - 179 with __goframe__: ---> 180 d() - 181 +File ~/src/tools/go/pygolang-master/golang/__init__.py:180, in _GoFrame.__exit__(__goframe__, exc_type, exc_val, exc_tb) + 179 with __goframe__: +--> 180 d() + 182 return __goframe__.recovered -~/src/tools/go/pygolang-master/golang/testprog/golang_test_defer_excchain.py in d1() +File ~/src/tools/go/pygolang-master/golang/testprog/golang_test_defer_excchain.py:31, in d1() 30 def d1(): ---> 31 raise RuntimeError("d1: aaa") - 32 def d2(): RuntimeError: d1: aaa During handling of the above exception, another exception occurred: ZeroDivisionError Traceback (most recent call last) -~/src/tools/go/pygolang-master/golang/__init__.py in __exit__(__goframe__, exc_type, exc_val, exc_tb) - 179 with __goframe__: ---> 180 d() - 181 +File ~/src/tools/go/pygolang-master/golang/__init__.py:180, in _GoFrame.__exit__(__goframe__, exc_type, exc_val, exc_tb) + 179 with __goframe__: +--> 180 d() + 182 return __goframe__.recovered -~/src/tools/go/pygolang-master/golang/testprog/golang_test_defer_excchain.py in d2() +File ~/src/tools/go/pygolang-master/golang/testprog/golang_test_defer_excchain.py:33, in d2() 32 def d2(): ---> 33 1/0 - 34 def d3(): ZeroDivisionError: division by zero During handling of the above exception, another exception occurred: RuntimeError Traceback (most recent call last) -/usr/lib/python3.11/runpy.py in run_module(mod_name, init_globals, run_name, alter_sys) +File <frozen runpy>:226, in run_module(mod_name, init_globals, run_name, alter_sys) -/usr/lib/python3.11/runpy.py in _run_module_code(code, init_globals, mod_name, mod_spec, pkg_name, script_name) +File <frozen runpy>:98, in _run_module_code(code, init_globals, mod_name, mod_spec, pkg_name, script_name) -/usr/lib/python3.11/runpy.py in _run_code(code, run_globals, init_globals, mod_name, mod_spec, pkg_name, script_name) +File <frozen runpy>:88, in _run_code(code, run_globals, init_globals, mod_name, mod_spec, pkg_name, script_name) -~/src/tools/go/pygolang-master/golang/testprog/golang_test_defer_excchain.py in <module> - 43 +File ~/src/tools/go/pygolang-master/golang/testprog/golang_test_defer_excchain.py:45 + 42 raise RuntimeError("err") 44 if __name__ == "__main__": ---> 45 main() -~/src/tools/go/py3.venv/lib/python3.11/site-packages/decorator.py in fun(*args, **kw) - 230 if not kwsyntax: - 231 args, kw = fix(args, kw, sig) ---> 232 return caller(func, *(extras + args), **kw) - 233 fun.__name__ = func.__name__ - 234 fun.__doc__ = func.__doc__ +File ~/src/tools/go/py3.venv/lib/python3.11/site-packages/decorator.py:232, in decorate.<locals>.fun(*args, **kw) + 230 if not kwsyntax: + 231 args, kw = fix(args, kw, sig) +--> 232 return caller(func, *(extras + args), **kw) -~/src/tools/go/pygolang-master/golang/__init__.py in _(f, *argv, **kw) - 100 # run f under separate frame, where defer will register calls. - 101 __goframe__ = _GoFrame() ---> 102 with __goframe__: - 103 return f(*argv, **kw) - 104 +File ~/src/tools/go/pygolang-master/golang/__init__.py:102, in _func.<locals>._(f, *argv, **kw) + 99 def _(f, *argv, **kw): + 100 # run f under separate frame, where defer will register calls. + 101 __goframe__ = _GoFrame() +--> 102 with __goframe__: + 103 return f(*argv, **kw) -~/src/tools/go/pygolang-master/golang/__init__.py in __exit__(__goframe__, exc_type, exc_val, exc_tb) - 177 - 178 # even if d panics - we have to call other defers ---> 179 with __goframe__: - 180 d() - 181 +File ~/src/tools/go/pygolang-master/golang/__init__.py:179, in _GoFrame.__exit__(__goframe__, exc_type, exc_val, exc_tb) + 176 d = __goframe__.deferv.pop() + 178 # even if d panics - we have to call other defers +--> 179 with __goframe__: + 180 d() + 182 return __goframe__.recovered -~/src/tools/go/pygolang-master/golang/__init__.py in __exit__(__goframe__, exc_type, exc_val, exc_tb) - 177 - 178 # even if d panics - we have to call other defers ---> 179 with __goframe__: - 180 d() - 181 +File ~/src/tools/go/pygolang-master/golang/__init__.py:179, in _GoFrame.__exit__(__goframe__, exc_type, exc_val, exc_tb) + 176 d = __goframe__.deferv.pop() + 178 # even if d panics - we have to call other defers +--> 179 with __goframe__: + 180 d() + 182 return __goframe__.recovered -~/src/tools/go/pygolang-master/golang/__init__.py in __exit__(__goframe__, exc_type, exc_val, exc_tb) - 178 # even if d panics - we have to call other defers - 179 with __goframe__: ---> 180 d() - 181 - 182 return __goframe__.recovered +File ~/src/tools/go/pygolang-master/golang/__init__.py:180, in _GoFrame.__exit__(__goframe__, exc_type, exc_val, exc_tb) + 178 # even if d panics - we have to call other defers + 179 with __goframe__: +--> 180 d() + 182 return __goframe__.recovered -~/src/tools/go/pygolang-master/golang/testprog/golang_test_defer_excchain.py in d3() - 33 1/0 +File ~/src/tools/go/pygolang-master/golang/testprog/golang_test_defer_excchain.py:35, in d3() 34 def d3(): ---> 35 raise RuntimeError("d3: bbb") - 36 - 37 @func RuntimeError: d3: bbb
-
Kirill Smelkov authored
Starting from python3.11 inspect.formatargspec was removed: f = <function test_func.<locals>.zzz at 0x7fb6d265fec0> def fmtargspec(f): # -> str with warnings.catch_warnings(): warnings.simplefilter('ignore', DeprecationWarning) > return inspect.formatargspec(*inspect.getargspec(f)) E AttributeError: module 'inspect' has no attribute 'formatargspec' golang/golang_test.py:1823: AttributeError We were already handling formatargspec deprecation in 45f4df9e (golang: tests: Silence inspect deprecation warning), but now is the time to actually replace its usage. -> Fix it by using `str(inspect.signature(f))` instead of `inspect.formatargspec(*inspect.getargspec(f))`.
-
Kirill Smelkov authored
With setuptools 65 running test_pyx_build_cmdclass is failing because besides cmdclass_custom.py it sees nearby golang_pyx_user/ and golang_dso_user/ with top-project setups and rejects it: ---- 8< ---- golang/pyx/build_test.py::test_pyx_build_cmdclass error: Multiple top-level packages discovered in a flat-layout: ['golang_pyx_user', 'golang_dso_user']. To avoid accidental inclusion of unwanted files or directories, setuptools will not proceed with this build. If you are trying to create a single distribution with multiple packages on purpose, you should not rely on automatic discovery. Instead, consider the following options: 1. set up custom discovery (`find` directive with `include` or `exclude`) 2. use a `src-layout` 3. explicitly set `py_modules` or `packages` with a list of names To find more information, look for "package discovery" on setuptools docs. FAILED ================================ FAILURES ================================= _________________________ test_pyx_build_cmdclass _________________________ def test_pyx_build_cmdclass(): > _ = pyout(["cmdclass_custom.py", "build_ext"], cwd=testprog) golang/pyx/build_test.py:60: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ golang/golang_test.py:1742: in pyout return pyrun(argv, stdin=stdin, stdout=stdout, stderr=stderr, **kw) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ argv = ['cmdclass_custom.py', 'build_ext'], stdin = None, stdout = b'', stderr = None kw = {'cwd': '/home/kirr/src/tools/go/pygolang-master/golang/pyx/testprog'}, 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: cmdclass_custom.py build_ext E (failed) golang/golang_test.py:1736: RuntimeError ---- 8< ---- -> Work it around by defining py_modules explicitly as suggested in https://stackoverflow.com/a/72547402/9456786.
-
- 23 Jan, 2023 1 commit
-
-
Kirill Smelkov authored
We use &vector[0] in several places to get the pointer to vector data, but std::vector[i] states invariant that i must be < vector.size(). If the vector is not empty - then &vector[0] works ok. However if the vector is empty - then the invariant is broken. Normally it should not be a problem, since with empty vector we usually use (&vector[0], vector.size()) pair, and for empty vector its size is zero. In other words even if &vector[0] returns some not good pointer with zero size that data should never be accessed. But a build of libstdc++ could have asserts turned on and verify that i is actually < size. For example with default install on Fedora the following program with plain select() from golang import select select() crashes with assert triggered on the breakage of that invariant [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". /usr/include/c++/10/bits/stl_vector.h:1042: std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](std::vector<_Tp, _Alloc>::size_type) [with _Tp = golang::_selcase; _Alloc = std::allocator<golang::_selcase>; std::vector<_Tp, _Alloc>::reference = golang::_selcase&; std::vector<_Tp, _Alloc>::size_type = long unsigned int]: Assertion '__builtin_expect(__n < this->size(), true)' failed. Program received signal SIGABRT, Aborted. 0x00007ffff7e22a25 in raise () from /lib64/libc.so.6 (gdb) bt #0 0x00007ffff7e22a25 in raise () from /lib64/libc.so.6 #1 0x00007ffff7e0b895 in abort () from /lib64/libc.so.6 #2 0x00007fffea638d6d in std::__replacement_assert (__condition=0x7fffea63ea88 "__builtin_expect(__n < this->size(), true)", __function=0x7fffea63eab8 "std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](std::vector<_Tp, _Alloc>::size_type) [with _Tp = golang::_selcase; _Alloc = std::allocator<golang::_selcase>; std::vector<_Tp, "..., __line=1042, __file=0x7fffea63ebe8 "/usr/include/c++/10/bits/stl_vector.h") at /usr/include/c++/10/x86_64-redhat-linux/bits/c++config.h:2552 #3 std::vector<golang::_selcase, std::allocator<golang::_selcase> >::operator[] (this=<synthetic pointer>, __n=0) at /usr/include/c++/10/bits/stl_vector.h:1042 #4 std::vector<golang::_selcase, std::allocator<golang::_selcase> >::operator[] (__n=0, this=<synthetic pointer>) at /usr/include/c++/10/bits/stl_vector.h:1040 #5 __pyx_pf_6golang_7_golang_6pyselect (__pyx_self=<optimized out>, __pyx_v_pycasev=<optimized out>) at golang/_golang.cpp:7930 #6 __pyx_pw_6golang_7_golang_7pyselect (__pyx_self=<optimized out>, __pyx_args=<optimized out>, __pyx_kwds=<optimized out>) at golang/_golang.cpp:7284 #7 0x00007ffff7bceeab in cfunction_call_varargs (func=<built-in function pyselect>, args=(), kwargs=0x0) at /usr/src/debug/python3-3.8.10-1.fc32.x86_64/Objects/call.c:743 ... -> Fix it all via replacing &vector[0] with vector.data() everywhere. No need to add new test since select() is used by test_blockforever() and running that test on Fedora was crashing as well. /reviewed-by @jerome /reviewed-at nexedi/pygolang!22
-
- 05 Oct, 2022 2 commits
-
-
Kirill Smelkov authored
Since the beginning (9bf03d9c "py.bench: New command to benchmark python code similarly to `go test -bench`") py.bench was automatically discovering benchmarks in bench_*.py files only. This was inherited from wendelin.core which keeps its benchmarks in those files. However in pygolang, following Go convention(*), we already have several benchmarks that reside together with tests in same *_test.py files. And currently just running py.bench does not discover them. -> Let's fix this and teach py.bench to automatically discover benchmarks in the test files by default as well. Pytest's default is to look for tests in test_*.py and *_test.py (+). Add those patterns and also keep bench_*.py for backward compatibility. Before this patch running py.bench inside pygolang repository does not run any benchmark at all. After the patch py.bench runs all the benchmarks by default: (z-dev) kirr@deca:~/src/tools/go/pygolang$ py.bench ========================= test session starts ========================== platform linux2 -- Python 2.7.18, pytest-4.6.11, py-1.10.0, pluggy-0.13.1 rootdir: /home/kirr/src/tools/go/pygolang plugins: timeout-1.4.2, profiling-1.7.0, mock-2.0.0 collected 18 items pymod: golang/golang_str_test.py Benchmarkstddecode 2000000 0.756 µs/op Benchmarkudecode 20000 74.359 µs/op Benchmarkstdencode 3000000 0.327 µs/op Benchmarkbencode 40000 32.613 µs/op pymod: golang/golang_test.py Benchmarkpyx_select_nogil 500000 2.051 µs/op Benchmarkpyx_go_nogil 90000 12.177 µs/op Benchmarkpyx_chan_nogil 600000 1.826 µs/op Benchmarkgo 80000 13.267 µs/op Benchmarkchan 500000 2.076 µs/op Benchmarkselect 300000 3.835 µs/op Benchmarkdef 30000000 0.035 µs/op Benchmarkfunc_def 40000 29.387 µs/op Benchmarkcall 30000000 0.043 µs/op Benchmarkfunc_call 2000000 0.819 µs/op Benchmarktry_finally 20000000 0.096 µs/op Benchmarkdefer 600000 1.755 µs/op pymod: golang/sync_test.py Benchmarkworkgroup_empty 40000 25.807 µs/op Benchmarkworkgroup_raise 40000 31.637 µs/op [100%] =========================== warnings summary =========================== (*) see https://pkg.go.dev/cmd/go#hdr-Test_packages (+) see https://docs.pytest.org/en/7.1.x/reference/reference.html#confval-python_files /reviewed-by @jerome /reviewed-on nexedi/pygolang!20
-
Kirill Smelkov authored
We recently moved our custom UTF-8 encoding/decoding routines to Cython. Now we can start taking speedup advantage on C level to make our own UTF-8 decoder a bit less horribly slow on py2: name old time/op new time/op delta stddecode 752ns ± 0% 743ns ± 0% -1.19% (p=0.000 n=9+10) udecode 216µs ± 0% 75µs ± 0% -65.19% (p=0.000 n=9+10) stdencode 328ns ± 2% 327ns ± 1% ~ (p=0.252 n=10+9) bencode 34.1µs ± 1% 32.1µs ± 1% -5.92% (p=0.000 n=10+10) So it is ~ 3x speedup for u(), but still significantly slower compared to std unicode.decode('utf-8'). Only low-hanging fruit here to make _utf_decode_rune a bit more prompt, since it sits in the most inner loop. In the future _utf8_decode_surrogateescape might be reworked as well to avoid constructing resulting unicode via py-level list of py-unicode character objects. And similarly for _utf8_encode_surrogateescape. On py3 the performance of std and u/b decode/encode is approximately the same. /trusted-by @jerome /reviewed-on nexedi/pygolang!19
-
- 04 Oct, 2022 4 commits
-
-
Kirill Smelkov authored
Error rune (u+fffd) is returned by _utf8_decode_rune to indicate an error in decoding. But the error rune itself is valid unicode codepoint: >>> x = u"�" >>> x u'\ufffd' >>> x.encode('utf-8') '\xef\xbf\xbd' This way only (r=_rune_error, size=1) should be treated by the caller as utf8 decoding error. But e.g. strconv.quote was not careful to also inspect the size, and this way was quoting � into just "\xef" instead of "\xef\xbf\xbd". _utf8_decode_surrogateescape was also subject to similar error. -> Fix it. Without the fix e.g. added test for strconv.quote fails as > assert quote(tin) == tquoted E assert '"\xef"' == '"�"' E - "\xef" E + "�" /reviewed-by @jerome /reviewed-at nexedi/pygolang!18
-
Kirill Smelkov authored
So that those routines could be just called and do what is expected without the caller caring whether it is py2 or py3. We will soon need to use those routines from several callsites, and having that py2/py3 conditioning being spread over all usage places would be inconvenient. /reviewed-by @jerome /reviewed-at nexedi/pygolang!18
-
Kirill Smelkov authored
- Move _utf8_decode_rune, _utf8_decode_surrogateescape, _utf8_encode_surrogateescape out from strconv into _golang_str - Factor _bstr/_ustr code into pyb/pyu. _bstr/_ustr become plain wrappers over pyb/pyu. - work-around emerged golang
↔ strconv dependency with at-runtime import. Moved routines belong to the main part of golang strings processing -> their home should be in _golang_str.pyx /reviewed-by @jerome /reviewed-at nexedi/pygolang!18 -
Kirill Smelkov authored
We are going to significantly extend py-strings related functionality soon - to the point where amount of strings related code will be approximately the same compared to the amount of all other python-related code inside golang module. -> First move everything related to py strings to dedicated _golang_str.pyx as a preparatory step. Keep that new file included from _golang.pyx instead of being real new module, because we want strings functionality to be provided by golang main namespace itself, and to ease internal code interdependencies. Plain code movement. /reviewed-by @jerome /reviewed-at !18
-
- 26 Jan, 2022 15 commits
-
-
Kirill Smelkov authored
-
Kirill Smelkov authored
On Python2 without .tp_print printing _pystr crashes as: pygolang$ ./golang/testprog/golang_test_str.py Traceback (most recent call last): File "./golang/testprog/golang_test_str.py", line 39, in <module> main() File "./golang/testprog/golang_test_str.py", line 34, in main print("print(qq(b)):", qq(sb)) RuntimeError: print recursion See added comments for details.
-
Kirill Smelkov authored
Add convenient utility to read whole file and return its content similarly to Go. The code is taken from wendelin.core: https://lab.nexedi.com/nexedi/wendelin.core/blob/wendelin.core-2.0.alpha1-18-g38dde766/wcfs/client/wcfs_misc.cpp#L246-281
-
Kirill Smelkov authored
Provide os/signal package that can be used to setup signal delivery to nogil channels. This way for user code signal handling becomes regular handling of a signalling channel instead of being something special or limited to only-main python thread. The rationale for why we need it is explained below: There are several problems with regular python's stdlib signal module: 1. Python2 does not call signal handler from under blocked lock.acquire. This means that if the main thread is blocked waiting on a semaphore, signal delivery will be delayed indefinitely, similarly to e.g. problem described in nxdtest!14 (comment 147527) where raising KeyboardInterrupt is delayed after SIGINT for many, potentially unbounded, seconds until ~semaphore wait finishes. Note that Python3 does not have this problem wrt stdlib locks and semaphores, but read below for the next point. 2. all pygolang communication operations (channels send/recv, sync.Mutex, sync.RWMutex, sync.Sema, sync.WaitGroup, sync.WorkGroup, ...) run with GIL released, but if blocked do not handle EINTR and do not schedule python signal handler to run (on main thread). Even if we could theoretically adjust this behaviour of pygolang at python level to match Python3, there are also C++ and pyx/nogil worlds. And we want gil and nogil worlds to interoperate (see https://pypi.org/project/pygolang/#cython-nogil-api), so that e.g. if completely nogil code happens to run on the main thread, signal handling is still possible, even if that signal handling was setup at python level. With signals delivered to nogil channels both nogil world and python world can setup signal handlers and to be notified of them irregardles of whether main python thread is currently blocked in nogil wait or not. /reviewed-on !17
-
Kirill Smelkov authored
To convert an object to str of current python. It will be handy to use __pystr when implementing __str__ methods. /reviewed-on nexedi/pygolang!17
-
Kirill Smelkov authored
Provide C++ package "os" with File, Pipe, etc similarly to what is provided on Go side. The package works through IO methods provided by runtimes. We need IO facility because os/signal package will need to use pipe in cooperative IO mode in its receiving-loop goroutine. os.h and os.cpp are based on drafts from wendelin.core: https://lab.nexedi.com/nexedi/wendelin.core/blob/wendelin.core-2.0.alpha1-18-g38dde766/wcfs/client/wcfs_misc.h https://lab.nexedi.com/nexedi/wendelin.core/blob/wendelin.core-2.0.alpha1-18-g38dde766/wcfs/client/wcfs_misc.cpp /reviewed-on !17
-
Kirill Smelkov authored
Else as https://github.com/python-greenlet/greenlet/pull/285 demonstrates there can be segmentation faults and crashes due to exceptions from one greenlet propagating to C stack of another greenlet. No test here. I've tried to do it, but with gevent (contrary to plain greenlets), spawning new task only schedules corresponding greenlet to run in the end of current event loop cycle instead of switching to created greenlet immediately. With this delaying, it was hard for me to develop corresponding test in a reasonable time. Hopefully having the test I've done for greenlet itself + hereby protection is good enough. /reviewed-on nexedi/pygolang!17
-
Kirill Smelkov authored
This package provides special kind of atomic that is automatically reset to zero after fork in child. This kind of atomic will be used in os package to implement IO that does not deadlock in Close after fork. /reviewed-on nexedi/pygolang!17
-
Kirill Smelkov authored
This package provides wrappers to OS system calls. Minimal functionality that will be used to implement os and os/signal pacakges. /reviewed-on nexedi/pygolang!17
-
Kirill Smelkov authored
Package os will need to access runtime operations to implement IO. /reviewed-on nexedi/pygolang!17
-
Kirill Smelkov authored
We will soon need to use common functionality(*) from both runtimes and other packages. The "other packages" are all C++ and it is handy to keep common functionality in C++ as well. While we could also maintain `extern "C"` interface, it duplicates the work. Let's switch everything to C++ to ease further maintenance. (*) e.g. package internal/syscall from both runtimes and from package os. /reviewed-on !17
-
Kirill Smelkov authored
Without defined std::hash it is not possible to use channels as keys in dict or set. We will be using set<chan> in os/signal package implementation. /reviewed-on nexedi/pygolang!17
-
Kirill Smelkov authored
I forgot to include it in ad00be70 (libgolang: Introduce runtimes). /reviewed-on !17
-
Kirill Smelkov authored
/reviewed-on !17
-
Kirill Smelkov authored
$ check-manifest lists of files in version control and sdist do not match! missing from sdist: .nxdtest /reviewed-on !17
-
- 08 Dec, 2021 5 commits
-
-
Kirill Smelkov authored
-
Kirill Smelkov authored
See https://foss.heptapod.net/pypy/pypy/-/issues/3610 for stdin case. -m started to behave as CPython.
-
Kirill Smelkov authored
On py3 'ps1' and b'ps1' are different keys and it was failing on PyPy3 as follows: # -i after stdin (also tests interactive mode as -i forces interactive even on non-tty) d = { b'hellopy': b(hellopy), b'ps1': b'' # cpython emits prompt to stderr } if is_pypy and not is_gpython: d['ps1'] = b'>>>> ' # native pypy emits prompt to stdout and >>>> instead of >>> _ = pyout(['-i'], stdin=b'import hello\n', cwd=testdata) > assert _ == b"%(ps1)shello\nworld\n['']\n%(ps1)s" % d E assert b">>>> hello\...\n['']\n>>>> " == b"hello\nworld\n['']\n" E At index 0 diff: b'>' != b'h' E Full diff: E - b"hello\nworld\n['']\n" E + b">>>> hello\nworld\n['']\n>>>> " E ? +++++ +++++ gpython/gpython_test.py:200: AssertionError Fix it. Amends e205dbf6 (gpython: Implement -i (interactive inspect after program run) + promised interactive-mode tests)
-
Kirill Smelkov authored
When _BaseCtx is setting up cancel propagation it locks a parent, checks for parent.err != nil, and, if it is, calls ctx._cancel(parent.err) _with_ _holding_ parent.mu. Since _cancel internally also goes through parents and locks them, this was deadlocking on the second call to parent.mu.lock(). -> Fix it by calling ctx._cancel(err) in the constructor outside of parent lock. The bug was there from the beginning - from e9567c7b (context: New package that mirrors Go's context). /trusted-by @jerome /reviewed-on nexedi/pygolang!16
-
Kirill Smelkov authored
- _propagateCancel is used only in _BaseCtx constructor -> inline it there. Being run in the constructor makes it clear that this code works on new _BaseCtx object with empty set of children. - since _cancelFrom interacts with the code moved from _propagateCancel, also move it to be close to cancel propagation setup. No functional changes, just plain code movement. /trusted-by @jerome /reviewed-on !16
-
- 16 Aug, 2021 1 commit
-
-
Kirill Smelkov authored
The function that verifies "no exception/panic" case was prepared but not called at all. This oversight was there from 5146eb0b "Add support for defer & recover".
-
- 07 Apr, 2021 5 commits
-
-
Kirill Smelkov authored
/reviewed-by @jerome /reviewed-on !15
-
Kirill Smelkov authored
Because else sys.modules['__main__'] points to the module of gpython itself, not user program. This difference can be important when e.g. user defines classes in main module and tries to pickle them. Such pickling will fail if gpython is not careful to run user's code in its own main. Without this patch added test fails as File "check_main.py", line 51, in <module> main() File "check_main.py", line 39, in main assert hasattr(mainmod, 'MyUniqueClassXYZ'), dir(mainmod) AssertionError: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'main'] The problem was discovered while trying to run test program from https://github.com/zopefoundation/ZEO/issues/166 : $ gpython zopenrace-zeo.py Traceback (most recent call last): File "/home/kirr/tmp/trashme/Z/py2.venv/bin/gpython", line 8, in <module> sys.exit(main()) File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/gpython/__init__.py", line 395, in main pymain(argv, init) File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/gpython/__init__.py", line 266, in pymain run() File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/gpython/__init__.py", line 172, in run _execfile(filepath, g) File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/gpython/__init__.py", line 275, in _execfile six.exec_(code, globals, locals) File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/six.py", line 719, in exec_ exec("""exec _code_ in _globs_, _locs_""") File "<string>", line 1, in <module> File "zopenrace-zeo.py", line 205, in <module> main() File "zopenrace-zeo.py", line 190, in main init() File "zopenrace-zeo.py", line 126, in init transaction.commit() File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/transaction/_manager.py", line 257, in commit return self.manager.commit() File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/transaction/_manager.py", line 134, in commit return self.get().commit() File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/transaction/_transaction.py", line 282, in commit reraise(t, v, tb) File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/transaction/_transaction.py", line 273, in commit self._commitResources() File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/transaction/_transaction.py", line 456, in _commitResources reraise(t, v, tb) File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/transaction/_transaction.py", line 430, in _commitResources rm.commit(self) File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/ZODB/Connection.py", line 497, in commit self._commit(transaction) File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/ZODB/Connection.py", line 546, in _commit self._store_objects(ObjectWriter(obj), transaction) File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/ZODB/Connection.py", line 578, in _store_objects p = writer.serialize(obj) # This calls __getstate__ of obj File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/ZODB/serialize.py", line 430, in serialize return self._dump(meta, obj.__getstate__()) File "/home/kirr/tmp/trashme/Z/py2.venv/lib/python2.7/site-packages/ZODB/serialize.py", line 439, in _dump self._p.dump(state) PicklingError: Can't pickle <class '__main__.PInt'>: attribute lookup __main__.PInt failed /reviewed-by @jerome /reviewed-on !15
-
Kirill Smelkov authored
To match python behaviour: $ python >/dev/null Python 2.7.18 (default, Apr 20 2020, 20:30:41) [GCC 9.3.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> 1+1 # NOTE the prompt (printed to stderr) $ python 2>/dev/null >>> 1+1 # NOTE the prompt (printed to stdout) Tests pending. /reviewed-by @jerome /reviewed-on nexedi/pygolang!15
-
Kirill Smelkov authored
Not through interactive console, because it was printing prompts, while `python <prog.py` does not emit anything: $ cat prog.py print 'Hello World' $ python <prog.py Hello World $ gpython <prog.py Python 2.7.18 (default, Apr 20 2020, 20:30:41) [GCC 9.3.0] [GPython 0.0.8] [gevent 20.9.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) Hello World After the patch gpython output is the same as of python: $ gpython <prog.py Hello World Test coverage for interactive mode is pending. We'll add them soon in a follow-up patch after implementing -i. For _interact - by this patch logic - we should be dropping custom raw_input, since now _interact is called only when sys.stdin is tty. But we'll soon be invoking _interact when stdin is not a tty (for `gpython -i <prog.py`), so leave that logic in place as is. /reviewed-by @jerome /reviewed-on nexedi/pygolang!15
-
Kirill Smelkov authored
We will soon need this to be run from several places when implementing support for -i. /reviewed-by @jerome /reviewed-on nexedi/pygolang!15
-
- 26 Mar, 2021 1 commit
-
-
Kirill Smelkov authored
setuptools_dso 2 started to emit those autogenerated files. See https://github.com/mdavidsaver/setuptools_dso/pull/15 for details.
-
- 16 Mar, 2021 1 commit
-
-
Kirill Smelkov authored
Those are quote codes that Go strconv.Quote might produce. And even though Python does not use them when quoting, it too handles those quote codes when decoding: In [1]: '\r' Out[1]: '\r' In [2]: '\a\b\v\f' Out[2]: '\x07\x08\x0b\x0c' https://github.com/python/cpython/blob/2.7.18-0-g8d21aa21f2c/Objects/stringobject.c#L677-L688 -> Teach strconv.unquote + friends to handle them as well. /reviewed-by @jerome /reviewed-on !14
-
- 14 Dec, 2020 1 commit
-
-
Kirill Smelkov authored
https://bugs.python.org/issue20443 This broke test_defer_excchain_dump because testprog/golang_test_defer_excchain.txt is prepared with output where `python file` shows that file name in traceback as it was specified on the command line, e.g. .../pygolang/golang/testprog$ python golang_test_defer_excchain.py Traceback (most recent call last): File ".../pygolang/golang/__init__.py", line 103, in _ return f(*argv, **kw) File "golang_test_defer_excchain.py", line 42, in main raise RuntimeError("err") RuntimeError: err while with py39 it became .../pygolang/golang/testprog$ python golang_test_defer_excchain.py Traceback (most recent call last): File ".../pygolang/golang/__init__.py", line 103, in _ return f(*argv, **kw) File ".../pygolang/golang/testprog/golang_test_defer_excchain.py", line 42, in main raise RuntimeError("err") RuntimeError: err (notice the difference related to "line 42") -> Fix it: - amend the test to conditionally prefix golang_test_defer_excchain.py in expected output with PYGOLANG/golang/testprog/ if it is Python >= 3.9. - amend `gpython file` to match behaviour of underlying `python file`, so that the test passes unconditionally whether it is run by python or gpython. -------- @jerome also says (nexedi/pygolang!13 (comment 122826)): FYI, buildout (and many zope packages) essentially use doctests for testing and they had to deal with similar differences in output. `zope.testing` comes with a doctest checker named "renormalizing" which normalize output with regular expressions, see for example setup of some buildout test [here](https://github.com/buildout/buildout/blob/db3d6e2fbf5d7ff2cc4b2507253c7a221cfc3e32/src/zc/buildout/tests.py#L3615-L3651). We definitely don't need this here for the moment, but maybe one day it can be useful. /reviewed-on nexedi/pygolang!13
-