From 8a295793a0a24d606f6ad0c81941ee96664982ec Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Fri, 12 May 2017 22:05:00 -0700 Subject: [PATCH] include py3 ffi info into crate --- Cargo.toml | 28 +- Makefile | 13 +- build.rs | 404 +++- python3-sys/.gitignore | 2 - python3-sys/Cargo.toml | 50 - python3-sys/build.rs | 428 ---- python3-sys/examples/version.rs | 15 - src/buffer.rs | 33 +- src/err.rs | 18 - {python3-sys => src/ffi}/LICENSE | 0 {python3-sys => src/ffi}/README.md | 0 {python3-sys/src => src/ffi}/bltinmodule.rs | 2 +- {python3-sys/src => src/ffi}/boolobject.rs | 6 +- .../src => src/ffi}/bytearrayobject.rs | 6 +- {python3-sys/src => src/ffi}/bytesobject.rs | 6 +- {python3-sys/src => src/ffi}/ceval.rs | 14 +- {python3-sys/src => src/ffi}/code.rs | 10 +- {python3-sys/src => src/ffi}/codecs.rs | 4 +- {python3-sys/src => src/ffi}/compile.rs | 10 +- {python3-sys/src => src/ffi}/complexobject.rs | 4 +- {python3-sys/src => src/ffi}/descrobject.rs | 8 +- {python3-sys/src => src/ffi}/dictobject.rs | 6 +- {python3-sys/src => src/ffi}/enumobject.rs | 2 +- {python3-sys/src => src/ffi}/eval.rs | 4 +- {python3-sys/src => src/ffi}/fileobject.rs | 4 +- {python3-sys/src => src/ffi}/floatobject.rs | 4 +- {python3-sys/src => src/ffi}/frameobject.rs | 8 +- {python3-sys/src => src/ffi}/genobject.rs | 12 +- {python3-sys/src => src/ffi}/import.rs | 4 +- {python3-sys/src => src/ffi}/intrcheck.rs | 0 {python3-sys/src => src/ffi}/iterobject.rs | 4 +- {python3-sys/src => src/ffi}/listobject.rs | 6 +- {python3-sys/src => src/ffi}/longobject.rs | 7 +- {python3-sys/src => src/ffi}/memoryobject.rs | 6 +- {python3-sys/src => src/ffi}/methodobject.rs | 8 +- python3-sys/src/lib.rs => src/ffi/mod.rs | 107 +- {python3-sys/src => src/ffi}/modsupport.rs | 10 +- {python3-sys/src => src/ffi}/moduleobject.rs | 8 +- {python3-sys/src => src/ffi}/object.rs | 253 +-- .../src => src/ffi}/objectabstract.rs | 10 +- {python3-sys/src => src/ffi}/objimpl.rs | 9 +- {python3-sys/src => src/ffi}/osmodule.rs | 2 +- {python3-sys/src => src/ffi}/pyarena.rs | 0 {python3-sys/src => src/ffi}/pycapsule.rs | 4 +- {python3-sys/src => src/ffi}/pydebug.rs | 0 {python3-sys/src => src/ffi}/pyerrors.rs | 6 +- {python3-sys/src => src/ffi}/pyhash.rs | 6 +- {python3-sys/src => src/ffi}/pymem.rs | 0 {python3-sys/src => src/ffi}/pyport.rs | 5 +- {python3-sys/src => src/ffi}/pystate.rs | 6 +- {python3-sys/src => src/ffi}/pystrtod.rs | 4 +- {python3-sys/src => src/ffi}/pythonrun.rs | 11 +- {python3-sys/src => src/ffi}/rangeobject.rs | 4 +- {python3-sys/src => src/ffi}/setobject.rs | 6 +- {python3-sys/src => src/ffi}/sliceobject.rs | 6 +- {python3-sys/src => src/ffi}/structmember.rs | 6 +- {python3-sys/src => src/ffi}/structseq.rs | 6 +- {python3-sys/src => src/ffi}/sysmodule.rs | 2 +- {python3-sys/src => src/ffi}/traceback.rs | 6 +- {python3-sys/src => src/ffi}/tupleobject.rs | 6 +- {python3-sys/src => src/ffi}/typeslots.rs | 0 {python3-sys/src => src/ffi}/unicodeobject.rs | 7 +- {python3-sys/src => src/ffi}/warnings.rs | 6 +- {python3-sys/src => src/ffi}/weakrefobject.rs | 4 +- src/lib.rs | 71 +- src/objectprotocol.rs | 25 - src/objects/bytearray.rs | 18 +- src/objects/exc.rs | 18 - src/objects/mod.rs | 14 - src/objects/num.rs | 91 - src/objects/slice.rs | 18 +- src/objects/string.rs | 183 +- src/objects/tests.rs | 2 +- src/py_class/gc.rs | 14 +- src/py_class/mod.rs | 11 +- .../{py_class_impl3.rs => py_class_impl.rs} | 0 src/py_class/py_class_impl2.rs | 1973 ----------------- src/py_class/slots.rs | 4 - tests/check_symbols.py | 2 +- tests/test_class.rs | 11 - 80 files changed, 752 insertions(+), 3339 deletions(-) delete mode 100644 python3-sys/.gitignore delete mode 100644 python3-sys/Cargo.toml delete mode 100644 python3-sys/build.rs delete mode 100644 python3-sys/examples/version.rs rename {python3-sys => src/ffi}/LICENSE (100%) rename {python3-sys => src/ffi}/README.md (100%) rename {python3-sys/src => src/ffi}/bltinmodule.rs (86%) rename {python3-sys/src => src/ffi}/boolobject.rs (87%) rename {python3-sys/src => src/ffi}/bytearrayobject.rs (92%) rename {python3-sys/src => src/ffi}/bytesobject.rs (95%) rename {python3-sys/src => src/ffi}/ceval.rs (85%) rename {python3-sys/src => src/ffi}/code.rs (93%) rename {python3-sys/src => src/ffi}/codecs.rs (96%) rename {python3-sys/src => src/ffi}/compile.rs (94%) rename {python3-sys/src => src/ffi}/complexobject.rs (92%) rename {python3-sys/src => src/ffi}/descrobject.rs (91%) rename {python3-sys/src => src/ffi}/dictobject.rs (97%) rename {python3-sys/src => src/ffi}/enumobject.rs (83%) rename {python3-sys/src => src/ffi}/eval.rs (92%) rename {python3-sys/src => src/ffi}/fileobject.rs (93%) rename {python3-sys/src => src/ffi}/floatobject.rs (92%) rename {python3-sys/src => src/ffi}/frameobject.rs (95%) rename {python3-sys/src => src/ffi}/genobject.rs (89%) rename {python3-sys/src => src/ffi}/import.rs (97%) rename {python3-sys/src => src/ffi}/intrcheck.rs (100%) rename {python3-sys/src => src/ffi}/iterobject.rs (92%) rename {python3-sys/src => src/ffi}/listobject.rs (95%) rename {python3-sys/src => src/ffi}/longobject.rs (93%) rename {python3-sys/src => src/ffi}/memoryobject.rs (89%) rename {python3-sys/src => src/ffi}/methodobject.rs (93%) rename python3-sys/src/lib.rs => src/ffi/mod.rs (75%) rename {python3-sys/src => src/ffi}/modsupport.rs (95%) rename {python3-sys/src => src/ffi}/moduleobject.rs (96%) rename {python3-sys/src => src/ffi}/object.rs (78%) rename {python3-sys/src => src/ffi}/objectabstract.rs (98%) rename {python3-sys/src => src/ffi}/objimpl.rs (95%) rename {python3-sys/src => src/ffi}/osmodule.rs (85%) rename {python3-sys/src => src/ffi}/pyarena.rs (100%) rename {python3-sys/src => src/ffi}/pycapsule.rs (96%) rename {python3-sys/src => src/ffi}/pydebug.rs (100%) rename {python3-sys/src => src/ffi}/pyerrors.rs (99%) rename {python3-sys/src => src/ffi}/pyhash.rs (77%) rename {python3-sys/src => src/ffi}/pymem.rs (100%) rename {python3-sys/src => src/ffi}/pyport.rs (56%) rename {python3-sys/src => src/ffi}/pystate.rs (94%) rename {python3-sys/src => src/ffi}/pystrtod.rs (93%) rename {python3-sys/src => src/ffi}/pythonrun.rs (98%) rename {python3-sys/src => src/ffi}/rangeobject.rs (88%) rename {python3-sys/src => src/ffi}/setobject.rs (95%) rename {python3-sys/src => src/ffi}/sliceobject.rs (94%) rename {python3-sys/src => src/ffi}/structmember.rs (95%) rename {python3-sys/src => src/ffi}/structseq.rs (90%) rename {python3-sys/src => src/ffi}/sysmodule.rs (97%) rename {python3-sys/src => src/ffi}/traceback.rs (74%) rename {python3-sys/src => src/ffi}/tupleobject.rs (96%) rename {python3-sys/src => src/ffi}/typeslots.rs (100%) rename {python3-sys/src => src/ffi}/unicodeobject.rs (99%) rename {python3-sys/src => src/ffi}/warnings.rs (90%) rename {python3-sys/src => src/ffi}/weakrefobject.rs (96%) rename src/py_class/{py_class_impl3.rs => py_class_impl.rs} (100%) delete mode 100644 src/py_class/py_class_impl2.rs diff --git a/Cargo.toml b/Cargo.toml index 7e6c33d2..6f12e171 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,43 +1,35 @@ [package] - -name = "cpython" +name = "pyo3" version = "0.1.0" description = "Bindings to Python" -authors = ["Daniel Grunwald "] +authors = ["PyO3 Project and Contributors $@ - -src/py_class/py_class_impl3.rs: src/py_class/py_class_impl.py +src/py_class/py_class_impl.rs: src/py_class/py_class_impl.py PY=3 python $< >$@ -cog: python27-sys/build.rs .travis.yml - cog.py -r $^ - -build: src/py_class/py_class_impl2.rs src/py_class/py_class_impl3.rs +build: src/py_class/py_class_impl.rs cargo build $(CARGO_FLAGS) test: build diff --git a/build.rs b/build.rs index 2d87257c..301c3af7 100644 --- a/build.rs +++ b/build.rs @@ -1,41 +1,385 @@ +extern crate regex; + +use std::process::Command; +use std::collections::HashMap; use std::env; -use std::io::Write; +use regex::Regex; +use std::fmt; + +#[derive(Debug)] +struct PythonVersion { + major: u8, + // minor == None means any minor version will do + minor: Option +} + +impl fmt::Display for PythonVersion { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + try!(self.major.fmt(f)); + try!(f.write_str(".")); + match self.minor { + Some(minor) => try!(minor.fmt(f)), + None => try!(f.write_str("*")) + }; + Ok(()) + } +} + +const MIN_MINOR: u8 = 4; const CFG_KEY: &'static str = "py_sys_config"; -#[cfg(feature="python3-sys")] -const PYTHONSYS_ENV_VAR: &'static str = "DEP_PYTHON3_PYTHON_FLAGS"; +// windows' python writes out lines with the windows crlf sequence; +// posix platforms and mac os should write out lines with just lf. +#[cfg(target_os="windows")] +static NEWLINE_SEQUENCE: &'static str = "\r\n"; -fn main() { - // python{27,3.x}-sys/build.rs passes python interpreter compile flags via - // environment variable (using the 'links' mechanism in the cargo.toml). - let flags = match env::var(PYTHONSYS_ENV_VAR) { - Ok(flags) => flags, - Err(_) => { - writeln!(std::io::stderr(), - "Environment variable {} not found - this is supposed to be \ - exported from the pythonXX-sys dependency, so the build chain is broken", - PYTHONSYS_ENV_VAR).unwrap(); - std::process::exit(1); +#[cfg(not(target_os="windows"))] +static NEWLINE_SEQUENCE: &'static str = "\n"; + +// A list of python interpreter compile-time preprocessor defines that +// we will pick up and pass to rustc via --cfg=py_sys_config={varname}; +// this allows using them conditional cfg attributes in the .rs files, so +// +// #[cfg(py_sys_config="{varname}"] +// +// is the equivalent of #ifdef {varname} name in C. +// +// see Misc/SpecialBuilds.txt in the python source for what these mean. +// +// (hrm, this is sort of re-implementing what distutils does, except +// by passing command line args instead of referring to a python.h) +#[cfg(not(target_os="windows"))] +static SYSCONFIG_FLAGS: [&'static str; 7] = [ + "Py_USING_UNICODE", + "Py_UNICODE_WIDE", + "WITH_THREAD", + "Py_DEBUG", + "Py_REF_DEBUG", + "Py_TRACE_REFS", + "COUNT_ALLOCS", +]; + +static SYSCONFIG_VALUES: [&'static str; 1] = [ + // cfg doesn't support flags with values, just bools - so flags + // below are translated into bools as {varname}_{val} + // + // for example, Py_UNICODE_SIZE_2 or Py_UNICODE_SIZE_4 + "Py_UNICODE_SIZE" // note - not present on python 3.3+, which is always wide +]; + +/// Examine python's compile flags to pass to cfg by launching +/// the interpreter and printing variables of interest from +/// sysconfig.get_config_vars. +#[cfg(not(target_os="windows"))] +fn get_config_vars(python_path: &String) -> Result, String> { + let mut script = "import sysconfig; \ +config = sysconfig.get_config_vars();".to_owned(); + + for k in SYSCONFIG_FLAGS.iter().chain(SYSCONFIG_VALUES.iter()) { + script.push_str(&format!("print(config.get('{}', {}))", k, + if is_value(k) { "None" } else { "0" } )); + script.push_str(";"); + } + + let mut cmd = Command::new(python_path); + cmd.arg("-c").arg(script); + + let out = try!(cmd.output().map_err(|e| { + format!("failed to run python interpreter `{:?}`: {}", cmd, e) + })); + + if !out.status.success() { + let stderr = String::from_utf8(out.stderr).unwrap(); + let mut msg = format!("python script failed with stderr:\n\n"); + msg.push_str(&stderr); + return Err(msg); + } + + let stdout = String::from_utf8(out.stdout).unwrap(); + let split_stdout: Vec<&str> = stdout.trim_right().split(NEWLINE_SEQUENCE).collect(); + if split_stdout.len() != SYSCONFIG_VALUES.len() + SYSCONFIG_FLAGS.len() { + return Err( + format!("python stdout len didn't return expected number of lines: +{}", split_stdout.len()).to_string()); + } + let all_vars = SYSCONFIG_FLAGS.iter().chain(SYSCONFIG_VALUES.iter()); + // let var_map: HashMap = HashMap::new(); + let mut all_vars = all_vars.zip(split_stdout.iter()) + .fold(HashMap::new(), |mut memo: HashMap, (&k, &v)| { + if !(v.to_owned() == "None" && is_value(k)) { + memo.insert(k.to_owned(), v.to_owned()); + } + memo + }); + + let debug = if let Some(val) = all_vars.get("Py_DEBUG") { val == "1" } else { false }; + if debug { + all_vars.insert("Py_REF_DEBUG".to_owned(), "1".to_owned()); + all_vars.insert("Py_TRACE_REFS".to_owned(), "1".to_owned()); + all_vars.insert("COUNT_ALLOCS".to_owned(), "1".to_owned()); + } + + Ok(all_vars) +} + +#[cfg(target_os="windows")] +fn get_config_vars(_: &String) -> Result, String> { + // sysconfig is missing all the flags on windows, so we can't actually + // query the interpreter directly for its build flags. + // + // For the time being, this is the flags as defined in the python source's + // PC\pyconfig.h. This won't work correctly if someone has built their + // python with a modified pyconfig.h - sorry if that is you, you will have + // to comment/uncomment the lines below. + let mut map: HashMap = HashMap::new(); + map.insert("Py_USING_UNICODE".to_owned(), "1".to_owned()); + map.insert("Py_UNICODE_WIDE".to_owned(), "0".to_owned()); + map.insert("WITH_THREAD".to_owned(), "1".to_owned()); + map.insert("Py_UNICODE_SIZE".to_owned(), "2".to_owned()); + + // This is defined #ifdef _DEBUG. The visual studio build seems to produce + // a specially named pythonXX_d.exe and pythonXX_d.dll when you build the + // Debug configuration, which this script doesn't currently support anyway. + // map.insert("Py_DEBUG", "1"); + + // Uncomment these manually if your python was built with these and you want + // the cfg flags to be set in rust. + // + // map.insert("Py_REF_DEBUG", "1"); + // map.insert("Py_TRACE_REFS", "1"); + // map.insert("COUNT_ALLOCS", 1"); + Ok(map) +} + +fn is_value(key: &str) -> bool { + SYSCONFIG_VALUES.iter().find(|x| **x == key).is_some() +} + +fn cfg_line_for_var(key: &str, val: &str) -> Option { + if is_value(key) { + // is a value; suffix the key name with the value + Some(format!("cargo:rustc-cfg={}=\"{}_{}\"\n", CFG_KEY, key, val)) + } else if val != "0" { + // is a flag that isn't zero + Some(format!("cargo:rustc-cfg={}=\"{}\"", CFG_KEY, key)) + } else { + // is a flag that is zero + None + } +} + +/// Run a python script using the specified interpreter binary. +fn run_python_script(interpreter: &str, script: &str) -> Result { + let mut cmd = Command::new(interpreter); + cmd.arg("-c").arg(script); + + let out = try!(cmd.output().map_err(|e| { + format!("failed to run python interpreter `{:?}`: {}", cmd, e) + })); + + if !out.status.success() { + let stderr = String::from_utf8(out.stderr).unwrap(); + let mut msg = format!("python script failed with stderr:\n\n"); + msg.push_str(&stderr); + return Err(msg); + } + + let out = String::from_utf8(out.stdout).unwrap(); + return Ok(out); +} + +#[cfg(not(target_os="macos"))] +#[cfg(not(target_os="windows"))] +fn get_rustc_link_lib(_: &PythonVersion, ld_version: &str, enable_shared: bool) -> Result { + if enable_shared { + Ok(format!("cargo:rustc-link-lib=python{}", ld_version)) + } else { + Ok(format!("cargo:rustc-link-lib=static=python{}", ld_version)) + } +} + +#[cfg(target_os="macos")] +fn get_macos_linkmodel() -> Result { + let script = "import sysconfig; print('framework' if sysconfig.get_config_var('PYTHONFRAMEWORK') else ('shared' if sysconfig.get_config_var('Py_ENABLE_SHARED') else 'static'));"; + let out = run_python_script("python", script).unwrap(); + Ok(out.trim_right().to_owned()) +} + +#[cfg(target_os="macos")] +fn get_rustc_link_lib(_: &PythonVersion, ld_version: &str, _: bool) -> Result { + // 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)), + other => Err(format!("unknown linkmodel {}", other)) + } +} + +/// Parse string as interpreter version. +fn get_interpreter_version(line: &str) -> Result { + let version_re = Regex::new(r"\((\d+), (\d+)\)").unwrap(); + match version_re.captures(&line) { + Some(cap) => Ok(PythonVersion { + major: cap.at(1).unwrap().parse().unwrap(), + minor: Some(cap.at(2).unwrap().parse().unwrap()) + }), + None => Err( + format!("Unexpected response to version query {}", line)) + } +} + +#[cfg(target_os="windows")] +fn get_rustc_link_lib(version: &PythonVersion, _: &str, _: bool) -> Result { + // 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. +/// If the environment variable `PYTHON_SYS_EXECUTABLE`, use the provided +/// path a Python executable, and raises an error if the version doesn't match. +/// Else tries to execute the interpreter as "python", "python{major version}", +/// "python{major version}.{minor version}" in order until one +/// is of the version we are expecting. +fn find_interpreter_and_get_config() -> Result<(PythonVersion, String, Vec), String> +{ + if let Some(sys_executable) = env::var_os("PYTHON_SYS_EXECUTABLE") { + println!("1111"); + let interpreter_path = sys_executable.to_str() + .expect("Unable to get PYTHON_SYS_EXECUTABLE value"); + let (interpreter_version, lines) = try!(get_config_from_interpreter(interpreter_path)); + + if MIN_MINOR > interpreter_version.minor.unwrap_or(0) { + return Err(format!("Unsupported python version in PYTHON_SYS_EXECUTABLE={}\n\ + \tmin version 3.4 != found {}", + interpreter_path, + interpreter_version)); + } else { + return Ok((interpreter_version, interpreter_path.to_owned(), lines)); } - }; + } - if flags.len() > 0 { - for f in flags.split(",") { - // write out flags as --cfg so that the same #cfg blocks can be used - // in rust-cpython as in the -sys libs - if f.starts_with("CFG") { - println!("cargo:rustc-cfg={}", &f[4..]) - } else { - let key_and_val: Vec<&str> = f.split("=").collect(); - let key = key_and_val[0]; - let val = key_and_val[1]; - if key.starts_with("FLAG") { - println!("cargo:rustc-cfg={}=\"{}\"", CFG_KEY, &key[5..]); - } else { - println!("cargo:rustc-cfg={}=\"{}_{}\"", CFG_KEY, &key[4..], val); - } + { + let interpreter_path = "python"; + let (interpreter_version, lines) = try!(get_config_from_interpreter(interpreter_path)); + if MIN_MINOR < interpreter_version.minor.unwrap_or(0) { + return Ok((interpreter_version, interpreter_path.to_owned(), lines)); + } + } + + Err(format!("No python interpreter found")) +} + +/// Extract compilation vars from the specified interpreter. +fn get_config_from_interpreter(interpreter: &str) -> Result<(PythonVersion, Vec), String> { + let script = "import sys; import sysconfig; print(sys.version_info[0:2]); \ +print(sysconfig.get_config_var('LIBDIR')); \ +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);"; + let out = try!(run_python_script(interpreter, script)); + let lines: Vec = out.split(NEWLINE_SEQUENCE).map(|line| line.to_owned()).collect(); + let interpreter_version = try!(get_interpreter_version(&lines[0])); + Ok((interpreter_version, lines)) +} + +/// Deduce configuration from the 'python' in the current PATH and print +/// cargo vars to stdout. +/// +/// Note that if the python doesn't satisfy expected_version, this will error. +fn configure_from_path() -> Result<(String, String), String> { + + let (interpreter_version, interpreter_path, lines) = try!( + find_interpreter_and_get_config()); + + let libpath: &str = &lines[1]; + let enable_shared: &str = &lines[2]; + let ld_version: &str = &lines[3]; + let exec_prefix: &str = &lines[4]; + + let is_extension_module = env::var_os("CARGO_FEATURE_EXTENSION_MODULE").is_some(); + if !is_extension_module || cfg!(target_os="windows") { + println!("{}", get_rustc_link_lib(&interpreter_version, + ld_version, enable_shared == "1").unwrap()); + if libpath != "None" { + println!("cargo:rustc-link-search=native={}", libpath); + } else if cfg!(target_os="windows") { + println!("cargo:rustc-link-search=native={}\\libs", exec_prefix); + } + } + + let mut flags = String::new(); + + println!("test: {:?}", interpreter_version); + if let PythonVersion { major: 3, minor: some_minor} = interpreter_version { + if env::var_os("CARGO_FEATURE_PEP_384").is_some() { + println!("cargo:rustc-cfg=Py_LIMITED_API"); + } + if let Some(minor) = some_minor { + for i in 4..(minor+1) { + println!("cargo:rustc-cfg=Py_3_{}", i); + flags += format!("CFG_Py_3_{},", i).as_ref(); } } } + return Ok((interpreter_path, flags)); +} + + +fn main() { + // 1. Setup cfg variables so we can do conditional compilation in this + // library based on the python interpeter's compilation flags. This is + // necessary for e.g. matching the right unicode and threading interfaces. + // + // This locates the python interpreter based on the PATH, which should + // work smoothly with an activated virtualenv. + // + // If you have troubles with your shell accepting '.' in a var name, + // try using 'env' (sorry but this isn't our fault - it just has to + // match the pkg-config package name, which is going to have a . in it). + let (python_interpreter_path, flags) = configure_from_path().unwrap(); + println!('3'); + let config_map = get_config_vars(&python_interpreter_path).unwrap(); + for (key, val) in &config_map { + match cfg_line_for_var(key, val) { + Some(line) => println!("{}", line), + None => () + } + } + + // 2. Export python interpreter compilation flags as cargo variables that + // will be visible to dependents. All flags will be available to dependent + // build scripts in the environment variable DEP_PYTHON27_PYTHON_FLAGS as + // comma separated list; each item in the list looks like + // + // {VAL,FLAG}_{flag_name}=val; + // + // FLAG indicates the variable is always 0 or 1 + // VAL indicates it can take on any value + // + // rust-cypthon/build.rs contains an example of how to unpack this data + // into cfg flags that replicate the ones present in this library, so + // you can use the same cfg syntax. + //let mut flags = flags; + let flags: String = config_map.iter().fold("".to_owned(), |memo, (key, val)| { + if is_value(key) { + memo + format!("VAL_{}={},", key, val).as_ref() + } else if val != "0" { + memo + format!("FLAG_{}={},", key, val).as_ref() + } else { + memo + } + }) + flags.as_str(); + + println!("cargo:python_flags={}", + if flags.len() > 0 { &flags[..flags.len()-1] } else { "" }); } diff --git a/python3-sys/.gitignore b/python3-sys/.gitignore deleted file mode 100644 index 4fffb2f8..00000000 --- a/python3-sys/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target -/Cargo.lock diff --git a/python3-sys/Cargo.toml b/python3-sys/Cargo.toml deleted file mode 100644 index 1672859d..00000000 --- a/python3-sys/Cargo.toml +++ /dev/null @@ -1,50 +0,0 @@ -[package] -name = "python3-sys" -version = "0.1.3" -description = "FFI Declarations for Python 3" -readme = "README.md" -keywords = [ - "python", - "cpython", - "libpython3", -] -homepage = "https://github.com/dgrunwald/rust-cpython/tree/master/python3-sys" -repository = "https://github.com/dgrunwald/rust-cpython/tree/master/python3-sys" -categories = ["external-ffi-bindings"] -license = "Python-2.0" -authors = ["Daniel Grunwald "] -links = "python3" -build = "build.rs" -exclude = [ - ".gitignore", - ".travis.yml", -] -workspace = ".." - -[dependencies] -libc = "0.2" - -[build-dependencies] -regex = "0.1" - -[features] -# This is examined by ./build.rs to determine which python version -# to try to bind to. -default = ["python-3"] - -# Use this feature when building an extension module. -# It tells the linker to keep the python symbols unresolved, -# so that the module can also be used with statically linked python interpreters. -extension-module = [ ] - -# Bind to any python 3.x. -python-3 = [] - -# Or, bind to a particular minor version. -python-3-4 = [] -python-3-5 = [] -python-3-6 = [] - -# Restrict to PEP-384 stable ABI -pep-384 = [] - diff --git a/python3-sys/build.rs b/python3-sys/build.rs deleted file mode 100644 index 46ead570..00000000 --- a/python3-sys/build.rs +++ /dev/null @@ -1,428 +0,0 @@ -extern crate regex; - -use std::process::Command; -use std::collections::HashMap; -use std::env; -use regex::Regex; -use std::fmt; - -struct PythonVersion { - major: u8, - // minor == None means any minor version will do - minor: Option -} - -impl fmt::Display for PythonVersion { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - try!(self.major.fmt(f)); - try!(f.write_str(".")); - match self.minor { - Some(minor) => try!(minor.fmt(f)), - None => try!(f.write_str("*")) - }; - Ok(()) - } -} - -const CFG_KEY: &'static str = "py_sys_config"; - -// windows' python writes out lines with the windows crlf sequence; -// posix platforms and mac os should write out lines with just lf. -#[cfg(target_os="windows")] -static NEWLINE_SEQUENCE: &'static str = "\r\n"; - -#[cfg(not(target_os="windows"))] -static NEWLINE_SEQUENCE: &'static str = "\n"; - -// A list of python interpreter compile-time preprocessor defines that -// we will pick up and pass to rustc via --cfg=py_sys_config={varname}; -// this allows using them conditional cfg attributes in the .rs files, so -// -// #[cfg(py_sys_config="{varname}"] -// -// is the equivalent of #ifdef {varname} name in C. -// -// see Misc/SpecialBuilds.txt in the python source for what these mean. -// -// (hrm, this is sort of re-implementing what distutils does, except -// by passing command line args instead of referring to a python.h) -#[cfg(not(target_os="windows"))] -static SYSCONFIG_FLAGS: [&'static str; 7] = [ - "Py_USING_UNICODE", - "Py_UNICODE_WIDE", - "WITH_THREAD", - "Py_DEBUG", - "Py_REF_DEBUG", - "Py_TRACE_REFS", - "COUNT_ALLOCS", -]; - -static SYSCONFIG_VALUES: [&'static str; 1] = [ - // cfg doesn't support flags with values, just bools - so flags - // below are translated into bools as {varname}_{val} - // - // for example, Py_UNICODE_SIZE_2 or Py_UNICODE_SIZE_4 - "Py_UNICODE_SIZE" // note - not present on python 3.3+, which is always wide -]; - -/// Examine python's compile flags to pass to cfg by launching -/// the interpreter and printing variables of interest from -/// sysconfig.get_config_vars. -#[cfg(not(target_os="windows"))] -fn get_config_vars(python_path: &String) -> Result, String> { - let mut script = "import sysconfig; \ -config = sysconfig.get_config_vars();".to_owned(); - - for k in SYSCONFIG_FLAGS.iter().chain(SYSCONFIG_VALUES.iter()) { - script.push_str(&format!("print(config.get('{}', {}))", k, - if is_value(k) { "None" } else { "0" } )); - script.push_str(";"); - } - - let mut cmd = Command::new(python_path); - cmd.arg("-c").arg(script); - - let out = try!(cmd.output().map_err(|e| { - format!("failed to run python interpreter `{:?}`: {}", cmd, e) - })); - - if !out.status.success() { - let stderr = String::from_utf8(out.stderr).unwrap(); - let mut msg = format!("python script failed with stderr:\n\n"); - msg.push_str(&stderr); - return Err(msg); - } - - let stdout = String::from_utf8(out.stdout).unwrap(); - let split_stdout: Vec<&str> = stdout.trim_right().split(NEWLINE_SEQUENCE).collect(); - if split_stdout.len() != SYSCONFIG_VALUES.len() + SYSCONFIG_FLAGS.len() { - return Err( - format!("python stdout len didn't return expected number of lines: -{}", split_stdout.len()).to_string()); - } - let all_vars = SYSCONFIG_FLAGS.iter().chain(SYSCONFIG_VALUES.iter()); - // let var_map: HashMap = HashMap::new(); - let mut all_vars = all_vars.zip(split_stdout.iter()) - .fold(HashMap::new(), |mut memo: HashMap, (&k, &v)| { - if !(v.to_owned() == "None" && is_value(k)) { - memo.insert(k.to_owned(), v.to_owned()); - } - memo - }); - - let debug = if let Some(val) = all_vars.get("Py_DEBUG") { val == "1" } else { false }; - if debug { - all_vars.insert("Py_REF_DEBUG".to_owned(), "1".to_owned()); - all_vars.insert("Py_TRACE_REFS".to_owned(), "1".to_owned()); - all_vars.insert("COUNT_ALLOCS".to_owned(), "1".to_owned()); - } - - Ok(all_vars) -} - -#[cfg(target_os="windows")] -fn get_config_vars(_: &String) -> Result, String> { - // sysconfig is missing all the flags on windows, so we can't actually - // query the interpreter directly for its build flags. - // - // For the time being, this is the flags as defined in the python source's - // PC\pyconfig.h. This won't work correctly if someone has built their - // python with a modified pyconfig.h - sorry if that is you, you will have - // to comment/uncomment the lines below. - let mut map: HashMap = HashMap::new(); - map.insert("Py_USING_UNICODE".to_owned(), "1".to_owned()); - map.insert("Py_UNICODE_WIDE".to_owned(), "0".to_owned()); - map.insert("WITH_THREAD".to_owned(), "1".to_owned()); - map.insert("Py_UNICODE_SIZE".to_owned(), "2".to_owned()); - - // This is defined #ifdef _DEBUG. The visual studio build seems to produce - // a specially named pythonXX_d.exe and pythonXX_d.dll when you build the - // Debug configuration, which this script doesn't currently support anyway. - // map.insert("Py_DEBUG", "1"); - - // Uncomment these manually if your python was built with these and you want - // the cfg flags to be set in rust. - // - // map.insert("Py_REF_DEBUG", "1"); - // map.insert("Py_TRACE_REFS", "1"); - // map.insert("COUNT_ALLOCS", 1"); - Ok(map) -} - -fn is_value(key: &str) -> bool { - SYSCONFIG_VALUES.iter().find(|x| **x == key).is_some() -} - -fn cfg_line_for_var(key: &str, val: &str) -> Option { - if is_value(key) { - // is a value; suffix the key name with the value - Some(format!("cargo:rustc-cfg={}=\"{}_{}\"\n", CFG_KEY, key, val)) - } else if val != "0" { - // is a flag that isn't zero - Some(format!("cargo:rustc-cfg={}=\"{}\"", CFG_KEY, key)) - } else { - // is a flag that is zero - None - } -} - -/// Run a python script using the specified interpreter binary. -fn run_python_script(interpreter: &str, script: &str) -> Result { - let mut cmd = Command::new(interpreter); - cmd.arg("-c").arg(script); - - let out = try!(cmd.output().map_err(|e| { - format!("failed to run python interpreter `{:?}`: {}", cmd, e) - })); - - if !out.status.success() { - let stderr = String::from_utf8(out.stderr).unwrap(); - let mut msg = format!("python script failed with stderr:\n\n"); - msg.push_str(&stderr); - return Err(msg); - } - - let out = String::from_utf8(out.stdout).unwrap(); - return Ok(out); -} - -#[cfg(not(target_os="macos"))] -#[cfg(not(target_os="windows"))] -fn get_rustc_link_lib(_: &PythonVersion, ld_version: &str, enable_shared: bool) -> Result { - if enable_shared { - Ok(format!("cargo:rustc-link-lib=python{}", ld_version)) - } else { - Ok(format!("cargo:rustc-link-lib=static=python{}", ld_version)) - } -} - -#[cfg(target_os="macos")] -fn get_macos_linkmodel() -> Result { - let script = "import sysconfig; print('framework' if sysconfig.get_config_var('PYTHONFRAMEWORK') else ('shared' if sysconfig.get_config_var('Py_ENABLE_SHARED') else 'static'));"; - let out = run_python_script("python", script).unwrap(); - Ok(out.trim_right().to_owned()) -} - -#[cfg(target_os="macos")] -fn get_rustc_link_lib(_: &PythonVersion, ld_version: &str, _: bool) -> Result { - // 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)), - other => Err(format!("unknown linkmodel {}", other)) - } -} - -/// Parse string as interpreter version. -fn get_interpreter_version(line: &str) -> Result { - let version_re = Regex::new(r"\((\d+), (\d+)\)").unwrap(); - match version_re.captures(&line) { - Some(cap) => Ok(PythonVersion { - major: cap.at(1).unwrap().parse().unwrap(), - minor: Some(cap.at(2).unwrap().parse().unwrap()) - }), - None => Err( - format!("Unexpected response to version query {}", line)) - } -} - -#[cfg(target_os="windows")] -fn get_rustc_link_lib(version: &PythonVersion, _: &str, _: bool) -> Result { - // 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() - })) -} - -fn matching_version(expected_version: &PythonVersion, actual_version: &PythonVersion) -> bool { - actual_version.major == expected_version.major && - (expected_version.minor.is_none() || - actual_version.minor == expected_version.minor) -} - -/// Locate a suitable python interpreter and extract config from it. -/// If the environment variable `PYTHON_SYS_EXECUTABLE`, use the provided -/// path a Python executable, and raises an error if the version doesn't match. -/// Else tries to execute the interpreter as "python", "python{major version}", -/// "python{major version}.{minor version}" in order until one -/// is of the version we are expecting. -fn find_interpreter_and_get_config(expected_version: &PythonVersion) -> - Result<(PythonVersion, String, Vec), String> { - if let Some(sys_executable) = env::var_os("PYTHON_SYS_EXECUTABLE") { - let interpreter_path = sys_executable.to_str() - .expect("Unable to get PYTHON_SYS_EXECUTABLE value"); - let (interpreter_version, lines) = try!(get_config_from_interpreter(interpreter_path)); - if matching_version(expected_version, &interpreter_version) { - return Ok((interpreter_version, interpreter_path.to_owned(), lines)); - } else { - return Err(format!("Wrong python version in PYTHON_SYS_EXECUTABLE={}\n\ - \texpected {} != found {}", - interpreter_path, - expected_version, - interpreter_version)); - } - } - { - let interpreter_path = "python"; - let (interpreter_version, lines) = - try!(get_config_from_interpreter(interpreter_path)); - if matching_version(expected_version, &interpreter_version) { - return Ok((interpreter_version, interpreter_path.to_owned(), lines)); - } - } - { - let major_interpreter_path = &format!("python{}", expected_version.major); - let (interpreter_version, lines) = try!(get_config_from_interpreter( - major_interpreter_path)); - if matching_version(expected_version, &interpreter_version) { - return Ok((interpreter_version, major_interpreter_path.to_owned(), lines)); - } - } - if let Some(minor) = expected_version.minor { - let minor_interpreter_path = &format!("python{}.{}", - expected_version.major, minor); - let (interpreter_version, lines) = try!(get_config_from_interpreter( - minor_interpreter_path)); - if matching_version(expected_version, &interpreter_version) { - return Ok((interpreter_version, minor_interpreter_path.to_owned(), lines)); - } - } - Err(format!("No python interpreter found of version {}", - expected_version)) -} - -/// Extract compilation vars from the specified interpreter. -fn get_config_from_interpreter(interpreter: &str) -> Result<(PythonVersion, Vec), String> { - let script = "import sys; import sysconfig; print(sys.version_info[0:2]); \ -print(sysconfig.get_config_var('LIBDIR')); \ -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);"; - let out = try!(run_python_script(interpreter, script)); - let lines: Vec = out.split(NEWLINE_SEQUENCE).map(|line| line.to_owned()).collect(); - let interpreter_version = try!(get_interpreter_version(&lines[0])); - Ok((interpreter_version, lines)) -} - -/// Deduce configuration from the 'python' in the current PATH and print -/// cargo vars to stdout. -/// -/// Note that if the python doesn't satisfy expected_version, this will error. -fn configure_from_path(expected_version: &PythonVersion) -> Result<(String, String), String> { - let (interpreter_version, interpreter_path, lines) = - try!(find_interpreter_and_get_config(expected_version)); - let libpath: &str = &lines[1]; - let enable_shared: &str = &lines[2]; - let ld_version: &str = &lines[3]; - let exec_prefix: &str = &lines[4]; - - let is_extension_module = env::var_os("CARGO_FEATURE_EXTENSION_MODULE").is_some(); - if !is_extension_module || cfg!(target_os="windows") { - println!("{}", get_rustc_link_lib(&interpreter_version, - ld_version, enable_shared == "1").unwrap()); - if libpath != "None" { - println!("cargo:rustc-link-search=native={}", libpath); - } else if cfg!(target_os="windows") { - println!("cargo:rustc-link-search=native={}\\libs", exec_prefix); - } - } - - let mut flags = String::new(); - - if let PythonVersion { major: 3, minor: some_minor} = interpreter_version { - if env::var_os("CARGO_FEATURE_PEP_384").is_some() { - println!("cargo:rustc-cfg=Py_LIMITED_API"); - } - if let Some(minor) = some_minor { - for i in 4..(minor+1) { - println!("cargo:rustc-cfg=Py_3_{}", i); - flags += format!("CFG_Py_3_{},", i).as_ref(); - } - } - } - return Ok((interpreter_path, flags)); -} - -/// Determine the python version we're supposed to be building -/// from the features passed via the environment. -/// -/// The environment variable can choose to omit a minor -/// version if the user doesn't care. -fn version_from_env() -> Result { - let re = Regex::new(r"CARGO_FEATURE_PYTHON_(\d+)(_(\d+))?").unwrap(); - // sort env::vars so we get more explicit version specifiers first - // so if the user passes e.g. the python-3 feature and the python-3-5 - // feature, python-3-5 takes priority. - let mut vars = env::vars().collect::>(); - vars.sort_by(|a, b| b.cmp(a)); - for (key, _) in vars { - match re.captures(&key) { - Some(cap) => return Ok(PythonVersion { - major: cap.at(1).unwrap().parse().unwrap(), - minor: match cap.at(3) { - Some(s) => Some(s.parse().unwrap()), - None => None - } - }), - None => () - } - } - Err("Python version feature was not found. At least one python version \ - feature must be enabled.".to_owned()) -} - -fn main() { - // 1. Setup cfg variables so we can do conditional compilation in this - // library based on the python interpeter's compilation flags. This is - // necessary for e.g. matching the right unicode and threading interfaces. - // - // This locates the python interpreter based on the PATH, which should - // work smoothly with an activated virtualenv. - // - // If you have troubles with your shell accepting '.' in a var name, - // try using 'env' (sorry but this isn't our fault - it just has to - // match the pkg-config package name, which is going to have a . in it). - let version = version_from_env().unwrap(); - let (python_interpreter_path, flags) = configure_from_path(&version).unwrap(); - let config_map = get_config_vars(&python_interpreter_path).unwrap(); - for (key, val) in &config_map { - match cfg_line_for_var(key, val) { - Some(line) => println!("{}", line), - None => () - } - } - - // 2. Export python interpreter compilation flags as cargo variables that - // will be visible to dependents. All flags will be available to dependent - // build scripts in the environment variable DEP_PYTHON27_PYTHON_FLAGS as - // comma separated list; each item in the list looks like - // - // {VAL,FLAG}_{flag_name}=val; - // - // FLAG indicates the variable is always 0 or 1 - // VAL indicates it can take on any value - // - // rust-cypthon/build.rs contains an example of how to unpack this data - // into cfg flags that replicate the ones present in this library, so - // you can use the same cfg syntax. - //let mut flags = flags; - let flags: String = config_map.iter().fold("".to_owned(), |memo, (key, val)| { - if is_value(key) { - memo + format!("VAL_{}={},", key, val).as_ref() - } else if val != "0" { - memo + format!("FLAG_{}={},", key, val).as_ref() - } else { - memo - } - }) + flags.as_str(); - - println!("cargo:python_flags={}", - if flags.len() > 0 { &flags[..flags.len()-1] } else { "" }); -} diff --git a/python3-sys/examples/version.rs b/python3-sys/examples/version.rs deleted file mode 100644 index e418cf59..00000000 --- a/python3-sys/examples/version.rs +++ /dev/null @@ -1,15 +0,0 @@ -extern crate libc; -extern crate python3_sys; - -unsafe fn get_str<'a>(s: *const libc::c_char) -> &'a str { - let bytes = std::ffi::CStr::from_ptr(s).to_bytes(); - std::str::from_utf8(bytes).unwrap() -} - -fn main() { - unsafe { - python3_sys::Py_Initialize(); - println!("{}", get_str(python3_sys::Py_GetVersion())); - } -} - diff --git a/src/buffer.rs b/src/buffer.rs index 4a0a8feb..d63bae84 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -16,6 +16,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use std::os::raw; use std::{mem, slice, cell}; use std::ffi::CStr; use ffi; @@ -62,18 +63,18 @@ impl ElementType { fn native_element_type_from_type_char(type_char: u8) -> ElementType { use self::ElementType::*; match type_char { - b'c' => UnsignedInteger { bytes: mem::size_of::() }, - b'b' => SignedInteger { bytes: mem::size_of::() }, - b'B' => UnsignedInteger { bytes: mem::size_of::() }, + b'c' => UnsignedInteger { bytes: mem::size_of::() }, + b'b' => SignedInteger { bytes: mem::size_of::() }, + b'B' => UnsignedInteger { bytes: mem::size_of::() }, b'?' => Bool, - b'h' => SignedInteger { bytes: mem::size_of::() }, - b'H' => UnsignedInteger { bytes: mem::size_of::() }, - b'i' => SignedInteger { bytes: mem::size_of::() }, - b'I' => UnsignedInteger { bytes: mem::size_of::() }, - b'l' => SignedInteger { bytes: mem::size_of::() }, - b'L' => UnsignedInteger { bytes: mem::size_of::() }, - b'q' => SignedInteger { bytes: mem::size_of::() }, - b'Q' => UnsignedInteger { bytes: mem::size_of::() }, + b'h' => SignedInteger { bytes: mem::size_of::() }, + b'H' => UnsignedInteger { bytes: mem::size_of::() }, + b'i' => SignedInteger { bytes: mem::size_of::() }, + b'I' => UnsignedInteger { bytes: mem::size_of::() }, + b'l' => SignedInteger { bytes: mem::size_of::() }, + b'L' => UnsignedInteger { bytes: mem::size_of::() }, + b'q' => SignedInteger { bytes: mem::size_of::() }, + b'Q' => UnsignedInteger { bytes: mem::size_of::() }, b'n' => SignedInteger { bytes: mem::size_of::() }, b'N' => UnsignedInteger { bytes: mem::size_of::() }, b'e' => Float { bytes: 2 }, @@ -150,14 +151,14 @@ impl PyBuffer { /// Warning: the buffer memory might be mutated by other Python functions, /// and thus may only be accessed while the GIL is held. #[inline] - pub fn buf_ptr(&self) -> *mut libc::c_void { + pub fn buf_ptr(&self) -> *mut raw::c_void { self.0.buf } /// Gets a pointer to the specified item. /// /// If `indices.len() < self.dimensions()`, returns the start address of the sub-array at the specified dimension. - pub fn get_ptr(&self, indices: &[usize]) -> *mut libc::c_void { + pub fn get_ptr(&self, indices: &[usize]) -> *mut raw::c_void { let shape = &self.shape()[..indices.len()]; for i in 0..indices.len() { assert!(indices[i] < shape[i]); @@ -397,7 +398,7 @@ impl PyBuffer { } unsafe { err::error_on_minusone(py, ffi::PyBuffer_ToContiguous( - target.as_ptr() as *mut libc::c_void, + target.as_ptr() as *mut raw::c_void, &*self.0 as *const ffi::Py_buffer as *mut ffi::Py_buffer, self.0.len, fort as libc::c_char @@ -432,7 +433,7 @@ impl PyBuffer { // Copy the buffer into the uninitialized space in the vector. // Due to T:Copy, we don't need to be concerned with Drop impls. err::error_on_minusone(py, ffi::PyBuffer_ToContiguous( - vec.as_mut_ptr() as *mut libc::c_void, + vec.as_mut_ptr() as *mut raw::c_void, &*self.0 as *const ffi::Py_buffer as *mut ffi::Py_buffer, self.0.len, fort as libc::c_char @@ -484,7 +485,7 @@ impl PyBuffer { unsafe { err::error_on_minusone(py, ffi::PyBuffer_FromContiguous( &*self.0 as *const ffi::Py_buffer as *mut ffi::Py_buffer, - source.as_ptr() as *mut libc::c_void, + source.as_ptr() as *mut raw::c_void, self.0.len, fort as libc::c_char )) diff --git a/src/err.rs b/src/err.rs index 8576bb2f..51c021ab 100644 --- a/src/err.rs +++ b/src/err.rs @@ -20,8 +20,6 @@ use std; use python::{PythonObject, ToPythonPointer, Python, PythonObjectDowncastError, PythonObjectWithTypeObject, PyClone, PyDrop}; use objects::{PyObject, PyType, ToPyTuple, exc}; -#[cfg(feature="python27-sys")] -use objects::oldstyle::PyClass; use ffi; use libc; use std::ptr; @@ -330,22 +328,6 @@ impl PyErr { } /// Retrieves the exception type. - /// - /// If the exception type is an old-style class, returns `oldstyle::PyClass`. - #[cfg(feature="python27-sys")] - pub fn get_type(&self, py: Python) -> PyType { - match self.ptype.cast_as::(py) { - Ok(t) => t.clone_ref(py), - Err(_) => - match self.ptype.cast_as::(py) { - Ok(_) => py.get_type::(), - Err(_) => py.None().get_type(py) - } - } - } - - /// Retrieves the exception type. - #[cfg(not(feature="python27-sys"))] pub fn get_type(&self, py: Python) -> PyType { match self.ptype.cast_as::(py) { Ok(t) => t.clone_ref(py), diff --git a/python3-sys/LICENSE b/src/ffi/LICENSE similarity index 100% rename from python3-sys/LICENSE rename to src/ffi/LICENSE diff --git a/python3-sys/README.md b/src/ffi/README.md similarity index 100% rename from python3-sys/README.md rename to src/ffi/README.md diff --git a/python3-sys/src/bltinmodule.rs b/src/ffi/bltinmodule.rs similarity index 86% rename from python3-sys/src/bltinmodule.rs rename to src/ffi/bltinmodule.rs index 153e0c39..c99eac6d 100644 --- a/python3-sys/src/bltinmodule.rs +++ b/src/ffi/bltinmodule.rs @@ -1,4 +1,4 @@ -use object::PyTypeObject; +use ffi::object::PyTypeObject; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyFilter_Type: PyTypeObject; diff --git a/python3-sys/src/boolobject.rs b/src/ffi/boolobject.rs similarity index 87% rename from python3-sys/src/boolobject.rs rename to src/ffi/boolobject.rs index d4ab5f51..f30443c6 100644 --- a/python3-sys/src/boolobject.rs +++ b/src/ffi/boolobject.rs @@ -1,6 +1,6 @@ -use libc::{c_int, c_long}; -use object::*; -use longobject::PyLongObject; +use std::os::raw::{c_int, c_long}; +use ffi::object::*; +use ffi::longobject::PyLongObject; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyBool_Type: PyTypeObject; diff --git a/python3-sys/src/bytearrayobject.rs b/src/ffi/bytearrayobject.rs similarity index 92% rename from python3-sys/src/bytearrayobject.rs rename to src/ffi/bytearrayobject.rs index dc48942c..d5d28b6f 100644 --- a/python3-sys/src/bytearrayobject.rs +++ b/src/ffi/bytearrayobject.rs @@ -1,6 +1,6 @@ -use libc::{c_char, c_int}; -use object::*; -use pyport::Py_ssize_t; +use std::os::raw::{c_char, c_int}; +use ffi::object::*; +use ffi::pyport::Py_ssize_t; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyByteArray_Type: PyTypeObject; diff --git a/python3-sys/src/bytesobject.rs b/src/ffi/bytesobject.rs similarity index 95% rename from python3-sys/src/bytesobject.rs rename to src/ffi/bytesobject.rs index 4db51690..d2f2236a 100644 --- a/python3-sys/src/bytesobject.rs +++ b/src/ffi/bytesobject.rs @@ -1,6 +1,6 @@ -use libc::{c_char, c_int}; -use object::*; -use pyport::Py_ssize_t; +use std::os::raw::{c_char, c_int}; +use ffi::object::*; +use ffi::pyport::Py_ssize_t; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyBytes_Type: PyTypeObject; diff --git a/python3-sys/src/ceval.rs b/src/ffi/ceval.rs similarity index 85% rename from python3-sys/src/ceval.rs rename to src/ffi/ceval.rs index 8ced1230..57c26197 100644 --- a/python3-sys/src/ceval.rs +++ b/src/ffi/ceval.rs @@ -1,6 +1,6 @@ -use libc::{c_void, c_char, c_int}; -use object::PyObject; -use pystate::PyThreadState; +use std::os::raw::{c_void, c_char, c_int}; +use ffi::object::PyObject; +use ffi::pystate::PyThreadState; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub fn PyEval_CallObjectWithKeywords(func: *mut PyObject, @@ -11,7 +11,7 @@ use pystate::PyThreadState; #[inline] pub unsafe fn PyEval_CallObject(func: *mut PyObject, arg: *mut PyObject) -> *mut PyObject { - PyEval_CallObjectWithKeywords(func, arg, ::core::ptr::null_mut()) + PyEval_CallObjectWithKeywords(func, arg, ::std::ptr::null_mut()) } #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { @@ -25,7 +25,7 @@ pub unsafe fn PyEval_CallObject(func: *mut PyObject, arg: *mut PyObject) -> *mut pub fn PyEval_GetBuiltins() -> *mut PyObject; pub fn PyEval_GetGlobals() -> *mut PyObject; pub fn PyEval_GetLocals() -> *mut PyObject; - pub fn PyEval_GetFrame() -> *mut ::PyFrameObject; + pub fn PyEval_GetFrame() -> *mut ::ffi::PyFrameObject; pub fn Py_AddPendingCall(func: Option c_int>, arg: *mut c_void) -> c_int; pub fn Py_MakePendingCalls() -> c_int; @@ -43,8 +43,8 @@ pub unsafe fn PyEval_CallObject(func: *mut PyObject, arg: *mut PyObject) -> *mut pub fn PyEval_GetFuncName(arg1: *mut PyObject) -> *const c_char; pub fn PyEval_GetFuncDesc(arg1: *mut PyObject) -> *const c_char; pub fn PyEval_GetCallStats(arg1: *mut PyObject) -> *mut PyObject; - pub fn PyEval_EvalFrame(arg1: *mut ::PyFrameObject) -> *mut PyObject; - pub fn PyEval_EvalFrameEx(f: *mut ::PyFrameObject, exc: c_int) + pub fn PyEval_EvalFrame(arg1: *mut ::ffi::PyFrameObject) -> *mut PyObject; + pub fn PyEval_EvalFrameEx(f: *mut ::ffi::PyFrameObject, exc: c_int) -> *mut PyObject; pub fn PyEval_SaveThread() -> *mut PyThreadState; pub fn PyEval_RestoreThread(arg1: *mut PyThreadState) -> (); diff --git a/python3-sys/src/code.rs b/src/ffi/code.rs similarity index 93% rename from python3-sys/src/code.rs rename to src/ffi/code.rs index ea22f859..83770434 100644 --- a/python3-sys/src/code.rs +++ b/src/ffi/code.rs @@ -1,6 +1,6 @@ -use libc::{c_void, c_uchar, c_char, c_int}; -use pyport::Py_ssize_t; -use object::*; +use std::os::raw::{c_void, c_uchar, c_char, c_int}; +use ffi::pyport::Py_ssize_t; +use ffi::object::*; #[repr(C)] #[derive(Copy)] @@ -34,7 +34,7 @@ impl Clone for PyCodeObject { #[inline] fn clone(&self) -> Self { *self } } impl Default for PyCodeObject { - #[inline] fn default() -> Self { unsafe { ::core::mem::zeroed() } } + #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } } } /* Masks for co_flags */ @@ -98,6 +98,6 @@ pub unsafe fn PyCode_Check(op : *mut PyObject) -> c_int { #[inline] pub unsafe fn PyCode_GetNumFree(op : *mut PyCodeObject) -> Py_ssize_t { - ::tupleobject::PyTuple_GET_SIZE((*op).co_freevars) + ::ffi::tupleobject::PyTuple_GET_SIZE((*op).co_freevars) } diff --git a/python3-sys/src/codecs.rs b/src/ffi/codecs.rs similarity index 96% rename from python3-sys/src/codecs.rs rename to src/ffi/codecs.rs index 618374ee..5bf44130 100644 --- a/python3-sys/src/codecs.rs +++ b/src/ffi/codecs.rs @@ -1,5 +1,5 @@ -use libc::{c_char, c_int}; -use object::PyObject; +use std::os::raw::{c_char, c_int}; +use ffi::object::PyObject; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub fn PyCodec_Register(search_function: *mut PyObject) -> c_int; diff --git a/python3-sys/src/compile.rs b/src/ffi/compile.rs similarity index 94% rename from python3-sys/src/compile.rs rename to src/ffi/compile.rs index 9e49a7a9..d3d5b31c 100644 --- a/python3-sys/src/compile.rs +++ b/src/ffi/compile.rs @@ -1,8 +1,8 @@ -use libc::{c_char, c_int}; -use object::PyObject; -use pythonrun::*; -use code::*; -use pyarena::*; +use std::os::raw::{c_char, c_int}; +use ffi::object::PyObject; +use ffi::pythonrun::*; +use ffi::code::*; +use ffi::pyarena::*; #[repr(C)] #[derive(Copy, Clone)] diff --git a/python3-sys/src/complexobject.rs b/src/ffi/complexobject.rs similarity index 92% rename from python3-sys/src/complexobject.rs rename to src/ffi/complexobject.rs index 4aef697e..17642a47 100644 --- a/python3-sys/src/complexobject.rs +++ b/src/ffi/complexobject.rs @@ -1,5 +1,5 @@ -use libc::{c_double, c_int}; -use object::*; +use std::os::raw::{c_double, c_int}; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyComplex_Type: PyTypeObject; diff --git a/python3-sys/src/descrobject.rs b/src/ffi/descrobject.rs similarity index 91% rename from python3-sys/src/descrobject.rs rename to src/ffi/descrobject.rs index e6b927ca..9b7f20ff 100644 --- a/python3-sys/src/descrobject.rs +++ b/src/ffi/descrobject.rs @@ -1,7 +1,7 @@ -use libc::{c_void, c_char, c_int}; -use object::{PyObject, PyTypeObject}; -use structmember::PyMemberDef; -use methodobject::PyMethodDef; +use std::os::raw::{c_void, c_char, c_int}; +use ffi::object::{PyObject, PyTypeObject}; +use ffi::structmember::PyMemberDef; +use ffi::methodobject::PyMethodDef; pub type getter = unsafe extern "C" fn diff --git a/python3-sys/src/dictobject.rs b/src/ffi/dictobject.rs similarity index 97% rename from python3-sys/src/dictobject.rs rename to src/ffi/dictobject.rs index b8d947d1..d23e149a 100644 --- a/python3-sys/src/dictobject.rs +++ b/src/ffi/dictobject.rs @@ -1,6 +1,6 @@ -use libc::{c_char, c_int}; -use pyport::Py_ssize_t; -use object::*; +use std::os::raw::{c_char, c_int}; +use ffi::pyport::Py_ssize_t; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyDict_Type: PyTypeObject; diff --git a/python3-sys/src/enumobject.rs b/src/ffi/enumobject.rs similarity index 83% rename from python3-sys/src/enumobject.rs rename to src/ffi/enumobject.rs index 0de07b3c..b5762a6f 100644 --- a/python3-sys/src/enumobject.rs +++ b/src/ffi/enumobject.rs @@ -1,4 +1,4 @@ -use object::PyTypeObject; +use ffi::object::PyTypeObject; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyEnum_Type: PyTypeObject; diff --git a/python3-sys/src/eval.rs b/src/ffi/eval.rs similarity index 92% rename from python3-sys/src/eval.rs rename to src/ffi/eval.rs index 36fa04f9..3b23dd27 100644 --- a/python3-sys/src/eval.rs +++ b/src/ffi/eval.rs @@ -1,5 +1,5 @@ -use libc::c_int; -use object::PyObject; +use std::os::raw::c_int; +use ffi::object::PyObject; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub fn PyEval_EvalCode(arg1: *mut PyObject, arg2: *mut PyObject, diff --git a/python3-sys/src/fileobject.rs b/src/ffi/fileobject.rs similarity index 93% rename from python3-sys/src/fileobject.rs rename to src/ffi/fileobject.rs index 2534c3a7..0caa08dd 100644 --- a/python3-sys/src/fileobject.rs +++ b/src/ffi/fileobject.rs @@ -1,5 +1,5 @@ -use libc::{c_char, c_int}; -use object::PyObject; +use std::os::raw::{c_char, c_int}; +use ffi::object::PyObject; pub const PY_STDIOTEXTMODE : &'static str = "b"; diff --git a/python3-sys/src/floatobject.rs b/src/ffi/floatobject.rs similarity index 92% rename from python3-sys/src/floatobject.rs rename to src/ffi/floatobject.rs index 0a37581f..d58a8d77 100644 --- a/python3-sys/src/floatobject.rs +++ b/src/ffi/floatobject.rs @@ -1,5 +1,5 @@ -use libc::{c_int, c_double}; -use object::*; +use std::os::raw::{c_int, c_double}; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyFloat_Type: PyTypeObject; diff --git a/python3-sys/src/frameobject.rs b/src/ffi/frameobject.rs similarity index 95% rename from python3-sys/src/frameobject.rs rename to src/ffi/frameobject.rs index 44319ae4..cf973b77 100644 --- a/python3-sys/src/frameobject.rs +++ b/src/ffi/frameobject.rs @@ -1,7 +1,7 @@ -use libc::{c_char, c_int}; -use object::*; -use code::{PyCodeObject, CO_MAXBLOCKS}; -use pystate::PyThreadState; +use std::os::raw::{c_char, c_int}; +use ffi::object::*; +use ffi::code::{PyCodeObject, CO_MAXBLOCKS}; +use ffi::pystate::PyThreadState; #[repr(C)] #[derive(Copy, Clone)] diff --git a/python3-sys/src/genobject.rs b/src/ffi/genobject.rs similarity index 89% rename from python3-sys/src/genobject.rs rename to src/ffi/genobject.rs index e1a212f2..bf159265 100644 --- a/python3-sys/src/genobject.rs +++ b/src/ffi/genobject.rs @@ -1,7 +1,7 @@ -use libc::c_int; -use pyport::Py_ssize_t; -use object::*; -use frameobject::PyFrameObject; +use std::os::raw::c_int; +use ffi::pyport::Py_ssize_t; +use ffi::object::*; +use ffi::frameobject::PyFrameObject; #[repr(C)] #[derive(Copy, Clone)] @@ -49,7 +49,7 @@ pub unsafe fn PyCoro_Check(op: *mut PyObject) -> c_int { } #[cfg(not(Py_3_5))] #[inline(always)] -pub unsafe fn PyCoro_Check(op: *mut PyObject) -> c_int { +pub unsafe fn PyCoro_Check(_op: *mut PyObject) -> c_int { 0 } @@ -65,7 +65,7 @@ pub unsafe fn PyCoroWrapper_Check(op: *mut PyObject) -> c_int { } #[cfg(not(Py_3_5))] #[inline(always)] -pub unsafe fn PyCoroWrapper_Check(op: *mut PyObject) -> c_int { +pub unsafe fn PyCoroWrapper_Check(_op: *mut PyObject) -> c_int { 0 } diff --git a/python3-sys/src/import.rs b/src/ffi/import.rs similarity index 97% rename from python3-sys/src/import.rs rename to src/ffi/import.rs index 7377f16c..5dd73a6e 100644 --- a/python3-sys/src/import.rs +++ b/src/ffi/import.rs @@ -1,5 +1,5 @@ -use libc::{c_char, c_int, c_long}; -use object::PyObject; +use std::os::raw::{c_char, c_int, c_long}; +use ffi::object::PyObject; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub fn PyImport_GetMagicNumber() -> c_long; diff --git a/python3-sys/src/intrcheck.rs b/src/ffi/intrcheck.rs similarity index 100% rename from python3-sys/src/intrcheck.rs rename to src/ffi/intrcheck.rs diff --git a/python3-sys/src/iterobject.rs b/src/ffi/iterobject.rs similarity index 92% rename from python3-sys/src/iterobject.rs rename to src/ffi/iterobject.rs index 8d282834..5679b7af 100644 --- a/python3-sys/src/iterobject.rs +++ b/src/ffi/iterobject.rs @@ -1,5 +1,5 @@ -use libc::c_int; -use object::*; +use std::os::raw::c_int; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PySeqIter_Type: PyTypeObject; diff --git a/python3-sys/src/listobject.rs b/src/ffi/listobject.rs similarity index 95% rename from python3-sys/src/listobject.rs rename to src/ffi/listobject.rs index 62ec4574..2f0b13e1 100644 --- a/python3-sys/src/listobject.rs +++ b/src/ffi/listobject.rs @@ -1,6 +1,6 @@ -use libc::c_int; -use pyport::Py_ssize_t; -use object::*; +use std::os::raw::c_int; +use ffi::pyport::Py_ssize_t; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyList_Type: PyTypeObject; diff --git a/python3-sys/src/longobject.rs b/src/ffi/longobject.rs similarity index 93% rename from python3-sys/src/longobject.rs rename to src/ffi/longobject.rs index 6b6e4557..74722767 100644 --- a/python3-sys/src/longobject.rs +++ b/src/ffi/longobject.rs @@ -1,6 +1,7 @@ -use libc::{c_void, c_char, c_int, c_long, c_ulong, c_longlong, c_ulonglong, c_double, size_t}; -use object::*; -use pyport::Py_ssize_t; +use libc::size_t; +use std::os::raw::{c_void, c_char, c_int, c_long, c_ulong, c_longlong, c_ulonglong, c_double}; +use ffi::object::*; +use ffi::pyport::Py_ssize_t; pub enum PyLongObject {} diff --git a/python3-sys/src/memoryobject.rs b/src/ffi/memoryobject.rs similarity index 89% rename from python3-sys/src/memoryobject.rs rename to src/ffi/memoryobject.rs index e840cd68..d4ca50ca 100644 --- a/python3-sys/src/memoryobject.rs +++ b/src/ffi/memoryobject.rs @@ -1,6 +1,6 @@ -use libc::{c_int, c_char}; -use pyport::Py_ssize_t; -use object::*; +use std::os::raw::{c_int, c_char}; +use ffi::pyport::Py_ssize_t; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyMemoryView_Type: PyTypeObject; diff --git a/python3-sys/src/methodobject.rs b/src/ffi/methodobject.rs similarity index 93% rename from python3-sys/src/methodobject.rs rename to src/ffi/methodobject.rs index 3713cb11..7f6167c2 100644 --- a/python3-sys/src/methodobject.rs +++ b/src/ffi/methodobject.rs @@ -1,6 +1,6 @@ -use libc::{c_char, c_int}; -use core::{mem, ptr}; -use object::{PyObject, PyTypeObject, Py_TYPE}; +use std::os::raw::{c_char, c_int}; +use std::{mem, ptr}; +use ffi::object::{PyObject, PyTypeObject, Py_TYPE}; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyCFunction_Type: PyTypeObject; @@ -20,7 +20,7 @@ pub type PyCFunction = pub type _PyCFunctionFast = unsafe extern "C" fn (slf: *mut PyObject, args: *mut *mut PyObject, - nargs: ::pyport::Py_ssize_t, kwnames: *mut PyObject) + nargs: ::ffi::pyport::Py_ssize_t, kwnames: *mut PyObject) -> *mut PyObject; pub type PyCFunctionWithKeywords = diff --git a/python3-sys/src/lib.rs b/src/ffi/mod.rs similarity index 75% rename from python3-sys/src/lib.rs rename to src/ffi/mod.rs index df2ca100..9817febd 100644 --- a/python3-sys/src/lib.rs +++ b/src/ffi/mod.rs @@ -1,4 +1,3 @@ -#![no_std] #![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)] #![cfg_attr(Py_LIMITED_API, allow(unused_imports))] @@ -9,68 +8,66 @@ // new: // Based on the headers of Python 3.3.0, 3.4.0 and 3.5.0. -extern crate libc; +pub use self::pyport::*; +pub use self::pymem::*; -pub use pyport::*; -pub use pymem::*; +pub use self::object::*; +pub use self::objimpl::*; +pub use self::typeslots::*; +pub use self::pyhash::*; -pub use object::*; -pub use objimpl::*; -pub use typeslots::*; -#[cfg(Py_3_4)] pub use pyhash::*; +pub use self::pydebug::*; -pub use pydebug::*; +pub use self::bytearrayobject::*; +pub use self::bytesobject::*; +pub use self::unicodeobject::*; +pub use self::longobject::*; +pub use self::boolobject::*; +pub use self::floatobject::*; +pub use self::complexobject::*; +pub use self::rangeobject::*; +pub use self::memoryobject::*; +pub use self::tupleobject::*; +pub use self::listobject::*; +pub use self::dictobject::*; +pub use self::enumobject::*; +pub use self::setobject::*; +pub use self::methodobject::*; +pub use self::moduleobject::*; +pub use self::fileobject::*; +pub use self::pycapsule::*; +pub use self::traceback::*; +pub use self::sliceobject::*; +pub use self::iterobject::*; +pub use self::descrobject::*; +pub use self::warnings::*; +pub use self::weakrefobject::*; +pub use self::structseq::*; +pub use self::genobject::*; -pub use bytearrayobject::*; -pub use bytesobject::*; -pub use unicodeobject::*; -pub use longobject::*; -pub use boolobject::*; -pub use floatobject::*; -pub use complexobject::*; -pub use rangeobject::*; -pub use memoryobject::*; -pub use tupleobject::*; -pub use listobject::*; -pub use dictobject::*; -pub use enumobject::*; -pub use setobject::*; -pub use methodobject::*; -pub use moduleobject::*; -pub use fileobject::*; -pub use pycapsule::*; -pub use traceback::*; -pub use sliceobject::*; -pub use iterobject::*; -pub use descrobject::*; -pub use warnings::*; -pub use weakrefobject::*; -pub use structseq::*; -pub use genobject::*; +pub use self::codecs::*; +pub use self::pyerrors::*; -pub use codecs::*; -pub use pyerrors::*; +pub use self::pystate::*; -pub use pystate::*; +pub use self::pyarena::*; +pub use self::modsupport::*; +pub use self::pythonrun::*; +pub use self::ceval::*; +pub use self::sysmodule::*; +#[cfg(Py_3_6)] pub use self::osmodule::*; +pub use self::intrcheck::*; +pub use self::import::*; -pub use pyarena::*; -pub use modsupport::*; -pub use pythonrun::*; -pub use ceval::*; -pub use sysmodule::*; -#[cfg(Py_3_6)] pub use osmodule::*; -pub use intrcheck::*; -pub use import::*; +pub use self::objectabstract::*; +pub use self::bltinmodule::*; -pub use objectabstract::*; -pub use bltinmodule::*; +pub use self::code::*; +pub use self::compile::*; +pub use self::eval::*; -pub use code::*; -pub use compile::*; -pub use eval::*; - -pub use pystrtod::*; -pub use frameobject::PyFrameObject; +pub use self::pystrtod::*; +pub use self::frameobject::PyFrameObject; mod pyport; // mod pymacro; contains nothing of interest for Rust @@ -87,7 +84,7 @@ mod pymem; mod object; mod objimpl; mod typeslots; -#[cfg(Py_3_4)] mod pyhash; +mod pyhash; mod pydebug; diff --git a/python3-sys/src/modsupport.rs b/src/ffi/modsupport.rs similarity index 95% rename from python3-sys/src/modsupport.rs rename to src/ffi/modsupport.rs index b393b284..55ae1dbf 100644 --- a/python3-sys/src/modsupport.rs +++ b/src/ffi/modsupport.rs @@ -1,9 +1,9 @@ -use libc::{c_char, c_int, c_long}; -use pyport::Py_ssize_t; -use object::PyObject; -use moduleobject::PyModuleDef; +use std::os::raw::{c_char, c_int, c_long}; +use ffi::pyport::Py_ssize_t; +use ffi::object::PyObject; +use ffi::moduleobject::PyModuleDef; #[cfg(Py_3_5)] -use methodobject::PyMethodDef; +use ffi::methodobject::PyMethodDef; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub fn PyArg_Parse(arg1: *mut PyObject, arg2: *const c_char, ...) diff --git a/python3-sys/src/moduleobject.rs b/src/ffi/moduleobject.rs similarity index 96% rename from python3-sys/src/moduleobject.rs rename to src/ffi/moduleobject.rs index a8e00acd..5934b6c3 100644 --- a/python3-sys/src/moduleobject.rs +++ b/src/ffi/moduleobject.rs @@ -1,7 +1,7 @@ -use libc::{c_char, c_int, c_void}; -use pyport::Py_ssize_t; -use object::*; -use methodobject::PyMethodDef; +use std::os::raw::{c_char, c_int, c_void}; +use ffi::pyport::Py_ssize_t; +use ffi::object::*; +use ffi::methodobject::PyMethodDef; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyModule_Type: PyTypeObject; diff --git a/python3-sys/src/object.rs b/src/ffi/object.rs similarity index 78% rename from python3-sys/src/object.rs rename to src/ffi/object.rs index 7fc52b11..2e5a3d1b 100644 --- a/python3-sys/src/object.rs +++ b/src/ffi/object.rs @@ -1,6 +1,6 @@ -use core::ptr; -use libc::{c_void, c_int, c_uint, c_ulong, c_char}; -use pyport::{Py_ssize_t, Py_hash_t}; +use std::ptr; +use std::os::raw::{c_void, c_int, c_uint, c_ulong, c_char}; +use ffi::pyport::{Py_ssize_t, Py_hash_t}; #[repr(C)] #[derive(Copy, Clone)] @@ -88,14 +88,14 @@ pub type objobjargproc = #[cfg(not(Py_LIMITED_API))] mod bufferinfo { - use libc::{c_void, c_int, c_char}; - use pyport::Py_ssize_t; + use std::os::raw::{c_void, c_int, c_char}; + use ffi::pyport::Py_ssize_t; #[repr(C)] #[derive(Copy)] pub struct Py_buffer { pub buf: *mut c_void, - pub obj: *mut ::object::PyObject, + pub obj: *mut ::PyObject, pub len: Py_ssize_t, pub itemsize: Py_ssize_t, pub readonly: c_int, @@ -110,17 +110,17 @@ mod bufferinfo { #[inline] fn clone(&self) -> Self { *self } } impl Default for Py_buffer { - #[inline] fn default() -> Self { unsafe { ::core::mem::zeroed() } } + #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } } } pub type getbufferproc = - unsafe extern "C" fn(arg1: *mut ::object::PyObject, - arg2: *mut Py_buffer, - arg3: c_int) - -> c_int; + unsafe extern "C" fn(arg1: *mut ::PyObject, + arg2: *mut Py_buffer, + arg3: c_int) + -> c_int; pub type releasebufferproc = - unsafe extern "C" fn(arg1: *mut ::object::PyObject, - arg2: *mut Py_buffer) -> (); + unsafe extern "C" fn(arg1: *mut ::PyObject, + arg2: *mut Py_buffer) -> (); /// Maximum number of dimensions pub const PyBUF_MAX_NDIM : c_int = 64; @@ -236,56 +236,57 @@ pub enum PyTypeObject { } #[cfg(not(Py_LIMITED_API))] mod typeobject { - use libc::{c_void, c_char, c_ulong, c_uint}; - use pyport::Py_ssize_t; + use ffi::{self, object}; + use std::os::raw::{c_void, c_char, c_ulong, c_uint}; + use ffi::pyport::Py_ssize_t; #[repr(C)] #[derive(Copy)] pub struct PyNumberMethods { - pub nb_add: Option<::object::binaryfunc>, - pub nb_subtract: Option<::object::binaryfunc>, - pub nb_multiply: Option<::object::binaryfunc>, - pub nb_remainder: Option<::object::binaryfunc>, - pub nb_divmod: Option<::object::binaryfunc>, - pub nb_power: Option<::object::ternaryfunc>, - pub nb_negative: Option<::object::unaryfunc>, - pub nb_positive: Option<::object::unaryfunc>, - pub nb_absolute: Option<::object::unaryfunc>, - pub nb_bool: Option<::object::inquiry>, - pub nb_invert: Option<::object::unaryfunc>, - pub nb_lshift: Option<::object::binaryfunc>, - pub nb_rshift: Option<::object::binaryfunc>, - pub nb_and: Option<::object::binaryfunc>, - pub nb_xor: Option<::object::binaryfunc>, - pub nb_or: Option<::object::binaryfunc>, - pub nb_int: Option<::object::unaryfunc>, + pub nb_add: Option, + pub nb_subtract: Option, + pub nb_multiply: Option, + pub nb_remainder: Option, + pub nb_divmod: Option, + pub nb_power: Option, + pub nb_negative: Option, + pub nb_positive: Option, + pub nb_absolute: Option, + pub nb_bool: Option, + pub nb_invert: Option, + pub nb_lshift: Option, + pub nb_rshift: Option, + pub nb_and: Option, + pub nb_xor: Option, + pub nb_or: Option, + pub nb_int: Option, pub nb_reserved: *mut c_void, - pub nb_float: Option<::object::unaryfunc>, - pub nb_inplace_add: Option<::object::binaryfunc>, - pub nb_inplace_subtract: Option<::object::binaryfunc>, - pub nb_inplace_multiply: Option<::object::binaryfunc>, - pub nb_inplace_remainder: Option<::object::binaryfunc>, - pub nb_inplace_power: Option<::object::ternaryfunc>, - pub nb_inplace_lshift: Option<::object::binaryfunc>, - pub nb_inplace_rshift: Option<::object::binaryfunc>, - pub nb_inplace_and: Option<::object::binaryfunc>, - pub nb_inplace_xor: Option<::object::binaryfunc>, - pub nb_inplace_or: Option<::object::binaryfunc>, - pub nb_floor_divide: Option<::object::binaryfunc>, - pub nb_true_divide: Option<::object::binaryfunc>, - pub nb_inplace_floor_divide: Option<::object::binaryfunc>, - pub nb_inplace_true_divide: Option<::object::binaryfunc>, - pub nb_index: Option<::object::unaryfunc>, + pub nb_float: Option, + pub nb_inplace_add: Option, + pub nb_inplace_subtract: Option, + pub nb_inplace_multiply: Option, + pub nb_inplace_remainder: Option, + pub nb_inplace_power: Option, + pub nb_inplace_lshift: Option, + pub nb_inplace_rshift: Option, + pub nb_inplace_and: Option, + pub nb_inplace_xor: Option, + pub nb_inplace_or: Option, + pub nb_floor_divide: Option, + pub nb_true_divide: Option, + pub nb_inplace_floor_divide: Option, + pub nb_inplace_true_divide: Option, + pub nb_index: Option, #[cfg(Py_3_5)] - pub nb_matrix_multiply: Option<::object::binaryfunc>, + pub nb_matrix_multiply: Option, #[cfg(Py_3_5)] - pub nb_inplace_matrix_multiply: Option<::object::binaryfunc>, + pub nb_inplace_matrix_multiply: Option, } impl Clone for PyNumberMethods { #[inline] fn clone(&self) -> Self { *self } } impl Default for PyNumberMethods { - #[inline] fn default() -> Self { unsafe { ::core::mem::zeroed() } } + #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } } } macro_rules! as_expr { ($e:expr) => {$e} } @@ -346,22 +347,22 @@ mod typeobject { #[repr(C)] #[derive(Copy)] pub struct PySequenceMethods { - pub sq_length: Option<::object::lenfunc>, - pub sq_concat: Option<::object::binaryfunc>, - pub sq_repeat: Option<::object::ssizeargfunc>, - pub sq_item: Option<::object::ssizeargfunc>, + pub sq_length: Option, + pub sq_concat: Option, + pub sq_repeat: Option, + pub sq_item: Option, pub was_sq_slice: *mut c_void, - pub sq_ass_item: Option<::object::ssizeobjargproc>, + pub sq_ass_item: Option, pub was_sq_ass_slice: *mut c_void, - pub sq_contains: Option<::object::objobjproc>, - pub sq_inplace_concat: Option<::object::binaryfunc>, - pub sq_inplace_repeat: Option<::object::ssizeargfunc>, + pub sq_contains: Option, + pub sq_inplace_concat: Option, + pub sq_inplace_repeat: Option, } impl Clone for PySequenceMethods { #[inline] fn clone(&self) -> Self { *self } } impl Default for PySequenceMethods { - #[inline] fn default() -> Self { unsafe { ::core::mem::zeroed() } } + #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } } } pub const PySequenceMethods_INIT : PySequenceMethods = PySequenceMethods { sq_length: None, @@ -378,15 +379,15 @@ mod typeobject { #[repr(C)] #[derive(Copy)] pub struct PyMappingMethods { - pub mp_length: Option<::object::lenfunc>, - pub mp_subscript: Option<::object::binaryfunc>, - pub mp_ass_subscript: Option<::object::objobjargproc>, + pub mp_length: Option, + pub mp_subscript: Option, + pub mp_ass_subscript: Option, } impl Clone for PyMappingMethods { #[inline] fn clone(&self) -> Self { *self } } impl Default for PyMappingMethods { - #[inline] fn default() -> Self { unsafe { ::core::mem::zeroed() } } + #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } } } pub const PyMappingMethods_INIT : PyMappingMethods = PyMappingMethods { mp_length: None, @@ -397,9 +398,9 @@ mod typeobject { #[derive(Copy)] #[cfg(Py_3_5)] pub struct PyAsyncMethods { - pub am_await: Option<::object::unaryfunc>, - pub am_aiter: Option<::object::unaryfunc>, - pub am_anext: Option<::object::unaryfunc>, + pub am_await: Option, + pub am_aiter: Option, + pub am_anext: Option, } #[cfg(Py_3_5)] impl Clone for PyAsyncMethods { @@ -407,7 +408,7 @@ mod typeobject { } #[cfg(Py_3_5)] impl Default for PyAsyncMethods { - #[inline] fn default() -> Self { unsafe { ::core::mem::zeroed() } } + #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } } } #[cfg(Py_3_5)] pub const PyAsyncMethods_INIT : PyAsyncMethods = PyAsyncMethods { @@ -418,14 +419,14 @@ mod typeobject { #[repr(C)] #[derive(Copy)] pub struct PyBufferProcs { - pub bf_getbuffer: Option<::object::getbufferproc>, - pub bf_releasebuffer: Option<::object::releasebufferproc>, + pub bf_getbuffer: Option, + pub bf_releasebuffer: Option, } impl Clone for PyBufferProcs { #[inline] fn clone(&self) -> Self { *self } } impl Default for PyBufferProcs { - #[inline] fn default() -> Self { unsafe { ::core::mem::zeroed() } } + #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } } } pub const PyBufferProcs_INIT : PyBufferProcs = PyBufferProcs { bf_getbuffer: None, @@ -435,58 +436,58 @@ mod typeobject { #[repr(C)] #[derive(Copy)] pub struct PyTypeObject { - pub ob_base: ::object::PyVarObject, + pub ob_base: object::PyVarObject, pub tp_name: *const c_char, pub tp_basicsize: Py_ssize_t, pub tp_itemsize: Py_ssize_t, - pub tp_dealloc: Option<::object::destructor>, - pub tp_print: Option<::object::printfunc>, - pub tp_getattr: Option<::object::getattrfunc>, - pub tp_setattr: Option<::object::setattrfunc>, + pub tp_dealloc: Option, + pub tp_print: Option, + pub tp_getattr: Option, + pub tp_setattr: Option, #[cfg(Py_3_5)] pub tp_as_async: *mut PyAsyncMethods, #[cfg(not(Py_3_5))] pub tp_reserved: *mut c_void, - pub tp_repr: Option<::object::reprfunc>, + pub tp_repr: Option, pub tp_as_number: *mut PyNumberMethods, pub tp_as_sequence: *mut PySequenceMethods, pub tp_as_mapping: *mut PyMappingMethods, - pub tp_hash: Option<::object::hashfunc>, - pub tp_call: Option<::object::ternaryfunc>, - pub tp_str: Option<::object::reprfunc>, - pub tp_getattro: Option<::object::getattrofunc>, - pub tp_setattro: Option<::object::setattrofunc>, + pub tp_hash: Option, + pub tp_call: Option, + pub tp_str: Option, + pub tp_getattro: Option, + pub tp_setattro: Option, pub tp_as_buffer: *mut PyBufferProcs, pub tp_flags: c_ulong, pub tp_doc: *const c_char, - pub tp_traverse: Option<::object::traverseproc>, - pub tp_clear: Option<::object::inquiry>, - pub tp_richcompare: Option<::object::richcmpfunc>, + pub tp_traverse: Option, + pub tp_clear: Option, + pub tp_richcompare: Option, pub tp_weaklistoffset: Py_ssize_t, - pub tp_iter: Option<::object::getiterfunc>, - pub tp_iternext: Option<::object::iternextfunc>, - pub tp_methods: *mut ::methodobject::PyMethodDef, - pub tp_members: *mut ::structmember::PyMemberDef, - pub tp_getset: *mut ::descrobject::PyGetSetDef, + pub tp_iter: Option, + pub tp_iternext: Option, + pub tp_methods: *mut ffi::methodobject::PyMethodDef, + pub tp_members: *mut ffi::structmember::PyMemberDef, + pub tp_getset: *mut ffi::descrobject::PyGetSetDef, pub tp_base: *mut PyTypeObject, - pub tp_dict: *mut ::object::PyObject, - pub tp_descr_get: Option<::object::descrgetfunc>, - pub tp_descr_set: Option<::object::descrsetfunc>, + pub tp_dict: *mut ffi::object::PyObject, + pub tp_descr_get: Option, + pub tp_descr_set: Option, pub tp_dictoffset: Py_ssize_t, - pub tp_init: Option<::object::initproc>, - pub tp_alloc: Option<::object::allocfunc>, - pub tp_new: Option<::object::newfunc>, - pub tp_free: Option<::object::freefunc>, - pub tp_is_gc: Option<::object::inquiry>, - pub tp_bases: *mut ::object::PyObject, - pub tp_mro: *mut ::object::PyObject, - pub tp_cache: *mut ::object::PyObject, - pub tp_subclasses: *mut ::object::PyObject, - pub tp_weaklist: *mut ::object::PyObject, - pub tp_del: Option<::object::destructor>, + pub tp_init: Option, + pub tp_alloc: Option, + pub tp_new: Option, + pub tp_free: Option, + pub tp_is_gc: Option, + pub tp_bases: *mut ffi::object::PyObject, + pub tp_mro: *mut ffi::object::PyObject, + pub tp_cache: *mut ffi::object::PyObject, + pub tp_subclasses: *mut ffi::object::PyObject, + pub tp_weaklist: *mut ffi::object::PyObject, + pub tp_del: Option, pub tp_version_tag: c_uint, #[cfg(Py_3_4)] - pub tp_finalize: Option<::object::destructor>, + pub tp_finalize: Option, #[cfg(py_sys_config="COUNT_ALLOCS")] pub tp_allocs: Py_ssize_t, #[cfg(py_sys_config="COUNT_ALLOCS")] @@ -506,8 +507,8 @@ mod typeobject { ($tp_as_async:ident, $($tail:tt)*) => { as_expr! { PyTypeObject { - ob_base: ::object::PyVarObject { - ob_base: ::object::PyObject_HEAD_INIT, + ob_base: ffi::object::PyVarObject { + ob_base: ffi::object::PyObject_HEAD_INIT, ob_size: 0 }, tp_name: 0 as *const c_char, @@ -528,7 +529,7 @@ mod typeobject { tp_getattro: None, tp_setattro: None, tp_as_buffer: 0 as *mut PyBufferProcs, - tp_flags: ::object::Py_TPFLAGS_DEFAULT, + tp_flags: ffi::object::Py_TPFLAGS_DEFAULT, tp_doc: 0 as *const c_char, tp_traverse: None, tp_clear: None, @@ -536,11 +537,11 @@ mod typeobject { tp_weaklistoffset: 0, tp_iter: None, tp_iternext: None, - tp_methods: 0 as *mut ::methodobject::PyMethodDef, - tp_members: 0 as *mut ::structmember::PyMemberDef, - tp_getset: 0 as *mut ::descrobject::PyGetSetDef, + tp_methods: 0 as *mut ffi::methodobject::PyMethodDef, + tp_members: 0 as *mut ffi::structmember::PyMemberDef, + tp_getset: 0 as *mut ffi::descrobject::PyGetSetDef, tp_base: 0 as *mut PyTypeObject, - tp_dict: 0 as *mut ::object::PyObject, + tp_dict: 0 as *mut ffi::object::PyObject, tp_descr_get: None, tp_descr_set: None, tp_dictoffset: 0, @@ -549,11 +550,11 @@ mod typeobject { tp_new: None, tp_free: None, tp_is_gc: None, - tp_bases: 0 as *mut ::object::PyObject, - tp_mro: 0 as *mut ::object::PyObject, - tp_cache: 0 as *mut ::object::PyObject, - tp_subclasses: 0 as *mut ::object::PyObject, - tp_weaklist: 0 as *mut ::object::PyObject, + tp_bases: 0 as *mut ffi::object::PyObject, + tp_mro: 0 as *mut ffi::object::PyObject, + tp_cache: 0 as *mut ffi::object::PyObject, + tp_subclasses: 0 as *mut ffi::object::PyObject, + tp_weaklist: 0 as *mut ffi::object::PyObject, tp_del: None, tp_version_tag: 0, $($tail)* @@ -610,23 +611,23 @@ mod typeobject { pub as_mapping: PyMappingMethods, pub as_sequence: PySequenceMethods, pub as_buffer: PyBufferProcs, - pub ht_name: *mut ::object::PyObject, - pub ht_slots: *mut ::object::PyObject, - pub ht_qualname: *mut ::object::PyObject, + pub ht_name: *mut ffi::object::PyObject, + pub ht_slots: *mut ffi::object::PyObject, + pub ht_qualname: *mut ffi::object::PyObject, pub ht_cached_keys: *mut c_void, } impl Clone for PyHeapTypeObject { #[inline] fn clone(&self) -> Self { *self } } impl Default for PyHeapTypeObject { - #[inline] fn default() -> Self { unsafe { ::core::mem::zeroed() } } + #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } } } #[inline] - pub unsafe fn PyHeapType_GET_MEMBERS(etype: *mut PyHeapTypeObject) -> *mut ::structmember::PyMemberDef { + pub unsafe fn PyHeapType_GET_MEMBERS(etype: *mut PyHeapTypeObject) -> *mut ffi::structmember::PyMemberDef { (etype as *mut c_char).offset( - (*::object::Py_TYPE(etype as *mut ::object::PyObject)).tp_basicsize as isize - ) as *mut ::structmember::PyMemberDef + (*ffi::object::Py_TYPE(etype as *mut ffi::object::PyObject)).tp_basicsize as isize + ) as *mut ffi::structmember::PyMemberDef } } #[cfg(not(Py_LIMITED_API))] @@ -642,7 +643,7 @@ impl Clone for PyType_Slot { fn clone(&self) -> PyType_Slot { *self } } impl Default for PyType_Slot { - fn default() -> PyType_Slot { unsafe { ::core::mem::zeroed() } } + fn default() -> PyType_Slot { unsafe { ::std::mem::zeroed() } } } #[repr(C)] @@ -658,7 +659,7 @@ impl Clone for PyType_Spec { fn clone(&self) -> PyType_Spec { *self } } impl Default for PyType_Spec { - fn default() -> PyType_Spec { unsafe { ::core::mem::zeroed() } } + fn default() -> PyType_Spec { unsafe { ::std::mem::zeroed() } } } #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { diff --git a/python3-sys/src/objectabstract.rs b/src/ffi/objectabstract.rs similarity index 98% rename from python3-sys/src/objectabstract.rs rename to src/ffi/objectabstract.rs index 6a0588a5..522751ea 100644 --- a/python3-sys/src/objectabstract.rs +++ b/src/ffi/objectabstract.rs @@ -1,7 +1,7 @@ -use libc::{c_void, c_char, c_int}; -use pyport::Py_ssize_t; -use core::ptr; -use object::*; +use std::ptr; +use std::os::raw::{c_void, c_char, c_int}; +use ffi::pyport::Py_ssize_t; +use ffi::object::*; #[inline] pub unsafe fn PyObject_DelAttrString(o: *mut PyObject, attr_name: *const c_char) -> c_int { @@ -115,7 +115,7 @@ pub unsafe fn PyObject_CheckBuffer(o: *mut PyObject) -> c_int { #[inline] pub unsafe fn PyIter_Check(o: *mut PyObject) -> c_int { (match (*(*o).ob_type).tp_iternext { - Some(tp_iternext) => tp_iternext as *const c_void != ::object::_PyObject_NextNotImplemented as *const c_void, + Some(tp_iternext) => tp_iternext as *const c_void != ::ffi::object::_PyObject_NextNotImplemented as *const c_void, None => false }) as c_int } diff --git a/python3-sys/src/objimpl.rs b/src/ffi/objimpl.rs similarity index 95% rename from python3-sys/src/objimpl.rs rename to src/ffi/objimpl.rs index f4cf5ba5..6731ba65 100644 --- a/python3-sys/src/objimpl.rs +++ b/src/ffi/objimpl.rs @@ -1,6 +1,7 @@ -use libc::{c_void, c_int, size_t}; -use pyport::Py_ssize_t; -use object::*; +use libc::size_t; +use std::os::raw::{c_void, c_int}; +use ffi::pyport::Py_ssize_t; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub fn PyObject_Malloc(size: size_t) -> *mut c_void; @@ -41,7 +42,7 @@ impl Clone for PyObjectArenaAllocator { } #[cfg(all(not(Py_LIMITED_API), Py_3_4))] impl Default for PyObjectArenaAllocator { - #[inline] fn default() -> Self { unsafe { ::core::mem::zeroed() } } + #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } } } #[cfg(all(not(Py_LIMITED_API), Py_3_4))] #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { diff --git a/python3-sys/src/osmodule.rs b/src/ffi/osmodule.rs similarity index 85% rename from python3-sys/src/osmodule.rs rename to src/ffi/osmodule.rs index 44d7e797..d3a7dc37 100644 --- a/python3-sys/src/osmodule.rs +++ b/src/ffi/osmodule.rs @@ -1,5 +1,5 @@ // This header is new in Python 3.6 -use object::PyObject; +use ffi::object::PyObject; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub fn PyOS_FSPath(path: *mut PyObject) -> *mut PyObject; diff --git a/python3-sys/src/pyarena.rs b/src/ffi/pyarena.rs similarity index 100% rename from python3-sys/src/pyarena.rs rename to src/ffi/pyarena.rs diff --git a/python3-sys/src/pycapsule.rs b/src/ffi/pycapsule.rs similarity index 96% rename from python3-sys/src/pycapsule.rs rename to src/ffi/pycapsule.rs index 35cd0136..ab9483a9 100644 --- a/python3-sys/src/pycapsule.rs +++ b/src/ffi/pycapsule.rs @@ -1,5 +1,5 @@ -use libc::{c_void, c_char, c_int}; -use object::*; +use std::os::raw::{c_void, c_char, c_int}; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyCapsule_Type: PyTypeObject; diff --git a/python3-sys/src/pydebug.rs b/src/ffi/pydebug.rs similarity index 100% rename from python3-sys/src/pydebug.rs rename to src/ffi/pydebug.rs diff --git a/python3-sys/src/pyerrors.rs b/src/ffi/pyerrors.rs similarity index 99% rename from python3-sys/src/pyerrors.rs rename to src/ffi/pyerrors.rs index 95567662..997b0068 100644 --- a/python3-sys/src/pyerrors.rs +++ b/src/ffi/pyerrors.rs @@ -1,6 +1,6 @@ -use libc::{c_char, c_int}; -use pyport::Py_ssize_t; -use object::*; +use std::os::raw::{c_char, c_int}; +use ffi::pyport::Py_ssize_t; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub fn PyErr_SetNone(arg1: *mut PyObject) -> (); diff --git a/python3-sys/src/pyhash.rs b/src/ffi/pyhash.rs similarity index 77% rename from python3-sys/src/pyhash.rs rename to src/ffi/pyhash.rs index d4eb1c15..b52a92c7 100644 --- a/python3-sys/src/pyhash.rs +++ b/src/ffi/pyhash.rs @@ -1,5 +1,5 @@ -use libc::{c_void, c_char, c_int}; -use pyport::{Py_ssize_t, Py_hash_t}; +use std::os::raw::{c_void, c_char, c_int}; +use ffi::pyport::{Py_ssize_t, Py_hash_t}; #[repr(C)] #[derive(Copy)] @@ -15,7 +15,7 @@ impl Clone for PyHash_FuncDef { #[inline] fn clone(&self) -> Self { *self } } impl Default for PyHash_FuncDef { - #[inline] fn default() -> Self { unsafe { ::core::mem::zeroed() } } + #[inline] fn default() -> Self { unsafe { ::std::mem::zeroed() } } } #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { diff --git a/python3-sys/src/pymem.rs b/src/ffi/pymem.rs similarity index 100% rename from python3-sys/src/pymem.rs rename to src/ffi/pymem.rs diff --git a/python3-sys/src/pyport.rs b/src/ffi/pyport.rs similarity index 56% rename from python3-sys/src/pyport.rs rename to src/ffi/pyport.rs index 9ac73372..ab3410af 100644 --- a/python3-sys/src/pyport.rs +++ b/src/ffi/pyport.rs @@ -6,6 +6,5 @@ pub type Py_ssize_t = ::libc::ssize_t; pub type Py_hash_t = Py_ssize_t; pub type Py_uhash_t = ::libc::size_t; -pub const PY_SSIZE_T_MIN : Py_ssize_t = ::core::isize::MIN as Py_ssize_t; -pub const PY_SSIZE_T_MAX : Py_ssize_t = ::core::isize::MAX as Py_ssize_t; - +pub const PY_SSIZE_T_MIN : Py_ssize_t = ::std::isize::MIN as Py_ssize_t; +pub const PY_SSIZE_T_MAX : Py_ssize_t = ::std::isize::MAX as Py_ssize_t; diff --git a/python3-sys/src/pystate.rs b/src/ffi/pystate.rs similarity index 94% rename from python3-sys/src/pystate.rs rename to src/ffi/pystate.rs index a7130123..822160d4 100644 --- a/python3-sys/src/pystate.rs +++ b/src/ffi/pystate.rs @@ -1,6 +1,6 @@ -use libc::{c_int, c_long}; -use object::PyObject; -use moduleobject::PyModuleDef; +use std::os::raw::{c_int, c_long}; +use ffi::object::PyObject; +use ffi::moduleobject::PyModuleDef; #[cfg(Py_3_6)] pub const MAX_CO_EXTRA_USERS: c_int = 255; diff --git a/python3-sys/src/pystrtod.rs b/src/ffi/pystrtod.rs similarity index 93% rename from python3-sys/src/pystrtod.rs rename to src/ffi/pystrtod.rs index e14cfa3b..a587383f 100644 --- a/python3-sys/src/pystrtod.rs +++ b/src/ffi/pystrtod.rs @@ -1,5 +1,5 @@ -use libc::{c_char, c_int, c_double}; -use object::PyObject; +use std::os::raw::{c_char, c_int, c_double}; +use ffi::object::PyObject; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub fn PyOS_string_to_double(str: *const c_char, diff --git a/python3-sys/src/pythonrun.rs b/src/ffi/pythonrun.rs similarity index 98% rename from python3-sys/src/pythonrun.rs rename to src/ffi/pythonrun.rs index 20a3fb17..f73faa78 100644 --- a/python3-sys/src/pythonrun.rs +++ b/src/ffi/pythonrun.rs @@ -1,9 +1,10 @@ -use libc::{c_char, c_int, wchar_t, FILE}; -use core::ptr; -use object::*; -use pystate::PyThreadState; +use std::os::raw::{c_char, c_int}; +use std::ptr; +use libc::{wchar_t, FILE}; +use ffi::object::*; +use ffi::pystate::PyThreadState; #[cfg(not(Py_LIMITED_API))] -use pyarena::PyArena; +use ffi::pyarena::PyArena; // TODO: PyCF_MASK etc. constants diff --git a/python3-sys/src/rangeobject.rs b/src/ffi/rangeobject.rs similarity index 88% rename from python3-sys/src/rangeobject.rs rename to src/ffi/rangeobject.rs index 7452a39c..5fb84996 100644 --- a/python3-sys/src/rangeobject.rs +++ b/src/ffi/rangeobject.rs @@ -1,5 +1,5 @@ -use libc::c_int; -use object::*; +use std::os::raw::c_int; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PyRange_Type: PyTypeObject; diff --git a/python3-sys/src/setobject.rs b/src/ffi/setobject.rs similarity index 95% rename from python3-sys/src/setobject.rs rename to src/ffi/setobject.rs index 08a536fe..31757418 100644 --- a/python3-sys/src/setobject.rs +++ b/src/ffi/setobject.rs @@ -1,6 +1,6 @@ -use libc::c_int; -use pyport::Py_ssize_t; -use object::*; +use std::os::raw::c_int; +use ffi::pyport::Py_ssize_t; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub static mut PySet_Type: PyTypeObject; diff --git a/python3-sys/src/sliceobject.rs b/src/ffi/sliceobject.rs similarity index 94% rename from python3-sys/src/sliceobject.rs rename to src/ffi/sliceobject.rs index 6be40b0f..f1e21802 100644 --- a/python3-sys/src/sliceobject.rs +++ b/src/ffi/sliceobject.rs @@ -1,6 +1,6 @@ -use libc::c_int; -use pyport::Py_ssize_t; -use object::*; +use std::os::raw::c_int; +use ffi::pyport::Py_ssize_t; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { static mut _Py_EllipsisObject: PyObject; diff --git a/python3-sys/src/structmember.rs b/src/ffi/structmember.rs similarity index 95% rename from python3-sys/src/structmember.rs rename to src/ffi/structmember.rs index 896cd1c6..bf88aa27 100644 --- a/python3-sys/src/structmember.rs +++ b/src/ffi/structmember.rs @@ -1,6 +1,6 @@ -use libc::{c_char, c_int}; -use pyport::Py_ssize_t; -use object::PyObject; +use std::os::raw::{c_char, c_int}; +use ffi::pyport::Py_ssize_t; +use ffi::object::PyObject; #[repr(C)] #[derive(Copy, Clone)] diff --git a/python3-sys/src/structseq.rs b/src/ffi/structseq.rs similarity index 90% rename from python3-sys/src/structseq.rs rename to src/ffi/structseq.rs index 30f07ff2..db678d3a 100644 --- a/python3-sys/src/structseq.rs +++ b/src/ffi/structseq.rs @@ -1,6 +1,6 @@ -use libc::{c_char, c_int}; -use pyport::Py_ssize_t; -use object::{PyObject, PyTypeObject}; +use std::os::raw::{c_char, c_int}; +use ffi::pyport::Py_ssize_t; +use ffi::object::{PyObject, PyTypeObject}; #[repr(C)] #[derive(Copy)] diff --git a/python3-sys/src/sysmodule.rs b/src/ffi/sysmodule.rs similarity index 97% rename from python3-sys/src/sysmodule.rs rename to src/ffi/sysmodule.rs index 908bc26c..f8a46fbf 100644 --- a/python3-sys/src/sysmodule.rs +++ b/src/ffi/sysmodule.rs @@ -1,5 +1,5 @@ use libc::{c_char, c_int, wchar_t}; -use object::PyObject; +use ffi::object::PyObject; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub fn PySys_GetObject(arg1: *const c_char) -> *mut PyObject; diff --git a/python3-sys/src/traceback.rs b/src/ffi/traceback.rs similarity index 74% rename from python3-sys/src/traceback.rs rename to src/ffi/traceback.rs index 1f646d97..c24bcb2d 100644 --- a/python3-sys/src/traceback.rs +++ b/src/ffi/traceback.rs @@ -1,8 +1,8 @@ -use libc::c_int; -use object::*; +use std::os::raw::c_int; +use ffi::object::*; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { - pub fn PyTraceBack_Here(arg1: *mut ::PyFrameObject) -> c_int; + pub fn PyTraceBack_Here(arg1: *mut ::ffi::PyFrameObject) -> c_int; pub fn PyTraceBack_Print(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int; diff --git a/python3-sys/src/tupleobject.rs b/src/ffi/tupleobject.rs similarity index 96% rename from python3-sys/src/tupleobject.rs rename to src/ffi/tupleobject.rs index 8b8e1cd7..253cacf6 100644 --- a/python3-sys/src/tupleobject.rs +++ b/src/ffi/tupleobject.rs @@ -1,6 +1,6 @@ -use libc::c_int; -use pyport::Py_ssize_t; -use object::*; +use std::os::raw::c_int; +use ffi::pyport::Py_ssize_t; +use ffi::object::*; #[repr(C)] #[cfg(not(Py_LIMITED_API))] diff --git a/python3-sys/src/typeslots.rs b/src/ffi/typeslots.rs similarity index 100% rename from python3-sys/src/typeslots.rs rename to src/ffi/typeslots.rs diff --git a/python3-sys/src/unicodeobject.rs b/src/ffi/unicodeobject.rs similarity index 99% rename from python3-sys/src/unicodeobject.rs rename to src/ffi/unicodeobject.rs index d8a615a3..6b41450c 100644 --- a/python3-sys/src/unicodeobject.rs +++ b/src/ffi/unicodeobject.rs @@ -1,6 +1,7 @@ -use libc::{c_void, c_char, c_int, wchar_t}; -use object::*; -use pyport::Py_ssize_t; +use libc::wchar_t; +use std::os::raw::{c_void, c_char, c_int}; +use ffi::object::*; +use ffi::pyport::Py_ssize_t; #[cfg(not(Py_LIMITED_API))] pub type Py_UNICODE = wchar_t; diff --git a/python3-sys/src/warnings.rs b/src/ffi/warnings.rs similarity index 90% rename from python3-sys/src/warnings.rs rename to src/ffi/warnings.rs index 7b6932f6..d2980572 100644 --- a/python3-sys/src/warnings.rs +++ b/src/ffi/warnings.rs @@ -1,6 +1,6 @@ -use libc::{c_char, c_int}; -use pyport::Py_ssize_t; -use object::PyObject; +use std::os::raw::{c_char, c_int}; +use ffi::pyport::Py_ssize_t; +use ffi::object::PyObject; #[cfg_attr(windows, link(name="pythonXY"))] extern "C" { pub fn PyErr_WarnEx(category: *mut PyObject, diff --git a/python3-sys/src/weakrefobject.rs b/src/ffi/weakrefobject.rs similarity index 96% rename from python3-sys/src/weakrefobject.rs rename to src/ffi/weakrefobject.rs index c8518b15..e0f9aa5e 100644 --- a/python3-sys/src/weakrefobject.rs +++ b/src/ffi/weakrefobject.rs @@ -1,5 +1,5 @@ -use libc::c_int; -use object::*; +use std::os::raw::c_int; +use ffi::object::*; pub enum PyWeakReference {} diff --git a/src/lib.rs b/src/lib.rs index 23d18285..3d5bf4d9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -80,12 +80,7 @@ extern crate libc; -#[cfg(feature="python27-sys")] -extern crate python27_sys as ffi; - -#[cfg(feature="python3-sys")] -extern crate python3_sys as ffi; - +pub mod ffi; pub use ffi::Py_ssize_t; pub use err::{PyErr, PyResult}; pub use objects::*; @@ -95,11 +90,6 @@ pub use conversion::{FromPyObject, RefFromPyObject, ToPyObject}; pub use py_class::{CompareOp}; pub use objectprotocol::{ObjectProtocol}; -#[cfg(feature="python27-sys")] -#[allow(non_camel_case_types)] -pub type Py_hash_t = libc::c_long; - -#[cfg(feature="python3-sys")] #[allow(non_camel_case_types)] pub type Py_hash_t = ffi::Py_hash_t; @@ -193,7 +183,7 @@ pub mod _detail { pub use ::ffi::*; } pub mod libc { - pub use ::libc::{c_char, c_void, c_int}; + pub use std::os::raw::{c_char, c_void, c_int}; } pub use err::{from_owned_ptr_or_panic, result_from_owned_ptr}; pub use function::{handle_callback, py_fn_impl, AbortOnDrop, @@ -256,66 +246,16 @@ pub mod _detail { /// ``` /// #[macro_export] -#[cfg(feature="python27-sys")] macro_rules! py_module_initializer { - ($name: ident, $py2: ident, $py3: ident, |$py_id: ident, $m_id: ident| $body: expr) => { + ($name: ident, $py3: ident, |$py_id: ident, $m_id: ident| $body: expr) => { #[no_mangle] #[allow(non_snake_case)] - pub unsafe extern "C" fn $py2() { + pub unsafe extern "C" fn $py3() -> *mut $crate::ffi::PyObject { // Nest init function so that $body isn't in unsafe context fn init($py_id: $crate::Python, $m_id: &$crate::PyModule) -> $crate::PyResult<()> { $body } - let name = concat!(stringify!($name), "\0").as_ptr() as *const _; - $crate::py_module_initializer_impl(name, init) - } - } -} - - -#[doc(hidden)] -#[cfg(feature="python27-sys")] -pub unsafe fn py_module_initializer_impl( - name: *const libc::c_char, - init: fn(Python, &PyModule) -> PyResult<()> -) { - let guard = function::AbortOnDrop("py_module_initializer"); - let py = Python::assume_gil_acquired(); - ffi::PyEval_InitThreads(); - let module = ffi::Py_InitModule(name, ptr::null_mut()); - if module.is_null() { - mem::forget(guard); - return; - } - - let module = match PyObject::from_borrowed_ptr(py, module).cast_into::(py) { - Ok(m) => m, - Err(e) => { - PyErr::from(e).restore(py); - mem::forget(guard); - return; - } - }; - let ret = match init(py, &module) { - Ok(()) => (), - Err(e) => e.restore(py) - }; - mem::forget(guard); - ret -} - -#[macro_export] -#[cfg(feature="python3-sys")] -macro_rules! py_module_initializer { - ($name: ident, $py2: ident, $py3: ident, |$py_id: ident, $m_id: ident| $body: expr) => { - #[no_mangle] - #[allow(non_snake_case)] - pub unsafe extern "C" fn $py3() -> *mut $crate::_detail::ffi::PyObject { - // Nest init function so that $body isn't in unsafe context - fn init($py_id: $crate::Python, $m_id: &$crate::PyModule) -> $crate::PyResult<()> { - $body - } - static mut MODULE_DEF: $crate::_detail::ffi::PyModuleDef = $crate::_detail::ffi::PyModuleDef_INIT; + static mut MODULE_DEF: $crate::ffi::PyModuleDef = $crate::_detail::ffi::PyModuleDef_INIT; // We can't convert &'static str to *const c_char within a static initializer, // so we'll do it here in the module initialization: MODULE_DEF.m_name = concat!(stringify!($name), "\0").as_ptr() as *const _; @@ -325,7 +265,6 @@ macro_rules! py_module_initializer { } #[doc(hidden)] -#[cfg(feature="python3-sys")] pub unsafe fn py_module_initializer_impl( def: *mut ffi::PyModuleDef, init: fn(Python, &PyModule) -> PyResult<()> diff --git a/src/objectprotocol.rs b/src/objectprotocol.rs index aaa4dda3..bd0ba9c1 100644 --- a/src/objectprotocol.rs +++ b/src/objectprotocol.rs @@ -85,21 +85,6 @@ pub trait ObjectProtocol : PythonObject { /// raise TypeError("ObjectProtocol::compare(): All comparisons returned false") /// ``` fn compare(&self, py: Python, other: O) -> PyResult where O: ToPyObject { - #[cfg(feature="python27-sys")] - unsafe fn do_compare(py: Python, a: *mut ffi::PyObject, b: *mut ffi::PyObject) -> PyResult { - let mut result = -1; - try!(err::error_on_minusone(py, - ffi::PyObject_Cmp(a, b, &mut result))); - Ok(if result < 0 { - Ordering::Less - } else if result > 0 { - Ordering::Greater - } else { - Ordering::Equal - }) - } - - #[cfg(feature="python3-sys")] unsafe fn do_compare(py: Python, a: *mut ffi::PyObject, b: *mut ffi::PyObject) -> PyResult { let result = ffi::PyObject_RichCompareBool(a, b, ffi::Py_EQ); if result == 1 { @@ -160,16 +145,6 @@ pub trait ObjectProtocol : PythonObject { } } - /// Compute the unicode string representation of self. - /// This is equivalent to the Python expression 'unistr(self)'. - #[inline] - #[cfg(feature="python27-sys")] - fn unistr(&self, py: Python) -> PyResult<::objects::PyUnicode> { - unsafe { - err::result_cast_from_owned_ptr(py, ffi::PyObject_Unicode(self.as_ptr())) - } - } - /// Determines whether this object is callable. #[inline] fn is_callable(&self, _py: Python) -> bool { diff --git a/src/objects/bytearray.rs b/src/objects/bytearray.rs index 7bf5286d..6f13ae6d 100644 --- a/src/objects/bytearray.rs +++ b/src/objects/bytearray.rs @@ -1,20 +1,4 @@ -// Copyright (c) 2017 Nikolay Kim -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. +// Copyright (c) 2017-present PyO3 Project and Contributors use std; use std::{mem, str, char, ptr}; diff --git a/src/objects/exc.rs b/src/objects/exc.rs index 805a3e20..1375b064 100644 --- a/src/objects/exc.rs +++ b/src/objects/exc.rs @@ -73,8 +73,6 @@ macro_rules! exc_type( exc_type!(BaseException, PyExc_BaseException); exc_type!(Exception, PyExc_Exception); -#[cfg(feature="python27-sys")] -exc_type!(StandardError, PyExc_StandardError); exc_type!(LookupError, PyExc_LookupError); exc_type!(AssertionError, PyExc_AssertionError); exc_type!(AttributeError, PyExc_AttributeError); @@ -104,36 +102,20 @@ exc_type!(WindowsError, PyExc_WindowsError); exc_type!(ZeroDivisionError, PyExc_ZeroDivisionError); exc_type!(BufferError, PyExc_BufferError); - -#[cfg(Py_3_4)] exc_type!(BlockingIOError, PyExc_BlockingIOError); -#[cfg(Py_3_4)] exc_type!(BrokenPipeError, PyExc_BrokenPipeError); -#[cfg(Py_3_4)] exc_type!(ChildProcessError, PyExc_ChildProcessError); -#[cfg(Py_3_4)] exc_type!(ConnectionError, PyExc_ConnectionError); -#[cfg(Py_3_4)] exc_type!(ConnectionAbortedError, PyExc_ConnectionAbortedError); -#[cfg(Py_3_4)] exc_type!(ConnectionRefusedError, PyExc_ConnectionRefusedError); -#[cfg(Py_3_4)] exc_type!(ConnectionResetError, PyExc_ConnectionResetError); -#[cfg(Py_3_4)] exc_type!(FileExistsError, PyExc_FileExistsError); -#[cfg(Py_3_4)] exc_type!(FileNotFoundError, PyExc_FileNotFoundError); -#[cfg(Py_3_4)] exc_type!(InterruptedError, PyExc_InterruptedError); -#[cfg(Py_3_4)] exc_type!(IsADirectoryError, PyExc_IsADirectoryError); -#[cfg(Py_3_4)] exc_type!(NotADirectoryError, PyExc_NotADirectoryError); -#[cfg(Py_3_4)] exc_type!(PermissionError, PyExc_PermissionError); -#[cfg(Py_3_4)] exc_type!(ProcessLookupError, PyExc_ProcessLookupError); -#[cfg(Py_3_4)] exc_type!(TimeoutError, PyExc_TimeoutError); exc_type!(UnicodeDecodeError, PyExc_UnicodeDecodeError); diff --git a/src/objects/mod.rs b/src/objects/mod.rs index 1ddbdbe9..245dbe85 100644 --- a/src/objects/mod.rs +++ b/src/objects/mod.rs @@ -19,23 +19,13 @@ pub use self::object::PyObject; pub use self::typeobject::PyType; pub use self::module::PyModule; - pub use self::string::{PyBytes, PyString, PyStringData}; -#[cfg(feature="python27-sys")] -pub use self::string::PyUnicode; -#[cfg(feature="python3-sys")] -pub use self::string::PyString as PyUnicode; - pub use self::iterator::PyIterator; pub use self::boolobject::PyBool; pub use self::bytearray::PyByteArray; pub use self::tuple::{PyTuple, NoArgs, ToPyTuple}; pub use self::dict::PyDict; pub use self::list::PyList; -#[cfg(feature="python27-sys")] -pub use self::num::PyInt; -#[cfg(feature="python3-sys")] -pub use self::num::PyLong as PyInt; pub use self::num::{PyLong, PyFloat}; pub use self::sequence::PySequence; pub use self::slice::PySlice; @@ -137,9 +127,5 @@ mod num; mod sequence; mod slice; pub mod exc; - -#[cfg(feature="python27-sys")] -pub mod oldstyle; - mod tests; diff --git a/src/objects/num.rs b/src/objects/num.rs index 23ebe6ff..9dcb9de9 100644 --- a/src/objects/num.rs +++ b/src/objects/num.rs @@ -29,24 +29,6 @@ use conversion::{ToPyObject, FromPyObject}; /// Represents a Python `int` object. /// -/// Note that in Python 2.x, `int` and `long` are different types. -/// When rust-cpython is compiled for Python 3.x, -/// `PyInt` and `PyLong` are aliases for the same type, which -/// corresponds to a Python `int`. -/// -/// You can usually avoid directly working with this type -/// by using [ToPyObject](trait.ToPyObject.html) -/// and [extract](struct.PyObject.html#method.extract) -/// with the primitive Rust integer types. -#[cfg(feature="python27-sys")] -pub struct PyInt(PyObject); -#[cfg(feature="python27-sys")] -pyobject_newtype!(PyInt, PyInt_Check, PyInt_Type); - -/// In Python 2.x, represents a Python `long` object. -/// In Python 3.x, represents a Python `int` object. -/// Both `PyInt` and `PyLong` refer to the same type on Python 3.x. -/// /// You can usually avoid directly working with this type /// by using [ToPyObject](trait.ToPyObject.html) /// and [extract](struct.PyObject.html#method.extract) @@ -63,30 +45,6 @@ pyobject_newtype!(PyLong, PyLong_Check, PyLong_Type); pub struct PyFloat(PyObject); pyobject_newtype!(PyFloat, PyFloat_Check, PyFloat_Type); -#[cfg(feature="python27-sys")] -impl PyInt { - /// Creates a new Python 2.7 `int` object. - /// - /// Note: you might want to call `val.to_py_object(py)` instead - /// to avoid truncation if the value does not fit into a `c_long`, - /// and to make your code compatible with Python 3.x. - pub fn new(py: Python, val: c_long) -> PyInt { - unsafe { - err::cast_from_owned_ptr_or_panic(py, ffi::PyInt_FromLong(val)) - } - } - - /// Gets the value of this integer. - /// - /// Warning: `PyInt::value()` is only supported for Python 2.7 `int` objects, - /// but not for `long` objects. - /// In almost all cases, you can avoid the distinction between these types - /// by simply calling `obj.extract::(py)`. - pub fn value(&self, _py: Python) -> c_long { - unsafe { ffi::PyInt_AS_LONG(self.0.as_ptr()) } - } -} - impl PyFloat { /// Creates a new Python `float` object. @@ -104,19 +62,6 @@ impl PyFloat { macro_rules! int_fits_c_long( ($rust_type:ty) => ( - #[cfg(feature="python27-sys")] - impl ToPyObject for $rust_type { - type ObjectType = PyInt; - - fn to_py_object(&self, py: Python) -> PyInt { - unsafe { - err::cast_from_owned_ptr_or_panic(py, - ffi::PyInt_FromLong(*self as c_long)) - } - } - } - - #[cfg(feature="python3-sys")] impl ToPyObject for $rust_type { type ObjectType = PyLong; @@ -177,24 +122,8 @@ fn err_if_invalid_value<'p, T: PartialEq> macro_rules! int_convert_u64_or_i64 ( ($rust_type:ty, $pylong_from_ll_or_ull:expr, $pylong_as_ull_or_ull:expr) => ( impl <'p> ToPyObject for $rust_type { - #[cfg(feature="python27-sys")] - type ObjectType = PyObject; - - #[cfg(feature="python3-sys")] type ObjectType = PyLong; - #[cfg(feature="python27-sys")] - fn to_py_object(&self, py: Python) -> PyObject { - unsafe { - let ptr = match cast::<$rust_type, c_long>(*self) { - Some(v) => ffi::PyInt_FromLong(v), - None => $pylong_from_ll_or_ull(*self) - }; - err::from_owned_ptr_or_panic(py, ptr) - } - } - - #[cfg(feature="python3-sys")] fn to_py_object(&self, py: Python) -> PyLong { unsafe { err::cast_from_owned_ptr_or_panic(py, $pylong_from_ll_or_ull(*self)) @@ -203,26 +132,6 @@ macro_rules! int_convert_u64_or_i64 ( } impl <'source> FromPyObject<'source> for $rust_type { - #[cfg(feature="python27-sys")] - fn extract(py: Python, obj: &'source PyObject) -> PyResult<$rust_type> { - let ptr = obj.as_ptr(); - - unsafe { - if ffi::PyLong_Check(ptr) != 0 { - err_if_invalid_value(py, !0, $pylong_as_ull_or_ull(ptr)) - } else if ffi::PyInt_Check(ptr) != 0 { - match cast::(ffi::PyInt_AS_LONG(ptr)) { - Some(v) => Ok(v), - None => Err(overflow_error(py)) - } - } else { - let num = try!(err::result_from_owned_ptr(py, ffi::PyNumber_Long(ptr))); - err_if_invalid_value(py, !0, $pylong_as_ull_or_ull(num.as_ptr())) - } - } - } - - #[cfg(feature="python3-sys")] fn extract(py: Python, obj: &'source PyObject) -> PyResult<$rust_type> { let ptr = obj.as_ptr(); unsafe { diff --git a/src/objects/slice.rs b/src/objects/slice.rs index f2fbc5df..34c74881 100644 --- a/src/objects/slice.rs +++ b/src/objects/slice.rs @@ -1,20 +1,4 @@ -// Copyright (c) 2017 Nikolay Kim -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. +// Copyright (c) 2017-present PyO3 Project and Contributors use std::mem; use libc::c_long; diff --git a/src/objects/string.rs b/src/objects/string.rs index 59b9e7c5..e20c04b3 100644 --- a/src/objects/string.rs +++ b/src/objects/string.rs @@ -28,72 +28,15 @@ use err::{self, PyResult, PyErr}; use conversion::{FromPyObject, RefFromPyObject, ToPyObject}; /// Represents a Python string. -/// Corresponds to `basestring` in Python 2, and `str` in Python 3. pub struct PyString(PyObject); -#[cfg(feature="python27-sys")] -pyobject_newtype!(PyString); -#[cfg(feature="python3-sys")] pyobject_newtype!(PyString, PyUnicode_Check, PyUnicode_Type); /// Represents a Python byte string. -/// Corresponds to `str` in Python 2, and `bytes` in Python 3. pub struct PyBytes(PyObject); pyobject_newtype!(PyBytes, PyBytes_Check, PyBytes_Type); -/// Represents a Python unicode string. -/// Corresponds to `unicode` in Python 2, and `str` in Python 3. -#[cfg(feature="python27-sys")] -pub struct PyUnicode(PyObject); - -#[cfg(feature="python27-sys")] -pyobject_newtype!(PyUnicode, PyUnicode_Check, PyUnicode_Type); - -/// Represents a Python unicode string. -/// Corresponds to `unicode` in Python 2, and `str` in Python 3. -#[cfg(feature="python3-sys")] -pub use PyString as PyUnicode; - -#[cfg(feature="python27-sys")] -impl ::python::PythonObjectWithCheckedDowncast for PyString { - #[inline] - fn downcast_from<'p>(py: Python<'p>, obj: PyObject) -> Result> { - if is_base_string(&obj) { - Ok(PyString(obj)) - } else { - Err(PythonObjectDowncastError(py)) - } - } - - #[inline] - fn downcast_borrow_from<'a, 'p>(py: Python<'p>, obj: &'a PyObject) -> Result<&'a PyString, PythonObjectDowncastError<'p>> { - unsafe { - if is_base_string(obj) { - Ok(::std::mem::transmute(obj)) - } else { - Err(::python::PythonObjectDowncastError(py)) - } - } - } -} - -#[cfg(feature="python27-sys")] -#[inline] -fn is_base_string(obj: &PyObject) -> bool { - unsafe { - ffi::PyType_FastSubclass(ffi::Py_TYPE(obj.as_ptr()), - ffi::Py_TPFLAGS_STRING_SUBCLASS | ffi::Py_TPFLAGS_UNICODE_SUBCLASS) != 0 - } -} - -#[cfg(feature="python27-sys")] -impl ::python::PythonObjectWithTypeObject for PyString { - #[inline] - fn type_object(py: Python) -> super::PyType { - unsafe { ::objects::typeobject::PyType::from_type_ptr(py, &mut ::ffi::PyBaseString_Type) } - } -} /// Enum of possible Python string representations. #[derive(Clone, Copy, Debug)] @@ -211,24 +154,12 @@ impl PyString { /// /// Panics if out of memory. pub fn new(py: Python, s: &str) -> PyString { - #[cfg(feature="python27-sys")] - fn new_impl(py: Python, s: &str) -> PyString { - if s.is_ascii() { - PyBytes::new(py, s.as_bytes()).into_basestring() - } else { - PyUnicode::new(py, s).into_basestring() - } + let ptr = s.as_ptr() as *const c_char; + let len = s.len() as ffi::Py_ssize_t; + unsafe { + err::cast_from_owned_ptr_or_panic(py, + ffi::PyUnicode_FromStringAndSize(ptr, len)) } - #[cfg(feature="python3-sys")] - fn new_impl(py: Python, s: &str) -> PyString { - let ptr = s.as_ptr() as *const c_char; - let len = s.len() as ffi::Py_ssize_t; - unsafe { - err::cast_from_owned_ptr_or_panic(py, - ffi::PyUnicode_FromStringAndSize(ptr, len)) - } - } - new_impl(py, s) } pub fn from_object(py: Python, src: &PyObject, encoding: &str, errors: &str) -> PyResult { @@ -240,27 +171,7 @@ impl PyString { } /// Gets the python string data in its underlying representation. - /// - /// For Python 2 byte strings, this function always returns `PyStringData::Utf8`, - /// even if the bytes are not valid UTF-8. - /// For unicode strings, returns the underlying representation used by Python. pub fn data(&self, py: Python) -> PyStringData { - self.data_impl(py) - } - - #[cfg(feature="python27-sys")] - fn data_impl(&self, py: Python) -> PyStringData { - if let Ok(bytes) = self.0.cast_as::(py) { - PyStringData::Utf8(bytes.data(py)) - } else if let Ok(unicode) = self.0.cast_as::(py) { - unicode.data(py) - } else { - panic!("PyString is neither `str` nor `unicode`") - } - } - - #[cfg(feature="python3-sys")] - fn data_impl(&self, py: Python) -> PyStringData { // TODO: return the original representation instead // of forcing the UTF-8 representation to be created. unsafe { @@ -276,22 +187,15 @@ impl PyString { /// Convert the `PyString` into a Rust string. /// - /// On Python 2.7, if the `PyString` refers to a byte string, - /// it will be decoded using UTF-8. - /// /// Returns a `UnicodeDecodeError` if the input is not valid unicode - /// (containing unpaired surrogates, or a Python 2.7 byte string that is - /// not valid UTF-8). + /// (containing unpaired surrogates). pub fn to_string(&self, py: Python) -> PyResult> { self.data(py).to_string(py) } /// Convert the `PyString` into a Rust string. /// - /// On Python 2.7, if the `PyString` refers to a byte string, - /// it will be decoded using UTF-8. - /// - /// Unpaired surrogates and (on Python 2.7) invalid UTF-8 sequences are + /// Unpaired surrogates invalid UTF-8 sequences are /// replaced with U+FFFD REPLACEMENT CHARACTER. pub fn to_string_lossy(&self, py: Python) -> Cow { self.data(py).to_string_lossy() @@ -320,77 +224,6 @@ impl PyBytes { std::slice::from_raw_parts(buffer, length) } } - - /// Converts from `PyBytes` to `PyString`. - /// This method is only available on Python 2. - #[cfg(feature="python27-sys")] - #[inline] - pub fn as_basestring(&self) -> &PyString { - unsafe { self.0.unchecked_cast_as() } - } - - /// Converts from `PyBytes` to `PyString`. - /// This method is only available on Python 2. - #[cfg(feature="python27-sys")] - #[inline] - pub fn into_basestring(self) -> PyString { - unsafe { self.0.unchecked_cast_into() } - } -} - -#[cfg(feature="python27-sys")] -impl PyUnicode { - /// Creates a new Python unicode string object. - /// - /// Panics if out of memory. - pub fn new(py: Python, s: &str) -> PyUnicode { - let ptr = s.as_ptr() as *const c_char; - let len = s.len() as ffi::Py_ssize_t; - unsafe { - err::cast_from_owned_ptr_or_panic(py, - ffi::PyUnicode_FromStringAndSize(ptr, len)) - } - } - - /// Converts from `PyUnicode` to `PyString`. - /// This method is only available on Python 2. - /// (note: on Python 3, `PyUnicode` is a type alias for `PyString`) - #[inline] - pub fn as_basestring(&self) -> &PyString { - unsafe { self.0.unchecked_cast_as() } - } - - /// Converts from `PyUnicode` to `PyString`. - /// This method is only available on Python 2. - /// (note: on Python 3, `PyUnicode` is a type alias for `PyString`) - #[inline] - pub fn into_basestring(self) -> PyString { - unsafe { self.0.unchecked_cast_into() } - } - - /// Gets the python string data in its underlying representation. - pub fn data(&self, _py: Python) -> PyStringData { - unsafe { - let buffer = ffi::PyUnicode_AS_UNICODE(self.as_ptr()); - let length = ffi::PyUnicode_GET_SIZE(self.as_ptr()) as usize; - std::slice::from_raw_parts(buffer, length).into() - } - } - - /// Convert the `PyUnicode` into a Rust string. - /// - /// Returns a `UnicodeDecodeError` if the input is not valid unicode - /// (containing unpaired surrogates). - pub fn to_string(&self, py: Python) -> PyResult> { - self.data(py).to_string(py) - } - - /// Convert the `PyUnicode` into a Rust string. - /// - /// Unpaired surrogates are replaced with U+FFFD REPLACEMENT CHARACTER. - pub fn to_string_lossy(&self, py: Python) -> Cow { - self.data(py).to_string_lossy() - } } /// Converts Rust `str` to Python object. @@ -428,7 +261,6 @@ impl ToPyObject for String { /// Allows extracting strings from Python objects. /// Accepts Python `str` and `unicode` objects. -/// In Python 2.7, `str` is expected to be UTF-8 encoded. impl <'source> FromPyObject<'source> for Cow<'source, str> { fn extract(py: Python, obj: &'source PyObject) -> PyResult { try!(obj.cast_as::(py)).to_string(py) @@ -437,7 +269,6 @@ impl <'source> FromPyObject<'source> for Cow<'source, str> { /// Allows extracting strings from Python objects. /// Accepts Python `str` and `unicode` objects. -/// In Python 2.7, `str` is expected to be UTF-8 encoded. impl <'source> FromPyObject<'source> for String { fn extract(py: Python, obj: &'source PyObject) -> PyResult { obj.extract::>(py).map(Cow::into_owned) diff --git a/src/objects/tests.rs b/src/objects/tests.rs index fc0c9233..015aee97 100644 --- a/src/objects/tests.rs +++ b/src/objects/tests.rs @@ -16,7 +16,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use {Python, PyDict, ToPyObject, PyInt}; +use {Python, PyDict, ToPyObject, PyLong}; use std::collections::{BTreeMap, HashMap}; // TODO: move these tests into the dict module diff --git a/src/py_class/gc.rs b/src/py_class/gc.rs index ec69f8c0..ef713869 100644 --- a/src/py_class/gc.rs +++ b/src/py_class/gc.rs @@ -16,7 +16,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use libc; +use std::os::raw::{c_void, c_int}; use ffi; use std::mem; use python::{Python, PythonObject, PyDrop, ToPythonPointer}; @@ -25,12 +25,12 @@ use function::AbortOnDrop; // TODO: what's the semantics of the traverse return code? // If it's just a normal python exception, we might want to use PyErr instead. -pub struct TraverseError(libc::c_int); +pub struct TraverseError(c_int); #[derive(Copy, Clone)] pub struct VisitProc<'a> { visit: ffi::visitproc, - arg: *mut libc::c_void, + arg: *mut c_void, /// VisitProc contains a Python instance to ensure that /// 1) it is cannot be moved out of the traverse() call /// 2) it cannot be sent to other threads @@ -88,9 +88,8 @@ pub unsafe fn tp_traverse( location: &str, slf: *mut ffi::PyObject, visit: ffi::visitproc, - arg: *mut libc::c_void, - callback: F -) -> libc::c_int + arg: *mut c_void, + callback: F) -> c_int where C: PythonObject, F: FnOnce(&C, Python, VisitProc) -> Result<(), TraverseError> { @@ -127,8 +126,7 @@ macro_rules! py_class_tp_clear { pub unsafe fn tp_clear( location: &str, slf: *mut ffi::PyObject, - callback: F -) -> libc::c_int + callback: F) -> c_int where C: PythonObject, F: FnOnce(&C, Python) { diff --git a/src/py_class/mod.rs b/src/py_class/mod.rs index d4641042..0b0e6b9d 100644 --- a/src/py_class/mod.rs +++ b/src/py_class/mod.rs @@ -17,16 +17,13 @@ // DEALINGS IN THE SOFTWARE. mod py_class; -#[cfg(feature="python27-sys")] -mod py_class_impl2; -#[cfg(feature="python3-sys")] -mod py_class_impl3; +mod py_class_impl; #[doc(hidden)] pub mod slots; #[doc(hidden)] pub mod members; #[doc(hidden)] pub mod properties; pub mod gc; -use libc; +use std::os::raw::c_void; use std::{mem, ptr, cell}; use python::{self, Python, PythonObject}; use objects::{PyObject, PyType, PyModule}; @@ -139,9 +136,9 @@ impl BaseObject for PyObject { // we have to manually un-do the work of PyType_GenericAlloc: let ty = ffi::Py_TYPE(obj); if ffi::PyType_IS_GC(ty) != 0 { - ffi::PyObject_GC_Del(obj as *mut libc::c_void); + ffi::PyObject_GC_Del(obj as *mut c_void); } else { - ffi::PyObject_Free(obj as *mut libc::c_void); + ffi::PyObject_Free(obj as *mut c_void); } // For heap types, PyType_GenericAlloc calls INCREF on the type objects, // so we need to call DECREF here: diff --git a/src/py_class/py_class_impl3.rs b/src/py_class/py_class_impl.rs similarity index 100% rename from src/py_class/py_class_impl3.rs rename to src/py_class/py_class_impl.rs diff --git a/src/py_class/py_class_impl2.rs b/src/py_class/py_class_impl2.rs deleted file mode 100644 index eb566245..00000000 --- a/src/py_class/py_class_impl2.rs +++ /dev/null @@ -1,1973 +0,0 @@ - -// Copyright (c) 2016 Daniel Grunwald -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - - -// !!!!!!!!!!!!!!!!!!!!!!!!!!! -// THIS IS A GENERATED FILE !! -// DO NOT MODIFY !! -// !!!!!!!!!!!!!!!!!!!!!!!!!!! - -#[macro_export] -#[doc(hidden)] -macro_rules! py_class_impl { - // TT muncher macro. Results are accumulated in $info $slots $impls and $members. - - - // Base case: we're done munching and can start producing code: - { {} - $class:ident $py:ident - /* info: */ { - $base_type:ty, - $size:expr, - { $( $class_visibility:tt )* }, - $gc:tt, - /* data: */ [ $( { $data_offset:expr, $data_name:ident, $data_ty:ty } )* ] - } - $slots:tt { $( $imp:item )* } $members:tt $properties:tt - } => { - py_coerce_item! { - $($class_visibility)* struct $class { _unsafe_inner: $crate::PyObject } - } - - py_impl_to_py_object_for_python_object!($class); - py_impl_from_py_object_for_python_object!($class); - - impl $crate::PythonObject for $class { - #[inline] - fn as_object(&self) -> &$crate::PyObject { - &self._unsafe_inner - } - - #[inline] - fn into_object(self) -> $crate::PyObject { - self._unsafe_inner - } - - /// Unchecked downcast from PyObject to Self. - /// Undefined behavior if the input object does not have the expected type. - #[inline] - unsafe fn unchecked_downcast_from(obj: $crate::PyObject) -> Self { - $class { _unsafe_inner: obj } - } - - /// Unchecked downcast from PyObject to Self. - /// Undefined behavior if the input object does not have the expected type. - #[inline] - unsafe fn unchecked_downcast_borrow_from<'a>(obj: &'a $crate::PyObject) -> &'a Self { - ::std::mem::transmute(obj) - } - } - - impl $crate::PythonObjectWithCheckedDowncast for $class { - #[inline] - fn downcast_from<'p>(py: $crate::Python<'p>, obj: $crate::PyObject) -> Result<$class, $crate::PythonObjectDowncastError<'p>> { - if py.get_type::<$class>().is_instance(py, &obj) { - Ok($class { _unsafe_inner: obj }) - } else { - Err($crate::PythonObjectDowncastError(py)) - } - } - - #[inline] - fn downcast_borrow_from<'a, 'p>(py: $crate::Python<'p>, obj: &'a $crate::PyObject) -> Result<&'a $class, $crate::PythonObjectDowncastError<'p>> { - if py.get_type::<$class>().is_instance(py, obj) { - unsafe { Ok(::std::mem::transmute(obj)) } - } else { - Err($crate::PythonObjectDowncastError(py)) - } - } - } - - py_coerce_item! { - impl $crate::py_class::BaseObject for $class { - type InitType = ( $( $data_ty, )* ); - - #[inline] - fn size() -> usize { - $size - } - - unsafe fn alloc( - py: $crate::Python, - ty: &$crate::PyType, - ( $( $data_name, )* ): Self::InitType - ) -> $crate::PyResult<$crate::PyObject> - { - let obj = try!(<$base_type as $crate::py_class::BaseObject>::alloc(py, ty, ())); - $( $crate::py_class::data_init::<$data_ty>(py, &obj, $data_offset, $data_name); )* - Ok(obj) - } - - unsafe fn dealloc(py: $crate::Python, obj: *mut $crate::_detail::ffi::PyObject) { - $( $crate::py_class::data_drop::<$data_ty>(py, obj, $data_offset); )* - <$base_type as $crate::py_class::BaseObject>::dealloc(py, obj) - } - } - } - $($imp)* - py_coerce_item! { - impl $class { - fn create_instance(py: $crate::Python $( , $data_name : $data_ty )* ) -> $crate::PyResult<$class> { - let obj = try!(unsafe { - <$class as $crate::py_class::BaseObject>::alloc( - py, &py.get_type::<$class>(), ( $($data_name,)* ) - ) - }); - return Ok($class { _unsafe_inner: obj }); - - // hide statics in create_instance to avoid name conflicts - static mut TYPE_OBJECT : $crate::_detail::ffi::PyTypeObject - = py_class_type_object_static_init!($class, $gc, $slots); - static mut INIT_ACTIVE: bool = false; - - // trait implementations that need direct access to TYPE_OBJECT - impl $crate::PythonObjectWithTypeObject for $class { - fn type_object(py: $crate::Python) -> $crate::PyType { - unsafe { - if $crate::py_class::is_ready(py, &TYPE_OBJECT) { - $crate::PyType::from_type_ptr(py, &mut TYPE_OBJECT) - } else { - // automatically initialize the class on-demand - <$class as $crate::py_class::PythonObjectFromPyClassMacro>::initialize(py, None) - .expect(concat!("An error occurred while initializing class ", stringify!($class))) - } - } - } - } - - impl $crate::py_class::PythonObjectFromPyClassMacro for $class { - fn initialize(py: $crate::Python, module_name: Option<&str>) -> $crate::PyResult<$crate::PyType> { - unsafe { - if $crate::py_class::is_ready(py, &TYPE_OBJECT) { - return Ok($crate::PyType::from_type_ptr(py, &mut TYPE_OBJECT)); - } - assert!(!INIT_ACTIVE, - concat!("Reentrancy detected: already initializing class ", - stringify!($class))); - INIT_ACTIVE = true; - let res = init(py, module_name); - INIT_ACTIVE = false; - res - } - } - - fn add_to_module(py: $crate::Python, module: &$crate::PyModule) -> $crate::PyResult<()> { - let ty = <$class as $crate::py_class::PythonObjectFromPyClassMacro>::initialize(py, module.name(py).ok())?; - module.add(py, stringify!($class), ty) - } - } - - fn init($py: $crate::Python, module_name: Option<&str>) -> $crate::PyResult<$crate::PyType> { - py_class_type_object_dynamic_init!($class, $py, TYPE_OBJECT, module_name, $slots); - py_class_init_members!($class, $py, TYPE_OBJECT, $members); - py_class_init_properties!($class, $py, TYPE_OBJECT, $properties); - unsafe { - if $crate::_detail::ffi::PyType_Ready(&mut TYPE_OBJECT) == 0 { - Ok($crate::PyType::from_type_ptr($py, &mut TYPE_OBJECT)) - } else { - Err($crate::PyErr::fetch($py)) - } - } - } - } - } - } - }; - - { { property $name:ident { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt $slots:tt { $( $imp:item )* } $members:tt - { $( $properties:expr; )* } - } => { py_class_impl! { - { $($tail)* } - $class $py $info $slots { $($imp)* } $members - /* properties: */ { - $( $properties; )* - py_class_property_impl! { { $($body)* } $class $py $name { } }; - } - }}; - - { { data $data_name:ident : $data_type:ty; $($tail:tt)* } - $class:ident $py:ident - /* info: */ { - $base_type: ty, - $size: expr, - $class_visibility: tt, - $gc: tt, - [ $( $data:tt )* ] - } - $slots:tt - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py - /* info: */ { - $base_type, - /* size: */ $crate::py_class::data_new_size::<$data_type>($size), - $class_visibility, - $gc, - /* data: */ [ - $($data)* - { - $crate::py_class::data_offset::<$data_type>($size), - $data_name, - $data_type - } - ] - } - $slots - /* impl: */ { - $($imp)* - impl $class { - fn $data_name<'a>(&'a self, py: $crate::Python<'a>) -> &'a $data_type { - unsafe { - $crate::py_class::data_get::<$data_type>( - py, - &self._unsafe_inner, - $crate::py_class::data_offset::<$data_type>($size) - ) - } - } - } - } - $members $properties - }}; - { { def __traverse__(&$slf:tt, $visit:ident) $body:block $($tail:tt)* } - $class:ident $py:ident - /* info: */ { - $base_type: ty, - $size: expr, - $class_visibility: tt, - /* gc: */ { - /* traverse_proc: */ None, - $traverse_data: tt - }, - $datas: tt - } - $slots:tt - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py - /* info: */ { - $base_type, - $size, - $class_visibility, - /* gc: */ { - /* traverse_proc: */ $class::__traverse__, - $traverse_data - }, - $datas - } - $slots - /* impl: */ { - $($imp)* - py_coerce_item!{ - impl $class { - fn __traverse__(&$slf, - $py: $crate::Python, - $visit: $crate::py_class::gc::VisitProc) - -> Result<(), $crate::py_class::gc::TraverseError> - $body - } - } - } - $members $properties - }}; - { { def __clear__ (&$slf:ident) $body:block $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - /* type_slots */ [ - $( $tp_slot_name : $tp_slot_value, )* - tp_clear: py_class_tp_clear!($class), - ] - $as_async $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_coerce_item!{ - impl $class { - fn __clear__(&$slf, $py: $crate::Python) $body - } - } - } - $members $properties - }}; - { { def __abs__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_absolute: py_class_unary_slot!($class::__abs__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __abs__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __abs__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __abs__" } - }; - { { def __add__($left:ident, $right:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_add: py_class_binary_numeric_slot!($class::__add__), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __add__() $res_type; { $($body)* } [ { $left : &$crate::PyObject = {} } { $right : &$crate::PyObject = {} } ] } - } - $members $properties - }}; - - { { def __add__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for binary numeric operator __add__" } - }; - - { { def __aenter__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__aenter__ is not supported by py_class! yet." } - }; - - { { def __aexit__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__aexit__ is not supported by py_class! yet." } - }; - { { def __aiter__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt - /* as_async */ [ $( $am_slot_name:ident : $am_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots - /* as_async */ [ - $( $am_slot_name : $am_slot_value, )* - am_aiter: py_class_unary_slot!($class::__aiter__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __aiter__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __aiter__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __aiter__" } - }; - { { def __and__($left:ident, $right:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_and: py_class_binary_numeric_slot!($class::__and__), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __and__() $res_type; { $($body)* } [ { $left : &$crate::PyObject = {} } { $right : &$crate::PyObject = {} } ] } - } - $members $properties - }}; - - { { def __and__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for binary numeric operator __and__" } - }; - { { def __anext__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt - /* as_async */ [ $( $am_slot_name:ident : $am_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots - /* as_async */ [ - $( $am_slot_name : $am_slot_value, )* - am_anext: py_class_unary_slot!($class::__anext__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __anext__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __anext__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __anext__" } - }; - { { def __await__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt - /* as_async */ [ $( $am_slot_name:ident : $am_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots - /* as_async */ [ - $( $am_slot_name : $am_slot_value, )* - am_await: py_class_unary_slot!($class::__await__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __await__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __await__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __await__" } - }; - { { def __bool__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_nonzero: py_class_unary_slot!($class::__bool__, $crate::_detail::libc::c_int, $crate::py_class::slots::BoolConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __bool__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __bool__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __bool__" } - }; - { { def __buffer_get__(&$slf:ident, $view:ident , $flags:ident ) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt - /* as_buffer */ [ $( $bf_slot_name:ident : $bf_slot_value:expr, )* ] - $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async $as_number $as_sequence $as_mapping - /* as_buffer */ [ - $( $bf_slot_name : $bf_slot_value, )* - bf_getbuffer: py_class_ternary_internal!($class::__buffer_get__, *mut $crate::_detail::ffi::Py_buffer, $crate::_detail::libc::c_int, $crate::_detail::libc::c_int, $crate::py_class::slots::SuccessConverter), - ] - $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __buffer_get__(&$slf,) $res_type; { $($body)* } [{ $view : *mut $crate::_detail::ffi::Py_buffer = {} } { $flags : $crate::_detail::libc::c_int = {} }] } - } - $members $properties - }}; - - { { def __buffer_get__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __buffer_get__" } - }; - { { def __buffer_release__(&$slf:ident, $view:ident ) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt - /* as_buffer */ [ $( $bf_slot_name:ident : $bf_slot_value:expr, )* ] - $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async $as_number $as_sequence $as_mapping - /* as_buffer */ [ - $( $bf_slot_name : $bf_slot_value, )* - bf_releasebuffer: py_class_binary_slot!($class::__buffer_release__, *mut $crate::_detail::ffi::Py_buffer, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PythonObjectCallbackConverter::<$crate::void>(::std::marker::PhantomData)), - ] - $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __buffer_release__(&$slf,) $res_type; { $($body)* } [{ $view : *mut $crate::_detail::ffi::Py_buffer = {} }] } - } - $members $properties - }}; - - { { def __buffer_release__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __buffer_release__" } - }; - { { def __call__ (&$slf:ident) -> $res_type:ty { $( $body:tt )* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - /* type_slots */ [ - $( $tp_slot_name : $tp_slot_value, )* - tp_call: py_class_call_slot!{$class::__call__ []}, - ] - $as_async $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __call__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - { { def __call__ (&$slf:ident, $($p:tt)+) -> $res_type:ty { $( $body:tt )* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - /* type_slots */ [ - $( $tp_slot_name : $tp_slot_value, )* - tp_call: py_argparse_parse_plist_impl!{py_class_call_slot {$class::__call__} [] ($($p)+,)}, - ] - $as_async $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_argparse_parse_plist_impl!{ - py_class_impl_item { $class, $py, __call__(&$slf,) $res_type; { $($body)* } } - [] ($($p)+,) - } - } - $members $properties - }}; - - { { def __cmp__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__cmp__ is not supported by py_class! use __richcmp__ instead." } - }; - - { { def __coerce__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__coerce__ is not supported by py_class! yet." } - }; - - { { def __complex__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__complex__ is not supported by py_class! yet." } - }; - { { def __contains__(&$slf:ident, $item:ident : $item_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt $as_number:tt - /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] - $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async $as_number - /* as_sequence */ [ - $( $sq_slot_name : $sq_slot_value, )* - sq_contains: py_class_contains_slot!($class::__contains__, $item_type), - ] - $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __contains__(&$slf,) $res_type; { $($body)* } [{ $item : $item_type = {} }] } - } - $members $properties - }}; - - { { def __contains__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __contains__" } - }; - - { { def __del__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__del__ is not supported by py_class!; Use a data member with a Drop impl instead." } - }; - - { { def __delattr__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__delattr__ is not supported by py_class! yet." } - }; - - { { def __delete__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__delete__ is not supported by py_class! yet." } - }; - { { def __delitem__(&$slf:ident, $key:ident : $key_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt - /* setdelitem */ [ - sdi_setitem: $sdi_setitem_slot_value:tt, - sdi_delitem: {}, - ] - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async $as_number $as_sequence $as_mapping $as_buffer - /* setdelitem */ [ - sdi_setitem: $sdi_setitem_slot_value, - sdi_delitem: { py_class_binary_slot!($class::__delitem__, $key_type, $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, - ] - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __delitem__(&$slf,) $res_type; { $($body)* } [{ $key : $key_type = {} }] } - } - $members $properties - }}; - - { { def __delitem__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __delitem__" } - }; - - { { def __dir__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__dir__ is not supported by py_class! yet." } - }; - - { { def __div__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__div__ is not supported by py_class! yet." } - }; - - { { def __divmod__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__divmod__ is not supported by py_class! yet." } - }; - - { { def __eq__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__eq__ is not supported by py_class! use __richcmp__ instead." } - }; - - { { def __float__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__float__ is not supported by py_class! yet." } - }; - - { { def __floordiv__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__floordiv__ is not supported by py_class! yet." } - }; - - { { def __ge__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__ge__ is not supported by py_class! use __richcmp__ instead." } - }; - - { { def __get__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__get__ is not supported by py_class! yet." } - }; - - { { def __getattr__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__getattr__ is not supported by py_class! yet." } - }; - - { { def __getattribute__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__getattribute__ is not supported by py_class! yet." } - }; - { { def __getitem__(&$slf:ident, $key:ident : $key_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt $as_number:tt - /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] - /* as_mapping */ [ $( $mp_slot_name:ident : $mp_slot_value:expr, )* ] - $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async $as_number - /* as_sequence */ [ - $( $sq_slot_name : $sq_slot_value, )* - sq_item: Some($crate::py_class::slots::sq_item), - ] - /* as_mapping */ [ - $( $mp_slot_name : $mp_slot_value, )* - mp_subscript: py_class_binary_slot!($class::__getitem__, $key_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __getitem__(&$slf,) $res_type; { $($body)* } [{ $key : $key_type = {} }] } - } - $members $properties - }}; - - { { def __getitem__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __getitem__" } - }; - - { { def __gt__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__gt__ is not supported by py_class! use __richcmp__ instead." } - }; - { { def __hash__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - /* type_slots */ [ - $( $tp_slot_name : $tp_slot_value, )* - tp_hash: py_class_unary_slot!($class::__hash__, $crate::Py_hash_t, $crate::py_class::slots::HashConverter), - ] - $as_async $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __hash__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __hash__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __hash__" } - }; - { { def __iadd__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_inplace_add: py_class_binary_slot!($class::__iadd__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __iadd__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] } - } - $members $properties - }}; - - { { def __iadd__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __iadd__" } - }; - { { def __iand__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_inplace_and: py_class_binary_slot!($class::__iand__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __iand__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] } - } - $members $properties - }}; - - { { def __iand__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __iand__" } - }; - - { { def __idiv__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__idiv__ is not supported by py_class! yet." } - }; - { { def __ifloordiv__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_inplace_floor_divide: py_class_binary_slot!($class::__ifloordiv__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __ifloordiv__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] } - } - $members $properties - }}; - - { { def __ifloordiv__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __ifloordiv__" } - }; - { { def __ilshift__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_inplace_lshift: py_class_binary_slot!($class::__ilshift__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __ilshift__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] } - } - $members $properties - }}; - - { { def __ilshift__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __ilshift__" } - }; - { { def __imatmul__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_inplace_matrix_multiply: py_class_binary_slot!($class::__imatmul__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __imatmul__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] } - } - $members $properties - }}; - - { { def __imatmul__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __imatmul__" } - }; - { { def __imod__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_inplace_remainder: py_class_binary_slot!($class::__imod__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __imod__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] } - } - $members $properties - }}; - - { { def __imod__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __imod__" } - }; - { { def __imul__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_inplace_multiply: py_class_binary_slot!($class::__imul__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __imul__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] } - } - $members $properties - }}; - - { { def __imul__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __imul__" } - }; - - { { def __index__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__index__ is not supported by py_class! yet." } - }; - - { { def __init__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__init__ is not supported by py_class!; use __new__ instead." } - }; - - { { def __instancecheck__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__instancecheck__ is not supported by py_class! yet." } - }; - - { { def __int__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__int__ is not supported by py_class! yet." } - }; - { { def __invert__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_invert: py_class_unary_slot!($class::__invert__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __invert__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __invert__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __invert__" } - }; - { { def __ior__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_inplace_or: py_class_binary_slot!($class::__ior__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __ior__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] } - } - $members $properties - }}; - - { { def __ior__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __ior__" } - }; - - { { def __ipow__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__ipow__ is not supported by py_class! yet." } - }; - { { def __irshift__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_inplace_rshift: py_class_binary_slot!($class::__irshift__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __irshift__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] } - } - $members $properties - }}; - - { { def __irshift__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __irshift__" } - }; - { { def __isub__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_inplace_subtract: py_class_binary_slot!($class::__isub__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __isub__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] } - } - $members $properties - }}; - - { { def __isub__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __isub__" } - }; - { { def __iter__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - /* type_slots */ [ - $( $tp_slot_name : $tp_slot_value, )* - tp_iter: py_class_unary_slot!($class::__iter__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_async $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __iter__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __iter__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __iter__" } - }; - { { def __itruediv__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_inplace_true_divide: py_class_binary_slot!($class::__itruediv__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __itruediv__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] } - } - $members $properties - }}; - - { { def __itruediv__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __itruediv__" } - }; - { { def __ixor__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_inplace_xor: py_class_binary_slot!($class::__ixor__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __ixor__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] } - } - $members $properties - }}; - - { { def __ixor__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __ixor__" } - }; - - { { def __le__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__le__ is not supported by py_class! use __richcmp__ instead." } - }; - { { def __len__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt $as_number:tt - /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] - /* as_mapping */ [ $( $mp_slot_name:ident : $mp_slot_value:expr, )* ] - $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async $as_number - /* as_sequence */ [ - $( $sq_slot_name : $sq_slot_value, )* - sq_length: py_class_unary_slot!($class::__len__, $crate::_detail::ffi::Py_ssize_t, $crate::py_class::slots::LenResultConverter), - ] - /* as_mapping */ [ - $( $mp_slot_name : $mp_slot_value, )* - mp_length: Some($crate::_detail::ffi::PySequence_Size), - ] - $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __len__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __len__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __len__" } - }; - - { { def __long__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__long__ is not supported by py_class! yet." } - }; - { { def __lshift__($left:ident, $right:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_lshift: py_class_binary_numeric_slot!($class::__lshift__), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __lshift__() $res_type; { $($body)* } [ { $left : &$crate::PyObject = {} } { $right : &$crate::PyObject = {} } ] } - } - $members $properties - }}; - - { { def __lshift__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for binary numeric operator __lshift__" } - }; - - { { def __lt__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__lt__ is not supported by py_class! use __richcmp__ instead." } - }; - - { { def __matmul__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__matmul__ is not supported by py_class! yet." } - }; - - { { def __mod__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__mod__ is not supported by py_class! yet." } - }; - { { def __mul__($left:ident, $right:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_multiply: py_class_binary_numeric_slot!($class::__mul__), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __mul__() $res_type; { $($body)* } [ { $left : &$crate::PyObject = {} } { $right : &$crate::PyObject = {} } ] } - } - $members $properties - }}; - - { { def __mul__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for binary numeric operator __mul__" } - }; - - { { def __ne__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__ne__ is not supported by py_class! use __richcmp__ instead." } - }; - { { def __neg__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_negative: py_class_unary_slot!($class::__neg__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __neg__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __neg__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __neg__" } - }; - { { def __new__ ($cls:ident) -> $res_type:ty { $( $body:tt )* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - /* type_slots */ [ - $( $tp_slot_name : $tp_slot_value, )* - tp_new: py_class_wrap_newfunc!{$class::__new__ []}, - ] - $as_async $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py,__new__($cls: &$crate::PyType,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - { { def __new__ ($cls:ident, $($p:tt)+) -> $res_type:ty { $( $body:tt )* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - /* type_slots */ [ - $( $tp_slot_name : $tp_slot_value, )* - tp_new: py_argparse_parse_plist_impl!{py_class_wrap_newfunc {$class::__new__} [] ($($p)+,)}, - ] - $as_async $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_argparse_parse_plist_impl!{ - py_class_impl_item { $class, $py, __new__($cls: &$crate::PyType,) $res_type; { $($body)* } } - [] ($($p)+,) - } - } - $members $properties - }}; - { { def __next__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - /* type_slots */ [ - $( $tp_slot_name : $tp_slot_value, )* - tp_iternext: py_class_unary_slot!($class::__next__, *mut $crate::_detail::ffi::PyObject, $crate::py_class::slots::IterNextResultConverter), - ] - $as_async $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __next__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __next__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __next__" } - }; - - { { def __nonzero__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__nonzero__ is not supported by py_class!; use the Python 3 spelling __bool__ instead." } - }; - { { def __or__($left:ident, $right:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_or: py_class_binary_numeric_slot!($class::__or__), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __or__() $res_type; { $($body)* } [ { $left : &$crate::PyObject = {} } { $right : &$crate::PyObject = {} } ] } - } - $members $properties - }}; - - { { def __or__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for binary numeric operator __or__" } - }; - { { def __pos__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_positive: py_class_unary_slot!($class::__pos__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __pos__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __pos__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __pos__" } - }; - - { { def __pow__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__pow__ is not supported by py_class! yet." } - }; - - { { def __radd__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __radd__ is not supported by py_class! Use __add__ instead!" } - }; - - { { def __rand__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rand__ is not supported by py_class! Use __and__ instead!" } - }; - - { { def __rdiv__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rdiv__ is not supported by py_class! Use __div__ instead!" } - }; - - { { def __rdivmod__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rdivmod__ is not supported by py_class! Use __divmod__ instead!" } - }; - { { def __repr__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - /* type_slots */ [ - $( $tp_slot_name : $tp_slot_value, )* - tp_repr: py_class_unary_slot!($class::__repr__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PythonObjectCallbackConverter::<$crate::PyString>(::std::marker::PhantomData)), - ] - $as_async $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __repr__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __repr__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __repr__" } - }; - - { { def __rfloordiv__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rfloordiv__ is not supported by py_class! Use __floordiv__ instead!" } - }; - { { def __richcmp__(&$slf:ident, $other:ident : $other_type:ty, $op:ident : $op_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - /* type_slots */ [ - $( $tp_slot_name : $tp_slot_value, )* - tp_richcompare: py_class_richcompare_slot!($class::__richcmp__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), - ] - $as_async $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __richcmp__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} } { $op : $op_type = {} }] } - } - $members $properties - }}; - - { { def __richcmp__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __richcmp__" } - }; - - { { def __rlshift__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rlshift__ is not supported by py_class! Use __lshift__ instead!" } - }; - - { { def __rmatmul__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rmatmul__ is not supported by py_class! Use __matmul__ instead!" } - }; - - { { def __rmod__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rmod__ is not supported by py_class! Use __mod__ instead!" } - }; - - { { def __rmul__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rmul__ is not supported by py_class! Use __mul__ instead!" } - }; - - { { def __ror__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __ror__ is not supported by py_class! Use __or__ instead!" } - }; - - { { def __round__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__round__ is not supported by py_class! yet." } - }; - - { { def __rpow__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rpow__ is not supported by py_class! Use __pow__ instead!" } - }; - - { { def __rrshift__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rrshift__ is not supported by py_class! Use __rshift__ instead!" } - }; - { { def __rshift__($left:ident, $right:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_rshift: py_class_binary_numeric_slot!($class::__rshift__), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __rshift__() $res_type; { $($body)* } [ { $left : &$crate::PyObject = {} } { $right : &$crate::PyObject = {} } ] } - } - $members $properties - }}; - - { { def __rshift__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for binary numeric operator __rshift__" } - }; - - { { def __rsub__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rsub__ is not supported by py_class! Use __sub__ instead!" } - }; - - { { def __rtruediv__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rtruediv__ is not supported by py_class! Use __truediv__ instead!" } - }; - - { { def __rxor__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Reflected numeric operator __rxor__ is not supported by py_class! Use __xor__ instead!" } - }; - - { { def __set__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__set__ is not supported by py_class! yet." } - }; - - { { def __setattr__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__setattr__ is not supported by py_class! yet." } - }; - { { def __setitem__(&$slf:ident, $key:ident : $key_type:ty, $value:ident : $value_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt - /* setdelitem */ [ - sdi_setitem: {}, - sdi_delitem: $sdi_delitem_slot_value:tt, - ] - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async $as_number $as_sequence $as_mapping $as_buffer - /* setdelitem */ [ - sdi_setitem: { py_class_ternary_slot!($class::__setitem__, $key_type, $value_type, $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, - sdi_delitem: $sdi_delitem_slot_value, - ] - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __setitem__(&$slf,) $res_type; { $($body)* } [{ $key : $key_type = {} } { $value : $value_type = {} }] } - } - $members $properties - }}; - - { { def __setitem__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __setitem__" } - }; - { { def __str__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_async:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - /* type_slots */ [ - $( $tp_slot_name : $tp_slot_value, )* - tp_str: py_class_unary_slot!($class::__str__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PythonObjectCallbackConverter::<$crate::PyString>(::std::marker::PhantomData)), - ] - $as_async $as_number $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __str__(&$slf,) $res_type; { $($body)* } [] } - } - $members $properties - }}; - - { { def __str__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for operator __str__" } - }; - { { def __sub__($left:ident, $right:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_subtract: py_class_binary_numeric_slot!($class::__sub__), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __sub__() $res_type; { $($body)* } [ { $left : &$crate::PyObject = {} } { $right : &$crate::PyObject = {} } ] } - } - $members $properties - }}; - - { { def __sub__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for binary numeric operator __sub__" } - }; - - { { def __subclasscheck__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__subclasscheck__ is not supported by py_class! yet." } - }; - - { { def __truediv__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "__truediv__ is not supported by py_class! yet." } - }; - { { def __xor__($left:ident, $right:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } - $class:ident $py:ident $info:tt - /* slots: */ { - $type_slots:tt $as_async:tt - /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt - } - { $( $imp:item )* } - $members:tt $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info - /* slots: */ { - $type_slots $as_async - /* as_number */ [ - $( $nb_slot_name : $nb_slot_value, )* - nb_xor: py_class_binary_numeric_slot!($class::__xor__), - ] - $as_sequence $as_mapping $as_buffer $setdelitem - } - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, __xor__() $res_type; { $($body)* } [ { $left : &$crate::PyObject = {} } { $right : &$crate::PyObject = {} } ] } - } - $members $properties - }}; - - { { def __xor__ $($tail:tt)* } $( $stuff:tt )* } => { - py_error! { "Invalid signature for binary numeric operator __xor__" } - }; - { { def $name:ident (&$slf:ident) -> $res_type:ty { $( $body:tt )* } $($tail:tt)* } - $class:ident $py:ident $info:tt $slots:tt - { $( $imp:item )* } - { $( $member_name:ident = $member_expr:expr; )* } $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info $slots - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py, $name(&$slf,) $res_type; { $($body)* } [] } - } - /* members: */ { - $( $member_name = $member_expr; )* - $name = py_class_instance_method!{$py, $class::$name []}; - } $properties - }}; - { { def $name:ident (&$slf:ident, $($p:tt)+) -> $res_type:ty { $( $body:tt )* } $($tail:tt)* } - $class:ident $py:ident $info:tt $slots:tt - { $( $imp:item )* } - { $( $member_name:ident = $member_expr:expr; )* } $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info $slots - /* impl: */ { - $($imp)* - py_argparse_parse_plist_impl!{ - py_class_impl_item { $class, $py, $name(&$slf,) $res_type; { $($body)* } } - [] ($($p)+,) - } - } - /* members: */ { - $( $member_name = $member_expr; )* - $name = py_argparse_parse_plist_impl!{py_class_instance_method {$py, $class::$name} [] ($($p)+,)}; - } $properties - }}; - { { @classmethod def $name:ident ($cls:ident) -> $res_type:ty { $( $body:tt )* } $($tail:tt)* } - $class:ident $py:ident $info:tt $slots:tt - { $( $imp:item )* } - { $( $member_name:ident = $member_expr:expr; )* } $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info $slots - /* impl: */ { - $($imp)* - py_class_impl_item! { $class, $py,$name($cls: &$crate::PyType,) $res_type; { $($body)* } [] } - } - /* members: */ { - $( $member_name = $member_expr; )* - $name = py_class_class_method!{$py, $class::$name []}; - } $properties - }}; - { { @classmethod def $name:ident ($cls:ident, $($p:tt)+) -> $res_type:ty { $( $body:tt )* } $($tail:tt)* } - $class:ident $py:ident $info:tt $slots:tt - { $( $imp:item )* } - { $( $member_name:ident = $member_expr:expr; )* } $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info $slots - /* impl: */ { - $($imp)* - py_argparse_parse_plist_impl!{ - py_class_impl_item { $class, $py, $name($cls: &$crate::PyType,) $res_type; { $($body)* } } - [] ($($p)+,) - } - } - /* members: */ { - $( $member_name = $member_expr; )* - $name = py_argparse_parse_plist_impl!{py_class_class_method {$py, $class::$name} [] ($($p)+,)}; - } $properties - }}; - { { @staticmethod def $name:ident ($($p:tt)*) -> $res_type:ty { $( $body:tt )* } $($tail:tt)* } - $class:ident $py:ident $info:tt $slots:tt - { $( $imp:item )* } - { $( $member_name:ident = $member_expr:expr; )* } $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info $slots - /* impl: */ { - $($imp)* - py_argparse_parse_plist!{ - py_class_impl_item { $class, $py, $name() $res_type; { $($body)* } } - ($($p)*) - } - } - /* members: */ { - $( $member_name = $member_expr; )* - $name = - py_argparse_parse_plist!{ - py_class_static_method {$py, $class::$name} - ($($p)*) - } - ; - } $properties - }}; - { { static $name:ident = $init:expr; $($tail:tt)* } - $class:ident $py:ident $info:tt $slots:tt $impls:tt - { $( $member_name:ident = $member_expr:expr; )* } $properties:tt - } => { py_class_impl! { - { $($tail)* } - $class $py $info $slots $impls - /* members: */ { - $( $member_name = $member_expr; )* - $name = $init; - } $properties - }}; - -} - diff --git a/src/py_class/slots.rs b/src/py_class/slots.rs index 7c89aec9..2d4e57c8 100644 --- a/src/py_class/slots.rs +++ b/src/py_class/slots.rs @@ -72,10 +72,6 @@ macro_rules! py_class_type_object_flags { }; } -#[cfg(feature="python27-sys")] -pub const TPFLAGS_DEFAULT : ::libc::c_long = ffi::Py_TPFLAGS_DEFAULT - | ffi::Py_TPFLAGS_CHECKTYPES; - #[cfg(feature="python3-sys")] pub const TPFLAGS_DEFAULT : ::libc::c_ulong = ffi::Py_TPFLAGS_DEFAULT; diff --git a/tests/check_symbols.py b/tests/check_symbols.py index 11390a59..88f57ee7 100755 --- a/tests/check_symbols.py +++ b/tests/check_symbols.py @@ -38,7 +38,7 @@ if sys.version_info.major == 3: for i in range(4, sys.version_info.minor+1): cfgs += ['--cfg', 'Py_3_{}'.format(i)] else: - sys_lib = 'python27-sys' + raise RuntimeError("Unsupported version: %s" % sys.version_info) interesting_config_flags = [ "Py_USING_UNICODE", diff --git a/tests/test_class.rs b/tests/test_class.rs index b5284b55..8cbc7f52 100644 --- a/tests/test_class.rs +++ b/tests/test_class.rs @@ -390,17 +390,6 @@ fn string_methods() { } #[test] -#[cfg(feature="python27-sys")] -fn python2_string_methods() { - let gil = Python::acquire_gil(); - let py = gil.python(); - - let obj = StringMethods::create_instance(py).unwrap(); - py_assert!(py, obj, "unicode(obj) == u'unicode'"); -} - -#[test] -#[cfg(feature="python3-sys")] fn python3_string_methods() { let gil = Python::acquire_gil(); let py = gil.python();