Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support rust extensions for PyPy via cpyext #393

Merged
merged 158 commits into from
Apr 23, 2019
Merged
Show file tree
Hide file tree
Changes from 153 commits
Commits
Show all changes
158 commits
Select commit Hold shift + click to select a range
9193855
wip
omerbenamram Mar 15, 2018
e67df5d
removed stuff
omerbenamram Mar 17, 2018
c9d6967
removed another change
omerbenamram Mar 17, 2018
d44a07c
implemented minimum amouth of ifdefs to make pypy3 hello world to com…
omerbenamram Mar 17, 2018
409849d
implemented minimum amount of ifdefs to make pypy3 hello world to com…
omerbenamram Mar 17, 2018
04334e5
Merge remote-tracking branch 'origin/feature/add-build-pypy-support' …
omerbenamram Mar 18, 2018
61ecd79
hacking on build.rs
omerbenamram Mar 18, 2018
63a986e
compiler is happy!
omerbenamram Mar 18, 2018
b3540b6
few todos remain
omerbenamram Mar 18, 2018
661f6ca
extracted build logic to seperate module
omerbenamram Mar 29, 2018
1e70333
added pypy test
omerbenamram Mar 29, 2018
8e19baf
finally fixed pypy structs
omerbenamram Apr 2, 2018
94db8c0
Merge remote-tracking branch 'PyO3/master' into feature/add-build-pyp…
omerbenamram Apr 2, 2018
7ee426a
removed some todos
omerbenamram Apr 2, 2018
6f464aa
test should now be machine independent
omerbenamram Apr 2, 2018
7abadd9
fixed all pypy3 symbols
omerbenamram Apr 3, 2018
eb99b24
added pypy feature
omerbenamram Apr 3, 2018
94426a7
removed `is_pypy`
omerbenamram Apr 3, 2018
d730494
added pypy2 declerations also
omerbenamram Apr 3, 2018
e945127
fix for cpython2
omerbenamram Apr 3, 2018
1d7deca
improved libpypy detection
omerbenamram Apr 3, 2018
1fe3f75
added all pypy2 macros
omerbenamram Apr 3, 2018
2ffa0ff
fixed errneous type
omerbenamram Apr 3, 2018
0075593
more fixes
omerbenamram Apr 3, 2018
aa5cc32
fix python2 string macros
omerbenamram Apr 3, 2018
8517db4
modsupport symbol
omerbenamram Apr 3, 2018
bed2cc7
fix
omerbenamram Apr 3, 2018
ba8a36e
fixed and added many symbols
omerbenamram Apr 3, 2018
4ad11d8
fixes
omerbenamram Apr 3, 2018
f4deaf5
remove dup
omerbenamram Apr 3, 2018
11a1423
remove mac-specific config
omerbenamram Apr 5, 2018
aca3917
fix all name mangling macros
omerbenamram Apr 7, 2018
075f4a5
unite imports
omerbenamram Apr 7, 2018
e68815f
missing symbol
omerbenamram Apr 26, 2018
89fe0ad
fix pybool
omerbenamram Apr 26, 2018
642a305
implemented another missing symbol
omerbenamram Apr 26, 2018
f947dd9
Merge remote-tracking branch 'PyO3/master' into feature/add-build-pyp…
omerbenamram May 2, 2018
e0e4684
it works
omerbenamram May 2, 2018
fc68c4a
fix merge conflict
omerbenamram May 2, 2018
937be45
uncomment non default features
omerbenamram May 4, 2018
9907633
cargo.toml
omerbenamram Dec 28, 2018
5c0b56c
Cargo fmt
omerbenamram Dec 28, 2018
7209f1e
Merge master
omerbenamram Dec 28, 2018
26e964b
small merge fixes
omerbenamram Dec 28, 2018
c5525c4
use newer build version
omerbenamram Dec 28, 2018
2b7c1e1
whoops
omerbenamram Dec 28, 2018
3b1e5da
Merge branch 'feature/add-build-pypy-support' of https://github.com/o…
omerbenamram Mar 8, 2019
729a2dd
fix build script
omerbenamram Mar 8, 2019
d1f7b93
Merge branch 'master' into master-pypy
omerbenamram Mar 8, 2019
d362b08
more build hacks
omerbenamram Mar 9, 2019
dd5ed85
some random hiccups
omerbenamram Mar 9, 2019
b87338f
small fixes
omerbenamram Mar 9, 2019
dbd1501
it builds!
omerbenamram Mar 9, 2019
15d9e58
it builds and runs
omerbenamram Mar 9, 2019
30d02b3
revert everything in FFI2
omerbenamram Mar 9, 2019
5509039
revert changes to ffi2
omerbenamram Mar 9, 2019
160b88d
check python3 for pypy
omerbenamram Mar 9, 2019
4099f3b
tiny fix
omerbenamram Mar 9, 2019
1e29a83
revert ffi2 for real
omerbenamram Mar 9, 2019
cc3da82
revert weird formatting changes
omerbenamram Mar 9, 2019
0960f58
bring back missing feature
omerbenamram Mar 9, 2019
547d5bd
tiny error
omerbenamram Mar 9, 2019
ad0be3a
fix py3.7 issue
omerbenamram Mar 9, 2019
5c98585
add pypy3.5 6.0 to travis
omerbenamram Mar 9, 2019
3333285
remove dbg!
omerbenamram Mar 9, 2019
38d779c
another tiny fix
omerbenamram Mar 9, 2019
fbf309e
removed some useless annotations, and fixed inlines annotations
omerbenamram Mar 18, 2019
fde4b64
Merge branch 'master' into master-pypy
omerbenamram Mar 18, 2019
4c97d9f
removed `pretty_assertions`
omerbenamram Mar 18, 2019
623eaf9
removed pypy feature from cargo.toml
omerbenamram Mar 18, 2019
b6d8abd
fix for Py_CompileStringFlags
omerbenamram Mar 18, 2019
51cdfd2
tox runs word_count!
omerbenamram Mar 18, 2019
5a2de19
__dict__ changes are not supported for PyPy
omerbenamram Mar 18, 2019
1b9c891
fix 3.7 and copy comment
omerbenamram Mar 18, 2019
fd28250
fix test script :flushed:
omerbenamram Mar 18, 2019
fa5337b
transfer ownership of strings to cpython when possible
omerbenamram Mar 18, 2019
9c52eec
Merge branch 'master' into master-pypy
omerbenamram Mar 18, 2019
e38ef28
remove cstr! macro
omerbenamram Mar 18, 2019
45366e9
added missing nuls
omerbenamram Mar 18, 2019
e232135
as_bytes() -> b’’ string
omerbenamram Mar 18, 2019
bb67345
symbol removed by mistake
omerbenamram Mar 18, 2019
7fed8a2
properly shim pypy date time API, some tests are passing!
omerbenamram Mar 18, 2019
42d6582
extension_module tests now not crashing! (some still skipped)
omerbenamram Mar 18, 2019
7089632
Merge master
omerbenamram Mar 18, 2019
81edda0
maybe travis has new pypy version?
omerbenamram Mar 18, 2019
31e4673
small error on windows (build script)
omerbenamram Mar 18, 2019
6ce45f2
fix conditional compilation
omerbenamram Mar 18, 2019
75511cd
try to make tests run on travis..
omerbenamram Mar 18, 2019
fbab780
invert condition
omerbenamram Mar 18, 2019
0996930
added pytest-faulthandler to facilitate debugging
omerbenamram Mar 18, 2019
893c0da
correctly name dir
omerbenamram Mar 18, 2019
f20b1b1
use full paths
omerbenamram Mar 18, 2019
cabbde7
say —yes to conda
omerbenamram Mar 18, 2019
c70a1d7
fix
omerbenamram Mar 18, 2019
e02643a
syntax error
omerbenamram Mar 18, 2019
c12b502
change PATH
omerbenamram Mar 18, 2019
842d3b1
fixed a terrible bug with PyTypeObjects in PyPy
omerbenamram Mar 19, 2019
e9b6bf1
fix PyTypeObject defs
omerbenamram Mar 19, 2019
cc66fc5
re-enabled tests!
omerbenamram Mar 19, 2019
a070f8f
all tests are passing!
omerbenamram Mar 19, 2019
a73dc69
make the fix ad-hoc for now
omerbenamram Mar 20, 2019
500be63
removed build module
omerbenamram Mar 20, 2019
7a93316
Merge branch 'master' into master-pypy
omerbenamram Mar 20, 2019
f7d208c
revert changes that cause an additional GC bug
omerbenamram Mar 20, 2019
920caa7
prevented buggy test from failing pypy
omerbenamram Mar 20, 2019
db709d1
removed unused comment
omerbenamram Mar 20, 2019
2a882d9
don’t run coverage on pypy
omerbenamram Mar 20, 2019
5d90545
removed some erroneous symbols from function calls which are actually…
omerbenamram Mar 20, 2019
41a1d5a
restore py37 pyunicode missing def
omerbenamram Mar 21, 2019
855cc75
Merge branch 'master' into master-pypy
omerbenamram Mar 21, 2019
d4ecf8c
use only `link_name` in PyPy specific declarations
omerbenamram Mar 21, 2019
fc787e7
only setup PyPy when testing against PyPy
omerbenamram Mar 21, 2019
2a75e19
annotation that was eaten during merge
omerbenamram Mar 21, 2019
e829747
remove change to comment by mistake + unnecessary changes to cargo.toml
omerbenamram Mar 21, 2019
2d20f72
xfail dates test only on pypy
omerbenamram Mar 25, 2019
27fb0f3
changed comment to be a little more helpful
omerbenamram Mar 25, 2019
75c0748
cleaned up some warnings
omerbenamram Mar 25, 2019
cd19587
Merge branch 'master' into master-pypy
konstin Mar 28, 2019
acc04bc
Update src/ffi3/ceval.rs
konstin Mar 28, 2019
1649156
@konstin PR notes
omerbenamram Mar 28, 2019
75bf1e3
Merge branch 'master-pypy' of https://github.com/omerbenamram/pyo3 in…
omerbenamram Mar 28, 2019
c531532
rustfmt
omerbenamram Mar 28, 2019
4c59546
some documentation
omerbenamram Mar 28, 2019
c593526
if configured via env var only, default to cpython
omerbenamram Mar 28, 2019
7cc7857
remove extra unsafe
omerbenamram Mar 28, 2019
9859f9e
refer users to guide for pypy
omerbenamram Mar 28, 2019
d11040c
Update guide/src/pypy.md
konstin Mar 28, 2019
d2dea54
Update guide/src/pypy.md
konstin Mar 28, 2019
7bd3c95
@konstin applied patch
omerbenamram Mar 28, 2019
0bd24e5
Merge branch 'master-pypy' of https://github.com/omerbenamram/pyo3 in…
omerbenamram Mar 28, 2019
0a482fb
Merge branch 'master' into master-pypy
konstin Mar 29, 2019
197c879
check that pypy at least build
omerbenamram Apr 3, 2019
95df2b1
search explicitly for libpypy
omerbenamram Apr 3, 2019
ba64ebb
Merge branch 'master' into master-pypy
omerbenamram Apr 3, 2019
b3fab3c
added note about some known unsupported features
omerbenamram Apr 3, 2019
c9fd1f1
use ld_version
omerbenamram Apr 3, 2019
8795827
export PYTHON_SYS_EXECUTABLE to `cargo build` test
omerbenamram Apr 4, 2019
92211e2
inverted if
omerbenamram Apr 4, 2019
d173de6
always link pypy dynamically
omerbenamram Apr 4, 2019
3b099ea
remove unused imports
omerbenamram Apr 4, 2019
8137db2
Merge branch 'master' into master-pypy
omerbenamram Apr 9, 2019
f4b91d5
Merge branch 'master' into master-pypy
omerbenamram Apr 13, 2019
958a897
Apply @kngwyu’s suggestion
omerbenamram Apr 13, 2019
a054e0a
fix tox configuration
omerbenamram Apr 13, 2019
bc48760
try conda virtualenv
omerbenamram Apr 13, 2019
efc34df
try to simply not install python at all inside pypy environment
omerbenamram Apr 13, 2019
d971e62
setup pypy before using “python"
omerbenamram Apr 13, 2019
faf7640
use system_site_packages
omerbenamram Apr 13, 2019
1932dd0
revert change to .travis
omerbenamram Apr 13, 2019
addbe9e
moved cpyext datetime documentation to module level, and revised it.
omerbenamram Apr 17, 2019
f291d8a
Update src/ffi/datetime.rs
konstin Apr 17, 2019
00ba223
rustfmt
omerbenamram Apr 17, 2019
b4a379c
Merge branch 'master-pypy' of https://github.com/omerbenamram/pyo3 in…
omerbenamram Apr 17, 2019
e677f2d
Update src/ffi/datetime.rs
pganssle Apr 17, 2019
92b2377
kept only notes that are relevant to users.
omerbenamram Apr 17, 2019
a382f86
Merge branch 'master' into master-pypy
omerbenamram Apr 21, 2019
21bf3ad
invert if
omerbenamram Apr 21, 2019
7d665c4
use bash and not sh
omerbenamram Apr 21, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ matrix:
python: "3.7"
# Keep this synced up with build.rs
env: TRAVIS_RUST_VERSION=nightly-2019-02-07
# Tested via anaconda PyPy (since travis's PyPy version is too old)
- name: PyPy3.5 7.0
python: "3.7"
env: FEATURES="pypy" PATH="$PATH:/opt/anaconda/envs/pypy3/bin"
allow_failures:
- python: "3.8-dev"

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ A comparison with rust-cpython can be found [in the guide](https://pyo3.rs/maste

PyO3 supports Python 3.5 and up. The minimum required rust version is 1.34.0-nightly 2019-02-06.

PyPy is also supported (via cpyext) for Python 3.5 only, targeted PyPy version is 7.0.0.
Please refer to the guide for installation instruction against PyPy.

You can either write a native Python module in rust or use Python from a Rust binary.

However, on some OSs, you need some additional packages. E.g. if you are on *Ubuntu 18.04*, please run
Expand Down
159 changes: 129 additions & 30 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,18 @@ use version_check::{is_min_date, is_min_version, supports_features};
const MIN_DATE: &'static str = "2019-02-06";
const MIN_VERSION: &'static str = "1.34.0-nightly";

#[derive(Debug, Clone, PartialEq)]
pub enum PythonInterpreterKind {
CPython,
PyPy,
}

#[derive(Debug)]
struct PythonVersion {
major: u8,
// minor == None means any minor version will do
minor: Option<u8>,
implementation: PythonInterpreterKind,
}

impl PartialEq for PythonVersion {
Expand Down Expand Up @@ -142,6 +149,7 @@ fn load_cross_compile_info() -> Result<(PythonVersion, HashMap<String, String>,
let python_version = PythonVersion {
major,
minor: Some(minor),
implementation: PythonInterpreterKind::CPython,
};

let config_map = parse_header_defines(python_include_dir.join("pyconfig.h"))?;
Expand Down Expand Up @@ -280,17 +288,43 @@ fn run_python_script(interpreter: &str, script: &str) -> Result<String, String>
Ok(String::from_utf8(out.stdout).unwrap())
}

fn get_library_link_name(version: &PythonVersion, ld_version: &str) -> String {
if cfg!(target_os = "windows") {
let minor_or_empty_string = match version.minor {
Some(minor) => format!("{}", minor),
None => String::new(),
};
match version.implementation {
PythonInterpreterKind::CPython => {
format!("python{}{}", version.major, minor_or_empty_string)
}
PythonInterpreterKind::PyPy => format!("pypy{}-c", version.major),
}
} else {
match version.implementation {
PythonInterpreterKind::CPython => format!("python{}", ld_version),
PythonInterpreterKind::PyPy => format!("pypy{}-c", version.major),
}
}
}

#[cfg(not(target_os = "macos"))]
#[cfg(not(target_os = "windows"))]
fn get_rustc_link_lib(
_: &PythonVersion,
version: &PythonVersion,
ld_version: &str,
enable_shared: bool,
) -> Result<String, String> {
if enable_shared {
Ok(format!("cargo:rustc-link-lib=python{}", ld_version))
Ok(format!(
"cargo:rustc-link-lib={}",
get_library_link_name(&version, ld_version)
))
} else {
Ok(format!("cargo:rustc-link-lib=static=python{}", ld_version))
Ok(format!(
"cargo:rustc-link-lib=static={}",
get_library_link_name(&version, ld_version)
))
}
}

Expand All @@ -311,42 +345,63 @@ else:
}

#[cfg(target_os = "macos")]
fn get_rustc_link_lib(_: &PythonVersion, ld_version: &str, _: bool) -> Result<String, String> {
fn get_rustc_link_lib(
version: &PythonVersion,
ld_version: &str,
_: bool,
) -> Result<String, String> {
// os x can be linked to a framework or static or dynamic, and
// Py_ENABLE_SHARED is wrong; framework means shared library
match get_macos_linkmodel().unwrap().as_ref() {
"static" => Ok(format!("cargo:rustc-link-lib=static=python{}", ld_version)),
"shared" => Ok(format!("cargo:rustc-link-lib=python{}", ld_version)),
"framework" => Ok(format!("cargo:rustc-link-lib=python{}", ld_version)),
"static" => Ok(format!(
"cargo:rustc-link-lib=static={}",
get_library_link_name(&version, ld_version)
)),
"shared" => Ok(format!(
"cargo:rustc-link-lib={}",
get_library_link_name(&version, ld_version)
)),
"framework" => Ok(format!(
"cargo:rustc-link-lib={}",
get_library_link_name(&version, ld_version)
)),
other => Err(format!("unknown linkmodel {}", other)),
}
}

#[cfg(target_os = "windows")]
fn get_rustc_link_lib(
version: &PythonVersion,
ld_version: &str,
_: bool,
) -> Result<String, String> {
// Py_ENABLE_SHARED doesn't seem to be present on windows.
Ok(format!(
"cargo:rustc-link-lib=pythonXY:{}",
get_library_link_name(&version, ld_version)
))
}

/// Parse string as interpreter version.
fn get_interpreter_version(line: &str) -> Result<PythonVersion, String> {
fn get_interpreter_version(line: &str, implementation: &str) -> Result<PythonVersion, String> {
let version_re = Regex::new(r"\((\d+), (\d+)\)").unwrap();
match version_re.captures(&line) {
Some(cap) => Ok(PythonVersion {
major: cap.get(1).unwrap().as_str().parse().unwrap(),
minor: Some(cap.get(2).unwrap().as_str().parse().unwrap()),
implementation: match implementation {
"CPython" => PythonInterpreterKind::CPython,
"PyPy" => PythonInterpreterKind::PyPy,
_ => panic!(format!(
"Unsupported python implementation `{}`",
implementation
)),
},
}),
None => Err(format!("Unexpected response to version query {}", line)),
}
}

#[cfg(target_os = "windows")]
fn get_rustc_link_lib(version: &PythonVersion, _: &str, _: bool) -> Result<String, String> {
// Py_ENABLE_SHARED doesn't seem to be present on windows.
Ok(format!(
"cargo:rustc-link-lib=pythonXY:python{}{}",
version.major,
match version.minor {
Some(minor) => minor.to_string(),
None => "".to_owned(),
}
))
}

/// Locate a suitable python interpreter and extract config from it.
///
/// The following locations are checked in the order listed:
Expand Down Expand Up @@ -387,10 +442,17 @@ fn find_interpreter_and_get_config(
let expected_version = version.unwrap_or(PythonVersion {
major: 3,
minor: None,
implementation: PythonInterpreterKind::CPython,
});

let binary_name = match expected_version.implementation {
PythonInterpreterKind::CPython => "python",
PythonInterpreterKind::PyPy => "pypy",
};

// check default python
let interpreter_path = "python";
let interpreter_path = binary_name;

let (interpreter_version, lines) = get_config_from_interpreter(interpreter_path)?;
if expected_version == interpreter_version {
return Ok((
Expand Down Expand Up @@ -430,20 +492,45 @@ fn get_config_from_interpreter(interpreter: &str) -> Result<(PythonVersion, Vec<
let script = r#"
import sys
import sysconfig
import platform

PYPY = platform.python_implementation() == "PyPy"

print(sys.version_info[0:2])
print(sysconfig.get_config_var('LIBDIR'))
print(sysconfig.get_config_var('Py_ENABLE_SHARED'))
if PYPY:
print("1")
else:
print(sysconfig.get_config_var('Py_ENABLE_SHARED'))
print(sysconfig.get_config_var('LDVERSION') or sysconfig.get_config_var('py_version_short'))
print(sys.exec_prefix)
print(platform.python_implementation())
"#;
let out = run_python_script(interpreter, script)?;
let lines: Vec<String> = out.lines().map(|line| line.to_owned()).collect();
let interpreter_version = get_interpreter_version(&lines[0])?;
let interpreter_version = get_interpreter_version(&lines[0], &lines[5])?;
Ok((interpreter_version, lines))
}

fn ensure_python_version_is_supported(version: &PythonVersion) -> Result<(), String> {
match (&version.implementation, version.major, version.minor) {
(PythonInterpreterKind::PyPy, 2, _) => {
Err("PyPy cpyext bindings is only supported for Python3".to_string())
}
(_, 3, Some(minor)) if minor < PY3_MIN_MINOR => Err(format!(
"Python 3 required version is 3.{}, current version is 3.{}",
PY3_MIN_MINOR, minor
)),
_ => Ok(()),
}
}

fn configure(interpreter_version: &PythonVersion, lines: Vec<String>) -> Result<(String), String> {
ensure_python_version_is_supported(&interpreter_version).expect(&format!(
"Unsupported interpreter {:?}",
interpreter_version
));

let libpath: &str = &lines[1];
let enable_shared: &str = &lines[2];
let ld_version: &str = &lines[3];
Expand All @@ -464,26 +551,28 @@ fn configure(interpreter_version: &PythonVersion, lines: Vec<String>) -> Result<

let mut flags = String::new();

if interpreter_version.implementation == PythonInterpreterKind::PyPy {
println!("cargo:rustc-cfg=PyPy");
flags += format!("CFG_PyPy").as_ref();
};

if let PythonVersion {
major: 3,
minor: some_minor,
implementation: _,
} = interpreter_version
{
if env::var_os("CARGO_FEATURE_ABI3").is_some() {
println!("cargo:rustc-cfg=Py_LIMITED_API");
}

if let Some(minor) = some_minor {
if minor < &PY3_MIN_MINOR {
return Err(format!(
"Python 3 required version is 3.{}, current version is 3.{}",
PY3_MIN_MINOR, minor
));
}
for i in 5..(minor + 1) {
println!("cargo:rustc-cfg=Py_3_{}", i);
flags += format!("CFG_Py_3_{},", i).as_ref();
}
}
println!("cargo:rustc-cfg=Py_3");
} else {
// fail PYTHON_SYS_EXECUTABLE=python2 cargo ...
return Err("Python 2 is not supported".to_string());
Expand Down Expand Up @@ -512,6 +601,7 @@ fn version_from_env() -> Option<PythonVersion> {
Some(s) => Some(s.as_str().parse().unwrap()),
None => None,
},
implementation: PythonInterpreterKind::CPython,
});
}
None => (),
Expand Down Expand Up @@ -589,6 +679,15 @@ fn main() -> Result<(), String> {
}
}

// These flags need to be enabled manually for PyPy, because it does not expose
// them in `sysconfig.get_config_vars()`
if interpreter_version.implementation == PythonInterpreterKind::PyPy {
config_map.insert("WITH_THREAD".to_owned(), "1".to_owned());
config_map.insert("Py_USING_UNICODE".to_owned(), "1".to_owned());
config_map.insert("Py_UNICODE_SIZE".to_owned(), "4".to_owned());
config_map.insert("Py_UNICODE_WIDE".to_owned(), "1".to_owned());
}

// WITH_THREAD is always on for 3.7
if interpreter_version.major == 3 && interpreter_version.minor.unwrap_or(0) >= 7 {
config_map.insert("WITH_THREAD".to_owned(), "1".to_owned());
Expand Down
6 changes: 6 additions & 0 deletions ci/travis/cover.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

set -ex

### PyPy does not run the test suite ###########################################

if ! [[ $FEATURES == *"pypy"* ]]; then
konstin marked this conversation as resolved.
Show resolved Hide resolved
exit 0
fi

### Run kcov in parallel #######################################################

rm -f target/debug/pyo3*.d
Expand Down
23 changes: 21 additions & 2 deletions ci/travis/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,28 @@ if [ "$TRAVIS_JOB_NAME" = "Minimum nightly" ]; then
rustup component add rustfmt
fi

### Setup PyPy ################################################################

if [[ $FEATURES == *"pypy"* ]]; then
wget --quiet https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
/bin/bash Miniconda3-latest-Linux-x86_64.sh -f -b -p /opt/anaconda && \
/opt/anaconda/bin/conda install --quiet --yes conda && \
/opt/anaconda/bin/conda config --system --add channels conda-forge && \
/opt/anaconda/bin/conda init bash && \
/opt/anaconda/bin/conda create -n pypy3 pypy3.5 -y && \
/opt/anaconda/envs/pypy3/bin/pypy3 -m ensurepip && \
/opt/anaconda/envs/pypy3/bin/pypy3 -m pip install setuptools-rust pytest pytest-benchmark tox
fi

### Setup python linker flags ##################################################

PYTHON_LIB=$(python -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))")
if [[ $FEATURES == *"pypy"* ]]; then
PYTHON_BINARY="pypy3"
else
PYTHON_BINARY="python"
fi

PYTHON_LIB=$($PYTHON_BINARY -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))")

export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PYTHON_LIB:$HOME/rust/lib"

Expand All @@ -32,4 +51,4 @@ if [ ! -f "$HOME/.cargo/bin/kcov" ]; then
make
install src/kcov $HOME/.cargo/bin/kcov
cd $TRAVIS_BUILD_DIR
fi
fi
18 changes: 15 additions & 3 deletions ci/travis/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,25 @@
set -ex

cargo clean
cargo test --features "$FEATURES num-complex"
( cd pyo3-derive-backend; cargo test )

# run `cargo test` only if testing against cpython.
if ! [[ $FEATURES == *"pypy"* ]]; then
cargo test --features "$FEATURES num-complex"
( cd pyo3-derive-backend; cargo test )
else
# check that pypy at least builds
PYTHON_SYS_EXECUTABLE="/opt/anaconda/envs/pypy3/bin/pypy3" cargo build;
fi

if [ "$TRAVIS_JOB_NAME" = "Minimum nightly" ]; then
cargo fmt --all -- --check
cargo clippy --features "$FEATURES num-complex"
fi

for example_dir in examples/*; do
tox -c "$example_dir/tox.ini" -e py
if [[ $FEATURES == *"pypy"* ]]; then
tox -c "$example_dir/tox.ini" -e pypy3
else
tox -c "$example_dir/tox.ini" -e py
fi
done
4 changes: 4 additions & 0 deletions examples/rustapi_module/setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sys
import platform

from setuptools import setup
from setuptools.command.test import test as TestCommand
Expand All @@ -25,6 +26,9 @@ def get_py_version_cfgs():
for minor in range(py3_min, version[1] + 1):
out_cfg.append("--cfg=Py_3_%d" % minor)

if platform.python_implementation() == "PyPy":
out_cfg.append("--cfg=PyPy")

return out_cfg


Expand Down
Loading