├── .gitignore ├── .gitmodules ├── .lsan-ignore.txt ├── .nxdtest ├── 3rdparty └── include │ └── linux │ └── list.h ├── CHANGELOG.rst ├── COPYING ├── MANIFEST.in ├── README.rst ├── conftest.py ├── golang ├── .gitignore ├── __init__.pxd ├── __init__.py ├── _compat │ └── windows │ │ ├── strings.h │ │ └── unistd.h ├── _context.pxd ├── _context.pyx ├── _cxx_test.pyx ├── _errors.pxd ├── _errors.pyx ├── _errors_test.pyx ├── _fmt.pxd ├── _fmt.pyx ├── _fmt_test.pyx ├── _golang.pxd ├── _golang.pyx ├── _golang_str.pyx ├── _golang_str_pickle.pyx ├── _golang_test.pyx ├── _gopath.py ├── _gopath_test.py ├── _io.pxd ├── _io.pyx ├── _os.pxd ├── _os.pyx ├── _os_test.pyx ├── _patch │ ├── __init__.py │ ├── ipython_py2.py │ └── pytest_py2.py ├── _strconv.pxd ├── _strconv.pyx ├── _strings_test.pyx ├── _sync.pxd ├── _sync.pyx ├── _sync_test.pyx ├── _testing.h ├── _time.pxd ├── _time.pyx ├── cmd │ ├── __init__.py │ └── pybench.py ├── context.cpp ├── context.h ├── context.pxd ├── context.py ├── context_test.py ├── cxx.h ├── cxx.pxd ├── cxx_test.cpp ├── cxx_test.py ├── errors.cpp ├── errors.h ├── errors.pxd ├── errors.py ├── errors_test.cpp ├── errors_test.py ├── fmt.cpp ├── fmt.h ├── fmt.pxd ├── fmt.py ├── fmt_test.cpp ├── fmt_test.py ├── gcompat.py ├── golang_str_pickle_test.py ├── golang_str_test.py ├── golang_test.py ├── io.cpp ├── io.h ├── io.pxd ├── io.py ├── io_test.py ├── libgolang.h ├── os.cpp ├── os.h ├── os.pxd ├── os │ ├── .gitignore │ ├── __init__.py │ ├── _signal.pxd │ ├── _signal.pyx │ ├── signal.cpp │ ├── signal.h │ ├── signal.pxd │ ├── signal.py │ ├── signal_test.py │ └── testprog │ │ └── signal_test_all.py ├── os_test.cpp ├── os_test.py ├── pyx │ ├── .gitignore │ ├── __init__.py │ ├── _runtime_test.pyx │ ├── build.py │ ├── build_test.py │ ├── runtime.h │ ├── runtime.pxd │ ├── runtime.pyx │ ├── runtime_test.py │ └── testprog │ │ ├── cmdclass_custom.py │ │ ├── golang_dso_user │ │ ├── dsouser │ │ │ ├── .gitignore │ │ │ ├── __init__.py │ │ │ ├── dso.cpp │ │ │ ├── dso.h │ │ │ └── test.pyx │ │ ├── pyproject.toml │ │ └── setup.py │ │ └── golang_pyx_user │ │ ├── pyproject.toml │ │ ├── pyxuser │ │ ├── .gitignore │ │ ├── __init__.py │ │ └── test.pyx │ │ └── setup.py ├── runtime.cpp ├── runtime.h ├── runtime │ ├── .gitignore │ ├── __init__.py │ ├── _libgolang.pxd │ ├── _runtime_gevent.pyx │ ├── _runtime_pymisc.pxd │ ├── _runtime_thread.pxd │ ├── _runtime_thread.pyx │ ├── internal.h │ ├── internal │ │ ├── __init__.pxd │ │ ├── atomic.cpp │ │ ├── atomic.h │ │ ├── syscall.cpp │ │ ├── syscall.h │ │ └── syscall.pxd │ ├── libgolang.cpp │ ├── libgolang_test.cpp │ ├── libgolang_test_c.c │ ├── libpyxruntime.cpp │ └── platform.h ├── strconv.pxd ├── strconv.py ├── strconv_test.py ├── strings.cpp ├── strings.h ├── strings.pxd ├── strings_test.cpp ├── strings_test.py ├── sync.cpp ├── sync.h ├── sync.pxd ├── sync.py ├── sync_test.cpp ├── sync_test.py ├── syscall.py ├── testdata │ └── src │ │ └── lab.nexedi.com │ │ └── kirr │ │ ├── hello.py │ │ └── world │ │ └── __init__.py ├── testing.py ├── testprog │ ├── golang_test_defer_excchain.py │ ├── golang_test_defer_excchain.txt │ ├── golang_test_defer_excchain.txt-ipython │ ├── golang_test_defer_excchain.txt-pytest │ ├── golang_test_goleaked.py │ ├── golang_test_str.py │ ├── golang_test_str.txt │ ├── golang_test_str_index2.py │ └── golang_test_str_index2.txt ├── time.cpp ├── time.h ├── time.pxd ├── time.py ├── time_test.py ├── unicode │ ├── __init__.py │ ├── _utf8.pxd │ ├── utf8.h │ └── utf8.pxd └── x │ ├── __init__.py │ └── perf │ ├── __init__.py │ └── benchlib.py ├── gpython ├── __init__.py ├── gpython_test.py ├── testdata │ ├── bundle.zip │ ├── dir.zip │ ├── dir │ │ ├── __main__.py │ │ └── mod.py │ ├── hello.py │ ├── pkg │ │ ├── __init__.py │ │ ├── __main__.py │ │ └── mod.py │ └── world.py └── testprog │ ├── check_main.py │ ├── future_print_function.py │ ├── print_faulthandler.py │ ├── print_opt.py │ ├── print_statement.py │ ├── print_stdio_bufmode.py │ ├── print_syspath.py │ └── print_warnings_setup.py ├── pyproject.toml ├── setup.py ├── tox.ini └── trun /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[co] 2 | __pycache__ 3 | build/ 4 | .tox/ 5 | .cache/ 6 | .pytest_cache/ 7 | 8 | *.o 9 | *.so 10 | *.so.* 11 | *.dylib 12 | *.dll 13 | *.lib 14 | *.exp 15 | *.pyd 16 | *_dsoinfo.py 17 | 18 | /dist/ 19 | /pip-wheel-metadata/ 20 | *.egg-info 21 | 22 | perf.data* 23 | core 24 | 25 | tags 26 | 27 | .*.sw? 28 | .sw? 29 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "3rdparty/ratas"] 2 | path = 3rdparty/ratas 3 | url = https://github.com/jsnell/ratas.git 4 | -------------------------------------------------------------------------------- /.nxdtest: -------------------------------------------------------------------------------- 1 | # setup to run tests on Nexedi testing infrastructure. 2 | # https://stack.nexedi.com/test_status 3 | 4 | TestCase('thread', ['python', '-m', 'pytest'], summaryf=PyTest.summary) 5 | TestCase('gevent', ['gpython', '-m', 'pytest'], summaryf=PyTest.summary) 6 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include COPYING README.rst CHANGELOG.rst tox.ini pyproject.toml trun .lsan-ignore.txt .nxdtest conftest.py 2 | include golang/libgolang.h 3 | include golang/runtime/libgolang.cpp 4 | include golang/runtime/libpyxruntime.cpp 5 | include golang/runtime/platform.h 6 | include golang/runtime.h 7 | include golang/runtime.cpp 8 | include golang/pyx/runtime.h 9 | include golang/pyx/testprog/golang_dso_user/dsouser/dso.h 10 | include golang/pyx/testprog/golang_dso_user/dsouser/dso.cpp 11 | include golang/runtime/internal.h 12 | include golang/runtime/internal/atomic.h 13 | include golang/runtime/internal/atomic.cpp 14 | include golang/runtime/internal/syscall.h 15 | include golang/runtime/internal/syscall.cpp 16 | include golang/context.h 17 | include golang/context.cpp 18 | include golang/cxx.h 19 | include golang/errors.h 20 | include golang/errors.cpp 21 | include golang/errors_test.cpp 22 | include golang/fmt.h 23 | include golang/fmt.cpp 24 | include golang/fmt_test.cpp 25 | include golang/io.h 26 | include golang/io.cpp 27 | include golang/os.h 28 | include golang/os.cpp 29 | include golang/os/signal.h 30 | include golang/os/signal.cpp 31 | include golang/strings.h 32 | include golang/strings.cpp 33 | include golang/strings_test.cpp 34 | include golang/sync.h 35 | include golang/sync.cpp 36 | include golang/sync_test.cpp 37 | include golang/time.h 38 | include golang/time.cpp 39 | include golang/_testing.h 40 | include golang/_compat/windows/strings.h 41 | include golang/_compat/windows/unistd.h 42 | recursive-include golang *.py *.pxd *.pyx *.toml *.txt* 43 | recursive-include gpython *.py 44 | recursive-include 3rdparty *.h 45 | recursive-exclude golang *_dsoinfo.py 46 | -------------------------------------------------------------------------------- /conftest.py: -------------------------------------------------------------------------------- 1 | # pygolang | pytest config 2 | # Copyright (C) 2021-2024 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | 21 | from __future__ import print_function, absolute_import 22 | 23 | import gc 24 | 25 | 26 | # Do full GC before pytest exits, to avoid false positives in the leak detector. 27 | def pytest_unconfigure(): 28 | gc.collect() 29 | -------------------------------------------------------------------------------- /golang/.gitignore: -------------------------------------------------------------------------------- 1 | /_context.cpp 2 | /_cxx_test.cpp 3 | /_errors.cpp 4 | /_errors_test.cpp 5 | /_fmt.cpp 6 | /_fmt_test.cpp 7 | /_golang.cpp 8 | /_golang_test.cpp 9 | /_io.cpp 10 | /_os.cpp 11 | /_os_test.cpp 12 | /_strconv.cpp 13 | /_strings_test.cpp 14 | /_sync.cpp 15 | /_sync_test.cpp 16 | /_time.cpp 17 | -------------------------------------------------------------------------------- /golang/__init__.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package golang.pyx provides Go-like features for Cython/nogil and runtime for golang.py. 21 | 22 | See _golang.pxd for package documentation. 23 | """ 24 | 25 | # redirect cimport: golang -> golang._golang 26 | # 27 | # we do this because we cannot put pyx code into __init__.pyx - else Python and 28 | # other tools (e.g. setuptools) fail to recognize golang/ as Python package. 29 | from golang._golang cimport * 30 | -------------------------------------------------------------------------------- /golang/_compat/windows/strings.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_COMPAT_WIN_STRINGS_H 2 | #define _NXD_LIBGOLANG_COMPAT_WIN_STRINGS_H 3 | // 4 | // Copyright (C) 2023 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | #include 24 | 25 | static inline void bzero(void *p, size_t n) { 26 | memset(p, '\0', n); 27 | } 28 | 29 | #endif // _NXD_LIBGOLANG_COMPAT_WIN_STRINGS_H 30 | 31 | -------------------------------------------------------------------------------- /golang/_compat/windows/unistd.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_COMPAT_WIN_UNISTD_H 2 | #define _NXD_LIBGOLANG_COMPAT_WIN_UNISTD_H 3 | // 4 | // Copyright (C) 2023 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // stub unistd.h to be used on Windows where it is absent. 24 | // we need this because e.g. `cimport posix.stat` forces inclusion of unistd.h 25 | // even if we use part of posix.stat that is available everywhere. 26 | 27 | #include 28 | 29 | #define O_CLOEXEC _O_NOINHERIT 30 | 31 | #endif // _NXD_LIBGOLANG_COMPAT_WIN_UNISTD_H 32 | -------------------------------------------------------------------------------- /golang/_context.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package context mirrors and amends Go package context. 21 | 22 | - `Context` represents operational context that carries deadline, cancellation 23 | signal and immutable context-local key -> value dict. 24 | - `background` returns empty context that is never canceled. 25 | - `with_cancel` creates new context that can be canceled on its own. 26 | - `with_deadline` creates new context with deadline. 27 | - `with_timeout` creates new context with timeout. 28 | - `with_value` creates new context with attached key=value. 29 | - `merge` creates new context from 2 parents(*). 30 | 31 | See also https://golang.org/pkg/context for Go context package documentation. 32 | See also https://blog.golang.org/context for overview. 33 | 34 | (*) not provided in Go version. 35 | """ 36 | 37 | from golang cimport chan, structZ, error, refptr, interface, Nil 38 | from golang cimport cxx 39 | from libcpp.utility cimport pair 40 | 41 | # XXX for std::function cython does not provide operator() and =nullptr 42 | #from libcpp.functional cimport function 43 | #ctypedef function[void()] cancelFunc 44 | cdef extern from "golang/libgolang.h" namespace "golang" nogil: 45 | cppclass cancelFunc "golang::func": 46 | void operator() () 47 | void operator= (Nil) 48 | 49 | cdef extern from "golang/context.h" namespace "golang::context" nogil: 50 | cppclass _Context: 51 | double deadline() 52 | chan[structZ] done() 53 | error err() 54 | interface value(const void *key) 55 | 56 | cppclass Context (refptr[_Context]): 57 | # Context.X = Context->X in C++ 58 | double deadline "_ptr()->deadline" () 59 | chan[structZ] done "_ptr()->done" () 60 | error err "_ptr()->err" () 61 | interface value "_ptr()->value" (const void *key) 62 | 63 | Context background() 64 | error canceled 65 | error deadlineExceeded 66 | 67 | pair[Context, cancelFunc] with_cancel (Context parent) 68 | Context with_value (Context parent, const void *key, interface value) 69 | pair[Context, cancelFunc] with_deadline (Context parent, double deadline) 70 | pair[Context, cancelFunc] with_timeout (Context parent, double timeout) 71 | pair[Context, cancelFunc] merge (Context parent1, Context parent2) 72 | 73 | # for testing 74 | cxx.set[Context] _tctxchildren(Context ctx) 75 | 76 | 77 | # ---- python bits ---- 78 | 79 | from golang cimport pychan 80 | from cython cimport final 81 | 82 | @final 83 | cdef class PyContext: 84 | cdef Context ctx 85 | cdef pychan _pydone # pychan wrapping ctx.done() 86 | 87 | # PyContext.from_ctx returns PyContext wrapping pyx/nogil-level Context ctx. 88 | @staticmethod 89 | cdef PyContext from_ctx (Context ctx) 90 | -------------------------------------------------------------------------------- /golang/_cxx_test.pyx: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # cython: language_level=2 3 | # distutils: language=c++ 4 | # 5 | # Copyright (C) 2020 Nexedi SA and Contributors. 6 | # Kirill Smelkov 7 | # 8 | # This program is free software: you can Use, Study, Modify and Redistribute 9 | # it under the terms of the GNU General Public License version 3, or (at your 10 | # option) any later version, as published by the Free Software Foundation. 11 | # 12 | # You can also Link and Combine this program with other software covered by 13 | # the terms of any of the Free Software licenses or any of the Open Source 14 | # Initiative approved licenses and Convey the resulting work. Corresponding 15 | # source of such a combination shall include the source code for all other 16 | # software used. 17 | # 18 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 19 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 20 | # 21 | # See COPYING file for full licensing terms. 22 | # See https://www.nexedi.com/licensing for rationale and options. 23 | 24 | from __future__ import print_function, absolute_import 25 | 26 | from golang cimport topyexc 27 | 28 | 29 | # cxx_test.cpp 30 | cdef extern from * nogil: 31 | """ 32 | extern void _test_cxx_dict(); 33 | extern void _test_cxx_set(); 34 | """ 35 | void _test_cxx_dict() except +topyexc 36 | void _test_cxx_set() except +topyexc 37 | def test_cxx_dict(): 38 | with nogil: 39 | _test_cxx_dict() 40 | def test_cxx_set(): 41 | with nogil: 42 | _test_cxx_set() 43 | -------------------------------------------------------------------------------- /golang/_errors.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package errors mirrors Go package errors. 21 | 22 | - `New` creates new error with provided text. 23 | - `Unwrap` tries to extract wrapped error. 24 | - `Is` tests whether an item in error's chain matches target. 25 | 26 | See also https://golang.org/pkg/errors for Go errors package documentation. 27 | See also https://blog.golang.org/go1.13-errors for error chaining overview. 28 | """ 29 | 30 | from golang cimport error, string, cbool 31 | 32 | cdef extern from "golang/errors.h" namespace "golang::errors" nogil: 33 | error New(const string& text) 34 | error Unwrap(error err) 35 | cbool Is(error err, error target) 36 | -------------------------------------------------------------------------------- /golang/_errors_test.pyx: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # cython: language_level=2 3 | # cython: c_string_type=str, c_string_encoding=utf8 4 | # distutils: language=c++ 5 | # 6 | # Copyright (C) 2020 Nexedi SA and Contributors. 7 | # Kirill Smelkov 8 | # 9 | # This program is free software: you can Use, Study, Modify and Redistribute 10 | # it under the terms of the GNU General Public License version 3, or (at your 11 | # option) any later version, as published by the Free Software Foundation. 12 | # 13 | # You can also Link and Combine this program with other software covered by 14 | # the terms of any of the Free Software licenses or any of the Open Source 15 | # Initiative approved licenses and Convey the resulting work. Corresponding 16 | # source of such a combination shall include the source code for all other 17 | # software used. 18 | # 19 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 20 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 21 | # 22 | # See COPYING file for full licensing terms. 23 | # See https://www.nexedi.com/licensing for rationale and options. 24 | 25 | from __future__ import print_function, absolute_import 26 | 27 | from golang cimport error, pyerror, nil, topyexc 28 | from golang cimport errors, fmt 29 | 30 | 31 | # pyerror_mkchain creates error chain from [] of text. 32 | def pyerror_mkchain(textv): 33 | cdef error err 34 | cdef const char *s 35 | for text in reversed(textv): 36 | if err == nil: 37 | err = errors.New(text) 38 | else: 39 | s = text 40 | err = fmt.errorf("%s: %w", s, err) 41 | return pyerror.from_error(err) 42 | 43 | 44 | # errors_test.cpp 45 | cdef extern from * nogil: 46 | """ 47 | extern void _test_errors_new_cpp(); 48 | extern void _test_errors_unwrap_cpp(); 49 | extern void _test_errors_is_cpp(); 50 | """ 51 | void _test_errors_new_cpp() except +topyexc 52 | void _test_errors_unwrap_cpp() except +topyexc 53 | void _test_errors_is_cpp() except +topyexc 54 | 55 | def test_errors_new_cpp(): 56 | with nogil: 57 | _test_errors_new_cpp() 58 | def test_errors_unwrap_cpp(): 59 | with nogil: 60 | _test_errors_unwrap_cpp() 61 | def test_errors_is_cpp(): 62 | with nogil: 63 | _test_errors_is_cpp() 64 | -------------------------------------------------------------------------------- /golang/_fmt.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package fmt mirrors Go package fmt. 21 | 22 | - `sprintf` formats text into string. 23 | - `errorf` formats text into error. 24 | 25 | NOTE: with exception of %w, formatting rules are those of libc, not Go(*). 26 | 27 | See also https://golang.org/pkg/fmt for Go fmt package documentation. 28 | 29 | (*) errorf additionally handles Go-like %w to wrap an error similarly to 30 | https://blog.golang.org/go1.13-errors . 31 | """ 32 | 33 | from golang cimport string, error 34 | 35 | cdef extern from "golang/fmt.h" namespace "golang::fmt" nogil: 36 | string sprintf(const string &format, ...) 37 | error errorf (const string &format, ...) 38 | 39 | string sprintf(const char *format, ...) 40 | error errorf (const char *format, ...) 41 | -------------------------------------------------------------------------------- /golang/_fmt.pyx: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # cython: language_level=2 3 | # cython: c_string_type=str, c_string_encoding=utf8 4 | # distutils: language=c++ 5 | # 6 | # Copyright (C) 2020 Nexedi SA and Contributors. 7 | # Kirill Smelkov 8 | # 9 | # This program is free software: you can Use, Study, Modify and Redistribute 10 | # it under the terms of the GNU General Public License version 3, or (at your 11 | # option) any later version, as published by the Free Software Foundation. 12 | # 13 | # You can also Link and Combine this program with other software covered by 14 | # the terms of any of the Free Software licenses or any of the Open Source 15 | # Initiative approved licenses and Convey the resulting work. Corresponding 16 | # source of such a combination shall include the source code for all other 17 | # software used. 18 | # 19 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 20 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 21 | # 22 | # See COPYING file for full licensing terms. 23 | # See https://www.nexedi.com/licensing for rationale and options. 24 | """_fmt.pyx implements fmt.pyx - see _fmt.pxd for package overview.""" 25 | 26 | from __future__ import print_function, absolute_import 27 | 28 | from golang cimport pyerror 29 | from golang cimport errors, fmt 30 | 31 | # _PyWrapError is the pyerror created by pyErrorf("...: %w", pyerr), for case 32 | # when pyerr is general python error - instead of being just pyerror wrapper 33 | # around raw C-level error. 34 | cdef class _PyWrapError(pyerror): 35 | cdef str _prefix 36 | cdef object _errSuffix 37 | 38 | def __cinit__(_PyWrapError pywerr, str prefix, object errSuffix): 39 | pywerr._prefix = prefix 40 | pywerr._errSuffix = errSuffix 41 | 42 | def Unwrap(_PyWrapError pywerr): # -> error | None 43 | return pywerr._errSuffix 44 | def Error(_PyWrapError pywerr): # -> str 45 | esuff = pywerr._errSuffix 46 | if esuff is None: 47 | esuff = "%!w()" # mimic go 48 | return "%s: %s" % (pywerr._prefix, esuff) 49 | 50 | 51 | def pyErrorf(str format, *argv): # -> error 52 | """Errorf formats text into error. 53 | 54 | format suffix ": %w" is additionally handled as in Go with 55 | `Errorf("... : %w", ..., err)` creating error that can be unwrapped back to err. 56 | """ 57 | xpyerr = None 58 | withW = False 59 | if format.endswith(": %w"): 60 | withW = True 61 | format = format[:-4] 62 | xpyerr = argv[-1] 63 | argv = argv[:-1] 64 | 65 | # NOTE: this will give TypeError if format vs args is not right. 66 | # NOTE: this will give ValueError if %w is used inside suffix-stripped format. 67 | prefix = format % argv 68 | 69 | if not withW: 70 | return pyerror.from_error(errors.New(prefix)) 71 | 72 | if not (isinstance(xpyerr, BaseException) or xpyerr is None): 73 | raise TypeError("fmt.Errorf: lastarg to wrap is not error: type(argv[-1])=%r" % type(xpyerr)) 74 | 75 | # xpyerr is arbitrary exception class - not a wrapper around C-level error object 76 | if type(xpyerr) is not pyerror: 77 | return _PyWrapError(prefix, xpyerr) 78 | 79 | # xpyerr is wrapper around C-level error object 80 | cdef pyerror pyerr = xpyerr 81 | return pyerror.from_error(fmt.errorf("%s: %w", prefix, pyerr.err)) 82 | -------------------------------------------------------------------------------- /golang/_fmt_test.pyx: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # cython: language_level=2 3 | # distutils: language=c++ 4 | # 5 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 6 | # Kirill Smelkov 7 | # 8 | # This program is free software: you can Use, Study, Modify and Redistribute 9 | # it under the terms of the GNU General Public License version 3, or (at your 10 | # option) any later version, as published by the Free Software Foundation. 11 | # 12 | # You can also Link and Combine this program with other software covered by 13 | # the terms of any of the Free Software licenses or any of the Open Source 14 | # Initiative approved licenses and Convey the resulting work. Corresponding 15 | # source of such a combination shall include the source code for all other 16 | # software used. 17 | # 18 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 19 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 20 | # 21 | # See COPYING file for full licensing terms. 22 | # See https://www.nexedi.com/licensing for rationale and options. 23 | 24 | from __future__ import print_function, absolute_import 25 | 26 | from golang cimport topyexc 27 | 28 | 29 | # fmt_test.cpp 30 | cdef extern from * nogil: 31 | """ 32 | extern void _test_fmt_sprintf_cpp(); 33 | extern void _test_fmt_errorf_cpp(); 34 | """ 35 | void _test_fmt_sprintf_cpp() except +topyexc 36 | void _test_fmt_errorf_cpp() except +topyexc 37 | def test_fmt_sprintf_cpp(): 38 | with nogil: 39 | _test_fmt_sprintf_cpp() 40 | def test_fmt_errorf_cpp(): 41 | with nogil: 42 | _test_fmt_errorf_cpp() 43 | -------------------------------------------------------------------------------- /golang/_gopath_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2018-2019 Nexedi SA and Contributors. 2 | # Kirill Smelkov 3 | # 4 | # This program is free software: you can Use, Study, Modify and Redistribute 5 | # it under the terms of the GNU General Public License version 3, or (at your 6 | # option) any later version, as published by the Free Software Foundation. 7 | # 8 | # You can also Link and Combine this program with other software covered by 9 | # the terms of any of the Free Software licenses or any of the Open Source 10 | # Initiative approved licenses and Convey the resulting work. Corresponding 11 | # source of such a combination shall include the source code for all other 12 | # software used. 13 | # 14 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | # 17 | # See COPYING file for full licensing terms. 18 | # See https://www.nexedi.com/licensing for rationale and options. 19 | 20 | from __future__ import print_function, absolute_import 21 | 22 | import os, os.path 23 | from golang._gopath import gimport 24 | import pytest 25 | 26 | # tgopath sets GOPATH to testdata/src during test execution. 27 | @pytest.fixture 28 | def tgopath(): 29 | gopath = os.environ.get('GOPATH') 30 | os.environ['GOPATH'] = '%s/testdata' % (os.path.dirname(__file__),) 31 | yield 32 | if gopath is None: 33 | del os.environ['GOPATH'] 34 | else: 35 | os.environ['GOPATH'] = gopath 36 | 37 | 38 | def test_import_module(tgopath): 39 | hello = gimport('lab.nexedi.com/kirr/hello') 40 | assert hello.TAG == 'gopath: test: hello.py' 41 | hello.TAG = 'loaded' 42 | 43 | # verify second gimport does not reload 44 | hello2 = gimport('lab.nexedi.com/kirr/hello') 45 | assert hello2 is hello 46 | 47 | # even though hello2 is hello - the module could be reloaded. 48 | # check it is not the case via .TAG . 49 | assert hello.TAG == 'loaded', 'module was reloaded' 50 | 51 | 52 | def test_import_package(tgopath): 53 | world = gimport('lab.nexedi.com/kirr/world') 54 | assert world.TAG == 'gopath: test: world/__init__.py' 55 | world.TAG = 'loaded' 56 | 57 | # verify second gimport does not reload 58 | world2 = gimport('lab.nexedi.com/kirr/world') 59 | assert world2 is world 60 | 61 | # even though world2 is world - the module could be reloaded. 62 | # check it is not the case via .TAG . 63 | assert world.TAG =='loaded', 'module was reloaded' 64 | -------------------------------------------------------------------------------- /golang/_io.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package io mirrors Go package io.""" 21 | 22 | from golang cimport error 23 | 24 | cdef extern from "golang/io.h" namespace "golang::io" nogil: 25 | error EOF "golang::io::EOF_" 26 | error ErrUnexpectedEOF 27 | -------------------------------------------------------------------------------- /golang/_io.pyx: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # cython: language_level=2 3 | # Copyright (C) 2020 Nexedi SA and Contributors. 4 | # Kirill Smelkov 5 | # 6 | # This program is free software: you can Use, Study, Modify and Redistribute 7 | # it under the terms of the GNU General Public License version 3, or (at your 8 | # option) any later version, as published by the Free Software Foundation. 9 | # 10 | # You can also Link and Combine this program with other software covered by 11 | # the terms of any of the Free Software licenses or any of the Open Source 12 | # Initiative approved licenses and Convey the resulting work. Corresponding 13 | # source of such a combination shall include the source code for all other 14 | # software used. 15 | # 16 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 17 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # 19 | # See COPYING file for full licensing terms. 20 | # See https://www.nexedi.com/licensing for rationale and options. 21 | """_io.pyx implements io.pyx - see _io.pxd for package overview.""" 22 | 23 | from __future__ import print_function, absolute_import 24 | 25 | from golang cimport pyerror 26 | 27 | 28 | pyEOF = pyerror.from_error(EOF) 29 | pyErrUnexpectedEOF = pyerror.from_error(ErrUnexpectedEOF) 30 | -------------------------------------------------------------------------------- /golang/_os.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2021-2022 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package os mirrors Go package os. 21 | 22 | - `Signal` represents OS-level signal. 23 | 24 | See also https://golang.org/pkg/os for Go os package documentation. 25 | """ 26 | 27 | #from golang cimport string # TODO restore after golang.pyx stops to import os.pyx 28 | from libcpp.string cimport string # golang::string = std::string TODO remove after ^^^ 29 | 30 | cdef extern from "golang/os.h" namespace "golang::os" nogil: 31 | struct Signal: 32 | int signo 33 | 34 | string String() 35 | 36 | Signal _Signal_from_int(int signo) 37 | 38 | # ---- python bits ---- 39 | 40 | from cython cimport final 41 | 42 | @final 43 | cdef class PySignal: 44 | cdef Signal sig 45 | 46 | # PySignal.from_sig returns PySignal wrapping py/nogil-level Signal sig 47 | @staticmethod 48 | cdef PySignal from_sig(Signal sig) 49 | -------------------------------------------------------------------------------- /golang/_os.pyx: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # cython: language_level=2 3 | # Copyright (C) 2021-2022 Nexedi SA and Contributors. 4 | # Kirill Smelkov 5 | # 6 | # This program is free software: you can Use, Study, Modify and Redistribute 7 | # it under the terms of the GNU General Public License version 3, or (at your 8 | # option) any later version, as published by the Free Software Foundation. 9 | # 10 | # You can also Link and Combine this program with other software covered by 11 | # the terms of any of the Free Software licenses or any of the Open Source 12 | # Initiative approved licenses and Convey the resulting work. Corresponding 13 | # source of such a combination shall include the source code for all other 14 | # software used. 15 | # 16 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 17 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # 19 | # See COPYING file for full licensing terms. 20 | # See https://www.nexedi.com/licensing for rationale and options. 21 | """_os.pyx implements os.pyx - see _os.pxd for package overview.""" 22 | 23 | from __future__ import print_function, absolute_import 24 | 25 | from golang cimport __pystr 26 | from cython cimport final 27 | 28 | 29 | # Signal represents an OS signal. 30 | @final 31 | cdef class PySignal: 32 | 33 | dtype = "C.os::Signal" 34 | 35 | @staticmethod 36 | cdef PySignal from_sig(Signal sig): 37 | cdef PySignal pysig = PySignal.__new__(PySignal) 38 | pysig.sig = sig 39 | return pysig 40 | 41 | property signo: 42 | def __get__(PySignal pysig): 43 | return pysig.sig.signo 44 | 45 | def __str__(PySignal pysig): 46 | return __pystr(pysig.sig.String()) 47 | 48 | def __repr__(PySignal pysig): 49 | return ("os.Signal(%d)" % pysig.sig.signo) 50 | 51 | # PySignal == PySignal 52 | def __hash__(PySignal pysig): 53 | return pysig.sig.signo 54 | # NOTE __ne__ not needed: PySignal does not have base class and for that 55 | # case cython automatically generates __ne__ based on __eq__. 56 | def __eq__(PySignal a, object rhs): 57 | if not isinstance(rhs, PySignal): 58 | return False 59 | cdef PySignal b = rhs 60 | return (a.sig == b.sig) 61 | 62 | 63 | def _PySignal_from_int(int signo): # -> PySignal 64 | return PySignal.from_sig(_Signal_from_int(signo)) 65 | -------------------------------------------------------------------------------- /golang/_os_test.pyx: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # cython: language_level=2 3 | # distutils: language=c++ 4 | # 5 | # Copyright (C) 2021-2022 Nexedi SA and Contributors. 6 | # Kirill Smelkov 7 | # 8 | # This program is free software: you can Use, Study, Modify and Redistribute 9 | # it under the terms of the GNU General Public License version 3, or (at your 10 | # option) any later version, as published by the Free Software Foundation. 11 | # 12 | # You can also Link and Combine this program with other software covered by 13 | # the terms of any of the Free Software licenses or any of the Open Source 14 | # Initiative approved licenses and Convey the resulting work. Corresponding 15 | # source of such a combination shall include the source code for all other 16 | # software used. 17 | # 18 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 19 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 20 | # 21 | # See COPYING file for full licensing terms. 22 | # See https://www.nexedi.com/licensing for rationale and options. 23 | 24 | from __future__ import print_function, absolute_import 25 | 26 | from golang cimport string, topyexc 27 | 28 | 29 | # os_test.cpp 30 | cdef extern from * nogil: 31 | """ 32 | extern void __test_os_fileio_cpp(const golang::string&); 33 | extern void _test_os_pipe_cpp(); 34 | """ 35 | void __test_os_fileio_cpp(string) except +topyexc 36 | void _test_os_pipe_cpp() except +topyexc 37 | def _test_os_fileio_cpp(tmp_path): 38 | cdef string _tmpd = tmp_path 39 | with nogil: 40 | __test_os_fileio_cpp(_tmpd) 41 | def test_os_pipe_cpp(): 42 | with nogil: 43 | _test_os_pipe_cpp() 44 | -------------------------------------------------------------------------------- /golang/_patch/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package _patch contains patch infrastructure and patches that Pygolang 21 | applies automatically.""" 22 | 23 | from __future__ import print_function, absolute_import 24 | 25 | from peak.util import imports # thanks PJE 26 | import sys 27 | 28 | # `@afterimport(modname) def f(mod)` arranges for f to be called after when, if 29 | # at all, module modname will be imported. 30 | # 31 | # modname must be top-level module. 32 | def afterimport(modname): 33 | if '.' in modname: 34 | raise AssertionError("BUG: modname has dot: %r" % (modname,)) 35 | def _(f): 36 | def patchmod(mod): 37 | #print('patching %s ...' % (modname,)) 38 | f() 39 | 40 | # XXX on pypy < 7.3 lazy-loading fails: https://foss.heptapod.net/pypy/pypy/-/issues/3099 41 | # -> import & patch eagerly 42 | if 'PyPy' in sys.version and sys.pypy_version_info < (7,3): 43 | try: 44 | mod = __import__(modname) 45 | except ImportError: 46 | return # module not available - nothing to patch 47 | patchmod(mod) 48 | return 49 | 50 | imports.whenImported(modname, patchmod) 51 | return f 52 | return _ 53 | -------------------------------------------------------------------------------- /golang/_patch/ipython_py2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """ipython: py2: pygolang integration patches.""" 21 | 22 | from __future__ import print_function, absolute_import 23 | 24 | from golang import _patch 25 | import inspect 26 | 27 | # PY3 adds support for chained exceptions created by defer. 28 | # 29 | # It returns False by default (we are running under py2) except when called 30 | # from IPython/core/ultratb.*.structured_traceback() for which it pretends to 31 | # be running py3 if raised exception has .__cause__ . 32 | class PY3: 33 | @staticmethod 34 | def __nonzero__(): 35 | fcall = inspect.currentframe().f_back 36 | if fcall.f_code.co_name != "structured_traceback": 37 | return False # XXX also check class/module? 38 | exc = fcall.f_locals.get('evalue', None) 39 | if exc is None: 40 | return False 41 | if not hasattr(exc, '__cause__'): 42 | return False 43 | return True 44 | 45 | @_patch.afterimport('IPython') 46 | def _(): 47 | from IPython.utils import py3compat 48 | py3compat.PY3 = PY3() 49 | -------------------------------------------------------------------------------- /golang/_patch/pytest_py2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """pytest: py2: pygolang integration patches.""" 21 | 22 | from __future__ import print_function, absolute_import 23 | 24 | from golang import _patch 25 | import inspect 26 | 27 | # _PY2 adds support for chained exceptions created by defer. 28 | # 29 | # It returns True by default (we are running under py2) except when called from 30 | # _pytest/_code/code.FormattedExcinfo.repr_excinfo() for which it pretends to 31 | # be running py3 if raised exception has .__cause__ . 32 | class _PY2: 33 | @staticmethod 34 | def __nonzero__(): 35 | fcall = inspect.currentframe().f_back 36 | if fcall.f_code.co_name != "repr_excinfo": 37 | return True # XXX also check class/module? 38 | exci = fcall.f_locals.get('excinfo', None) 39 | if exci is None: 40 | return True 41 | exc = getattr(exci, 'value', None) 42 | if exc is None: 43 | return True 44 | if not hasattr(exc, '__cause__'): 45 | return True 46 | return False 47 | 48 | @_patch.afterimport('_pytest') 49 | def _(): 50 | from _pytest._code import code 51 | code._PY2 = _PY2() 52 | -------------------------------------------------------------------------------- /golang/_strconv.pxd: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # cython: language_level=2 3 | # Copyright (C) 2018-2023 Nexedi SA and Contributors. 4 | # Kirill Smelkov 5 | # 6 | # This program is free software: you can Use, Study, Modify and Redistribute 7 | # it under the terms of the GNU General Public License version 3, or (at your 8 | # option) any later version, as published by the Free Software Foundation. 9 | # 10 | # You can also Link and Combine this program with other software covered by 11 | # the terms of any of the Free Software licenses or any of the Open Source 12 | # Initiative approved licenses and Convey the resulting work. Corresponding 13 | # source of such a combination shall include the source code for all other 14 | # software used. 15 | # 16 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 17 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # 19 | # See COPYING file for full licensing terms. 20 | # See https://www.nexedi.com/licensing for rationale and options. 21 | """Package strconv provides Go-compatible string conversions.""" 22 | 23 | from golang cimport byte 24 | 25 | cpdef pyquote(s) 26 | cdef bytes _quote(const byte[::1] s, char quote, bint* out_nonascii_escape) # -> (quoted, nonascii_escape) 27 | -------------------------------------------------------------------------------- /golang/_strings_test.pyx: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # cython: language_level=2 3 | # distutils: language=c++ 4 | # 5 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 6 | # Kirill Smelkov 7 | # 8 | # This program is free software: you can Use, Study, Modify and Redistribute 9 | # it under the terms of the GNU General Public License version 3, or (at your 10 | # option) any later version, as published by the Free Software Foundation. 11 | # 12 | # You can also Link and Combine this program with other software covered by 13 | # the terms of any of the Free Software licenses or any of the Open Source 14 | # Initiative approved licenses and Convey the resulting work. Corresponding 15 | # source of such a combination shall include the source code for all other 16 | # software used. 17 | # 18 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 19 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 20 | # 21 | # See COPYING file for full licensing terms. 22 | # See https://www.nexedi.com/licensing for rationale and options. 23 | 24 | from __future__ import print_function, absolute_import 25 | 26 | from golang cimport topyexc 27 | 28 | # strings_test.cpp 29 | cdef extern from * nogil: 30 | """ 31 | extern void _test_strings_has_prefix(); 32 | extern void _test_strings_trim_prefix(); 33 | extern void _test_strings_has_suffix(); 34 | extern void _test_strings_trim_suffix(); 35 | extern void _test_strings_split(); 36 | """ 37 | void _test_strings_has_prefix() except +topyexc 38 | void _test_strings_trim_prefix() except +topyexc 39 | void _test_strings_has_suffix() except +topyexc 40 | void _test_strings_trim_suffix() except +topyexc 41 | void _test_strings_split() except +topyexc 42 | def test_strings_has_prefix(): 43 | with nogil: 44 | _test_strings_has_prefix() 45 | def test_strings_trim_prefix(): 46 | with nogil: 47 | _test_strings_trim_prefix() 48 | def test_strings_has_suffix(): 49 | with nogil: 50 | _test_strings_has_suffix() 51 | def test_strings_trim_suffix(): 52 | with nogil: 53 | _test_strings_trim_suffix() 54 | def test_strings_split(): 55 | with nogil: 56 | _test_strings_split() 57 | -------------------------------------------------------------------------------- /golang/_sync.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package sync mirrors and amends Go package sync. 21 | 22 | - `WorkGroup` allows to spawn group of goroutines working on a common task(*). 23 | - `Once` allows to execute an action only once. 24 | - `WaitGroup` allows to wait for a collection of tasks to finish. 25 | - `Sema`(*), `Mutex` and `RWMutex` provide low-level synchronization. 26 | 27 | See also https://golang.org/pkg/sync for Go sync package documentation. 28 | 29 | (*) not provided in Go standard library, but package 30 | https://godoc.org/lab.nexedi.com/kirr/go123/xsync 31 | provides corresponding Go equivalents. 32 | """ 33 | 34 | from golang cimport error, refptr 35 | from golang cimport context 36 | 37 | cdef extern from "golang/sync.h" namespace "golang::sync" nogil: 38 | cppclass Sema: 39 | Sema() 40 | void acquire() 41 | void release() 42 | 43 | cppclass Mutex: 44 | void lock() 45 | void unlock() 46 | 47 | cppclass RWMutex: 48 | void Lock() 49 | void Unlock() 50 | void RLock() 51 | void RUnlock() 52 | void UnlockToRLock() 53 | 54 | cppclass Once: 55 | void do "do_" (...) # ... = func 56 | 57 | cppclass WaitGroup: 58 | void done() 59 | void add(int delta) 60 | void wait() 61 | 62 | # WorkGroup 63 | cppclass _WorkGroup: 64 | void go(...) # ... = func 65 | error wait() 66 | 67 | cppclass WorkGroup (refptr[_WorkGroup]): 68 | # WorkGroup.X = WorkGroup->X in C++. 69 | void go "_ptr()->go" (...) # ... = func 70 | error wait "_ptr()->wait" () 71 | 72 | WorkGroup NewWorkGroup(context.Context ctx) 73 | -------------------------------------------------------------------------------- /golang/_testing.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG__TESTING_H 2 | #define _NXD_LIBGOLANG__TESTING_H 3 | 4 | // Copyright (C) 2019-2020 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // Package _testing provides internal bits for testing libgolang and 24 | // accompanying packages. 25 | 26 | #include "golang/libgolang.h" 27 | #include 28 | #include 29 | #include 30 | 31 | // std::to_string - provide missing pieces. 32 | namespace std { 33 | using namespace golang; 34 | 35 | // string -> string (not in STL, huh ?!) 36 | string to_string(const string& s) { return s; } 37 | 38 | // error -> string 39 | string to_string(error err) { return (err == nil) ? "nil" : err->Error(); } 40 | 41 | // vector -> string 42 | template 43 | string to_string(const vector& v) { 44 | std::ostringstream ss; 45 | ss << "["; 46 | int i = 0; 47 | for (auto x : v) { 48 | if (i++ != 0) 49 | ss << " "; 50 | ss << x << ","; 51 | } 52 | ss << "]"; 53 | 54 | return ss.str(); 55 | } 56 | 57 | } // std:: 58 | 59 | 60 | // golang::_testing:: 61 | namespace golang { 62 | namespace _testing { 63 | 64 | #define __STR(X) #X 65 | #define STR(X) __STR(X) 66 | #define ASSERT(COND) do { \ 67 | if (!(COND)) \ 68 | panic(__FILE__ ":" STR(__LINE__) " assert `" #COND "` failed"); \ 69 | } while(0) 70 | 71 | #define ASSERT_EQ(A, B) golang::_testing::__assert_eq(__FILE__ ":" STR(__LINE__), #A, A, B) 72 | template 73 | void __assert_eq(const string& loc, const string &expr, const T &have, const U &want) { 74 | if (have != want) { 75 | string emsg = loc + ": " + expr + "\n"; 76 | emsg += "have: '" + std::to_string(have) + "'\n"; 77 | emsg += "want: '" + std::to_string(want) + "'"; 78 | 79 | panic(strdup(emsg.c_str())); // XXX strdup because panic just saves char* pointer 80 | } 81 | }; 82 | 83 | }} // golang::_testing:: 84 | 85 | 86 | #endif // _NXD_LIBGOLANG__TESTING_H 87 | -------------------------------------------------------------------------------- /golang/_time.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package time mirrors Go package time. 21 | 22 | - `now` returns current time. 23 | - `sleep` pauses current task. 24 | - `Ticker` and `Timer` provide timers integrated with channels. 25 | - `tick`, `after` and `after_func` are convenience wrappers to use 26 | tickers and timers easily. 27 | 28 | See also https://golang.org/pkg/time for Go time package documentation. 29 | """ 30 | 31 | from golang cimport chan, cbool, refptr 32 | 33 | cdef extern from "golang/time.h" namespace "golang::time" nogil: 34 | const double second 35 | const double nanosecond 36 | const double microsecond 37 | const double millisecond 38 | const double minute 39 | const double hour 40 | 41 | void sleep(double dt) 42 | double now() 43 | 44 | chan[double] tick(double dt) 45 | chan[double] after(double dt) 46 | Timer after_func(double dt, ...) # ... = func 47 | 48 | cppclass _Ticker: 49 | chan[double] c 50 | void stop() 51 | 52 | cppclass Ticker (refptr[_Ticker]): 53 | # Ticker.X = Ticker->X in C++. 54 | chan[double] c "_ptr()->c" 55 | void stop "_ptr()->stop" () 56 | 57 | Ticker new_ticker(double dt) 58 | 59 | 60 | cppclass _Timer: 61 | chan[double] c 62 | cbool stop() 63 | void reset(double dt) 64 | 65 | cppclass Timer (refptr[_Timer]): 66 | # Timer.X = Timer->X in C++. 67 | chan[double] c "_ptr()->c" 68 | cbool stop "_ptr()->stop" () 69 | void reset "_ptr()->reset" (double dt) 70 | 71 | Timer new_timer(double dt) 72 | -------------------------------------------------------------------------------- /golang/cmd/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navytux/pygolang/ab48eedd3addd8a8454b52e08bdffa32daa691d8/golang/cmd/__init__.py -------------------------------------------------------------------------------- /golang/context.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package context mirrors and amends Go package context. 21 | 22 | See _context.pxd for package documentation. 23 | """ 24 | 25 | # redirect cimport: golang.context -> golang._context (see __init__.pxd for rationale) 26 | from golang._context cimport * 27 | -------------------------------------------------------------------------------- /golang/context.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package context mirrors and amends Go package context. 21 | 22 | - `Context` represents operational context that carries deadline, cancellation 23 | signal and immutable context-local key -> value dict. 24 | - `background` returns empty context that is never canceled. 25 | - `with_cancel` creates new context that can be canceled on its own. 26 | - `with_deadline` creates new context with deadline. 27 | - `with_timeout` creates new context with timeout. 28 | - `with_value` creates new context with attached key=value. 29 | - `merge` creates new context from 2 parents(*). 30 | 31 | See also https://golang.org/pkg/context for Go context package documentation. 32 | See also https://blog.golang.org/context for overview. 33 | 34 | (*) not provided in Go version. 35 | """ 36 | 37 | from __future__ import print_function, absolute_import 38 | 39 | from golang._context import \ 40 | PyContext as Context, \ 41 | pybackground as background, \ 42 | pycanceled as canceled, \ 43 | pydeadlineExceeded as deadlineExceeded, \ 44 | pywith_cancel as with_cancel, \ 45 | pywith_value as with_value, \ 46 | pywith_deadline as with_deadline, \ 47 | pywith_timeout as with_timeout, \ 48 | pymerge as merge 49 | -------------------------------------------------------------------------------- /golang/cxx.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_CXX_H 2 | #define _NXD_LIBGOLANG_CXX_H 3 | 4 | // Copyright (C) 2019-2020 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // Package cxx provides C++ amendments to be used by libgolang and its users. 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | // golang::cxx:: 30 | namespace golang { 31 | namespace cxx { 32 | 33 | using std::tuple; 34 | using std::tie; 35 | using std::make_tuple; 36 | 37 | // dict wraps unordered_map into ergonomic interface. 38 | template 39 | struct dict : std::unordered_map { 40 | // has returns whether dict has element k. 41 | bool has(const Key &k) const { 42 | const dict &d = *this; 43 | return d.find(k) != d.end(); 44 | } 45 | 46 | // get implements `d[k] -> v`. 47 | Value get(const Key &k) const { 48 | Value v; bool _; tie(v, _) = get_(k); 49 | return v; 50 | } 51 | 52 | // get_ implements `d[k] -> (v, ok)`. 53 | tuple get_(const Key &k) const { 54 | const dict &d = *this; 55 | auto _ = d.find(k); 56 | if (_ == d.end()) 57 | return make_tuple(Value(), false); 58 | return make_tuple(_->second, true); 59 | } 60 | 61 | // pop implements `d[k] -> v; del d[k]`. 62 | Value pop(const Key &k) { 63 | Value v; bool _; tie(v, _) = pop_(k); 64 | return v; 65 | } 66 | 67 | // pop_ implements `d[k] -> (v, ok); del d[k]`. 68 | tuple pop_(const Key &k) { 69 | dict &d = *this; 70 | auto _ = d.find(k); 71 | if (_ == d.end()) 72 | return make_tuple(Value(), false); 73 | Value v = _->second; 74 | d.erase(_); 75 | return make_tuple(v, true); 76 | } 77 | }; 78 | 79 | // set wraps unordered_set into ergonomic interface. 80 | template 81 | struct set : std::unordered_set { 82 | // has returns whether set has element k. 83 | bool has(const Key &k) const { 84 | const set &s = *this; 85 | return s.find(k) != s.end(); 86 | } 87 | }; 88 | 89 | 90 | }} // golang::cxx:: 91 | 92 | 93 | #endif // _NXD_LIBGOLANG_CXX_H 94 | -------------------------------------------------------------------------------- /golang/cxx.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package cxx provides C++ amendments to be used by libgolang and its users.""" 21 | 22 | cimport libcpp.unordered_map 23 | cimport libcpp.unordered_set 24 | 25 | cdef extern from "" namespace "golang::cxx" nogil: 26 | cppclass dict[Key, Value] (libcpp.unordered_map.unordered_map[Key, Value]): 27 | bint has(Key k) const 28 | # TODO get/get_ 29 | # TODO pop/pop_ 30 | 31 | cppclass set[Key] (libcpp.unordered_set.unordered_set[Key]): 32 | bint has(Key k) const 33 | -------------------------------------------------------------------------------- /golang/cxx_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2020 Nexedi SA and Contributors. 2 | // Kirill Smelkov 3 | // 4 | // This program is free software: you can Use, Study, Modify and Redistribute 5 | // it under the terms of the GNU General Public License version 3, or (at your 6 | // option) any later version, as published by the Free Software Foundation. 7 | // 8 | // You can also Link and Combine this program with other software covered by 9 | // the terms of any of the Free Software licenses or any of the Open Source 10 | // Initiative approved licenses and Convey the resulting work. Corresponding 11 | // source of such a combination shall include the source code for all other 12 | // software used. 13 | // 14 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | // 17 | // See COPYING file for full licensing terms. 18 | // See https://www.nexedi.com/licensing for rationale and options. 19 | 20 | #include "golang/cxx.h" 21 | #include "golang/_testing.h" 22 | using namespace golang; 23 | using std::tie; 24 | 25 | void _test_cxx_dict() { 26 | cxx::dict d; 27 | d["abc"] = 1; 28 | d["def"] = 2; 29 | 30 | // has 31 | ASSERT(d.has("abc")); 32 | ASSERT(d.has("def")); 33 | ASSERT(!d.has("zzz")); 34 | 35 | // get 36 | ASSERT_EQ(d.get("abc"), 1); 37 | ASSERT_EQ(d.get("def"), 2); 38 | ASSERT_EQ(d.get("zzz"), 0); 39 | 40 | int v; bool ok; 41 | 42 | // get_ 43 | tie(v, ok) = d.get_("abc"); 44 | ASSERT_EQ(v, 1); ASSERT_EQ(ok, true); 45 | 46 | tie(v, ok) = d.get_("def"); 47 | ASSERT_EQ(v, 2); ASSERT_EQ(ok, true); 48 | 49 | tie(v, ok) = d.get_("zzz"); 50 | ASSERT_EQ(v, 0); ASSERT_EQ(ok, false); 51 | 52 | // pop / pop_ 53 | ASSERT_EQ(d.pop("zzz"), 0); 54 | tie(v, ok) = d.pop_("zzz"); 55 | ASSERT_EQ(v, 0); ASSERT_EQ(ok, false); 56 | 57 | ASSERT(d.has("def")); 58 | ASSERT_EQ(d.pop("def"), 2); 59 | ASSERT(!d.has("def")); 60 | ASSERT_EQ(d.pop("def"), 0); 61 | ASSERT(!d.has("def")); 62 | 63 | ASSERT(d.has("abc")); 64 | tie(v, ok) = d.pop_("abc"); 65 | ASSERT_EQ(v, 1); ASSERT_EQ(ok, true); 66 | ASSERT(!d.has("abc")); 67 | tie(v, ok) = d.pop_("abc"); 68 | ASSERT_EQ(v, 0); ASSERT_EQ(ok, false); 69 | } 70 | 71 | void _test_cxx_set() { 72 | cxx::set s; 73 | s.insert("abc"); 74 | s.insert("def"); 75 | 76 | // has 77 | ASSERT(s.has("abc")); 78 | ASSERT(s.has("def")); 79 | ASSERT(!s.has("zzz")); 80 | 81 | // has after erase 82 | s.erase("zzz"); 83 | ASSERT(s.has("abc")); 84 | ASSERT(s.has("def")); 85 | ASSERT(!s.has("zzz")); 86 | 87 | s.erase("def"); 88 | ASSERT(s.has("abc")); 89 | ASSERT(!s.has("def")); 90 | ASSERT(!s.has("zzz")); 91 | 92 | s.erase("abc"); 93 | ASSERT(!s.has("abc")); 94 | ASSERT(!s.has("def")); 95 | ASSERT(!s.has("zzz")); 96 | } 97 | -------------------------------------------------------------------------------- /golang/cxx_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | 21 | from __future__ import print_function, absolute_import 22 | 23 | from golang.golang_test import import_pyx_tests 24 | 25 | import_pyx_tests("golang._cxx_test") 26 | -------------------------------------------------------------------------------- /golang/errors.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019-2020 Nexedi SA and Contributors. 2 | // Kirill Smelkov 3 | // 4 | // This program is free software: you can Use, Study, Modify and Redistribute 5 | // it under the terms of the GNU General Public License version 3, or (at your 6 | // option) any later version, as published by the Free Software Foundation. 7 | // 8 | // You can also Link and Combine this program with other software covered by 9 | // the terms of any of the Free Software licenses or any of the Open Source 10 | // Initiative approved licenses and Convey the resulting work. Corresponding 11 | // source of such a combination shall include the source code for all other 12 | // software used. 13 | // 14 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | // 17 | // See COPYING file for full licensing terms. 18 | // See https://www.nexedi.com/licensing for rationale and options. 19 | 20 | // Package errors mirrors Go package errors. 21 | // See errors.h for package overview. 22 | 23 | #include "golang/errors.h" 24 | 25 | 26 | // golang::errors:: 27 | namespace golang { 28 | namespace errors { 29 | 30 | // _TextError implements error with text string created by New. 31 | struct _TextError final : _error, object { 32 | string _text; 33 | 34 | void incref() { 35 | object::incref(); 36 | } 37 | void decref() { 38 | if (__decref()) 39 | delete this; 40 | } 41 | ~_TextError() {} 42 | 43 | _TextError(const string& text) : _text(text) {} 44 | 45 | string Error() { 46 | return _text; 47 | } 48 | }; 49 | 50 | error New(const string& text) { 51 | return adoptref(static_cast<_error*>(new _TextError(text))); 52 | } 53 | 54 | 55 | error Unwrap(error err) { 56 | if (err == nil) 57 | return nil; 58 | 59 | _errorWrapper* _werr = dynamic_cast<_errorWrapper*>(err._ptr()); 60 | if (_werr == nil) 61 | return nil; 62 | 63 | return _werr->Unwrap(); 64 | } 65 | 66 | bool Is(error err, error target) { 67 | if (target == nil) 68 | return (err == nil); 69 | 70 | for(;;) { 71 | if (err == nil) 72 | return false; 73 | 74 | if (typeid(*err) == typeid(*target)) 75 | if (err->Error() == target->Error()) // XXX hack instead of dynamic == (not available in C++) 76 | return true; 77 | 78 | err = Unwrap(err); 79 | } 80 | } 81 | 82 | }} // golang::errors:: 83 | -------------------------------------------------------------------------------- /golang/errors.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_ERRORS_H 2 | #define _NXD_LIBGOLANG_ERRORS_H 3 | 4 | // Copyright (C) 2019-2020 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // Package errors mirrors Go package errors. 24 | // 25 | // - `New` creates new error with provided text. 26 | // - `Unwrap` tries to extract wrapped error. 27 | // - `Is` tests whether an item in error's chain matches target. 28 | // 29 | // See also https://golang.org/pkg/errors for Go errors package documentation. 30 | // See also https://blog.golang.org/go1.13-errors for error chaining overview. 31 | 32 | #include 33 | 34 | // golang::errors:: 35 | namespace golang { 36 | namespace errors { 37 | 38 | // New creates new error with provided text. 39 | LIBGOLANG_API error New(const string& text); 40 | 41 | // Unwrap tries to unwrap error. 42 | // 43 | // If err implements Unwrap method, it returns err.Unwrap(). 44 | // Otherwise it returns nil. 45 | LIBGOLANG_API error Unwrap(error err); 46 | 47 | // Is returns whether target matches any error in err's error chain. 48 | LIBGOLANG_API bool Is(error err, error target); 49 | 50 | }} // golang::errors:: 51 | 52 | #endif // _NXD_LIBGOLANG_ERRORS_H 53 | -------------------------------------------------------------------------------- /golang/errors.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package errors mirrors Go package errors. 21 | 22 | See _errors.pxd for package documentation. 23 | """ 24 | 25 | # redirect cimport: golang.errors -> golang._errors (see __init__.pxd for rationale) 26 | from golang._errors cimport * 27 | -------------------------------------------------------------------------------- /golang/errors.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package errors mirrors Go package errors. 21 | 22 | - `New` creates new error with provided text. 23 | - `Is` tests whether an item in error's chain matches target. 24 | 25 | See also https://golang.org/pkg/errors for Go errors package documentation. 26 | See also https://blog.golang.org/go1.13-errors for error chaining overview. 27 | """ 28 | 29 | from __future__ import print_function, absolute_import 30 | 31 | from golang._errors import \ 32 | pyNew as New, \ 33 | pyIs as Is 34 | -------------------------------------------------------------------------------- /golang/fmt.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package fmt mirrors Go package fmt. 21 | 22 | See _fmt.pxd for package documentation. 23 | """ 24 | 25 | # redirect cimport: golang.fmt -> golang._fmt (see __init__.pxd for rationale) 26 | from golang._fmt cimport * 27 | -------------------------------------------------------------------------------- /golang/fmt.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package fmt mirrors Go package fmt. 21 | 22 | - `Errorf` formats text into error. 23 | 24 | NOTE: with exception of %w, formatting rules are those of Python, not Go(*). 25 | 26 | See also https://golang.org/pkg/fmt for Go fmt package documentation. 27 | 28 | (*) Errorf additionally handles Go-like %w to wrap an error similarly to 29 | https://blog.golang.org/go1.13-errors . 30 | """ 31 | 32 | from __future__ import print_function, absolute_import 33 | 34 | from golang._fmt import \ 35 | pyErrorf as Errorf 36 | -------------------------------------------------------------------------------- /golang/gcompat.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2018-2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package gcompat provides Go-compatibility layer for Python.""" 21 | 22 | from __future__ import print_function, absolute_import 23 | 24 | # TODO deprecate qq in favour of -> fmt.Sprintf("%q") ? 25 | from golang._golang import pyqq as qq 26 | -------------------------------------------------------------------------------- /golang/io.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019-2020 Nexedi SA and Contributors. 2 | // Kirill Smelkov 3 | // 4 | // This program is free software: you can Use, Study, Modify and Redistribute 5 | // it under the terms of the GNU General Public License version 3, or (at your 6 | // option) any later version, as published by the Free Software Foundation. 7 | // 8 | // You can also Link and Combine this program with other software covered by 9 | // the terms of any of the Free Software licenses or any of the Open Source 10 | // Initiative approved licenses and Convey the resulting work. Corresponding 11 | // source of such a combination shall include the source code for all other 12 | // software used. 13 | // 14 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | // 17 | // See COPYING file for full licensing terms. 18 | // See https://www.nexedi.com/licensing for rationale and options. 19 | 20 | // Package io mirrors Go package io. 21 | // See io.h for package overview. 22 | 23 | #include "golang/errors.h" 24 | #include "golang/io.h" 25 | 26 | // golang::io:: 27 | namespace golang { 28 | namespace io { 29 | 30 | const global EOF_ = errors::New("EOF"); 31 | const global ErrUnexpectedEOF = errors::New("unexpected EOF"); 32 | 33 | }} // golang::io:: 34 | -------------------------------------------------------------------------------- /golang/io.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_IO_H 2 | #define _NXD_LIBGOLANG_IO_H 3 | 4 | // Copyright (C) 2019-2020 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // Package io mirrors Go package io. 24 | 25 | #include 26 | 27 | // golang::io:: 28 | namespace golang { 29 | namespace io { 30 | 31 | // EOF_ is the error that indicates that e.g. read reached end of file or stream. 32 | // 33 | // Note: the name is EOF_, not EOF, to avoid conflict with EOF define by stdio.h. 34 | extern LIBGOLANG_API const global EOF_; 35 | 36 | // ErrUnexpectedEOF is the error that indicates that EOF was reached, but was not expected. 37 | extern LIBGOLANG_API const global ErrUnexpectedEOF; 38 | 39 | }} // golang::io:: 40 | 41 | #endif // _NXD_LIBGOLANG_IO_H 42 | -------------------------------------------------------------------------------- /golang/io.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package io mirrors Go package io. 21 | 22 | See io.pxd for package documentation. 23 | """ 24 | 25 | # redirect cimport: golang.io -> golang._io (see __init__.pxd for rationale) 26 | from golang._io cimport * 27 | -------------------------------------------------------------------------------- /golang/io.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package io mirrors Go package io.""" 21 | 22 | from __future__ import print_function, absolute_import 23 | 24 | from golang._io import \ 25 | pyEOF as EOF, \ 26 | pyErrUnexpectedEOF as ErrUnexpectedEOF 27 | -------------------------------------------------------------------------------- /golang/io_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | 21 | from __future__ import print_function, absolute_import 22 | 23 | from golang import io 24 | 25 | def test_errors(): 26 | assert str(io.EOF) == "EOF" 27 | assert str(io.ErrUnexpectedEOF) == "unexpected EOF" 28 | assert (io.EOF == io.ErrUnexpectedEOF) == False 29 | assert (io.EOF != io.ErrUnexpectedEOF) == True 30 | -------------------------------------------------------------------------------- /golang/os.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2021-2022 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package os mirrors and amends Go package os. 21 | 22 | See _os.pxd for package documentation. 23 | """ 24 | 25 | # redirect cimport: golang.os -> golang._os (see __init__.pxd for rationale) 26 | from golang._os cimport * 27 | -------------------------------------------------------------------------------- /golang/os/.gitignore: -------------------------------------------------------------------------------- 1 | /_signal.cpp 2 | -------------------------------------------------------------------------------- /golang/os/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2021-2022 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package os mirrors Go package os. 21 | 22 | - `Signal` represents OS-level signal. 23 | 24 | See also https://golang.org/pkg/os for Go os package documentation. 25 | """ 26 | 27 | from __future__ import print_function, absolute_import 28 | 29 | from golang._os import \ 30 | PySignal as Signal 31 | -------------------------------------------------------------------------------- /golang/os/_signal.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2021-2022 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package signal mirrors Go package signal. 21 | 22 | - `Notify` arranges for signals to be delivered to channels. 23 | - `Stop` unsubscribes a channel from signal delivery. 24 | - `Ignore` requests signals to be ignored. 25 | - `Reset` requests signals to be handled as by default. 26 | 27 | See also https://golang.org/pkg/os/signal for Go signal package documentation. 28 | """ 29 | 30 | from golang cimport chan 31 | from golang cimport os 32 | 33 | from libcpp.vector cimport vector 34 | 35 | cdef extern from "golang/os/signal.h" namespace "golang::os::signal" nogil: 36 | void Notify(chan[os.Signal] ch, vector[os.Signal] sigv) 37 | void Stop(chan[os.Signal] ch) 38 | void Ignore(vector[os.Signal] sigv) 39 | void Reset(vector[os.Signal] sigv) 40 | -------------------------------------------------------------------------------- /golang/os/signal.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_OS_SIGNAL_H 2 | #define _NXD_LIBGOLANG_OS_SIGNAL_H 3 | // 4 | // Copyright (C) 2021-2022 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // Package signal mirrors Go package signal. 24 | // 25 | // - `Notify` arranges for signals to be delivered to channels. 26 | // - `Stop` unsubscribes a channel from signal delivery. 27 | // - `Ignore` requests signals to be ignored. 28 | // - `Reset` requests signals to be handled as by default. 29 | // 30 | // See also https://golang.org/pkg/os/signal for Go signal package documentation. 31 | 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | 38 | 39 | // golang::os::signal:: 40 | namespace golang { 41 | namespace os { 42 | namespace signal { 43 | 44 | // Notify requests that specified signals, when received, are sent to channel ch. 45 | // 46 | // The sending will be done in non-blocking way. If, at the moment of signal 47 | // reception, the channel is full and not being received-from, the signal won't 48 | // be delivered. 49 | // 50 | // If the list of specified signals is empty, it means "all signals". 51 | LIBGOLANG_API void Notify(chan ch, const std::initializer_list& sigv); 52 | LIBGOLANG_API void Notify(chan ch, const std::vector& sigv); 53 | 54 | // Stop undoes the effect of all previous calls to Notify with specified channel. 55 | // 56 | // After Stop completes, no more signals will be delivered to ch. 57 | LIBGOLANG_API void Stop(chan ch); 58 | 59 | // Ignore requests specified signals to be ignored by the program. 60 | // 61 | // In particular it undoes the effect of all previous calls to Notify with 62 | // specified signals. 63 | // 64 | // After Ignore completes specified signals won't be delivered to any channel. 65 | // 66 | // If the list of specified signals is empty, it means "all signals". 67 | LIBGOLANG_API void Ignore(const std::initializer_list& sigv); 68 | LIBGOLANG_API void Ignore(const std::vector& sigv); 69 | 70 | // Reset resets specified signals to be handled as by default. 71 | // 72 | // In particular it undoes the effect of all previous calls to Notify with 73 | // specified signals. 74 | // 75 | // After Reset completes specified signals won't be delivered to any channel. 76 | // 77 | // If the list of specified signals is empty, it means "all signals". 78 | LIBGOLANG_API void Reset(const std::initializer_list& sigv); 79 | LIBGOLANG_API void Reset(const std::vector& sigv); 80 | 81 | }}} // golang::os::signal:: 82 | 83 | #endif // _NXD_LIBGOLANG_OS_SIGNAL_H 84 | -------------------------------------------------------------------------------- /golang/os/signal.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2021-2022 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package signal mirrors and Go package signal. 21 | 22 | See _signal.pxd for package documentation. 23 | """ 24 | 25 | # redirect cimport: golang.os.signal -> golang.os._signal (see __init__.pxd for rationale) 26 | from golang.os._signal cimport * 27 | -------------------------------------------------------------------------------- /golang/os/signal.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2021-2022 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package signal mirrors Go package signal. 21 | 22 | - `Notify` arranges for signals to be delivered to channels. 23 | - `Stop` unsubscribes a channel from signal delivery. 24 | - `Ignore` requests signals to be ignored. 25 | - `Reset` requests signals to be handled as by default. 26 | 27 | See also https://golang.org/pkg/os/signal for Go signal package documentation. 28 | """ 29 | 30 | from __future__ import print_function, absolute_import 31 | 32 | from golang.os._signal import \ 33 | PyNotify as Notify, \ 34 | PyStop as Stop, \ 35 | PyIgnore as Ignore, \ 36 | PyReset as Reset 37 | -------------------------------------------------------------------------------- /golang/os/testprog/signal_test_all.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2021-2023 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """This program verifies signal.Notify(), Ignore() and Reset() with 'all signals' argument.""" 21 | 22 | from __future__ import print_function, absolute_import 23 | 24 | from golang import chan 25 | from golang import os as gos, syscall, time 26 | from golang.os import signal 27 | from golang.os.signal_test import killme 28 | import sys 29 | 30 | def main(): 31 | # build "all signals" list 32 | allsigv = [] 33 | for attr in dir(syscall): 34 | if attr.startswith("SIG") and "_" not in attr: 35 | sig = getattr(syscall, attr) 36 | if sig not in allsigv: # avoid e.g. SIGCHLD/SIGCLD dups 37 | allsigv.append(sig) 38 | allsigv.sort(key=lambda sig: sig.signo) 39 | def without(signame): 40 | sig = getattr(syscall, signame, None) 41 | if sig is not None: 42 | allsigv.remove(sig) 43 | without('SIGKILL') # SIGKILL/SIGSTOP cannot be caught 44 | without('SIGSTOP') 45 | without('SIGBUS') # AddressSanitizer crashes on SIGBUS/SIGFPE/SIGSEGV 46 | without('SIGFPE') 47 | without('SIGSEGV') 48 | without('SIGILL') # SIGILL/SIGABRT cause termination on windows 49 | without('SIGABRT') 50 | 51 | # Notify() -> kill * -> should be notified 52 | ch = chan(10, dtype=gos.Signal) 53 | signal.Notify(ch) # all signals 54 | for sig in allsigv: 55 | emit("-> %d %s" % (sig.signo, sig)) 56 | killme(sig) 57 | xsig = ch.recv() 58 | emit("<- %d %s" % (xsig.signo, xsig)) 59 | if xsig != sig: 60 | raise AssertionError("got %s, expected %s" % (xsig, sig)) 61 | emit("ok (notify)") 62 | 63 | # Ignore() -> kill * -> should not be notified 64 | emit() 65 | signal.Ignore() # all signals 66 | assert len(ch) == 0 67 | for sig in allsigv: 68 | emit("-> %d %s" % (sig.signo, sig)) 69 | killme(sig) 70 | assert len(ch) == 0 71 | time.sleep(0.3) 72 | assert len(ch) == 0 73 | emit("ok (ignore)") 74 | 75 | # Reset() -> kill * should be handled by OS by default 76 | emit() 77 | signal.Reset() # all signals 78 | emit("terminating ...") 79 | killme(syscall.SIGTERM) 80 | raise AssertionError("not terminated") 81 | 82 | def emit(msg=''): 83 | print(msg) 84 | sys.stdout.flush() 85 | 86 | 87 | if __name__ == '__main__': 88 | main() 89 | -------------------------------------------------------------------------------- /golang/os_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2021-2022 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | 21 | from __future__ import print_function, absolute_import 22 | 23 | from golang.golang_test import import_pyx_tests 24 | import_pyx_tests("golang._os_test") 25 | 26 | from golang._os_test import _test_os_fileio_cpp 27 | from golang import b 28 | 29 | # import_pyx_tests does not support passing fixtures into tests 30 | def test_pyx_os_fileio_cpp(tmp_path): 31 | _test_os_fileio_cpp(b(str(tmp_path))) 32 | -------------------------------------------------------------------------------- /golang/pyx/.gitignore: -------------------------------------------------------------------------------- 1 | /runtime.cpp 2 | /_runtime_test.cpp 3 | -------------------------------------------------------------------------------- /golang/pyx/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navytux/pygolang/ab48eedd3addd8a8454b52e08bdffa32daa691d8/golang/pyx/__init__.py -------------------------------------------------------------------------------- /golang/pyx/_runtime_test.pyx: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | 21 | # Tests for pyx/runtime.pyx + libpyxruntime. 22 | 23 | from __future__ import print_function, absolute_import 24 | 25 | from golang cimport go, chan, makechan, structZ, select, panic 26 | from golang cimport time 27 | from golang.pyx cimport runtime 28 | 29 | from cpython cimport PyObject 30 | from libc.stdio cimport printf 31 | 32 | 33 | ctypedef chan[structZ] chanZ 34 | cdef structZ Z 35 | 36 | # verify that there is no deadlock in libpyxruntime.pygil_ensure(): 37 | # it used to lock pyexitedMu -> GIL, which if also called with GIL initially 38 | # held leads to deadlocks in AB BA scenario. 39 | def test_pyfunc_vs_gil_deadlock(): 40 | def f(): 41 | time.sleep(0.001*time.second) # NOTE nogil sleep, _without_ releasing gil 42 | 43 | with nogil: 44 | _test_pyfunc_vs_gil_deadlock(runtime.PyFunc(f)) 45 | 46 | cdef void _test_pyfunc_vs_gil_deadlock(runtime.PyFunc pyf) nogil: 47 | N = 100 48 | 49 | cdef chanZ ready = makechan[structZ]() # main <- spawned "I'm ready" 50 | cdef chanZ start = makechan[structZ]() # main -> all spawned "Start running" 51 | cdef chanZ done = makechan[structZ]() # main <- spawned "I'm finished" 52 | go(_runGM, N, pyf, ready, start, done) 53 | go(_runMG, N, pyf, ready, start, done) 54 | ready.recv(); ready.recv() 55 | start.close() 56 | 57 | cdef int ndone = 0 58 | timeoutq = time.after(5*time.second) 59 | while 1: 60 | _ = select([ 61 | done.recvs(), # 0 62 | timeoutq.recvs(), # 1 63 | ]) 64 | if _ == 0: 65 | ndone += 1 66 | if ndone == 2: 67 | break # all ok 68 | if _ == 1: 69 | printf("\nSTUCK\n") 70 | panic("STUCK") 71 | 72 | cdef nogil: 73 | 74 | # run in a loop locking GIL -> pyexitMu 75 | void _runGM(int n, runtime.PyFunc pyf, chanZ ready, chanZ start, chanZ done): 76 | ready.send(Z) 77 | start.recv() 78 | for i in range(n): 79 | #printf("GM %d\n", i) 80 | with gil: 81 | pyf() 82 | done.send(Z) 83 | 84 | # run in a loop locking pyexitMu -> GIL 85 | void _runMG(int n, runtime.PyFunc pyf, chanZ ready, chanZ start, chanZ done): 86 | ready.send(Z) 87 | start.recv() 88 | for i in range(n): 89 | #printf("MG %d\n", i) 90 | # already in nogil 91 | pyf() 92 | done.send(Z) 93 | -------------------------------------------------------------------------------- /golang/pyx/build_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2019-2024 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | 21 | from __future__ import print_function, absolute_import 22 | 23 | from golang.golang_test import pyrun, pyout 24 | from os.path import dirname 25 | 26 | testprog = dirname(__file__) + "/testprog" 27 | 28 | # verify that we can build/run external package that uses pygolang in pyx mode. 29 | def test_pyx_build(): 30 | pyxuser = testprog + "/golang_pyx_user" 31 | pyrun(["setup.py", "build_ext", "-i"], cwd=pyxuser, 32 | lsan=False) # gcc leaks 33 | 34 | # run built test. 35 | _ = pyout(["-c", 36 | # XXX `import golang` is a hack: it dynamically loads _golang.so -> libgolang.so, 37 | # and this way dynamic linker already has libgolang.so DSO found and in 38 | # memory for all further imports. If we don't, current state of setuptools_dso 39 | # is that `import pyxuser.test` will fail finding libgolang.so. 40 | "import golang;" + 41 | "from pyxuser import test; test.main()"], cwd=pyxuser) 42 | assert _ == b"test.pyx: OK\n" 43 | 44 | 45 | # verify that we can build/run external dso that uses libgolang. 46 | def test_dso_build(): 47 | dsouser = testprog + "/golang_dso_user" 48 | pyrun(["setup.py", "build_dso", "-i"], cwd=dsouser, lsan=False) # gcc leaks 49 | pyrun(["setup.py", "build_ext", "-i"], cwd=dsouser, lsan=False) # gcc leaks 50 | 51 | # run built test. 52 | _ = pyout(["-c", 53 | # XXX `import golang` is a hack - see test_pyx_build for details. 54 | "import golang;" + 55 | "from dsouser import test; test.main()"], cwd=dsouser) 56 | assert _ == b"dso.cpp: OK\n" 57 | 58 | 59 | # verify that custom classes can be used via cmdclass 60 | def test_pyx_build_cmdclass(): 61 | _ = pyout(["cmdclass_custom.py", "build_ext"], cwd=testprog) 62 | assert b"pyx.build:RUN_BUILD_EXT" in _ 63 | -------------------------------------------------------------------------------- /golang/pyx/runtime.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package pyx/runtime.pyx complements golang.pyx and provides support for 21 | Python/Cython runtimes that can be used from nogil code. 22 | 23 | - `PyError` represents Python exception, that can be caught/reraised from 24 | nogil code, and is interoperated with libgolang `error`. 25 | - `PyFunc` represents Python function that can be called from nogil code. 26 | """ 27 | 28 | from golang cimport error, _error, refptr, gobject, string 29 | from cpython cimport PyObject 30 | 31 | 32 | cdef extern from "golang/pyx/runtime.h" namespace "golang::pyx::runtime" nogil: 33 | const error ErrPyStopped 34 | 35 | cppclass _PyError (_error, gobject): 36 | string Error() 37 | 38 | cppclass PyError (refptr[_PyError]): 39 | # PyError.X = PyError->X in C++ 40 | string Error "_ptr()->Error" () 41 | 42 | error PyErr_Fetch() 43 | void PyErr_ReRaise(PyError pyerr) 44 | 45 | cppclass PyFunc: 46 | __init__(PyObject *pyf) 47 | error operator() () 48 | -------------------------------------------------------------------------------- /golang/pyx/runtime.pyx: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | 21 | # pyx/runtime.pyx implementation - see pyx/runtime.pxd for package overview. 22 | 23 | from __future__ import print_function, absolute_import 24 | 25 | # initialize libpyxruntime at import time. 26 | # NOTE golang.pyx imports us right after initializing libgolang. 27 | 28 | import atexit as pyatexit 29 | 30 | cdef extern from "golang/pyx/runtime.h" namespace "golang::pyx::runtime" nogil: 31 | void _init() 32 | void _pyatexit_nogil() 33 | 34 | # init libpyxruntime 35 | _init() 36 | 37 | # register its pyatexit hook 38 | cdef void _pyatexit(): 39 | with nogil: 40 | _pyatexit_nogil() 41 | 42 | pyatexit.register(_pyatexit) 43 | -------------------------------------------------------------------------------- /golang/pyx/runtime_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | 21 | from __future__ import print_function, absolute_import 22 | 23 | from golang.golang_test import import_pyx_tests 24 | 25 | import_pyx_tests("golang.pyx._runtime_test") 26 | -------------------------------------------------------------------------------- /golang/pyx/testprog/cmdclass_custom.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019-2022 Nexedi SA and Contributors. 2 | # Kirill Smelkov 3 | # 4 | # This program is free software: you can Use, Study, Modify and Redistribute 5 | # it under the terms of the GNU General Public License version 3, or (at your 6 | # option) any later version, as published by the Free Software Foundation. 7 | # 8 | # You can also Link and Combine this program with other software covered by 9 | # the terms of any of the Free Software licenses or any of the Open Source 10 | # Initiative approved licenses and Convey the resulting work. Corresponding 11 | # source of such a combination shall include the source code for all other 12 | # software used. 13 | # 14 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | # 17 | # See COPYING file for full licensing terms. 18 | # See https://www.nexedi.com/licensing for rationale and options. 19 | """cmdclass_custom.py helps tests to verify that e.g. custom build_ext can be used""" 20 | 21 | from __future__ import print_function, absolute_import 22 | 23 | from golang.pyx.build import setup, build_ext 24 | 25 | class mybuild_ext(build_ext): 26 | def run(self): 27 | print('pyx.build:RUN_BUILD_EXT') 28 | # just print - _not_ recursing into build_ext.run 29 | 30 | setup( 31 | cmdclass = {'build_ext': mybuild_ext}, 32 | 33 | # avoid setuptools thinking nearby golang_pyx_user/ golang_dso_user/ also 34 | # relate to hereby setup and rejecting the build. 35 | # https://stackoverflow.com/questions/72294299/multiple-top-level-packages-discovered-in-a-flat-layout 36 | py_modules = [], 37 | ) 38 | -------------------------------------------------------------------------------- /golang/pyx/testprog/golang_dso_user/dsouser/.gitignore: -------------------------------------------------------------------------------- 1 | /test.cpp 2 | -------------------------------------------------------------------------------- /golang/pyx/testprog/golang_dso_user/dsouser/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navytux/pygolang/ab48eedd3addd8a8454b52e08bdffa32daa691d8/golang/pyx/testprog/golang_dso_user/dsouser/__init__.py -------------------------------------------------------------------------------- /golang/pyx/testprog/golang_dso_user/dsouser/dso.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019-2023 Nexedi SA and Contributors. 2 | // Kirill Smelkov 3 | // 4 | // This program is free software: you can Use, Study, Modify and Redistribute 5 | // it under the terms of the GNU General Public License version 3, or (at your 6 | // option) any later version, as published by the Free Software Foundation. 7 | // 8 | // You can also Link and Combine this program with other software covered by 9 | // the terms of any of the Free Software licenses or any of the Open Source 10 | // Initiative approved licenses and Convey the resulting work. Corresponding 11 | // source of such a combination shall include the source code for all other 12 | // software used. 13 | // 14 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | // 17 | // See COPYING file for full licensing terms. 18 | // See https://www.nexedi.com/licensing for rationale and options. 19 | 20 | // Small library that uses a bit of libgolang features, mainly to verify 21 | // that external project can build against libgolang. 22 | 23 | #include "dso.h" 24 | using namespace golang; 25 | 26 | #include 27 | 28 | void dsotest() { 29 | chan ch = makechan(); 30 | ch.close(); 31 | 32 | printf("dso.cpp: OK\n"); 33 | } 34 | -------------------------------------------------------------------------------- /golang/pyx/testprog/golang_dso_user/dsouser/dso.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023 Nexedi SA and Contributors. 2 | // Kirill Smelkov 3 | // 4 | // This program is free software: you can Use, Study, Modify and Redistribute 5 | // it under the terms of the GNU General Public License version 3, or (at your 6 | // option) any later version, as published by the Free Software Foundation. 7 | // 8 | // You can also Link and Combine this program with other software covered by 9 | // the terms of any of the Free Software licenses or any of the Open Source 10 | // Initiative approved licenses and Convey the resulting work. Corresponding 11 | // source of such a combination shall include the source code for all other 12 | // software used. 13 | // 14 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | // 17 | // See COPYING file for full licensing terms. 18 | // See https://www.nexedi.com/licensing for rationale and options. 19 | 20 | #ifndef _NXD_GOLANG_DSOUSER_DSO_H 21 | #define _NXD_GOLANG_DSOUSER_DSO_H 22 | 23 | #include 24 | 25 | #if BUILDING_DSOUSER_DSO 26 | # define DSOUSER_DSO_API LIBGOLANG_DSO_EXPORT 27 | #else 28 | # define DSOUSER_DSO_API LIBGOLANG_DSO_IMPORT 29 | #endif 30 | 31 | DSOUSER_DSO_API void dsotest(); 32 | 33 | #endif // _NXD_GOLANG_DSOUSER_DSO_H 34 | -------------------------------------------------------------------------------- /golang/pyx/testprog/golang_dso_user/dsouser/test.pyx: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # 3 | # Copyright (C) 2019-2023 Nexedi SA and Contributors. 4 | # Kirill Smelkov 5 | # 6 | # This program is free software: you can Use, Study, Modify and Redistribute 7 | # it under the terms of the GNU General Public License version 3, or (at your 8 | # option) any later version, as published by the Free Software Foundation. 9 | # 10 | # You can also Link and Combine this program with other software covered by 11 | # the terms of any of the Free Software licenses or any of the Open Source 12 | # Initiative approved licenses and Convey the resulting work. Corresponding 13 | # source of such a combination shall include the source code for all other 14 | # software used. 15 | # 16 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 17 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # 19 | # See COPYING file for full licensing terms. 20 | # See https://www.nexedi.com/licensing for rationale and options. 21 | 22 | # Small test driver that calls dso.so . 23 | 24 | cdef extern from "dso.h" nogil: 25 | void dsotest() 26 | 27 | def main(): 28 | dsotest() 29 | -------------------------------------------------------------------------------- /golang/pyx/testprog/golang_dso_user/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["pygolang[pyx.build]"] 3 | -------------------------------------------------------------------------------- /golang/pyx/testprog/golang_dso_user/setup.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019-2023 Nexedi SA and Contributors. 2 | # Kirill Smelkov 3 | # 4 | # This program is free software: you can Use, Study, Modify and Redistribute 5 | # it under the terms of the GNU General Public License version 3, or (at your 6 | # option) any later version, as published by the Free Software Foundation. 7 | # 8 | # You can also Link and Combine this program with other software covered by 9 | # the terms of any of the Free Software licenses or any of the Open Source 10 | # Initiative approved licenses and Convey the resulting work. Corresponding 11 | # source of such a combination shall include the source code for all other 12 | # software used. 13 | # 14 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | # 17 | # See COPYING file for full licensing terms. 18 | # See https://www.nexedi.com/licensing for rationale and options. 19 | """Demo package that links to and uses libgolang from a DSO.""" 20 | 21 | from golang.pyx.build import setup, DSO, Extension 22 | 23 | setup( 24 | name = 'golang_dso_user', 25 | description = 'test project that uses libgolang from a dso', 26 | 27 | x_dsos = [DSO('dsouser.dso', 28 | ['dsouser/dso.cpp'], 29 | define_macros = [('BUILDING_DSOUSER_DSO', None)])], 30 | ext_modules = [Extension('dsouser.test', 31 | ['dsouser/test.pyx'], 32 | dsos = ['dsouser.dso'])], 33 | ) 34 | -------------------------------------------------------------------------------- /golang/pyx/testprog/golang_pyx_user/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["pygolang[pyx.build]"] 3 | -------------------------------------------------------------------------------- /golang/pyx/testprog/golang_pyx_user/pyxuser/.gitignore: -------------------------------------------------------------------------------- 1 | /test.cpp 2 | -------------------------------------------------------------------------------- /golang/pyx/testprog/golang_pyx_user/pyxuser/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navytux/pygolang/ab48eedd3addd8a8454b52e08bdffa32daa691d8/golang/pyx/testprog/golang_pyx_user/pyxuser/__init__.py -------------------------------------------------------------------------------- /golang/pyx/testprog/golang_pyx_user/pyxuser/test.pyx: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # distutils: language=c++ 3 | # 4 | # Copyright (C) 2019 Nexedi SA and Contributors. 5 | # Kirill Smelkov 6 | # 7 | # This program is free software: you can Use, Study, Modify and Redistribute 8 | # it under the terms of the GNU General Public License version 3, or (at your 9 | # option) any later version, as published by the Free Software Foundation. 10 | # 11 | # You can also Link and Combine this program with other software covered by 12 | # the terms of any of the Free Software licenses or any of the Open Source 13 | # Initiative approved licenses and Convey the resulting work. Corresponding 14 | # source of such a combination shall include the source code for all other 15 | # software used. 16 | # 17 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | # 20 | # See COPYING file for full licensing terms. 21 | # See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | # Small program that uses a bit of golang.pyx nogil features, mainly to verify 24 | # that external project can build against golang in pyx mode. 25 | 26 | from golang cimport go, chan, makechan, topyexc 27 | from libc.stdio cimport printf 28 | 29 | cdef nogil: 30 | 31 | void worker(chan[int] ch, int i, int j): 32 | ch.send(i*j) 33 | 34 | void _main() except +topyexc: 35 | cdef chan[int] ch = makechan[int]() 36 | cdef int i 37 | for i in range(3): 38 | go(worker, ch, i, 4) 39 | 40 | for i in range(3): 41 | ch.recv() 42 | 43 | ch.close() 44 | #_, ok = ch.recv_() # TODO teach Cython to coerce pair[X,Y] -> (X,Y) 45 | ch.recv_() 46 | 47 | printf("test.pyx: OK\n") 48 | 49 | def main(): 50 | _main() 51 | -------------------------------------------------------------------------------- /golang/pyx/testprog/golang_pyx_user/setup.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 Nexedi SA and Contributors. 2 | # Kirill Smelkov 3 | # 4 | # This program is free software: you can Use, Study, Modify and Redistribute 5 | # it under the terms of the GNU General Public License version 3, or (at your 6 | # option) any later version, as published by the Free Software Foundation. 7 | # 8 | # You can also Link and Combine this program with other software covered by 9 | # the terms of any of the Free Software licenses or any of the Open Source 10 | # Initiative approved licenses and Convey the resulting work. Corresponding 11 | # source of such a combination shall include the source code for all other 12 | # software used. 13 | # 14 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | # 17 | # See COPYING file for full licensing terms. 18 | # See https://www.nexedi.com/licensing for rationale and options. 19 | """Demo package that links to and uses golang in pyx mode.""" 20 | 21 | from golang.pyx.build import setup, Extension 22 | 23 | setup( 24 | name = 'golang_pyx_user', 25 | description = 'test project that uses pygolang in pyx mode', 26 | 27 | ext_modules = [Extension('pyxuser.test', ['pyxuser/test.pyx'])], 28 | ) 29 | -------------------------------------------------------------------------------- /golang/runtime.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2023-2024 Nexedi SA and Contributors. 2 | // Kirill Smelkov 3 | // 4 | // This program is free software: you can Use, Study, Modify and Redistribute 5 | // it under the terms of the GNU General Public License version 3, or (at your 6 | // option) any later version, as published by the Free Software Foundation. 7 | // 8 | // You can also Link and Combine this program with other software covered by 9 | // the terms of any of the Free Software licenses or any of the Open Source 10 | // Initiative approved licenses and Convey the resulting work. Corresponding 11 | // source of such a combination shall include the source code for all other 12 | // software used. 13 | // 14 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | // 17 | // See COPYING file for full licensing terms. 18 | // See https://www.nexedi.com/licensing for rationale and options. 19 | 20 | // Package runtime mirrors Go package runtime. 21 | // See runtime.h for package overview. 22 | 23 | #include "golang/runtime.h" 24 | 25 | 26 | // golang::runtime:: 27 | namespace golang { 28 | namespace runtime { 29 | 30 | const string OS = 31 | #ifdef LIBGOLANG_OS_linux 32 | "linux" 33 | #elif defined(LIBGOLANG_OS_darwin) 34 | "darwin" 35 | #elif defined(LIBGOLANG_OS_windows) 36 | "windows" 37 | #else 38 | # error 39 | #endif 40 | ; 41 | 42 | 43 | const string CC = 44 | #ifdef LIBGOLANG_CC_gcc 45 | "gcc" 46 | #elif defined(LIBGOLANG_CC_clang) 47 | "clang" 48 | #elif defined(LIBGOLANG_CC_msc) 49 | "msc" 50 | #else 51 | # error 52 | #endif 53 | ; 54 | 55 | 56 | }} // golang::runtime:: 57 | -------------------------------------------------------------------------------- /golang/runtime.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_RUNTIME_H 2 | #define _NXD_LIBGOLANG_RUNTIME_H 3 | 4 | // Copyright (C) 2023-2024 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // Package runtime mirrors Go package runtime. 24 | 25 | #include "golang/libgolang.h" 26 | 27 | 28 | // golang::runtime:: 29 | namespace golang { 30 | namespace runtime { 31 | 32 | // OS indicates operating system, that is running the program. 33 | // 34 | // e.g. "linux", "darwin", "windows", ... 35 | extern LIBGOLANG_API const string OS; 36 | 37 | // CC indicates C/C++ compiler, that compiled the program. 38 | // 39 | // e.g. "gcc", "clang", "msc", ... 40 | extern LIBGOLANG_API const string CC; 41 | 42 | 43 | }} // golang::runtime:: 44 | 45 | #endif // _NXD_LIBGOLANG_RUNTIME_H 46 | -------------------------------------------------------------------------------- /golang/runtime/.gitignore: -------------------------------------------------------------------------------- 1 | /_runtime_gevent.cpp 2 | /_runtime_thread.cpp 3 | -------------------------------------------------------------------------------- /golang/runtime/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navytux/pygolang/ab48eedd3addd8a8454b52e08bdffa32daa691d8/golang/runtime/__init__.py -------------------------------------------------------------------------------- /golang/runtime/_libgolang.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019-2024 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """pyx declarations for libgolang bits that are only interesting for runtimes.""" 21 | 22 | from libc.stdint cimport uint64_t 23 | from posix.fcntl cimport mode_t 24 | from posix.stat cimport struct_stat 25 | 26 | cdef extern from "golang/libgolang.h" namespace "golang" nogil: 27 | struct _libgolang_sema 28 | struct _libgolang_ioh 29 | enum _libgolang_runtime_flags: 30 | STACK_DEAD_WHILE_PARKED 31 | 32 | struct _libgolang_runtime_ops: 33 | _libgolang_runtime_flags flags 34 | 35 | void (*go)(void (*f)(void *) nogil, void *arg); 36 | 37 | _libgolang_sema* (*sema_alloc) () 38 | void (*sema_free) (_libgolang_sema*) 39 | bint (*sema_acquire)(_libgolang_sema*, uint64_t timeout_ns) 40 | void (*sema_release)(_libgolang_sema*) 41 | 42 | void (*nanosleep)(uint64_t) 43 | uint64_t (*nanotime)() 44 | 45 | _libgolang_ioh* (*io_open) (int* out_syserr, const char *path, int flags, mode_t mode) 46 | _libgolang_ioh* (*io_fdopen) (int* out_syserr, int sysfd) 47 | int (*io_close) (_libgolang_ioh* ioh) 48 | void (*io_free) (_libgolang_ioh* ioh) 49 | int (*io_sysfd) (_libgolang_ioh* ioh) 50 | int (*io_read) (_libgolang_ioh* ioh, void *buf, size_t count) 51 | int (*io_write) (_libgolang_ioh* ioh, const void *buf, size_t count) 52 | int (*io_fstat) (struct_stat* out_st, _libgolang_ioh* ioh) 53 | 54 | 55 | # XXX better take from golang.pxd, but there it is declared in `namespace 56 | # "golang"` which fails for C-mode compiles. 57 | void panic(const char *) 58 | -------------------------------------------------------------------------------- /golang/runtime/_runtime_pymisc.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """_runtime_pymisc.pxd provides miscellaneous Python-related utilities for _runtime_*.pyx""" 21 | 22 | # PyExc and pyexc_fetch/pyexc_restore provide non-noisy way to save/restore 23 | # current python exception. 24 | cdef extern from "Python.h": 25 | """ 26 | typedef struct PyExc { 27 | PyObject *pyexc_type; 28 | PyObject *pyexc_value; 29 | PyObject *pyexc_traceback; 30 | } PyExc; 31 | 32 | static inline void pyexc_fetch(PyExc *e) { 33 | PyErr_Fetch(&e->pyexc_type, &e->pyexc_value, &e->pyexc_traceback); 34 | } 35 | 36 | static inline void pyexc_restore(PyExc e) { 37 | PyErr_Restore(e.pyexc_type, e.pyexc_value, e.pyexc_traceback); 38 | } 39 | """ 40 | struct PyExc: 41 | pass 42 | void pyexc_fetch(PyExc*) 43 | void pyexc_restore(PyExc) 44 | -------------------------------------------------------------------------------- /golang/runtime/_runtime_thread.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | 21 | from libc.stdint cimport uint64_t 22 | 23 | cdef nogil: 24 | # _runtime_gevent reuses thread's nanotime 25 | uint64_t nanotime() 26 | -------------------------------------------------------------------------------- /golang/runtime/internal.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_RUNTIME_INTERNAL_H 2 | #define _NXD_LIBGOLANG_RUNTIME_INTERNAL_H 3 | 4 | // Copyright (C) 2021-2022 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // Header runtime/internal.h is used internally by libgolang. 24 | 25 | #include 26 | 27 | // golang::internal:: 28 | namespace golang { 29 | namespace internal { 30 | 31 | extern const _libgolang_runtime_ops* _runtime; 32 | 33 | }} // golang::internal:: 34 | 35 | #endif // _NXD_LIBGOLANG_RUNTIME_INTERNAL_H 36 | -------------------------------------------------------------------------------- /golang/runtime/internal/__init__.pxd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navytux/pygolang/ab48eedd3addd8a8454b52e08bdffa32daa691d8/golang/runtime/internal/__init__.pxd -------------------------------------------------------------------------------- /golang/runtime/internal/atomic.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2022-2024 Nexedi SA and Contributors. 2 | // Kirill Smelkov 3 | // 4 | // This program is free software: you can Use, Study, Modify and Redistribute 5 | // it under the terms of the GNU General Public License version 3, or (at your 6 | // option) any later version, as published by the Free Software Foundation. 7 | // 8 | // You can also Link and Combine this program with other software covered by 9 | // the terms of any of the Free Software licenses or any of the Open Source 10 | // Initiative approved licenses and Convey the resulting work. Corresponding 11 | // source of such a combination shall include the source code for all other 12 | // software used. 13 | // 14 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | // 17 | // See COPYING file for full licensing terms. 18 | // See https://www.nexedi.com/licensing for rationale and options. 19 | 20 | #include "golang/runtime/internal/atomic.h" 21 | #include "golang/libgolang.h" 22 | 23 | #ifndef LIBGOLANG_OS_windows 24 | #include 25 | #endif 26 | 27 | // golang::internal::atomic:: 28 | namespace golang { 29 | namespace internal { 30 | namespace atomic { 31 | 32 | // _forkEpoch is incremented in child processes on every fork 33 | // 34 | // NOTE being plain int32_t is ok, but ThreadSanitizer thinks that after fork 35 | // _forkEpoch++ is a race, tries to report it and deadlocks in its own runtime: 36 | // https://github.com/google/sanitizers/issues/1116 37 | // 38 | // -> workaround it via pretentding that _forkEpoch is atomic. 39 | static std::atomic _forkEpoch (0); 40 | 41 | static void _forkNewEpoch() { 42 | _forkEpoch++; 43 | } 44 | 45 | void _init() { 46 | // there is no fork on windows 47 | #ifndef LIBGOLANG_OS_windows 48 | int e = pthread_atfork(/*prepare*/nil, /*inparent*/nil, /*inchild*/_forkNewEpoch); 49 | if (e != 0) 50 | panic("pthread_atfork failed"); 51 | #endif 52 | } 53 | 54 | 55 | int32ForkReset::int32ForkReset() { 56 | int32ForkReset& x = *this; 57 | x.store(0); 58 | } 59 | 60 | int32ForkReset::int32ForkReset(int32_t value) { 61 | int32ForkReset& x = *this; 62 | x.store(value); 63 | } 64 | 65 | void int32ForkReset::store(int32_t value) noexcept { 66 | int32ForkReset& x = *this; 67 | x._state.store( (((uint64_t)(_forkEpoch)) << 32) | ((uint64_t)value) ); 68 | } 69 | 70 | int32_t int32ForkReset::load() noexcept { 71 | int32ForkReset& x = *this; 72 | 73 | while (1) { 74 | uint64_t s = x._state.load(); 75 | int32_t epoch = (int32_t)(s >> 32); 76 | int32_t value = (int32_t)(s & ((1ULL << 32) - 1)); 77 | if (epoch == _forkEpoch) 78 | return value; 79 | 80 | uint64_t s_ = (((uint64_t)(_forkEpoch)) << 32) | 0; // reset to 0 81 | if (x._state.compare_exchange_strong(s, s_)) 82 | return 0; 83 | } 84 | } 85 | 86 | int32_t int32ForkReset::fetch_add(int32_t delta) noexcept { 87 | int32ForkReset& x = *this; 88 | 89 | while (1) { 90 | int32_t value = x.load(); // resets value to 0 on new fork epoch 91 | int32_t value_ = value + delta; 92 | uint64_t s = (((uint64_t)(_forkEpoch)) << 32) | ((uint64_t)value); 93 | uint64_t s_ = (((uint64_t)(_forkEpoch)) << 32) | ((uint64_t)value_); 94 | if (x._state.compare_exchange_strong(s, s_)) 95 | return value; 96 | } 97 | } 98 | 99 | 100 | }}} // golang::internal::atomic:: 101 | -------------------------------------------------------------------------------- /golang/runtime/internal/atomic.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_RUNTIME_INTERNAL_ATOMIC_H 2 | #define _NXD_LIBGOLANG_RUNTIME_INTERNAL_ATOMIC_H 3 | 4 | // Copyright (C) 2022 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // Package internal/atomic provides specialized low-level atomic types. 24 | 25 | #include 26 | #include 27 | 28 | // golang::internal::atomic:: 29 | namespace golang { 30 | namespace internal { 31 | namespace atomic { 32 | 33 | // int32ForkReset is atomic int32 that is reset to zero in forked child. 34 | // 35 | // It helps to organize locks that do not deadlock in forked child. 36 | // See NOTES in https://man7.org/linux/man-pages/man3/pthread_atfork.3.html for 37 | // rationale and details. 38 | struct int32ForkReset { 39 | private: 40 | std::atomic _state; // [fork_epoch]₃₂[value]₃₂ 41 | 42 | public: 43 | int32ForkReset(); 44 | int32ForkReset(int32_t value); 45 | 46 | void store(int32_t value) noexcept; 47 | int32_t load() noexcept; 48 | int32_t fetch_add(int32_t delta) noexcept; 49 | }; 50 | 51 | }}} // golang::internal::atomic:: 52 | 53 | #endif // _NXD_LIBGOLANG_RUNTIME_INTERNAL_ATOMIC_H 54 | -------------------------------------------------------------------------------- /golang/runtime/internal/syscall.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_RUNTIME_INTERNAL_SYSCALL_H 2 | #define _NXD_LIBGOLANG_RUNTIME_INTERNAL_SYSCALL_H 3 | 4 | // Copyright (C) 2021-2024 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // Package syscall provides low-level interface to OS. 24 | 25 | #include "golang/libgolang.h" 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | 33 | // golang::internal::syscall:: 34 | namespace golang { 35 | namespace internal { 36 | namespace syscall { 37 | 38 | // errors returned by system calls are represented as negative error codes, for example -ENOENT. 39 | // Those error codes could be converted to error via NewErrno. 40 | typedef int __Errno; 41 | struct _Errno final : _error, object { 42 | __Errno syserr; 43 | 44 | private: 45 | _Errno(); 46 | ~_Errno(); 47 | friend error NewErrno(__Errno syserr); 48 | public: 49 | void incref(); 50 | void decref(); 51 | 52 | public: 53 | // Error returns string corresponding to system error syserr. 54 | string Error(); 55 | }; 56 | typedef refptr<_Errno> Errno; 57 | 58 | error NewErrno(__Errno syserr); // TODO better return Errno directly. 59 | 60 | // system calls 61 | 62 | LIBGOLANG_API int/*n|err*/ Read(int fd, void *buf, size_t count); 63 | LIBGOLANG_API int/*n|err*/ Write(int fd, const void *buf, size_t count); 64 | 65 | LIBGOLANG_API __Errno Close(int fd); 66 | #ifndef LIBGOLANG_OS_windows 67 | LIBGOLANG_API __Errno Fcntl(int fd, int cmd, int arg); 68 | #endif 69 | LIBGOLANG_API __Errno Fstat(int fd, struct ::stat *out_st); 70 | LIBGOLANG_API int/*fd|err*/ Open(const char *path, int flags, mode_t mode); 71 | LIBGOLANG_API __Errno Pipe(int vfd[2], int flags); 72 | #ifndef LIBGOLANG_OS_windows 73 | LIBGOLANG_API __Errno Sigaction(int signo, const struct ::sigaction *act, struct ::sigaction *oldact); 74 | #endif 75 | typedef void (*sighandler_t)(int); 76 | LIBGOLANG_API sighandler_t /*sigh|SIG_ERR*/ Signal(int signo, sighandler_t handler, int *out_psyserr); 77 | 78 | 79 | }}} // golang::internal::syscall:: 80 | 81 | #endif // _NXD_LIBGOLANG_RUNTIME_INTERNAL_SYSCALL_H 82 | -------------------------------------------------------------------------------- /golang/runtime/internal/syscall.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2021-2022 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | 21 | from posix.fcntl cimport mode_t 22 | from posix.stat cimport struct_stat 23 | 24 | cdef extern from "golang/runtime/internal/syscall.h" namespace "golang::internal::syscall" nogil: 25 | int Close(int fd) 26 | int Fcntl(int fd, int cmd, int arg) 27 | int Fstat(int fd, struct_stat *out_st) 28 | int Open(const char *path, int flags, mode_t mode) 29 | int Read(int fd, void *buf, size_t count) 30 | int Write(int fd, const void *buf, size_t count) 31 | -------------------------------------------------------------------------------- /golang/runtime/libgolang_test_c.c: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019 Nexedi SA and Contributors. 2 | // Kirill Smelkov 3 | // 4 | // This program is free software: you can Use, Study, Modify and Redistribute 5 | // it under the terms of the GNU General Public License version 3, or (at your 6 | // option) any later version, as published by the Free Software Foundation. 7 | // 8 | // You can also Link and Combine this program with other software covered by 9 | // the terms of any of the Free Software licenses or any of the Open Source 10 | // Initiative approved licenses and Convey the resulting work. Corresponding 11 | // source of such a combination shall include the source code for all other 12 | // software used. 13 | // 14 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | // 17 | // See COPYING file for full licensing terms. 18 | // See https://www.nexedi.com/licensing for rationale and options. 19 | 20 | // Test that exercises C-level libgolang.h API. 21 | 22 | #ifdef __cplusplus 23 | # error "this file must be compiled with C - not C++ - compiler" 24 | #endif 25 | 26 | #include "golang/libgolang.h" 27 | #include 28 | 29 | typedef struct Point { 30 | int x, y; 31 | } Point; 32 | 33 | void _test_chan_c(void) { 34 | _chan *done = _makechan(0, 0); 35 | _chan *chi = _makechan(sizeof(int), 1); 36 | _chan *chp = NULL; 37 | 38 | int i, j, _; 39 | Point p; 40 | bool jok; 41 | 42 | i=+1; _chansend(chi, &i); 43 | j=-1; _chanrecv(chi, &j); 44 | if (j != i) 45 | panic("send -> recv != I"); 46 | 47 | i = 2; 48 | _selcase sel[5]; 49 | sel[0] = _selrecv(done, NULL); 50 | sel[1] = _selsend(chi, &i); 51 | sel[2] = _selrecv(chp, &p); 52 | sel[3] = _selrecv_(chi, &j, &jok); 53 | sel[4] = _default; 54 | _ = _chanselect(sel, 5); 55 | if (_ != 1) 56 | panic("select: selected !1"); 57 | 58 | jok = _chanrecv_(chi, &j); 59 | if (!(j == 2 && jok == true)) 60 | panic("recv_ != (2, true)"); 61 | 62 | _chanclose(chi); 63 | jok = _chanrecv_(chi, &j); 64 | if (!(j == 0 && jok == false)) 65 | panic("recv_ from closed != (0, false)"); 66 | 67 | _chanxdecref(done); 68 | _chanxdecref(chi); 69 | _chanxdecref(chp); 70 | } 71 | 72 | // small test to verify C _taskgo. 73 | struct _work_arg{int i; _chan *done;}; 74 | static void _work(void *); 75 | void _test_go_c(void) { 76 | _chan *done = _makechan(0,0); 77 | struct _work_arg *_ = malloc(sizeof(*_)); 78 | if (_ == NULL) 79 | panic("malloc _work_arg -> failed"); 80 | _->i = 111; 81 | _->done = done; 82 | _taskgo(_work, _); 83 | _chanrecv(done, NULL); 84 | _chanxdecref(done); 85 | } 86 | static void _work(void *__) { 87 | struct _work_arg *_ = (struct _work_arg *)__; 88 | if (_->i != 111) 89 | panic("_work: i != 111"); 90 | _chanclose(_->done); 91 | free(_); 92 | } 93 | -------------------------------------------------------------------------------- /golang/runtime/platform.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_RUNTIME_PLATFORM_H 2 | #define _NXD_LIBGOLANG_RUNTIME_PLATFORM_H 3 | 4 | // Copyright (C) 2023-2024 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // Header platform.h provides preprocessor defines that describe target platform. 24 | 25 | // LIBGOLANG_OS_ is defined on operating system X. 26 | // 27 | // List of supported operating systems: linux, darwin, windows. 28 | #ifdef __linux__ 29 | # define LIBGOLANG_OS_linux 1 30 | #elif defined(__APPLE__) 31 | # define LIBGOLANG_OS_darwin 1 32 | #elif defined(_WIN32) || defined(__CYGWIN__) 33 | # define LIBGOLANG_OS_windows 1 34 | #else 35 | # error "unsupported operating system" 36 | #endif 37 | 38 | // LIBGOLANG_CC_ is defined on C/C++ compiler X. 39 | // 40 | // List of supported compilers: gcc, clang, msc. 41 | #ifdef __clang__ 42 | # define LIBGOLANG_CC_clang 1 43 | #elif defined(_MSC_VER) 44 | # define LIBGOLANG_CC_msc 1 45 | // NOTE gcc comes last because e.g. clang and icc define __GNUC__ as well 46 | #elif __GNUC__ 47 | # define LIBGOLANG_CC_gcc 1 48 | #else 49 | # error "unsupported compiler" 50 | #endif 51 | 52 | #endif // _NXD_LIBGOLANG_RUNTIME_PLATFORM_H 53 | -------------------------------------------------------------------------------- /golang/strconv.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2018-2023 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package strconv provides Go-compatible string conversions. 21 | 22 | See _strconv.pxd for package documentation. 23 | """ 24 | 25 | # redirect cimport: golang.strconv -> golang._strconv (see __init__.pxd for rationale) 26 | from golang._strconv cimport * 27 | -------------------------------------------------------------------------------- /golang/strconv.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2018-2023 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package strconv provides Go-compatible string conversions.""" 21 | 22 | from __future__ import print_function, absolute_import 23 | 24 | from golang._strconv import \ 25 | pyquote as quote, \ 26 | pyunquote as unquote, \ 27 | pyunquote_next as unquote_next 28 | -------------------------------------------------------------------------------- /golang/strings.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019 Nexedi SA and Contributors. 2 | // Kirill Smelkov 3 | // 4 | // This program is free software: you can Use, Study, Modify and Redistribute 5 | // it under the terms of the GNU General Public License version 3, or (at your 6 | // option) any later version, as published by the Free Software Foundation. 7 | // 8 | // You can also Link and Combine this program with other software covered by 9 | // the terms of any of the Free Software licenses or any of the Open Source 10 | // Initiative approved licenses and Convey the resulting work. Corresponding 11 | // source of such a combination shall include the source code for all other 12 | // software used. 13 | // 14 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | // 17 | // See COPYING file for full licensing terms. 18 | // See https://www.nexedi.com/licensing for rationale and options. 19 | 20 | // Package strings mirrors Go package strings. 21 | // See strings.h for package overview. 22 | 23 | #include "golang/strings.h" 24 | using std::vector; 25 | 26 | // golang::strings:: 27 | namespace golang { 28 | namespace strings { 29 | 30 | bool has_prefix(const string &s, const string &prefix) { 31 | return s.compare(0, prefix.size(), prefix) == 0; 32 | } 33 | 34 | bool has_prefix(const string &s, char prefix) { 35 | return (s.size() >= 1 && s[0] == prefix); 36 | } 37 | 38 | bool has_suffix(const string &s, const string &suffix) { 39 | return (s.size() >= suffix.size() && 40 | s.compare(s.size() - suffix.size(), suffix.size(), suffix) == 0); 41 | } 42 | 43 | bool has_suffix(const string &s, char suffix) { 44 | return (s.size() >= 1 && s[s.size()-1] == suffix); 45 | } 46 | 47 | string trim_prefix(const string &s, const string &prefix) { 48 | if (!has_prefix(s, prefix)) 49 | return s; 50 | return s.substr(prefix.size()); 51 | } 52 | 53 | string trim_prefix(const string &s, char prefix) { 54 | if (!has_prefix(s, prefix)) 55 | return s; 56 | return s.substr(1); 57 | } 58 | 59 | string trim_suffix(const string &s, const string &suffix) { 60 | if (!has_suffix(s, suffix)) 61 | return s; 62 | return s.substr(0, s.size()-suffix.size()); 63 | } 64 | 65 | string trim_suffix(const string &s, char suffix) { 66 | if (!has_suffix(s, suffix)) 67 | return s; 68 | return s.substr(0, s.size()-1); 69 | } 70 | 71 | vector split(const string &s, char sep) { 72 | vector r; 73 | int psep_prev=-1; 74 | size_t psep; 75 | if (s.size() == 0) 76 | return r; 77 | while (1) { 78 | psep = s.find(sep, psep_prev+1); 79 | if (psep == string::npos) { 80 | r.push_back(s.substr(psep_prev+1)); 81 | return r; 82 | } 83 | 84 | r.push_back(s.substr(psep_prev+1, psep-(psep_prev+1))); 85 | psep_prev = psep; 86 | } 87 | } 88 | 89 | }} // golang::strings:: 90 | -------------------------------------------------------------------------------- /golang/strings.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_STRINGS_H 2 | #define _NXD_LIBGOLANG_STRINGS_H 3 | 4 | // Copyright (C) 2019 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // Package strings mirrors Go package strings. 24 | // 25 | // - `has_prefix` checks whether string starts from prefix. 26 | // - `has_suffix` checks whether string ends with suffix. 27 | // - `trim_prefix` removes prefix from a string. 28 | // - `trim_suffix` removes suffix from a string. 29 | // - `split` splits string by delimiter. 30 | // 31 | // See also https://golang.org/pkg/strings for Go strings package documentation. 32 | 33 | #include 34 | #include 35 | 36 | // golang::strings:: 37 | namespace golang { 38 | namespace strings { 39 | 40 | // has_prefix checks whether string starts from prefix. 41 | LIBGOLANG_API bool has_prefix(const string &s, const string &prefix); 42 | LIBGOLANG_API bool has_prefix(const string &s, char prefix); 43 | 44 | // has_suffix checks whether string ends with suffix. 45 | LIBGOLANG_API bool has_suffix(const string &s, const string &suffix); 46 | LIBGOLANG_API bool has_suffix(const string &s, char suffix); 47 | 48 | // trim_prefix removes prefix from string s. 49 | // 50 | // If s does not start from prefix, nothing is removed. 51 | LIBGOLANG_API string trim_prefix(const string &s, const string &prefix); 52 | LIBGOLANG_API string trim_prefix(const string &s, char prefix); 53 | 54 | // trim_suffix removes suffix from string s. 55 | // 56 | // If s does not end with suffix, nothing is removed. 57 | LIBGOLANG_API string trim_suffix(const string &s, const string &suffix); 58 | LIBGOLANG_API string trim_suffix(const string &s, char suffix); 59 | 60 | // split splits string s by separator sep. 61 | // 62 | // For example split("hello world zzz", ' ') -> ["hello", "world", "zzz"]. 63 | LIBGOLANG_API std::vector split(const string &s, char sep); 64 | 65 | }} // golang::strings:: 66 | 67 | 68 | #endif // _NXD_LIBGOLANG_STRINGS_H 69 | -------------------------------------------------------------------------------- /golang/strings.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package strings mirrors Go package strings. 21 | 22 | - `has_prefix` checks whether string starts from prefix. 23 | - `has_suffix` checks whether string ends with suffix. 24 | - `trim_prefix` removes prefix from a string. 25 | - `trim_suffix` removes suffix from a string. 26 | - `split` splits string by delimiter. 27 | 28 | See also https://golang.org/pkg/strings for Go strings package documentation. 29 | """ 30 | 31 | from golang cimport string 32 | from libcpp.vector cimport vector 33 | cdef extern from *: 34 | ctypedef bint cbool "bool" 35 | 36 | cdef extern from "golang/strings.h" namespace "golang::strings" nogil: 37 | cbool has_prefix(const string &s, const string &prefix); 38 | cbool has_prefix(const string &s, char prefix); 39 | 40 | cbool has_suffix(const string &s, const string &suffix); 41 | cbool has_suffix(const string &s, char suffix); 42 | 43 | string trim_prefix(const string &s, const string &prefix); 44 | string trim_prefix(const string &s, char prefix); 45 | 46 | string trim_suffix(const string &s, const string &suffix); 47 | string trim_suffix(const string &s, char suffix); 48 | 49 | vector[string] split(const string &s, char sep); 50 | -------------------------------------------------------------------------------- /golang/strings_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | 21 | from __future__ import print_function, absolute_import 22 | 23 | from golang.golang_test import import_pyx_tests 24 | 25 | import_pyx_tests("golang._strings_test") 26 | -------------------------------------------------------------------------------- /golang/sync.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package sync mirrors Go package sync. 21 | 22 | See _sync.pxd for package documentation. 23 | """ 24 | 25 | # redirect cimport: golang.sync -> golang._sync (see __init__.pxd for rationale) 26 | from golang._sync cimport * 27 | -------------------------------------------------------------------------------- /golang/sync.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2019-2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package sync mirrors and amends Go package sync. 21 | 22 | - `WorkGroup` allows to spawn group of goroutines working on a common task(*). 23 | - `Once` allows to execute an action only once. 24 | - `WaitGroup` allows to wait for a collection of tasks to finish. 25 | - `Sema`(*), `Mutex` and `RWMutex` provide low-level synchronization. 26 | 27 | See also https://golang.org/pkg/sync for Go sync package documentation. 28 | 29 | (*) not provided in Go standard library, but package 30 | https://godoc.org/lab.nexedi.com/kirr/go123/xsync 31 | provides corresponding Go equivalents. 32 | """ 33 | 34 | from __future__ import print_function, absolute_import 35 | 36 | from golang._sync import \ 37 | PySema as Sema, \ 38 | PyMutex as Mutex, \ 39 | PyRWMutex as RWMutex, \ 40 | PyOnce as Once, \ 41 | PyWaitGroup as WaitGroup, \ 42 | PyWorkGroup as WorkGroup 43 | -------------------------------------------------------------------------------- /golang/sync_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2019-2020 Nexedi SA and Contributors. 2 | // Kirill Smelkov 3 | // 4 | // This program is free software: you can Use, Study, Modify and Redistribute 5 | // it under the terms of the GNU General Public License version 3, or (at your 6 | // option) any later version, as published by the Free Software Foundation. 7 | // 8 | // You can also Link and Combine this program with other software covered by 9 | // the terms of any of the Free Software licenses or any of the Open Source 10 | // Initiative approved licenses and Convey the resulting work. Corresponding 11 | // source of such a combination shall include the source code for all other 12 | // software used. 13 | // 14 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | // 17 | // See COPYING file for full licensing terms. 18 | // See https://www.nexedi.com/licensing for rationale and options. 19 | 20 | #include "golang/sync.h" 21 | #include "golang/_testing.h" 22 | using namespace golang; 23 | 24 | // verify that sync::Once works. 25 | void _test_sync_once_cpp() { 26 | sync::Once once; 27 | int ncall = 0; 28 | ASSERT(ncall == 0); 29 | once.do_([&]() { 30 | ncall++; 31 | }); 32 | ASSERT(ncall == 1); 33 | once.do_([&]() { 34 | ncall++; 35 | }); 36 | ASSERT(ncall == 1); 37 | once.do_([&]() { 38 | ncall++; 39 | panic("should not panic"); 40 | }); 41 | ASSERT(ncall == 1); 42 | } 43 | -------------------------------------------------------------------------------- /golang/syscall.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2021-2022 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package syscall mirrors Go package syscall. 21 | 22 | - SIG* provide constants for signals. 23 | 24 | See also https://golang.org/pkg/syscall for Go syscall package documentation. 25 | """ 26 | 27 | from __future__ import print_function, absolute_import 28 | 29 | 30 | # create signal constants wrapped into os.Signal 31 | # for example syscall.SIGTERM = _PySignal_from_int(SIGTERM) 32 | def _(): 33 | from golang._os import _PySignal_from_int 34 | import signal as _pysig 35 | for attr in dir(_pysig): 36 | if attr.startswith("SIG") and not attr.startswith("SIG_"): 37 | signo = getattr(_pysig, attr) 38 | sig = _PySignal_from_int(signo) 39 | globals()[attr] = sig 40 | _(); del _ 41 | -------------------------------------------------------------------------------- /golang/testdata/src/lab.nexedi.com/kirr/hello.py: -------------------------------------------------------------------------------- 1 | TAG = 'gopath: test: hello.py' 2 | -------------------------------------------------------------------------------- /golang/testdata/src/lab.nexedi.com/kirr/world/__init__.py: -------------------------------------------------------------------------------- 1 | TAG = 'gopath: test: world/__init__.py' 2 | -------------------------------------------------------------------------------- /golang/testing.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2017-2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package testing mirrors Go testing package for things missed in Python.""" 21 | 22 | from __future__ import print_function, absolute_import 23 | 24 | from golang import time 25 | from math import ceil, log10 26 | 27 | 28 | # B is benchmarking timer/request passed to benchmarks as fixture 29 | # similar to https://golang.org/pkg/testing/#B. 30 | # 31 | # Use benchmark to actually run a benchmark. 32 | class B: 33 | # .N number of iterations benchmarked function should do 34 | 35 | def __init__(self): 36 | self.N = 1 # preset to 1 iteration 37 | self._t_start = None # t of timer started; None if timer is currently stopped 38 | self.reset_timer() 39 | 40 | def reset_timer(self): 41 | self._t_total = 0. 42 | 43 | def start_timer(self): 44 | if self._t_start is not None: 45 | return 46 | 47 | self._t_start = time.now() 48 | 49 | def stop_timer(self): 50 | if self._t_start is None: 51 | return 52 | 53 | t = time.now() 54 | self._t_total += t - self._t_start 55 | self._t_start = None 56 | 57 | def total_time(self): 58 | return self._t_total 59 | 60 | 61 | # BenchmarkResult represent 62 | class BenchmarkResult: 63 | # .N number of iterations 64 | # .T total time taken 65 | # 66 | # TODO memalloc stats 67 | def __init__(self, n, t): 68 | self.N, self.T = n, t 69 | 70 | 71 | # _stopBenchmark, when returned by benchmarked function, tells benchmark driver 72 | # to stop benchmarking this function. 73 | # 74 | # it is private since only py.bench uses it, and noone else should. 75 | # (py.bench uses it to benchmark functions that do not take b as argument) 76 | _stopBenchmark = object() 77 | 78 | # benchmark benchmarks benchf auto-adjusting whole running time to ttarget. 79 | # 80 | # benchf is invoked as benchf(b). 81 | def benchmark(benchf, ttarget = 1.): # -> BenchmarkResult 82 | b = B() 83 | b.N = 0 84 | t = 0. 85 | while t < (ttarget * 0.9): 86 | if b.N == 0: 87 | b.N = 1 88 | else: 89 | n = b.N * (ttarget / t) # exact how to adjust b.N to reach ttarget 90 | order = int(log10(n)) # n = k·10^order, k ∈ [1,10) 91 | k = float(n) / (10**order) 92 | k = ceil(k) # lift up k to nearest int 93 | b.N = int(k * 10**order) # b.N = int([1,10))·10^order 94 | 95 | b.reset_timer() 96 | b.start_timer() 97 | x = benchf(b) 98 | b.stop_timer() 99 | t = b.total_time() 100 | 101 | # stop trying to reach ttarget if benchf asks us so. 102 | if x is _stopBenchmark: 103 | break 104 | 105 | return BenchmarkResult(b.N, t) 106 | -------------------------------------------------------------------------------- /golang/testprog/golang_test_defer_excchain.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """This program is used to test traceback dump of chained exceptions. 21 | 22 | When run it fails and Python should print the dump. 23 | The dump is verified by test driver against golang_test_defer_excchain.txt . 24 | """ 25 | 26 | from __future__ import print_function, absolute_import 27 | 28 | from golang import defer, func 29 | 30 | def d1(): 31 | raise RuntimeError("d1: aaa") 32 | def d2(): 33 | 1/0 34 | def d3(): 35 | raise RuntimeError("d3: bbb") 36 | 37 | @func 38 | def main(): 39 | defer(d3) 40 | defer(d2) 41 | defer(d1) 42 | raise RuntimeError("err") 43 | 44 | if __name__ == "__main__": 45 | main() 46 | -------------------------------------------------------------------------------- /golang/testprog/golang_test_defer_excchain.txt: -------------------------------------------------------------------------------- 1 | Traceback (most recent call last): 2 | File "PYGOLANG/golang/__init__.py", line ..., in _goframe 3 | return f(*argv, **kw) 4 | ^^^^^^^^^^^^^^ +PY311 5 | File "PY39(PYGOLANG/golang/testprog/)golang_test_defer_excchain.py", line 42, in main 6 | raise RuntimeError("err") 7 | RuntimeError: err 8 | 9 | During handling of the above exception, another exception occurred: 10 | 11 | Traceback (most recent call last): 12 | File "PYGOLANG/golang/__init__.py", line ..., in __exit__ 13 | ... 14 | File "PY39(PYGOLANG/golang/testprog/)golang_test_defer_excchain.py", line 31, in d1 15 | raise RuntimeError("d1: aaa") 16 | RuntimeError: d1: aaa 17 | 18 | During handling of the above exception, another exception occurred: 19 | 20 | Traceback (most recent call last): 21 | File "PYGOLANG/golang/__init__.py", line ..., in __exit__ 22 | ... 23 | File "PY39(PYGOLANG/golang/testprog/)golang_test_defer_excchain.py", line 33, in d2 24 | 1/0 25 | ~^~ +PY311 26 | ZeroDivisionError: ... 27 | 28 | During handling of the above exception, another exception occurred: 29 | 30 | Traceback (most recent call last): 31 | ... "PY39(PYGOLANG/golang/testprog/)golang_test_defer_excchain.py", line 45, in 32 | main() 33 | ... 34 | File "PYGOLANG/golang/__init__.py", line ..., in _goframe 35 | return f(*argv, **kw) -PY310 36 | with __goframe__: +PY310 37 | ^^^^^^^^^^^ +PY312 38 | File "PYGOLANG/golang/__init__.py", line ..., in __exit__ 39 | ... 40 | File "PYGOLANG/golang/__init__.py", line ..., in __exit__ 41 | ... 42 | File "PYGOLANG/golang/__init__.py", line ..., in __exit__ 43 | ... 44 | File "PY39(PYGOLANG/golang/testprog/)golang_test_defer_excchain.py", line 35, in d3 45 | raise RuntimeError("d3: bbb") 46 | RuntimeError: d3: bbb 47 | -------------------------------------------------------------------------------- /golang/testprog/golang_test_defer_excchain.txt-ipython: -------------------------------------------------------------------------------- 1 | ... 2 | RuntimeError Traceback (most recent call last) 3 | PYGOLANG/golang/__init__.py in _goframe(f, *argv, **kw) 4 | ... 5 | --> ... return f(*argv, **kw) 6 | ... 7 | 8 | PYGOLANG/golang/testprog/golang_test_defer_excchain.py in main() 9 | 41 defer(d1) 10 | ---> 42 raise RuntimeError("err") 11 | 43 12 | 13 | RuntimeError: err 14 | 15 | During handling of the above exception, another exception occurred: 16 | 17 | RuntimeError Traceback (most recent call last) 18 | PYGOLANG/golang/__init__.py in __exit__(__goframe__, exc_type, exc_val, exc_tb) 19 | ... 20 | 21 | PYGOLANG/golang/testprog/golang_test_defer_excchain.py in d1() 22 | 30 def d1(): 23 | ---> 31 raise RuntimeError("d1: aaa") 24 | 32 def d2(): 25 | 26 | RuntimeError: d1: aaa 27 | 28 | During handling of the above exception, another exception occurred: 29 | 30 | ZeroDivisionError Traceback (most recent call last) 31 | PYGOLANG/golang/__init__.py in __exit__(__goframe__, exc_type, exc_val, exc_tb) 32 | ... 33 | 34 | PYGOLANG/golang/testprog/golang_test_defer_excchain.py in d2() 35 | 32 def d2(): 36 | ---> 33 1/0 37 | 34 def d3(): 38 | 39 | ZeroDivisionError: ... 40 | 41 | During handling of the above exception, another exception occurred: 42 | 43 | RuntimeError Traceback (most recent call last) 44 | ... 45 | 46 | PYGOLANG/golang/testprog/golang_test_defer_excchain.py in ... 47 | 43 48 | 44 if __name__ == "__main__": 49 | ---> 45 main() 50 | 51 | ... 52 | 53 | PYGOLANG/golang/__init__.py in _goframe(f, *argv, **kw) 54 | ... 55 | --> ... return f(*argv, **kw) 56 | ... 57 | 58 | PYGOLANG/golang/__init__.py in __exit__(__goframe__, exc_type, exc_val, exc_tb) 59 | ... 60 | 61 | PYGOLANG/golang/__init__.py in __exit__(__goframe__, exc_type, exc_val, exc_tb) 62 | ... 63 | 64 | PYGOLANG/golang/__init__.py in __exit__(__goframe__, exc_type, exc_val, exc_tb) 65 | ... 66 | 67 | PYGOLANG/golang/testprog/golang_test_defer_excchain.py in d3() 68 | 33 1/0 69 | 34 def d3(): 70 | ---> 35 raise RuntimeError("d3: bbb") 71 | 36 72 | 37 @func 73 | 74 | RuntimeError: d3: bbb 75 | -------------------------------------------------------------------------------- /golang/testprog/golang_test_defer_excchain.txt-pytest: -------------------------------------------------------------------------------- 1 | ... 2 | ...________________ main ________________... 3 | ../__init__.py:...: in _goframe 4 | return f(*argv, **kw) 5 | golang_test_defer_excchain.py:42: in main 6 | raise RuntimeError("err") 7 | E RuntimeError: err 8 | 9 | During handling of the above exception, another exception occurred: 10 | ../__init__.py:...: in __exit__ 11 | ... 12 | golang_test_defer_excchain.py:31: in d1 13 | raise RuntimeError("d1: aaa") 14 | E RuntimeError: d1: aaa 15 | 16 | During handling of the above exception, another exception occurred: 17 | ../__init__.py:...: in __exit__ 18 | ... 19 | golang_test_defer_excchain.py:33: in d2 20 | 1/0 21 | E ZeroDivisionError: ... 22 | 23 | During handling of the above exception, another exception occurred: 24 | golang_test_defer_excchain.py:35: in d3 25 | raise RuntimeError("d3: bbb") 26 | E RuntimeError: d3: bbb 27 | =========================== ... 28 | -------------------------------------------------------------------------------- /golang/testprog/golang_test_goleaked.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (C) 2018-2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """This program tests that leaked goroutines don't prevent program to exit.""" 21 | 22 | from __future__ import print_function, absolute_import 23 | 24 | from golang import go, chan 25 | from golang import time 26 | import os, sys 27 | 28 | 29 | def main(): 30 | ng = 100 # N(tasks) to spawn 31 | gstarted = chan() # main <- g 32 | mainexit = chan() # main -> all g 33 | 34 | # a task that wants to live longer than main 35 | def leaktask(): 36 | gstarted.send(1) 37 | mainexit.recv() 38 | 39 | # normally when main thread exits, the whole process is terminated. 40 | # however if go spawns a thread with daemon=0, we are left here to continue. 41 | # make sure it is not the case 42 | time.sleep(3) 43 | print("leaked goroutine: process did not terminate", file=sys.stderr) 44 | sys.stderr.flush() 45 | time.sleep(1) 46 | os._exit(1) # not sys.exit - that can be used only from main thread 47 | 48 | for i in range(ng): 49 | go(leaktask) 50 | 51 | # make sure all tasks are started 52 | for i in range(ng): 53 | gstarted.recv() 54 | 55 | # now we can exit 56 | mainexit.close() 57 | sys.exit(0) 58 | 59 | 60 | if __name__ == '__main__': 61 | main() 62 | -------------------------------------------------------------------------------- /golang/testprog/golang_test_str.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (C) 2022-2023 Nexedi SA and Contributors. 4 | # Kirill Smelkov 5 | # 6 | # This program is free software: you can Use, Study, Modify and Redistribute 7 | # it under the terms of the GNU General Public License version 3, or (at your 8 | # option) any later version, as published by the Free Software Foundation. 9 | # 10 | # You can also Link and Combine this program with other software covered by 11 | # the terms of any of the Free Software licenses or any of the Open Source 12 | # Initiative approved licenses and Convey the resulting work. Corresponding 13 | # source of such a combination shall include the source code for all other 14 | # software used. 15 | # 16 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 17 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # 19 | # See COPYING file for full licensing terms. 20 | # See https://www.nexedi.com/licensing for rationale and options. 21 | """This program helps to verify b, u and underlying bstr and ustr. 22 | 23 | It complements golang_str_test.test_strings_print. 24 | """ 25 | 26 | from __future__ import print_function, absolute_import 27 | 28 | from golang import b, u 29 | from golang.gcompat import qq 30 | 31 | def main(): 32 | sb = b("привет αβγ b") 33 | su = u("привет αβγ u") 34 | print("print(b):", sb) 35 | print("print(u):", su) 36 | print("print(qq(b)):", qq(sb)) 37 | print("print(qq(u)):", qq(su)) 38 | print("print(repr(b)):", repr(sb)) 39 | print("print(repr(u)):", repr(su)) 40 | 41 | # py2: print(dict) calls PyObject_Print(flags=0) for both keys and values, 42 | # not with flags=Py_PRINT_RAW used by default almost everywhere else. 43 | # this way we can verify whether bstr.tp_print handles flags correctly. 44 | print("print({b: u}):", {sb: su}) 45 | 46 | 47 | if __name__ == '__main__': 48 | main() 49 | -------------------------------------------------------------------------------- /golang/testprog/golang_test_str.txt: -------------------------------------------------------------------------------- 1 | print(b): привет αβγ b 2 | print(u): привет αβγ u 3 | print(qq(b)): "привет αβγ b" 4 | print(qq(u)): "привет αβγ u" 5 | print(repr(b)): b('привет αβγ b') 6 | print(repr(u)): u('привет αβγ u') 7 | print({b: u}): {b('привет αβγ b'): u('привет αβγ u')} 8 | -------------------------------------------------------------------------------- /golang/testprog/golang_test_str_index2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (C) 2022-2023 Nexedi SA and Contributors. 4 | # Kirill Smelkov 5 | # 6 | # This program is free software: you can Use, Study, Modify and Redistribute 7 | # it under the terms of the GNU General Public License version 3, or (at your 8 | # option) any later version, as published by the Free Software Foundation. 9 | # 10 | # You can also Link and Combine this program with other software covered by 11 | # the terms of any of the Free Software licenses or any of the Open Source 12 | # Initiative approved licenses and Convey the resulting work. Corresponding 13 | # source of such a combination shall include the source code for all other 14 | # software used. 15 | # 16 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 17 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18 | # 19 | # See COPYING file for full licensing terms. 20 | # See https://www.nexedi.com/licensing for rationale and options. 21 | """This program helps to verify [:] handling for bstr and ustr. 22 | 23 | It complements golang_str_test.test_strings_index2. 24 | 25 | It needs to verify [:] only lightly because thorough verification is done in 26 | test_string_index, and here we need to verify only that __getslice__, inherited 27 | from builtin str/unicode, does not get into our way. 28 | """ 29 | 30 | from __future__ import print_function, absolute_import 31 | 32 | from golang import b, u, bstr, ustr 33 | from golang.gcompat import qq 34 | 35 | 36 | def main(): 37 | us = u("миру мир") 38 | bs = b("миру мир") 39 | 40 | def emit(what, uobj, bobj): 41 | assert type(uobj) is ustr 42 | assert type(bobj) is bstr 43 | print("u"+what, qq(uobj)) 44 | print("b"+what, qq(bobj)) 45 | 46 | emit("s", us, bs) 47 | emit("s[:]", us[:], bs[:]) 48 | emit("s[0:1]", us[0:1], bs[0:1]) 49 | emit("s[0:2]", us[0:2], bs[0:2]) 50 | emit("s[1:2]", us[1:2], bs[1:2]) 51 | emit("s[0:-1]", us[0:-1], bs[0:-1]) 52 | 53 | 54 | if __name__ == '__main__': 55 | main() 56 | -------------------------------------------------------------------------------- /golang/testprog/golang_test_str_index2.txt: -------------------------------------------------------------------------------- 1 | us "миру мир" 2 | bs "миру мир" 3 | us[:] "миру мир" 4 | bs[:] "миру мир" 5 | us[0:1] "м" 6 | bs[0:1] "\xd0" 7 | us[0:2] "ми" 8 | bs[0:2] "м" 9 | us[1:2] "и" 10 | bs[1:2] "\xbc" 11 | us[0:-1] "миру ми" 12 | bs[0:-1] "миру ми\xd1" 13 | -------------------------------------------------------------------------------- /golang/time.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package time mirrors Go package time. 21 | 22 | See _time.pxd for package documentation. 23 | """ 24 | 25 | # redirect cimport: golang.time -> golang._time (see __init__.pxd for rationale) 26 | from golang._time cimport * 27 | -------------------------------------------------------------------------------- /golang/time.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2019 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package time mirrors Go package time. 21 | 22 | - `now` returns current time. 23 | - `sleep` pauses current task. 24 | - `Ticker` and `Timer` provide timers integrated with channels. 25 | - `tick`, `after` and `after_func` are convenience wrappers to use 26 | tickers and timers easily. 27 | 28 | See also https://golang.org/pkg/time for Go time package documentation. 29 | """ 30 | 31 | from __future__ import print_function, absolute_import 32 | 33 | from golang._time import \ 34 | pysecond as second, \ 35 | pynanosecond as nanosecond, \ 36 | pymicrosecond as microsecond, \ 37 | pymillisecond as millisecond, \ 38 | pyminute as minute, \ 39 | pyhour as hour, \ 40 | \ 41 | pynow as now, \ 42 | pysleep as sleep, \ 43 | \ 44 | pytick as tick, \ 45 | pyafter as after, \ 46 | pyafter_func as after_func, \ 47 | PyTicker as Ticker, \ 48 | PyTimer as Timer 49 | -------------------------------------------------------------------------------- /golang/unicode/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navytux/pygolang/ab48eedd3addd8a8454b52e08bdffa32daa691d8/golang/unicode/__init__.py -------------------------------------------------------------------------------- /golang/unicode/_utf8.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2023 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package utf8 mirrors Go package utf8. 21 | 22 | See https://golang.org/pkg/unicode/utf8 for Go utf8 package documentation. 23 | """ 24 | 25 | from golang cimport rune 26 | 27 | cdef extern from "golang/unicode/utf8.h" namespace "golang::unicode::utf8" nogil: 28 | rune RuneError 29 | -------------------------------------------------------------------------------- /golang/unicode/utf8.h: -------------------------------------------------------------------------------- 1 | #ifndef _NXD_LIBGOLANG_UNICODE_UTF8_H 2 | #define _NXD_LIBGOLANG_UNICODE_UTF8_H 3 | 4 | // Copyright (C) 2023 Nexedi SA and Contributors. 5 | // Kirill Smelkov 6 | // 7 | // This program is free software: you can Use, Study, Modify and Redistribute 8 | // it under the terms of the GNU General Public License version 3, or (at your 9 | // option) any later version, as published by the Free Software Foundation. 10 | // 11 | // You can also Link and Combine this program with other software covered by 12 | // the terms of any of the Free Software licenses or any of the Open Source 13 | // Initiative approved licenses and Convey the resulting work. Corresponding 14 | // source of such a combination shall include the source code for all other 15 | // software used. 16 | // 17 | // This program is distributed WITHOUT ANY WARRANTY; without even the implied 18 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 | // 20 | // See COPYING file for full licensing terms. 21 | // See https://www.nexedi.com/licensing for rationale and options. 22 | 23 | // Package utf8 mirrors Go package utf8. 24 | 25 | #include 26 | 27 | // golang::unicode::utf8:: 28 | namespace golang { 29 | namespace unicode { 30 | namespace utf8 { 31 | 32 | constexpr rune RuneError = 0xFFFD; // unicode replacement character 33 | 34 | }}} // golang::os::utf8:: 35 | 36 | #endif // _NXD_LIBGOLANG_UNICODE_UTF8_H 37 | -------------------------------------------------------------------------------- /golang/unicode/utf8.pxd: -------------------------------------------------------------------------------- 1 | # cython: language_level=2 2 | # Copyright (C) 2023 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Package utf8 mirrors Go package utf8. 21 | 22 | See _utf8.pxd for package documentation. 23 | """ 24 | 25 | # redirect cimport: golang.unicode.utf8 -> golang.unicode._utf8 (see __init__.pxd for rationale) 26 | from golang.unicode._utf8 cimport * 27 | -------------------------------------------------------------------------------- /golang/x/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navytux/pygolang/ab48eedd3addd8a8454b52e08bdffa32daa691d8/golang/x/__init__.py -------------------------------------------------------------------------------- /golang/x/perf/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navytux/pygolang/ab48eedd3addd8a8454b52e08bdffa32daa691d8/golang/x/perf/__init__.py -------------------------------------------------------------------------------- /gpython/testdata/bundle.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navytux/pygolang/ab48eedd3addd8a8454b52e08bdffa32daa691d8/gpython/testdata/bundle.zip -------------------------------------------------------------------------------- /gpython/testdata/dir.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navytux/pygolang/ab48eedd3addd8a8454b52e08bdffa32daa691d8/gpython/testdata/dir.zip -------------------------------------------------------------------------------- /gpython/testdata/dir/__main__.py: -------------------------------------------------------------------------------- 1 | print('dir/__main__') 2 | 3 | # imports should be resolved relative to dir 4 | import mod 5 | 6 | # sys.argv 7 | import sys 8 | print(sys.argv) 9 | 10 | # variable in module namespace 11 | tag = '~~DIR/MAIN~~' 12 | -------------------------------------------------------------------------------- /gpython/testdata/dir/mod.py: -------------------------------------------------------------------------------- 1 | print('dir/mod') 2 | 3 | # variable in module namespace 4 | tag = '~~DIR/MOD~~' 5 | -------------------------------------------------------------------------------- /gpython/testdata/hello.py: -------------------------------------------------------------------------------- 1 | print('hello') 2 | 3 | # imports should be resolved relative to main py file 4 | import world 5 | 6 | # sys.argv 7 | import sys 8 | print(sys.argv) 9 | 10 | # variable in module namespace 11 | tag = '~~HELLO~~' 12 | -------------------------------------------------------------------------------- /gpython/testdata/pkg/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/navytux/pygolang/ab48eedd3addd8a8454b52e08bdffa32daa691d8/gpython/testdata/pkg/__init__.py -------------------------------------------------------------------------------- /gpython/testdata/pkg/__main__.py: -------------------------------------------------------------------------------- 1 | print('pkg/__main__') 2 | 3 | # imports should be resolved relative current module 4 | from . import mod 5 | 6 | # sys.argv 7 | import sys 8 | print(sys.argv) 9 | 10 | # variable in module namespace 11 | tag = '~~PKG/MAIN~~' 12 | -------------------------------------------------------------------------------- /gpython/testdata/pkg/mod.py: -------------------------------------------------------------------------------- 1 | print('pkg/mod') 2 | 3 | # variable in module namespace 4 | tag = '~~PKG/MOD~~' 5 | -------------------------------------------------------------------------------- /gpython/testdata/world.py: -------------------------------------------------------------------------------- 1 | print('world') 2 | 3 | # variable in module namespace 4 | tag = '~~WORLD~~' 5 | -------------------------------------------------------------------------------- /gpython/testprog/check_main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2021 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Program check_main verifies that __main__ module is correctly installed on 21 | program run.""" 22 | 23 | from __future__ import print_function, absolute_import 24 | 25 | import sys, pickle 26 | 27 | class MyUniqueClassXYZ(object): 28 | def __init__(self, value): 29 | self.value = value 30 | 31 | def main(): 32 | assert MyUniqueClassXYZ.__module__ == '__main__', MyUniqueClassXYZ.__module__ 33 | assert '__main__' in sys.modules, sys.modules 34 | mainmod = sys.modules['__main__'] 35 | mainmod_ = __import__('__main__') 36 | assert mainmod is mainmod_, (mainmod, mainmod_) 37 | 38 | # verify that mainmod actually refers to current module 39 | assert hasattr(mainmod, 'MyUniqueClassXYZ'), dir(mainmod) 40 | 41 | # pickle/unpickle would also fail if import('__main__') gives module different from current 42 | obj = MyUniqueClassXYZ(123) 43 | s = pickle.dumps(obj) 44 | obj_ = pickle.loads(s) 45 | assert type(obj_) is MyUniqueClassXYZ, type(obj) 46 | assert obj_.value == 123, obj_.value 47 | 48 | # ok 49 | 50 | assert __name__ == '__main__', __name__ 51 | main() 52 | -------------------------------------------------------------------------------- /gpython/testprog/future_print_function.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2020 Nexedi SA and Contributors. 3 | # Jérome Perrin 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Program future_print_function enable print_function future and use print 21 | as a function.""" 22 | 23 | from __future__ import print_function 24 | 25 | print("print", "is", "a", "function", "with", "print_function", "future") 26 | -------------------------------------------------------------------------------- /gpython/testprog/print_faulthandler.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2024 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Program print_faulthandler prints information about faulthandler settings.""" 21 | 22 | from __future__ import print_function, absolute_import 23 | 24 | import sys 25 | 26 | def main(): 27 | if 'faulthandler' not in sys.modules: 28 | print('faulthandler is not imported') 29 | return 30 | 31 | fh = sys.modules['faulthandler'] 32 | print('faulthandler imported') 33 | print('faulthandler %s' % ('enabled' if fh.is_enabled() else 'disabled')) 34 | 35 | 36 | if __name__ == '__main__': 37 | main() 38 | -------------------------------------------------------------------------------- /gpython/testprog/print_opt.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2020-2023 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Program print_opt prints information about optimizations.""" 21 | 22 | from __future__ import print_function, absolute_import 23 | 24 | import sys, os, os.path, tempfile, shutil 25 | 26 | def main(): 27 | print('sys.flags.debug: %s' % sys.flags.debug) 28 | print('sys.flags.optimize: %s' % sys.flags.optimize) 29 | print('__debug__: %s' % __debug__) 30 | print('assert: %s' % is_assert_enabled()) 31 | print('docstrings: %s' % is_docstrings_enabled()) 32 | print('import mod.py: %s' % modpy_imports_from()) 33 | 34 | 35 | # is_assert_enabled returns whether assert statements are enabled. 36 | def is_assert_enabled(): 37 | try: 38 | assert False # must raise AssertionError 39 | except AssertionError: 40 | return True 41 | else: 42 | return False 43 | 44 | # is_docstrings_enabled returns whether docstrings are enabled. 45 | def is_docstrings_enabled(): 46 | def _(): 47 | """hello world""" 48 | if _.__doc__ is None: 49 | return False 50 | if _.__doc__ == "hello world": 51 | return True 52 | raise AssertionError(_.__doc__) 53 | 54 | # modpy returns name for compiled version of python module mod.py 55 | def modpy_imports_from(): 56 | try: 57 | import mod 58 | except ImportError: 59 | # ok - should not be there 60 | pass 61 | else: 62 | raise AssertionError("module 'mod' is already there") 63 | 64 | tmpd = tempfile.mkdtemp('', 'modpy_imports_from') 65 | tmpd_ = tmpd + os.path.sep 66 | try: 67 | pymod = tmpd_ + "mod.py" 68 | with open(pymod, "w") as f: 69 | f.write("# hello up there\n") 70 | 71 | sys.path.insert(0, tmpd) 72 | import mod 73 | 74 | files = set() 75 | for dirpath, dirnames, filenames in os.walk(tmpd): 76 | for _ in filenames: 77 | f = os.path.join(dirpath, _) 78 | if f.startswith(tmpd_): 79 | f = f[len(tmpd_):] 80 | files.add(f) 81 | 82 | 83 | files.remove("mod.py") # must be there | raises if not 84 | if len(files) == 0: 85 | from_ = "mod.py" # source-only import 86 | else: 87 | if len(files) != 1: 88 | raise AssertionError("mod.py -> multiple compiled files (%s)" % (files,)) 89 | 90 | from_ = files.pop() 91 | 92 | return from_ 93 | 94 | finally: 95 | shutil.rmtree(tmpd) 96 | 97 | 98 | if __name__ == '__main__': 99 | main() 100 | -------------------------------------------------------------------------------- /gpython/testprog/print_statement.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2020 Nexedi SA and Contributors. 3 | # Jérome Perrin 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Program print_statement uses print as a statement, which is allowed on 21 | python2 when not using print_statement future.""" 22 | 23 | print "print", "is", "a", "statement" 24 | -------------------------------------------------------------------------------- /gpython/testprog/print_stdio_bufmode.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2025 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Program print_stdio_bufmode prints information about stdout/stderr buffering mode.""" 21 | 22 | from __future__ import print_function, absolute_import 23 | 24 | import sys, os 25 | 26 | 27 | def main(): 28 | null = os.open(os.devnull, os.O_WRONLY) 29 | 30 | def check(subj, ioobj): 31 | ioobj.write('%s: unbuffered if you see the next line; buffered otherwise\n' % subj) 32 | ioobj.flush() 33 | ioobj.write('%s: unbuffered' % subj) # NOTE: no \n to avoid flush even on line-bufferring 34 | os.close(ioobj.fileno()) 35 | os.dup2(null, ioobj.fileno()) # not to hit an error when ioobj is closed at the end 36 | 37 | check('stdout', sys.stdout) 38 | check('stderr', sys.stderr) 39 | 40 | 41 | if __name__ == '__main__': 42 | main() 43 | -------------------------------------------------------------------------------- /gpython/testprog/print_syspath.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Program/module print_syspath prints value of sys.path""" 21 | 22 | from __future__ import print_function, absolute_import 23 | 24 | import sys 25 | 26 | def main(): 27 | for p in sys.path: 28 | print(p) 29 | 30 | main() 31 | -------------------------------------------------------------------------------- /gpython/testprog/print_warnings_setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright (C) 2020 Nexedi SA and Contributors. 3 | # Kirill Smelkov 4 | # 5 | # This program is free software: you can Use, Study, Modify and Redistribute 6 | # it under the terms of the GNU General Public License version 3, or (at your 7 | # option) any later version, as published by the Free Software Foundation. 8 | # 9 | # You can also Link and Combine this program with other software covered by 10 | # the terms of any of the Free Software licenses or any of the Open Source 11 | # Initiative approved licenses and Convey the resulting work. Corresponding 12 | # source of such a combination shall include the source code for all other 13 | # software used. 14 | # 15 | # This program is distributed WITHOUT ANY WARRANTY; without even the implied 16 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | # 18 | # See COPYING file for full licensing terms. 19 | # See https://www.nexedi.com/licensing for rationale and options. 20 | """Program print_warnings_setup prints information about warnings module 21 | configuration.""" 22 | 23 | from __future__ import print_function, absolute_import 24 | 25 | import sys, warnings, re 26 | 27 | def main(): 28 | print('sys.warnoptions: %s' % sys.warnoptions) 29 | print('\nwarnings.filters:') 30 | for f in warnings.filters: 31 | print_filter(f) 32 | 33 | def print_filter(f): 34 | # see Lib/warnings.py 35 | action, message, klass, module, line = f 36 | message = wstr(message) 37 | module = wstr(module) 38 | klass = klass.__name__ 39 | if line == 0: 40 | line = '*' 41 | print('- %s:%s:%s:%s:%s' % (action, message, klass, module, line)) 42 | 43 | # wstr returns str corresponding to warning filter's message or module. 44 | REPattern = re.compile('').__class__ 45 | def wstr(obj): 46 | if obj is None: 47 | return '' 48 | if isinstance(obj, REPattern): 49 | return obj.pattern 50 | return obj 51 | 52 | 53 | if __name__ == '__main__': 54 | main() 55 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools", "wheel", "setuptools_dso >= 2.8", "cython < 3", "gevent"] 3 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = 3 | {py27d,py27,py38,py39d,py39,py310d,py310,py311d,py311,py312,pypy,pypy3}-{thread,gevent} 4 | 5 | 6 | # ThreadSanitizer 7 | 8 | # XXX under pypy tsan does not observe the GIL lock/release(*), and this 9 | # way reports even plain T1.Py_INCREF / T2.Py_DECREF as a race. 10 | # (*) PyPy locks its GIL (see RPyGilAcquire) by manually doing atomic cmpxchg 11 | # and other games, which TSAN cannot see if PyPy itself was not compiled with 12 | # -fsanitize=thread. 13 | {py27d,py27,py38,py39d,py39,py310d,py310,py311d,py311,py312 }-{thread }-tsan 14 | # XXX py*-gevent-tsan would be nice to have, but at present TSAN is not 15 | # effective with gevent, because it does not understand greenlet "thread" 16 | # switching and so perceives the program as having only one thread where races 17 | # are impossible. Disabled to save time. 18 | # {py27d,py27,py38,py39d,py39,py310d,py310,py311d,py311,py312 }-{ gevent}-tsan 19 | 20 | 21 | # AddressSanitizer 22 | 23 | # XXX asan does not work with gevent: https://github.com/python-greenlet/greenlet/issues/113 24 | {py27d,py27,py38,py39d,py39,py310d,py310,py311d,py311,py312,pypy,pypy3}-{thread }-asan 25 | 26 | [testenv] 27 | basepython = 28 | py27d: python2.7-dbg 29 | py27: python2.7 30 | py38: python3.8 31 | py39d: python3.9-dbg 32 | py39: python3.9 33 | py310d: python3.10-dbg 34 | py310: python3.10 35 | py311d: python3.11-dbg 36 | py311: python3.11 37 | py312: python3.12 38 | py312d: python3.12-dbg 39 | pypy: pypy 40 | pypy3: pypy3 41 | 42 | setenv = 43 | # distutils take CFLAGS for both C and C++. 44 | # distutils use CFLAGS also at link stage -> we don't need to set LDFLAGS separately. 45 | tsan: CFLAGS=-g -fsanitize=thread -fno-omit-frame-pointer 46 | asan: CFLAGS=-g -fsanitize=address -fno-omit-frame-pointer 47 | # XXX however distutils' try_link, which is used by numpy.distutils use only CC 48 | # as linker without CFLAGS and _without_ LDFLAGS, which fails if *.o were 49 | # compiled with -fsanitize=X and linked without that option. Work it around 50 | # with also adjusting CC. 51 | # XXX better arrange to pass CFLAGS to pygolang only, e.g. by adding --race or 52 | # --sanitize=thread to `setup.py build_ext`. 53 | tsan: CC=cc -fsanitize=thread -fno-omit-frame-pointer 54 | asan: CC=cc -fsanitize=address -fno-omit-frame-pointer 55 | 56 | # always compile pygolang from source and don't reuse binary pygolang wheels as 57 | # we compile each case with different CFLAGS. 58 | install_command = 59 | python -m pip install --no-binary pygolang {opts} {packages} 60 | 61 | deps = 62 | .[all_test] 63 | 64 | # gpython pre-imports installed golang, will get into conflict with 65 | # golang/ if we run pytest from pygolang worktree. Avoid that. 66 | changedir = {envsitepackagesdir} 67 | 68 | commands= 69 | {toxinidir}/trun \ 70 | thread: {envpython} \ 71 | gevent: gpython \ 72 | -m pytest \ 73 | # asan/tsan: tell pytest not to capture output - else it is not possible to see 74 | # reports from sanitizers because they crash tested process on error. 75 | # likewise for python debug builds. 76 | asan,tsan,py{27,39,310,311,312}d: -s \ 77 | gpython/ golang/ 78 | 79 | allowlist_externals={toxinidir}/trun 80 | --------------------------------------------------------------------------------