Skip to content

Commit

Permalink
refactor: Adapt pytox to the new tox_system stuff.
Browse files Browse the repository at this point in the history
  • Loading branch information
iphydf committed Dec 28, 2023
1 parent 1e75057 commit 5f7739c
Show file tree
Hide file tree
Showing 26 changed files with 544 additions and 122 deletions.
8 changes: 4 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ jobs:
-DTRACE=ON
-DMUST_BUILD_TOXAV=ON
- run: cd c-toxcore/_build && ninja install -j$(nproc)
# - run:
# export CFLAGS="-I$PWD/c-toxcore/_install/include -fsanitize=address";
# export LDFLAGS="-L$PWD/c-toxcore/_install/lib -Wl,-rpath,$PWD/c-toxcore/_install/lib";
# python3 setup.py build_ext --inplace
- run:
export CFLAGS="-I$PWD/c-toxcore/_install/include -fsanitize=address";
export LDFLAGS="-L$PWD/c-toxcore/_install/lib -Wl,-rpath,$PWD/c-toxcore/_install/lib";
python3 setup.py build_ext --inplace
# - run: ASAN_OPTIONS=detect_leaks=0
# LD_PRELOAD=libasan.so.5
# PYTHONPATH=.
Expand Down
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.mypy_cache
42 changes: 39 additions & 3 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,59 @@ load("//tools/project:build_defs.bzl", "project")

project()

SUBSYSTEMS = [
"log",
"memory",
"network",
"options",
"random",
"system",
"time",
]

[genrule(
name = "pytox/" + sys,
srcs = [
"pytox/src/%s.pxd" % sys,
"pytox/src/%s.pyx" % sys,
"//c-toxcore:public",
],
outs = [
"pytox/%s.pxd" % sys,
"pytox/%s.pyx" % sys,
],
cmd = " ".join([
"$(location //py_toxcore_c/tools:gen_api)",
"$(location pytox/src/%s.pyx)" % sys,
"$(GENDIR)/c-toxcore",
"> $(location pytox/%s.pyx);" % sys,
"$(location //py_toxcore_c/tools:gen_api)",
"$(location pytox/src/%s.pxd)" % sys,
"$(GENDIR)/c-toxcore",
"> $(location pytox/%s.pxd)" % sys,
]),
tools = ["//py_toxcore_c/tools:gen_api"],
) for sys in SUBSYSTEMS]

genrule(
name = "pytox/core",
srcs = [
"pytox/src/core.pyx",
"//c-toxcore:tox/tox.h",
"//c-toxcore:tox/toxcore/tox.h",
],
outs = ["pytox/core.pyx"],
cmd = "$(location //py_toxcore_c/tools:gen_api) $(location pytox/src/core.pyx) $(location //c-toxcore:tox/tox.h) > $@",
cmd = "$(location //py_toxcore_c/tools:gen_api) $(location pytox/src/core.pyx) $(GENDIR)/c-toxcore > $@",
tools = ["//py_toxcore_c/tools:gen_api"],
)

pyx_library(
name = "pytox",
srcs = [
"pytox.pxd",
"pytox/av.pyx",
"pytox/core.pyx",
],
"pytox/error.pyx",
] + ["pytox/%s.pxd" % sys for sys in SUBSYSTEMS] + ["pytox/%s.pyx" % sys for sys in SUBSYSTEMS],
cdeps = ["//c-toxcore"],
cython_directives = {"language_level": "3"},
tags = ["no-cross"],
Expand Down
34 changes: 29 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,44 @@ RUN apt-get update \
&& pip3 install cython mypy

WORKDIR /build
RUN git clone --depth=1 --recursive https://github.com/TokTok/c-toxcore /build/c-toxcore \
RUN git clone --recursive --depth=1 --branch=system https://github.com/iphydf/c-toxcore /build/c-toxcore \
&& cmake -GNinja -B/build/c-toxcore/_build -H/build/c-toxcore \
-DBOOTSTRAP_DAEMON=OFF \
-DENABLE_STATIC=OFF \
-DMUST_BUILD_TOXAV=ON \
&& cmake --build /build/c-toxcore/_build --target install --parallel "$(nproc)" \
&& ldconfig
&& ldconfig && echo 2

COPY pytox /build/pytox
# Tools first, they change less.
COPY tools /build/tools
COPY pytox.pxd /build/
COPY pytox /build/pytox

RUN mypy --strict tools/gen_api.py \
&& tools/gen_api.py pytox/src/core.pyx /usr/local/include/tox/tox.h > pytox/core.pyx \
&& cython pytox/av.pyx pytox/core.pyx
&& tools/gen_api.py pytox/src/core.pyx /usr/local/include > pytox/core.pyx \
&& tools/gen_api.py pytox/src/log.pxd /usr/local/include > pytox/log.pxd \
&& tools/gen_api.py pytox/src/log.pyx /usr/local/include > pytox/log.pyx \
&& tools/gen_api.py pytox/src/memory.pxd /usr/local/include > pytox/memory.pxd \
&& tools/gen_api.py pytox/src/memory.pyx /usr/local/include > pytox/memory.pyx \
&& tools/gen_api.py pytox/src/network.pxd /usr/local/include > pytox/network.pxd \
&& tools/gen_api.py pytox/src/network.pyx /usr/local/include > pytox/network.pyx \
&& tools/gen_api.py pytox/src/options.pxd /usr/local/include > pytox/options.pxd \
&& tools/gen_api.py pytox/src/options.pyx /usr/local/include > pytox/options.pyx \
&& tools/gen_api.py pytox/src/random.pxd /usr/local/include > pytox/random.pxd \
&& tools/gen_api.py pytox/src/random.pyx /usr/local/include > pytox/random.pyx \
&& tools/gen_api.py pytox/src/system.pxd /usr/local/include > pytox/system.pxd \
&& tools/gen_api.py pytox/src/system.pyx /usr/local/include > pytox/system.pyx \
&& tools/gen_api.py pytox/src/time.pxd /usr/local/include > pytox/time.pxd \
&& tools/gen_api.py pytox/src/time.pyx /usr/local/include > pytox/time.pyx \
&& cython -I $PWD -X "language_level=3" --line-directives pytox/av.pyx pytox/core.pyx \
pytox/error.pyx \
pytox/log.pyx \
pytox/memory.pyx \
pytox/network.pyx \
pytox/options.pyx \
pytox/random.pyx \
pytox/system.pyx \
pytox/time.pyx

COPY setup.py /build/
RUN python3 setup.py install \
Expand Down
1 change: 1 addition & 0 deletions pytox.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

14 changes: 14 additions & 0 deletions pytox/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/core.pxd
/core.pyx
/log.pxd
/log.pyx
/memory.pxd
/memory.pyx
/network.pxd
/network.pyx
/random.pxd
/random.pyx
/system.pxd
/system.pyx
/time.pxd
/time.pyx
15 changes: 15 additions & 0 deletions pytox/error.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class UseAfterFreeException(Exception):
def __init__(self):
super().__init__(
"object used after it was killed/freed (or it was never initialised)")

class ToxException(Exception):
pass

class ApiException(ToxException):
def __init__(self, err):
super().__init__(err)
self.error = err

class LengthException(ToxException):
pass
112 changes: 33 additions & 79 deletions pytox/src/core.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ from libcpp cimport bool
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t
from libc.stdlib cimport malloc, free

cdef extern from "tox/tox.h": pass
from pytox import error
from pytox.options cimport Tox_Options, ToxOptions
from pytox.system cimport Tox_System

cdef extern from "tox/toxcore/tox.h": pass


VERSION: str = "%d.%d.%d" % (tox_version_major(), tox_version_minor(), tox_version_patch())
Expand All @@ -28,72 +32,22 @@ MAX_FILENAME_LENGTH: int = tox_max_filename_length()
MAX_HOSTNAME_LENGTH: int = tox_max_hostname_length()


class UseAfterFreeException(Exception):
def __init__(self):
super().__init__(
"object used after it was killed/freed (or it was never initialised)")

class ToxException(Exception):
pass

class ApiException(ToxException):
def __init__(self, err):
super().__init__(err)
self.error = err

class LengthException(ToxException):
pass

cdef void _check_len(str name, bytes data, int expected_length) except *:
if len(data) != expected_length:
raise LengthException(
raise error.LengthException(
f"parameter '{name}' received bytes of invalid"
f"length {len(data)}, expected {expected_length}")


cdef class ToxOptions:

cdef Tox_Options *_ptr

def __init__(self):
cdef Tox_Err_Options_New err = TOX_ERR_OPTIONS_NEW_OK
self._ptr = tox_options_new(&err)
if err: raise ApiException(Tox_Err_Options_New(err))

def __dealloc__(self):
self.__exit__(None, None, None)

def __enter__(self):
return self

def __exit__(self, exc_type, exc_value, exc_traceback):
tox_options_free(self._ptr)
self._ptr = NULL

cdef Tox_Options *_get(self) except *:
if self._ptr is NULL:
raise UseAfterFreeException()
return self._ptr

@property
def ipv6_enabled(self) -> bool:
return tox_options_get_ipv6_enabled(self._get())

@ipv6_enabled.setter
def ipv6_enabled(self, value: bool):
tox_options_set_ipv6_enabled(self._get(), value)


cdef class Core:

cdef Tox *_ptr

def __init__(self, options: ToxOptions = None):
cdef Tox_Err_New err = TOX_ERR_NEW_OK
err = TOX_ERR_NEW_OK
if options is None:
options = ToxOptions()
self._ptr = tox_new(options._ptr, &err)
if err: raise ApiException(Tox_Err_New(err))
self._ptr = tox_new(options._get(), &err)
if err: raise error.ApiException(Tox_Err_New(err))

install_handlers(self._get())

Expand All @@ -109,13 +63,13 @@ cdef class Core:

cdef Tox *_get(self) except *:
if self._ptr is NULL:
raise UseAfterFreeException()
raise error.UseAfterFreeException()
return self._ptr

@property
def savedata(self) -> bytes:
cdef size_t size = tox_get_savedata_size(self._get())
cdef uint8_t *data = <uint8_t*> malloc(size * sizeof(uint8_t))
size = tox_get_savedata_size(self._get())
data = <uint8_t*> malloc(size * sizeof(uint8_t))
try:
tox_get_savedata(self._get(), data)
return data[:size]
Expand All @@ -124,7 +78,7 @@ cdef class Core:

def bootstrap(self, host: str, port: int, public_key: bytes) -> bool:
_check_len("public_key", public_key, tox_public_key_size())
cdef Tox_Err_Bootstrap err = TOX_ERR_BOOTSTRAP_OK
err = TOX_ERR_BOOTSTRAP_OK
return tox_bootstrap(self._get(), host.encode("utf-8"), port, public_key, &err)

@property
Expand All @@ -143,8 +97,8 @@ cdef class Core:

@property
def address(self) -> bytes:
cdef size_t size = tox_address_size()
cdef uint8_t *data = <uint8_t*> malloc(size * sizeof(uint8_t))
size = tox_address_size()
data = <uint8_t*> malloc(size * sizeof(uint8_t))
try:
tox_self_get_address(self._get(), data)
return data[:size]
Expand All @@ -157,8 +111,8 @@ cdef class Core:

@property
def public_key(self) -> bytes:
cdef size_t size = tox_public_key_size()
cdef uint8_t *data = <uint8_t*> malloc(size * sizeof(uint8_t))
size = tox_public_key_size()
data = <uint8_t*> malloc(size * sizeof(uint8_t))
try:
tox_self_get_public_key(self._get(), data)
return data[:tox_public_key_size()]
Expand All @@ -167,8 +121,8 @@ cdef class Core:

@property
def secret_key(self) -> bytes:
cdef size_t size = tox_secret_key_size()
cdef uint8_t *data = <uint8_t*> malloc(size * sizeof(uint8_t))
size = tox_secret_key_size()
data = <uint8_t*> malloc(size * sizeof(uint8_t))
try:
tox_self_get_secret_key(self._get(), data)
return data[:tox_secret_key_size()]
Expand All @@ -177,8 +131,8 @@ cdef class Core:

@property
def name(self) -> bytes:
cdef size_t size = tox_self_get_name_size(self._get())
cdef uint8_t *data = <uint8_t*> malloc(size * sizeof(uint8_t))
size = tox_self_get_name_size(self._get())
data = <uint8_t*> malloc(size * sizeof(uint8_t))
try:
tox_self_get_name(self._get(), data)
return data[:size]
Expand All @@ -187,14 +141,14 @@ cdef class Core:

@name.setter
def name(self, name: bytes) -> None:
cdef Tox_Err_Set_Info err = TOX_ERR_SET_INFO_OK
err = TOX_ERR_SET_INFO_OK
tox_self_set_name(self._get(), name, len(name), &err)
if err: raise ApiException(Tox_Err_Set_Info(err))
if err: raise error.ApiException(Tox_Err_Set_Info(err))

@property
def status_message(self) -> bytes:
cdef size_t size = tox_self_get_status_message_size(self._get())
cdef uint8_t *data = <uint8_t*> malloc(size * sizeof(uint8_t))
size = tox_self_get_status_message_size(self._get())
data = <uint8_t*> malloc(size * sizeof(uint8_t))
try:
tox_self_get_status_message(self._get(), data)
return data[:size]
Expand All @@ -203,9 +157,9 @@ cdef class Core:

@status_message.setter
def status_message(self, status_message: bytes) -> None:
cdef Tox_Err_Set_Info err = TOX_ERR_SET_INFO_OK
err = TOX_ERR_SET_INFO_OK
tox_self_set_status_message(self._get(), status_message, len(status_message), &err)
if err: raise ApiException(Tox_Err_Set_Info(err))
if err: raise error.ApiException(Tox_Err_Set_Info(err))

@property
def status(self) -> Tox_User_Status:
Expand All @@ -217,17 +171,17 @@ cdef class Core:

def friend_add(self, address: bytes, message: bytes):
_check_len("address", address, tox_address_size())
cdef Tox_Err_Friend_Add err = TOX_ERR_FRIEND_ADD_OK
err = TOX_ERR_FRIEND_ADD_OK
tox_friend_add(self._get(), address, message, len(message), &err)
if err: raise ApiException(Tox_Err_Friend_Add(err))
if err: raise error.ApiException(Tox_Err_Friend_Add(err))

def friend_add_norequest(self, public_key: bytes):
_check_len("public_key", public_key, tox_public_key_size())
cdef Tox_Err_Friend_Add err = TOX_ERR_FRIEND_ADD_OK
err = TOX_ERR_FRIEND_ADD_OK
tox_friend_add_norequest(self._get(), public_key, &err)
if err: raise ApiException(Tox_Err_Friend_Add(err))
if err: raise error.ApiException(Tox_Err_Friend_Add(err))

def friend_delete(self, friend_number: int):
cdef Tox_Err_Friend_Delete err = TOX_ERR_FRIEND_DELETE_OK
err = TOX_ERR_FRIEND_DELETE_OK
tox_friend_delete(self._get(), friend_number, &err)
if err: raise ApiException(Tox_Err_Friend_Delete(err))
if err: raise error.ApiException(Tox_Err_Friend_Delete(err))
18 changes: 18 additions & 0 deletions pytox/src/log.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# cython: language_level=3
cdef extern from "tox/toxcore/tox_log.h":
ctypedef struct Tox_Log

cpdef enum Tox_Log_Level:
TOX_LOG_LEVEL_TRACE,
TOX_LOG_LEVEL_DEBUG,
TOX_LOG_LEVEL_INFO,
TOX_LOG_LEVEL_WARNING,
TOX_LOG_LEVEL_ERROR,

cdef extern from "tox/toxcore/os_log.h": pass

cdef class ToxLog:

cdef Tox_Log *_ptr

cdef Tox_Log *_get(self) except *
Loading

0 comments on commit 5f7739c

Please sign in to comment.