Skip to content

Commit 10a0548

Browse files
committed
refactor: Rewrite pytox using Cython.
The C code was too brittle, too manual, and segfaulted all over the place if you hold it wrong. This is an attempt at making pytox more maintainable and safer, as well as giving it a better API.
1 parent 3ecf56b commit 10a0548

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+847
-5254
lines changed

.circleci/config.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ jobs:
4444
-DTRACE=ON
4545
-DMUST_BUILD_TOXAV=ON
4646
- run: cd c-toxcore/_build && ninja install -j$(nproc)
47-
- run:
48-
export CFLAGS="-I$PWD/c-toxcore/_install/include -fsanitize=address";
49-
export LDFLAGS="-L$PWD/c-toxcore/_install/lib -Wl,-rpath,$PWD/c-toxcore/_install/lib";
50-
python3 setup.py build_ext --inplace
51-
- run: ASAN_OPTIONS=detect_leaks=0
52-
LD_PRELOAD=libasan.so.5
53-
PYTHONPATH=.
54-
python3 tests/tests.py
47+
# - run:
48+
# export CFLAGS="-I$PWD/c-toxcore/_install/include -fsanitize=address";
49+
# export LDFLAGS="-L$PWD/c-toxcore/_install/lib -Wl,-rpath,$PWD/c-toxcore/_install/lib";
50+
# python3 setup.py build_ext --inplace
51+
# - run: ASAN_OPTIONS=detect_leaks=0
52+
# LD_PRELOAD=libasan.so.5
53+
# PYTHONPATH=.
54+
# python3 tests/tests.py

.github/workflows/ci.yml

Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5,55 +5,55 @@ on:
55
branches: [master]
66

77
jobs:
8-
build:
9-
name: python-${{ matrix.version }}
10-
runs-on: ubuntu-latest
11-
12-
strategy:
13-
matrix:
14-
include:
15-
- version: "2.7"
16-
- version: "3.5"
17-
- version: "3.6"
18-
- version: "3.8"
19-
- version: "3.9"
20-
- version: "3.10"
21-
22-
steps:
23-
- uses: actions/checkout@v2
24-
- uses: actions/setup-python@v2
25-
with:
26-
python-version: ${{ matrix.version }}
27-
- name: Install
28-
run: |
29-
sudo apt update
30-
sudo apt install -y --no-install-recommends --no-install-suggests libtoxcore-dev
31-
- name: Build
32-
run: python setup.py build_ext --inplace
33-
- name: Test
34-
run: PYTHONPATH=. python tests/tests.py
35-
36-
coverage:
37-
name: python-3.7-coverage
38-
runs-on: ubuntu-latest
39-
40-
steps:
41-
- uses: actions/checkout@v2
42-
- uses: actions/setup-python@v2
43-
with:
44-
python-version: "3.7"
45-
- name: Install
46-
run: |
47-
sudo apt update
48-
sudo apt install -y --no-install-recommends --no-install-suggests libtoxcore-dev
49-
- name: Build
50-
run: |
51-
export CFLAGS="-fprofile-arcs -ftest-coverage"
52-
python setup.py build_ext --inplace
53-
- name: Test
54-
run: PYTHONPATH=. python tests/tests.py
55-
- name: Upload coverage
56-
run: bash <(curl -s https://codecov.io/bash)
8+
# build:
9+
# name: python-${{ matrix.version }}
10+
# runs-on: ubuntu-latest
11+
#
12+
# strategy:
13+
# matrix:
14+
# include:
15+
# - version: "2.7"
16+
# - version: "3.5"
17+
# - version: "3.6"
18+
# - version: "3.8"
19+
# - version: "3.9"
20+
# - version: "3.10"
21+
#
22+
# steps:
23+
# - uses: actions/checkout@v2
24+
# - uses: actions/setup-python@v2
25+
# with:
26+
# python-version: ${{ matrix.version }}
27+
# - name: Install
28+
# run: |
29+
# sudo apt update
30+
# sudo apt install -y --no-install-recommends --no-install-suggests libtoxcore-dev
31+
# - name: Build
32+
# run: python setup.py build_ext --inplace
33+
# - name: Test
34+
# run: PYTHONPATH=. python tests/tests.py
35+
#
36+
# coverage:
37+
# name: python-3.7-coverage
38+
# runs-on: ubuntu-latest
39+
#
40+
# steps:
41+
# - uses: actions/checkout@v2
42+
# - uses: actions/setup-python@v2
43+
# with:
44+
# python-version: "3.7"
45+
# - name: Install
46+
# run: |
47+
# sudo apt update
48+
# sudo apt install -y --no-install-recommends --no-install-suggests libtoxcore-dev
49+
# - name: Build
50+
# run: |
51+
# export CFLAGS="-fprofile-arcs -ftest-coverage"
52+
# python setup.py build_ext --inplace
53+
# - name: Test
54+
# run: PYTHONPATH=. python tests/tests.py
55+
# - name: Upload coverage
56+
# run: bash <(curl -s https://codecov.io/bash)
5757

5858
docker:
5959
runs-on: ubuntu-latest
@@ -63,16 +63,16 @@ jobs:
6363
- name: Build
6464
run: docker build -t pytox .
6565

66-
clang-analyze:
67-
runs-on: ubuntu-latest
68-
69-
steps:
70-
- uses: actions/checkout@v2
71-
- name: Install
72-
run: |
73-
sudo apt update
74-
sudo apt install -y --no-install-recommends --no-install-suggests libtoxcore-dev
75-
- name: Build
76-
run: |
77-
clang -fsyntax-only pytox/*.c -Werror -Weverything -Wno-reserved-id-macro -Wno-documentation-deprecated-sync -Wno-shorten-64-to-32 -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-conversion -Wno-padded -Wno-conversion $(pkg-config --cflags-only-I python3)
78-
clang --analyze pytox/*.c $(pkg-config --cflags-only-I python3)
66+
# clang-analyze:
67+
# runs-on: ubuntu-latest
68+
#
69+
# steps:
70+
# - uses: actions/checkout@v2
71+
# - name: Install
72+
# run: |
73+
# sudo apt update
74+
# sudo apt install -y --no-install-recommends --no-install-suggests libtoxcore-dev
75+
# - name: Build
76+
# run: |
77+
# clang -fsyntax-only pytox/*.c -Werror -Weverything -Wno-reserved-id-macro -Wno-documentation-deprecated-sync -Wno-shorten-64-to-32 -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-conversion -Wno-padded -Wno-conversion $(pkg-config --cflags-only-I python3)
78+
# clang --analyze pytox/*.c $(pkg-config --cflags-only-I python3)

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
.*.swp
77
*.so
88
*.o
9-
.tox
9+
*.tox
10+
.mypy_cache

AUTHORS

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
11
Developers
22
----------
3-
AZ Huang <aitjcize@gmail.com>
4-
Alexander van der Meij <alexandervdm@gliese.me>
5-
6-
Contributors
7-
------------
8-
Alexandre Viau <reazem@reazem.net>
9-
Jman012 <jman012guy@gmail.com>
3+
Iphigenia Df <iphydf@gmail.com>

BUILD.bazel

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
load("@rules_cc//cc:defs.bzl", "cc_binary")
1+
load("//third_party/python:build_defs.bzl", "pyx_library")
22
load("//tools/project:build_defs.bzl", "project")
33

4+
package(features = ["layering_check"])
5+
46
project()
57

6-
cc_binary(
7-
name = "pytox.so",
8-
srcs = glob([
9-
"pytox/*.c",
10-
"pytox/*.h",
11-
]),
12-
copts = [
13-
"-DENABLE_AV",
14-
"-Wno-strict-aliasing",
8+
genrule(
9+
name = "pytox/core",
10+
srcs = [
11+
"pytox/src/core.pyx",
12+
"//c-toxcore:tox/tox.h",
1513
],
16-
linkopts = select({
17-
"@toktok//tools/config:freebsd": ["-Wl,--version-script,$(location pytox.ld)"],
18-
"@toktok//tools/config:linux": ["-Wl,--version-script,$(location pytox.ld)"],
19-
"@toktok//tools/config:osx": [],
20-
}),
21-
linkshared = True,
22-
visibility = ["//visibility:public"],
23-
deps = [
24-
"pytox.ld",
25-
"//c-toxcore",
26-
"@python3//:python",
14+
outs = ["pytox/core.pyx"],
15+
cmd = "$(location //py_toxcore_c/tools:gen_api) $(location pytox/src/core.pyx) $(location //c-toxcore:tox/tox.h) > $@",
16+
tools = ["//py_toxcore_c/tools:gen_api"],
17+
)
18+
19+
pyx_library(
20+
name = "pytox",
21+
srcs = [
22+
"pytox/av.pyx",
23+
"pytox/core.pyx",
2724
],
25+
cdeps = ["//c-toxcore"],
26+
cython_directives = {"language_level": "3"},
27+
visibility = ["//visibility:public"],
2828
)

Dockerfile

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,45 @@
1-
FROM ubuntu:18.04
1+
FROM ubuntu:20.04
22
LABEL maintainer="iphydf@gmail.com"
33

44
RUN apt-get update \
5-
&& apt-get install --no-install-recommends -y ca-certificates cmake gcc g++ git libopus-dev libsodium-dev libvpx-dev pkg-config python-dev \
5+
&& DEBIAN_FRONTEND="noninteractive" apt-get install --no-install-recommends -y \
6+
ca-certificates \
7+
cmake \
8+
cython \
9+
gcc \
10+
g++ \
11+
git \
12+
libopus-dev \
13+
libsodium-dev \
14+
libvpx-dev \
15+
ninja-build \
16+
pkg-config \
17+
python3 \
18+
python3-dev \
19+
python3-pip \
620
&& apt-get clean \
7-
&& rm -rf /var/lib/apt/lists/*
8-
9-
COPY pytox.ld setup.py /build/
10-
COPY pytox /build/pytox/
21+
&& rm -rf /var/lib/apt/lists/* \
22+
&& pip3 install mypy
1123

1224
WORKDIR /build
13-
RUN git clone https://github.com/TokTok/c-toxcore /build/c-toxcore \
14-
&& cmake -B/build/c-toxcore/_build -H/build/c-toxcore -DBOOTSTRAP_DAEMON=OFF -DMUST_BUILD_TOXAV=ON \
15-
&& make -C/build/c-toxcore/_build install -j"$(nproc)" \
16-
&& python setup.py install \
17-
&& rm -r /build/*
25+
RUN git clone --depth=1 https://github.com/TokTok/c-toxcore /build/c-toxcore \
26+
&& cmake -GNinja -B/build/c-toxcore/_build -H/build/c-toxcore \
27+
-DBOOTSTRAP_DAEMON=OFF \
28+
-DENABLE_STATIC=OFF \
29+
-DMUST_BUILD_TOXAV=ON \
30+
&& cmake --build /build/c-toxcore/_build --target install --parallel "$(nproc)" \
31+
&& ldconfig
32+
33+
COPY pytox /build/pytox
34+
COPY tools /build/tools
35+
36+
RUN mypy --strict tools/gen_api.py \
37+
&& tools/gen_api.py pytox/src/core.pyx /usr/local/include/tox/tox.h > pytox/core.pyx \
38+
&& cython pytox/av.pyx pytox/core.pyx
39+
40+
COPY setup.py /build/
41+
RUN python3 setup.py install \
42+
&& python3 -c 'from pytox import core; print(core.__doc__)'
43+
44+
COPY test /build/test
45+
RUN python3 test/core_test.py

MANIFEST.in

Lines changed: 0 additions & 7 deletions
This file was deleted.

README.md

Lines changed: 1 addition & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,5 @@
1-
[![Build Status](http://img.shields.io/travis/TokTok/py-toxcore-c.svg)](https://travis-ci.org/TokTok/py-toxcore-c)
2-
[![Coverage Status](https://coveralls.io/repos/github/TokTok/py-toxcore-c/badge.svg?branch=master)](https://coveralls.io/github/TokTok/py-toxcore-c?branch=master)
3-
41
# PyTox
52

63
Python binding for [Project Tox](https://github.com/TokTok/c-toxcore).
74

8-
Docker hub: <https://hub.docker.com/r/toxchat/py-toxcore-c/>
9-
10-
```sh
11-
docker pull toxchat/py-toxcore-c
12-
```
13-
14-
PyTox provides a Pythonic binding, i.e Object-oriented instead of C style, raise
15-
exception instead of returning error code. A simple example is as follows:
16-
17-
```python
18-
from pytox import Tox
19-
20-
class ToxOptions(object):
21-
def __init__(self):
22-
self.ipv6_enabled = True
23-
self.udp_enabled = True
24-
self.proxy_type = 0 # 1=http, 2=socks
25-
self.proxy_host = ''
26-
self.proxy_port = 0
27-
self.start_port = 0
28-
self.end_port = 0
29-
self.tcp_port = 0
30-
self.savedata_type = 0 # 1=toxsave, 2=secretkey
31-
self.savedata_data = b''
32-
self.savedata_length = 0
33-
34-
35-
class EchoBot(Tox):
36-
def __init__(self, opts):
37-
super(EchoBot, self).__init__(opts)
38-
39-
def loop(self):
40-
while True:
41-
self.iterate()
42-
time.sleep(0.03)
43-
44-
def on_friend_request(self, pk, message):
45-
print 'Friend request from %s: %s' % (pk, message)
46-
self.friend_add_norequest(pk)
47-
print 'Accepted.'
48-
49-
def on_friend_message(self, fid, message):
50-
name = self.self_get_name(fid)
51-
print '%s: %s' % (name, message)
52-
print 'EchoBot: %s' % message
53-
self.friend_send_message(fid, Tox.MESSAGE_TYPE_NORMAL, message)
54-
55-
56-
EchoBot(ToxOptions()).loop()
57-
```
58-
59-
As you can see callbacks are mapped into class method instead of using it the
60-
the c ways. For more details please refer to
61-
[examples/echo.py](https://github.com/TokTok/py-toxcore-c/blob/master/examples/echo.py).
62-
63-
## Getting started
64-
65-
To get started, a Makefile is provided to run PyTox inside a docker container:
66-
67-
- `make test`: This will launch tests in a container.
68-
- `make run`: This will launch an interactive container with PyTox installed.
69-
- `make echobot`: This will launch the example echobot in a container.
70-
71-
## Examples
72-
73-
- [echo.py](https://github.com/TokTok/py-toxcore-c/blob/master/examples/echo.py):
74-
A working echo bot that wait for friend requests, and than start echoing
75-
anything that friend send.
76-
77-
## Documentation
78-
79-
Full API documentation can be read [here](http://aitjcize.github.io/PyTox/).
80-
81-
## Todo
82-
83-
- Complete API binding (use tools/apicomplete.py to check)
84-
- Unittest for ToxAV
85-
86-
## Contributing
87-
88-
1. Fork it
89-
2. Create your feature branch (`git checkout -b my-new-feature`)
90-
3. Commit your changes (`git commit -am 'Add some feature'`)
91-
4. Push to the branch (`git push origin my-new-feature`)
92-
5. Create new Pull Request
5+
TODO: Docs.

0 commit comments

Comments
 (0)