Merge branch 'master' into abi3-merge-master

This commit is contained in:
Alex Gaynor 2020-10-19 14:32:49 -04:00
commit 90a825d0c2
26 changed files with 44 additions and 102 deletions

View File

@ -45,7 +45,7 @@ jobs:
fail-fast: false # If one platform fails, allow the rest to keep testing. fail-fast: false # If one platform fails, allow the rest to keep testing.
matrix: matrix:
rust: [stable] rust: [stable]
python-version: [3.5, 3.6, 3.7, 3.8, 3.9, pypy3] python-version: [3.6, 3.7, 3.8, 3.9, pypy3]
platform: [ platform: [
{ os: "macOS-latest", python-architecture: "x64", rust-target: "x86_64-apple-darwin" }, { os: "macOS-latest", python-architecture: "x64", rust-target: "x86_64-apple-darwin" },
{ os: "ubuntu-latest", python-architecture: "x64", rust-target: "x86_64-unknown-linux-gnu" }, { os: "ubuntu-latest", python-architecture: "x64", rust-target: "x86_64-unknown-linux-gnu" },

View File

@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased] ## [Unreleased]
### Packaging
- Drop support for Python 3.5 (as it is now end-of-life). [#1250](https://github.com/PyO3/pyo3/pull/1250)
### Added ### Added
- Add support for building for CPython limited API. This required a few minor changes to runtime behaviour of of pyo3 `#[pyclass]` types. See the migration guide for full details. [#1152](https://github.com/PyO3/pyo3/pull/1152) - Add support for building for CPython limited API. This required a few minor changes to runtime behaviour of of pyo3 `#[pyclass]` types. See the migration guide for full details. [#1152](https://github.com/PyO3/pyo3/pull/1152)
- Add argument names to `TypeError` messages generated by pymethod wrappers. [#1212](https://github.com/PyO3/pyo3/pull/1212) - Add argument names to `TypeError` messages generated by pymethod wrappers. [#1212](https://github.com/PyO3/pyo3/pull/1212)

View File

@ -18,7 +18,7 @@ A comparison with rust-cpython can be found [in the guide](https://pyo3.rs/maste
## Usage ## Usage
PyO3 supports Python 3.5 and up. The minimum required Rust version is 1.39.0. PyO3 supports Python 3.6 and up. The minimum required Rust version is 1.39.0.
Building with PyPy is also possible (via cpyext) for Python 3.6, targeted PyPy version is 7.3+. Building with PyPy is also possible (via cpyext) for Python 3.6, targeted PyPy version is 7.3+.
Please refer to the [pypy section in the guide](https://pyo3.rs/master/pypy.html). Please refer to the [pypy section in the guide](https://pyo3.rs/master/pypy.html).

View File

@ -775,7 +775,7 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<String> {
} }
if let Some(minor) = interpreter_config.version.minor { if let Some(minor) = interpreter_config.version.minor {
for i in 5..(minor + 1) { for i in 6..(minor + 1) {
println!("cargo:rustc-cfg=Py_3_{}", i); println!("cargo:rustc-cfg=Py_3_{}", i);
flags += format!("CFG_Py_3_{},", i).as_ref(); flags += format!("CFG_Py_3_{},", i).as_ref();
} }

View File

@ -59,7 +59,7 @@ class CargoModifiedSdist(SdistCommand):
def get_py_version_cfgs(): def get_py_version_cfgs():
# For now each Cfg Py_3_X flag is interpreted as "at least 3.X" # For now each Cfg Py_3_X flag is interpreted as "at least 3.X"
version = sys.version_info[0:2] version = sys.version_info[0:2]
py3_min = 5 py3_min = 6
out_cfg = [] out_cfg = []
for minor in range(py3_min, version[1] + 1): for minor in range(py3_min, version[1] + 1):
out_cfg.append("--cfg=Py_3_%d" % minor) out_cfg.append("--cfg=Py_3_%d" % minor)

View File

@ -42,7 +42,7 @@ fn make_time<'p>(
) )
} }
#[cfg(Py_3_6)] #[cfg(not(PyPy))]
#[pyfunction] #[pyfunction]
fn time_with_fold<'p>( fn time_with_fold<'p>(
py: Python<'p>, py: Python<'p>,
@ -77,7 +77,7 @@ fn get_time_tuple<'p>(py: Python<'p>, dt: &PyTime) -> &'p PyTuple {
) )
} }
#[cfg(all(Py_3_6, not(PyPy)))] #[cfg(not(PyPy))]
#[pyfunction] #[pyfunction]
fn get_time_tuple_fold<'p>(py: Python<'p>, dt: &PyTime) -> &'p PyTuple { fn get_time_tuple_fold<'p>(py: Python<'p>, dt: &PyTime) -> &'p PyTuple {
PyTuple::new( PyTuple::new(
@ -156,7 +156,7 @@ fn get_datetime_tuple<'p>(py: Python<'p>, dt: &PyDateTime) -> &'p PyTuple {
) )
} }
#[cfg(all(Py_3_6, not(PyPy)))] #[cfg(not(PyPy))]
#[pyfunction] #[pyfunction]
fn get_datetime_tuple_fold<'p>(py: Python<'p>, dt: &PyDateTime) -> &'p PyTuple { fn get_datetime_tuple_fold<'p>(py: Python<'p>, dt: &PyDateTime) -> &'p PyTuple {
PyTuple::new( PyTuple::new(
@ -226,16 +226,13 @@ fn datetime(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(get_datetime_tuple, m)?)?; m.add_function(wrap_pyfunction!(get_datetime_tuple, m)?)?;
m.add_function(wrap_pyfunction!(datetime_from_timestamp, m)?)?; m.add_function(wrap_pyfunction!(datetime_from_timestamp, m)?)?;
// Python 3.6+ functions // Functions not supported by PyPy
#[cfg(Py_3_6)]
{
m.add_function(wrap_pyfunction!(time_with_fold, m)?)?;
#[cfg(not(PyPy))] #[cfg(not(PyPy))]
{ {
m.add_function(wrap_pyfunction!(time_with_fold, m)?)?;
m.add_function(wrap_pyfunction!(get_time_tuple_fold, m)?)?; m.add_function(wrap_pyfunction!(get_time_tuple_fold, m)?)?;
m.add_function(wrap_pyfunction!(get_datetime_tuple_fold, m)?)?; m.add_function(wrap_pyfunction!(get_datetime_tuple_fold, m)?)?;
} }
}
m.add_function(wrap_pyfunction!(issue_219, m)?)?; m.add_function(wrap_pyfunction!(issue_219, m)?)?;
m.add_class::<TzClass>()?; m.add_class::<TzClass>()?;

View File

@ -70,18 +70,6 @@ else:
MAX_DATETIME = pdt.datetime(9999, 12, 31, 18, 59, 59) MAX_DATETIME = pdt.datetime(9999, 12, 31, 18, 59, 59)
PYPY = platform.python_implementation() == "PyPy" PYPY = platform.python_implementation() == "PyPy"
HAS_FOLD = getattr(pdt.datetime, "fold", False) and not PYPY
xfail_date_bounds = pytest.mark.xfail(
sys.version_info < (3, 6),
reason="Date bounds were not checked in the C constructor prior to version 3.6",
)
xfail_macos_datetime_bounds = pytest.mark.xfail(
sys.version_info < (3, 6) and platform.system() == "Darwin",
reason="Unclearly failing. See https://github.com/PyO3/pyo3/pull/830 for more.",
)
# Tests # Tests
@ -97,13 +85,11 @@ def test_date_accessors(d):
assert act == exp assert act == exp
@xfail_date_bounds
def test_invalid_date_fails(): def test_invalid_date_fails():
with pytest.raises(ValueError): with pytest.raises(ValueError):
rdt.make_date(2017, 2, 30) rdt.make_date(2017, 2, 30)
@xfail_macos_datetime_bounds
@given(d=st.dates(MIN_DATETIME.date(), MAX_DATETIME.date())) @given(d=st.dates(MIN_DATETIME.date(), MAX_DATETIME.date()))
def test_date_from_timestamp(d): def test_date_from_timestamp(d):
if PYPY and d < pdt.date(1900, 1, 1): if PYPY and d < pdt.date(1900, 1, 1):
@ -137,7 +123,7 @@ def test_time(t):
assert act == exp assert act == exp
@pytest.mark.skipif(not HAS_FOLD, reason="Feature not available before 3.6") @pytest.mark.xfail(PYPY, reason="Feature not available on PyPy")
@given(t=st.times()) @given(t=st.times())
def test_time_fold(t): def test_time_fold(t):
t_nofold = t.replace(fold=0) t_nofold = t.replace(fold=0)
@ -150,7 +136,7 @@ def test_time_fold(t):
assert act == exp assert act == exp
@pytest.mark.skipif(not HAS_FOLD, reason="Feature not available before 3.6") @pytest.mark.xfail(PYPY, reason="Feature not available on PyPy")
@pytest.mark.parametrize("fold", [False, True]) @pytest.mark.parametrize("fold", [False, True])
def test_time_fold(fold): def test_time_fold(fold):
t = rdt.time_with_fold(0, 0, 0, 0, None, fold) t = rdt.time_with_fold(0, 0, 0, 0, None, fold)
@ -166,7 +152,6 @@ def test_invalid_time_fails_xfail(args):
rdt.make_time(*args) rdt.make_time(*args)
@xfail_date_bounds
@pytest.mark.parametrize( @pytest.mark.parametrize(
"args", "args",
[ [
@ -219,7 +204,7 @@ def test_datetime_tuple(dt):
assert act == exp assert act == exp
@pytest.mark.skipif(not HAS_FOLD, reason="Feature not available before 3.6") @pytest.mark.xfail(PYPY, reason="Feature not available on PyPy")
@given(dt=st.datetimes()) @given(dt=st.datetimes())
def test_datetime_tuple_fold(dt): def test_datetime_tuple_fold(dt):
dt_fold = dt.replace(fold=1) dt_fold = dt.replace(fold=1)
@ -232,7 +217,6 @@ def test_datetime_tuple_fold(dt):
assert act == exp assert act == exp
@xfail_date_bounds
def test_invalid_datetime_fails(): def test_invalid_datetime_fails():
with pytest.raises(ValueError): with pytest.raises(ValueError):
rdt.make_datetime(2011, 1, 42, 0, 0, 0, 0) rdt.make_datetime(2011, 1, 42, 0, 0, 0, 0)
@ -243,7 +227,6 @@ def test_datetime_typeerror():
rdt.make_datetime("2011", 1, 1, 0, 0, 0, 0) rdt.make_datetime("2011", 1, 1, 0, 0, 0, 0)
@xfail_macos_datetime_bounds
@given(dt=st.datetimes(MIN_DATETIME, MAX_DATETIME)) @given(dt=st.datetimes(MIN_DATETIME, MAX_DATETIME))
@example(dt=pdt.datetime(1970, 1, 2, 0, 0)) @example(dt=pdt.datetime(1970, 1, 2, 0, 0))
def test_datetime_from_timestamp(dt): def test_datetime_from_timestamp(dt):

View File

@ -1,10 +1,10 @@
[tox] [tox]
envlist = py35, envlist = py36,
py36,
py37, py37,
py38, py38,
py39,
pypy3 pypy3
minversion = 3.4.0 minversion = 3.6.0
skip_missing_interpreters = true skip_missing_interpreters = true
isolated_build = true isolated_build = true

View File

@ -267,7 +267,7 @@ fn impl_class(
quote! { quote! {
impl pyo3::freelist::PyClassWithFreeList for #cls { impl pyo3::freelist::PyClassWithFreeList for #cls {
#[inline] #[inline]
fn get_free_list(_py: pyo3::Python) -> &'static mut pyo3::freelist::FreeList<*mut pyo3::ffi::PyObject> { fn get_free_list(_py: pyo3::Python) -> &mut pyo3::freelist::FreeList<*mut pyo3::ffi::PyObject> {
static mut FREELIST: *mut pyo3::freelist::FreeList<*mut pyo3::ffi::PyObject> = 0 as *mut _; static mut FREELIST: *mut pyo3::freelist::FreeList<*mut pyo3::ffi::PyObject> = 0 as *mut _;
unsafe { unsafe {
if FREELIST.is_null() { if FREELIST.is_null() {

View File

@ -308,7 +308,6 @@ impl_native_exception!(
impl_native_exception!(PyOSError, OSError, PyExc_OSError, ffi::PyOSErrorObject); impl_native_exception!(PyOSError, OSError, PyExc_OSError, ffi::PyOSErrorObject);
impl_native_exception!(PyImportError, ImportError, PyExc_ImportError); impl_native_exception!(PyImportError, ImportError, PyExc_ImportError);
#[cfg(Py_3_6)]
impl_native_exception!( impl_native_exception!(
PyModuleNotFoundError, PyModuleNotFoundError,
ModuleNotFoundError, ModuleNotFoundError,

View File

@ -1,4 +1,4 @@
#[cfg(all(Py_3_6, not(Py_LIMITED_API)))] #[cfg(not(Py_LIMITED_API))]
use crate::ffi::code::FreeFunc; use crate::ffi::code::FreeFunc;
use crate::ffi::object::PyObject; use crate::ffi::object::PyObject;
use crate::ffi::pystate::PyThreadState; use crate::ffi::pystate::PyThreadState;
@ -49,8 +49,7 @@ extern "C" {
fn _Py_CheckRecursiveCall(_where: *mut c_char) -> c_int; fn _Py_CheckRecursiveCall(_where: *mut c_char) -> c_int;
} }
// TODO: Py_EnterRecursiveCall etc. // TODO: Py_EnterRecursiveCall etc
#[cfg(Py_3_6)]
pub type _PyFrameEvalFunction = pub type _PyFrameEvalFunction =
extern "C" fn(*mut crate::ffi::PyFrameObject, c_int) -> *mut PyObject; extern "C" fn(*mut crate::ffi::PyFrameObject, c_int) -> *mut PyObject;
@ -59,12 +58,11 @@ extern "C" {
pub fn PyEval_GetFuncDesc(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_GetCallStats(arg1: *mut PyObject) -> *mut PyObject;
pub fn PyEval_EvalFrame(arg1: *mut crate::ffi::PyFrameObject) -> *mut PyObject; pub fn PyEval_EvalFrame(arg1: *mut crate::ffi::PyFrameObject) -> *mut PyObject;
#[cfg(Py_3_6)]
pub fn _PyEval_EvalFrameDefault( pub fn _PyEval_EvalFrameDefault(
arg1: *mut crate::ffi::PyFrameObject, arg1: *mut crate::ffi::PyFrameObject,
exc: c_int, exc: c_int,
) -> *mut PyObject; ) -> *mut PyObject;
#[cfg(all(Py_3_6, not(Py_LIMITED_API)))] #[cfg(not(Py_LIMITED_API))]
pub fn _PyEval_RequestCodeExtraIndex(func: FreeFunc) -> c_int; pub fn _PyEval_RequestCodeExtraIndex(func: FreeFunc) -> c_int;
pub fn PyEval_EvalFrameEx(f: *mut crate::ffi::PyFrameObject, exc: c_int) -> *mut PyObject; pub fn PyEval_EvalFrameEx(f: *mut crate::ffi::PyFrameObject, exc: c_int) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyEval_SaveThread")] #[cfg_attr(PyPy, link_name = "PyPyEval_SaveThread")]

View File

@ -14,7 +14,6 @@ pub struct PyCodeObject {
pub co_nlocals: c_int, pub co_nlocals: c_int,
pub co_stacksize: c_int, pub co_stacksize: c_int,
pub co_flags: c_int, pub co_flags: c_int,
#[cfg(Py_3_6)]
pub co_firstlineno: c_int, pub co_firstlineno: c_int,
pub co_code: *mut PyObject, pub co_code: *mut PyObject,
pub co_consts: *mut PyObject, pub co_consts: *mut PyObject,
@ -25,12 +24,9 @@ pub struct PyCodeObject {
pub co_cell2arg: *mut c_uchar, pub co_cell2arg: *mut c_uchar,
pub co_filename: *mut PyObject, pub co_filename: *mut PyObject,
pub co_name: *mut PyObject, pub co_name: *mut PyObject,
#[cfg(not(Py_3_6))]
pub co_firstlineno: c_int,
pub co_lnotab: *mut PyObject, pub co_lnotab: *mut PyObject,
pub co_zombieframe: *mut c_void, pub co_zombieframe: *mut c_void,
pub co_weakreflist: *mut PyObject, pub co_weakreflist: *mut PyObject,
#[cfg(Py_3_6)]
pub co_extra: *mut c_void, pub co_extra: *mut c_void,
#[cfg(Py_3_8)] #[cfg(Py_3_8)]
pub co_opcache_map: *mut c_uchar, pub co_opcache_map: *mut c_uchar,
@ -70,8 +66,6 @@ pub const CO_FUTURE_BARRY_AS_BDFL: c_int = 0x4_0000;
pub const CO_FUTURE_GENERATOR_STOP: c_int = 0x8_0000; pub const CO_FUTURE_GENERATOR_STOP: c_int = 0x8_0000;
pub const CO_MAXBLOCKS: usize = 20; pub const CO_MAXBLOCKS: usize = 20;
#[cfg(Py_3_6)]
pub type FreeFunc = extern "C" fn(*mut c_void) -> c_void; pub type FreeFunc = extern "C" fn(*mut c_void) -> c_void;
#[cfg_attr(windows, link(name = "pythonXY"))] #[cfg_attr(windows, link(name = "pythonXY"))]
@ -80,13 +74,11 @@ extern "C" {
} }
extern "C" { extern "C" {
#[cfg(Py_3_6)]
pub fn _PyCode_GetExtra( pub fn _PyCode_GetExtra(
code: *mut PyObject, code: *mut PyObject,
index: Py_ssize_t, index: Py_ssize_t,
extra: *const *mut c_void, extra: *const *mut c_void,
) -> c_int; ) -> c_int;
#[cfg(Py_3_6)]
pub fn _PyCode_SetExtra(code: *mut PyObject, index: Py_ssize_t, extra: *mut c_void) -> c_int; pub fn _PyCode_SetExtra(code: *mut PyObject, index: Py_ssize_t, extra: *mut c_void) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyCode_New")] #[cfg_attr(PyPy, link_name = "PyPyCode_New")]

View File

@ -29,7 +29,7 @@ pub struct PyDateTime_CAPI {
pub TimeType: *mut PyTypeObject, pub TimeType: *mut PyTypeObject,
pub DeltaType: *mut PyTypeObject, pub DeltaType: *mut PyTypeObject,
pub TZInfoType: *mut PyTypeObject, pub TZInfoType: *mut PyTypeObject,
#[cfg(Py_3_7)] #[cfg(all(Py_3_7, not(PyPy)))]
pub TimeZone_UTC: *mut PyObject, pub TimeZone_UTC: *mut PyObject,
#[cfg_attr(PyPy, link_name = "_PyPyDate_FromDate")] #[cfg_attr(PyPy, link_name = "_PyPyDate_FromDate")]
pub Date_FromDate: unsafe extern "C" fn( pub Date_FromDate: unsafe extern "C" fn(
@ -67,7 +67,7 @@ pub struct PyDateTime_CAPI {
normalize: c_int, normalize: c_int,
cls: *mut PyTypeObject, cls: *mut PyTypeObject,
) -> *mut PyObject, ) -> *mut PyObject,
#[cfg(Py_3_7)] #[cfg(all(Py_3_7, not(PyPy)))]
pub TimeZone_FromTimeZone: pub TimeZone_FromTimeZone:
unsafe extern "C" fn(offset: *mut PyObject, name: *mut PyObject) -> *mut PyObject, unsafe extern "C" fn(offset: *mut PyObject, name: *mut PyObject) -> *mut PyObject,
@ -80,7 +80,7 @@ pub struct PyDateTime_CAPI {
// Defined for PyPy as `PyDate_FromTimestamp` // Defined for PyPy as `PyDate_FromTimestamp`
pub Date_FromTimestamp: pub Date_FromTimestamp:
unsafe extern "C" fn(cls: *mut PyTypeObject, args: *mut PyObject) -> *mut PyObject, unsafe extern "C" fn(cls: *mut PyTypeObject, args: *mut PyObject) -> *mut PyObject,
#[cfg(Py_3_6)] #[cfg(not(PyPy))]
pub DateTime_FromDateAndTimeAndFold: unsafe extern "C" fn( pub DateTime_FromDateAndTimeAndFold: unsafe extern "C" fn(
year: c_int, year: c_int,
month: c_int, month: c_int,
@ -93,7 +93,7 @@ pub struct PyDateTime_CAPI {
fold: c_int, fold: c_int,
cls: *mut PyTypeObject, cls: *mut PyTypeObject,
) -> *mut PyObject, ) -> *mut PyObject,
#[cfg(Py_3_6)] #[cfg(not(PyPy))]
pub Time_FromTimeAndFold: unsafe extern "C" fn( pub Time_FromTimeAndFold: unsafe extern "C" fn(
hour: c_int, hour: c_int,
minute: c_int, minute: c_int,
@ -154,6 +154,7 @@ const _PyDateTime_DATETIME_DATASIZE: usize = 10;
/// Structure representing a `datetime.date` /// Structure representing a `datetime.date`
pub struct PyDateTime_Date { pub struct PyDateTime_Date {
pub ob_base: PyObject, pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t, pub hashcode: Py_hash_t,
pub hastzinfo: c_char, pub hastzinfo: c_char,
pub data: [c_uchar; _PyDateTime_DATE_DATASIZE], pub data: [c_uchar; _PyDateTime_DATE_DATASIZE],
@ -164,10 +165,12 @@ pub struct PyDateTime_Date {
/// Structure representing a `datetime.time` /// Structure representing a `datetime.time`
pub struct PyDateTime_Time { pub struct PyDateTime_Time {
pub ob_base: PyObject, pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t, pub hashcode: Py_hash_t,
pub hastzinfo: c_char, pub hastzinfo: c_char,
#[cfg(not(PyPy))]
pub data: [c_uchar; _PyDateTime_TIME_DATASIZE], pub data: [c_uchar; _PyDateTime_TIME_DATASIZE],
#[cfg(Py_3_6)] #[cfg(not(PyPy))]
pub fold: c_uchar, pub fold: c_uchar,
pub tzinfo: *mut PyObject, pub tzinfo: *mut PyObject,
} }
@ -177,10 +180,12 @@ pub struct PyDateTime_Time {
/// Structure representing a `datetime.datetime` /// Structure representing a `datetime.datetime`
pub struct PyDateTime_DateTime { pub struct PyDateTime_DateTime {
pub ob_base: PyObject, pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t, pub hashcode: Py_hash_t,
pub hastzinfo: c_char, pub hastzinfo: c_char,
#[cfg(not(PyPy))]
pub data: [c_uchar; _PyDateTime_DATETIME_DATASIZE], pub data: [c_uchar; _PyDateTime_DATETIME_DATASIZE],
#[cfg(Py_3_6)] #[cfg(not(PyPy))]
pub fold: c_uchar, pub fold: c_uchar,
pub tzinfo: *mut PyObject, pub tzinfo: *mut PyObject,
} }
@ -190,6 +195,7 @@ pub struct PyDateTime_DateTime {
/// Structure representing a `datetime.timedelta` /// Structure representing a `datetime.timedelta`
pub struct PyDateTime_Delta { pub struct PyDateTime_Delta {
pub ob_base: PyObject, pub ob_base: PyObject,
#[cfg(not(PyPy))]
pub hashcode: Py_hash_t, pub hashcode: Py_hash_t,
pub days: c_int, pub days: c_int,
pub seconds: c_int, pub seconds: c_int,
@ -381,7 +387,6 @@ macro_rules! _PyDateTime_GET_MICROSECOND {
}; };
} }
#[cfg(Py_3_6)]
#[cfg(not(PyPy))] #[cfg(not(PyPy))]
macro_rules! _PyDateTime_GET_FOLD { macro_rules! _PyDateTime_GET_FOLD {
($o: expr) => { ($o: expr) => {
@ -429,13 +434,10 @@ pub unsafe fn PyDateTime_DATE_GET_MICROSECOND(o: *mut PyObject) -> c_int {
_PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE) _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_DateTime), _PyDateTime_DATE_DATASIZE)
} }
#[cfg(Py_3_6)]
#[inline] #[inline]
#[cfg(not(PyPy))] #[cfg(not(PyPy))]
/// Retrieve the fold component of a `PyDateTime_DateTime`. /// Retrieve the fold component of a `PyDateTime_DateTime`.
/// Returns a signed integer in the interval `[0, 1]` /// Returns a signed integer in the interval `[0, 1]`
///
/// Added in version Python 3.6
pub unsafe fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_uchar { pub unsafe fn PyDateTime_DATE_GET_FOLD(o: *mut PyObject) -> c_uchar {
_PyDateTime_GET_FOLD!(o as *mut PyDateTime_DateTime) _PyDateTime_GET_FOLD!(o as *mut PyDateTime_DateTime)
} }
@ -482,12 +484,10 @@ pub unsafe fn PyDateTime_TIME_GET_MICROSECOND(o: *mut PyObject) -> c_int {
_PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_Time), 0) _PyDateTime_GET_MICROSECOND!((o as *mut PyDateTime_Time), 0)
} }
#[cfg(all(Py_3_6, not(PyPy)))] #[cfg(not(PyPy))]
#[inline] #[inline]
/// Retrieve the fold component of a `PyDateTime_Time`. /// Retrieve the fold component of a `PyDateTime_Time`.
/// Returns a signed integer in the interval `[0, 1]` /// Returns a signed integer in the interval `[0, 1]`
///
/// Added in version Python 3.6
pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_uchar { pub unsafe fn PyDateTime_TIME_GET_FOLD(o: *mut PyObject) -> c_uchar {
_PyDateTime_GET_FOLD!(o as *mut PyDateTime_Time) _PyDateTime_GET_FOLD!(o as *mut PyDateTime_Time)
} }

View File

@ -30,7 +30,6 @@ pub struct PyDictKeysObject {
pub struct PyDictObject { pub struct PyDictObject {
pub ob_base: PyObject, pub ob_base: PyObject,
pub ma_used: Py_ssize_t, pub ma_used: Py_ssize_t,
#[cfg(Py_3_6)]
pub ma_version_tag: u64, pub ma_version_tag: u64,
pub ma_keys: *mut PyDictKeysObject, pub ma_keys: *mut PyDictKeysObject,
pub ma_values: *mut *mut PyObject, pub ma_values: *mut *mut PyObject,

View File

@ -27,7 +27,6 @@ extern "C" {
#[cfg_attr(windows, link(name = "pythonXY"))] #[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" { extern "C" {
pub static mut Py_FileSystemDefaultEncoding: *const c_char; pub static mut Py_FileSystemDefaultEncoding: *const c_char;
#[cfg(Py_3_6)]
pub static mut Py_FileSystemDefaultEncodeErrors: *const c_char; pub static mut Py_FileSystemDefaultEncodeErrors: *const c_char;
pub static mut Py_HasFileSystemDefaultEncoding: c_int; pub static mut Py_HasFileSystemDefaultEncoding: c_int;
} }

View File

@ -58,20 +58,12 @@ pub unsafe fn PyCoroWrapper_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &mut _PyCoroWrapper_Type) PyObject_TypeCheck(op, &mut _PyCoroWrapper_Type)
} }
#[cfg(Py_3_6)]
#[cfg_attr(windows, link(name = "pythonXY"))] #[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" { extern "C" {
pub static mut PyAsyncGen_Type: PyTypeObject; pub static mut PyAsyncGen_Type: PyTypeObject;
} }
#[cfg(Py_3_6)]
#[inline] #[inline]
pub unsafe fn PyAsyncGen_Check(op: *mut PyObject) -> c_int { pub unsafe fn PyAsyncGen_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, &mut PyAsyncGen_Type) PyObject_TypeCheck(op, &mut PyAsyncGen_Type)
} }
#[cfg(not(Py_3_6))]
#[inline]
pub unsafe fn PyAsyncGen_Check(_op: *mut PyObject) -> c_int {
0
}

View File

@ -34,7 +34,6 @@ pub use self::moduleobject::*;
pub use self::object::*; pub use self::object::*;
pub use self::objectabstract::*; pub use self::objectabstract::*;
pub use self::objimpl::*; pub use self::objimpl::*;
#[cfg(Py_3_6)]
pub use self::osmodule::*; pub use self::osmodule::*;
pub use self::pyarena::*; pub use self::pyarena::*;
pub use self::pycapsule::*; pub use self::pycapsule::*;
@ -124,7 +123,6 @@ mod pythonrun; // TODO some functions need to be moved to pylifecycle
mod ceval; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 mod ceval; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
mod import; mod import;
mod intrcheck; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 mod intrcheck; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5
#[cfg(Py_3_6)]
mod osmodule; mod osmodule;
mod sysmodule; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5 mod sysmodule; // TODO supports PEP-384 only; needs adjustment for Python 3.3 and 3.5

View File

@ -1,4 +1,3 @@
// This header is new in Python 3.6
use crate::ffi::object::PyObject; use crate::ffi::object::PyObject;
extern "C" { extern "C" {

View File

@ -32,6 +32,6 @@ extern "C" {
#[cfg_attr(PyPy, link_name = "PyPy_HashRandomizationFlag")] #[cfg_attr(PyPy, link_name = "PyPy_HashRandomizationFlag")]
pub static mut Py_HashRandomizationFlag: c_int; pub static mut Py_HashRandomizationFlag: c_int;
pub static mut Py_IsolatedFlag: c_int; pub static mut Py_IsolatedFlag: c_int;
#[cfg(all(Py_3_6, windows))] #[cfg(windows)]
pub static mut Py_LegacyWindowsStdioFlag: c_int; pub static mut Py_LegacyWindowsStdioFlag: c_int;
} }

View File

@ -201,7 +201,6 @@ extern "C" {
pub static mut PyExc_OSError: *mut PyObject; pub static mut PyExc_OSError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_ImportError")] #[cfg_attr(PyPy, link_name = "PyPyExc_ImportError")]
pub static mut PyExc_ImportError: *mut PyObject; pub static mut PyExc_ImportError: *mut PyObject;
#[cfg(Py_3_6)]
#[cfg_attr(PyPy, link_name = "PyPyExc_ModuleNotFoundError")] #[cfg_attr(PyPy, link_name = "PyPyExc_ModuleNotFoundError")]
pub static mut PyExc_ModuleNotFoundError: *mut PyObject; pub static mut PyExc_ModuleNotFoundError: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_IndexError")] #[cfg_attr(PyPy, link_name = "PyPyExc_IndexError")]
@ -339,7 +338,6 @@ extern "C" {
) -> *mut PyObject; ) -> *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyErr_Format")] #[cfg_attr(PyPy, link_name = "PyPyErr_Format")]
pub fn PyErr_Format(exception: *mut PyObject, format: *const c_char, ...) -> *mut PyObject; pub fn PyErr_Format(exception: *mut PyObject, format: *const c_char, ...) -> *mut PyObject;
#[cfg(Py_3_6)]
pub fn PyErr_SetImportErrorSubclass( pub fn PyErr_SetImportErrorSubclass(
arg1: *mut PyObject, arg1: *mut PyObject,
arg2: *mut PyObject, arg2: *mut PyObject,

View File

@ -6,7 +6,6 @@ extern "C" {
pub fn Py_Initialize(); pub fn Py_Initialize();
pub fn Py_InitializeEx(arg1: c_int); pub fn Py_InitializeEx(arg1: c_int);
pub fn Py_Finalize(); pub fn Py_Finalize();
#[cfg(Py_3_6)]
pub fn Py_FinalizeEx() -> c_int; pub fn Py_FinalizeEx() -> c_int;
#[cfg_attr(PyPy, link_name = "PyPy_IsInitialized")] #[cfg_attr(PyPy, link_name = "PyPy_IsInitialized")]

View File

@ -1,17 +1,14 @@
#[cfg(Py_3_6)]
use crate::ffi::ceval::_PyFrameEvalFunction; use crate::ffi::ceval::_PyFrameEvalFunction;
use crate::ffi::moduleobject::PyModuleDef; use crate::ffi::moduleobject::PyModuleDef;
use crate::ffi::object::PyObject; use crate::ffi::object::PyObject;
use std::os::raw::{c_int, c_long}; use std::os::raw::{c_int, c_long};
#[cfg(Py_3_6)]
pub const MAX_CO_EXTRA_USERS: c_int = 255; pub const MAX_CO_EXTRA_USERS: c_int = 255;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct PyInterpreterState { pub struct PyInterpreterState {
pub ob_base: PyObject, pub ob_base: PyObject,
#[cfg(Py_3_6)]
pub eval_frame: _PyFrameEvalFunction, pub eval_frame: _PyFrameEvalFunction,
} }

View File

@ -16,7 +16,6 @@ extern "C" {
format: *const c_char, format: *const c_char,
... ...
) -> c_int; ) -> c_int;
#[cfg(Py_3_6)]
pub fn PyErr_ResourceWarning( pub fn PyErr_ResourceWarning(
source: *mut PyObject, source: *mut PyObject,
stack_level: Py_ssize_t, stack_level: Py_ssize_t,

View File

@ -12,7 +12,7 @@ use std::os::raw::c_void;
/// The performance improvement applies to types that are often created and deleted in a row, /// The performance improvement applies to types that are often created and deleted in a row,
/// so that they can benefit from a freelist. /// so that they can benefit from a freelist.
pub trait PyClassWithFreeList { pub trait PyClassWithFreeList {
fn get_free_list(py: Python) -> &'static mut FreeList<*mut ffi::PyObject>; fn get_free_list(py: Python) -> &mut FreeList<*mut ffi::PyObject>;
} }
pub enum Slot<T> { pub enum Slot<T> {

View File

@ -11,7 +11,7 @@ use crate::ffi;
use crate::ffi::datetime::{PyDateTime_FromTimestamp, PyDate_FromTimestamp}; use crate::ffi::datetime::{PyDateTime_FromTimestamp, PyDate_FromTimestamp};
use crate::ffi::PyDateTimeAPI; use crate::ffi::PyDateTimeAPI;
use crate::ffi::{PyDateTime_Check, PyDate_Check, PyDelta_Check, PyTZInfo_Check, PyTime_Check}; use crate::ffi::{PyDateTime_Check, PyDate_Check, PyDelta_Check, PyTZInfo_Check, PyTime_Check};
#[cfg(all(Py_3_6, not(PyPy)))] #[cfg(not(PyPy))]
use crate::ffi::{PyDateTime_DATE_GET_FOLD, PyDateTime_TIME_GET_FOLD}; use crate::ffi::{PyDateTime_DATE_GET_FOLD, PyDateTime_TIME_GET_FOLD};
use crate::ffi::{ use crate::ffi::{
PyDateTime_DATE_GET_HOUR, PyDateTime_DATE_GET_MICROSECOND, PyDateTime_DATE_GET_MINUTE, PyDateTime_DATE_GET_HOUR, PyDateTime_DATE_GET_MICROSECOND, PyDateTime_DATE_GET_MINUTE,
@ -57,7 +57,7 @@ pub trait PyTimeAccess {
fn get_minute(&self) -> u8; fn get_minute(&self) -> u8;
fn get_second(&self) -> u8; fn get_second(&self) -> u8;
fn get_microsecond(&self) -> u32; fn get_microsecond(&self) -> u32;
#[cfg(all(Py_3_6, not(PyPy)))] #[cfg(not(PyPy))]
fn get_fold(&self) -> u8; fn get_fold(&self) -> u8;
} }
@ -223,7 +223,7 @@ impl PyTimeAccess for PyDateTime {
unsafe { PyDateTime_DATE_GET_MICROSECOND(self.as_ptr()) as u32 } unsafe { PyDateTime_DATE_GET_MICROSECOND(self.as_ptr()) as u32 }
} }
#[cfg(all(Py_3_6, not(PyPy)))] #[cfg(not(PyPy))]
fn get_fold(&self) -> u8 { fn get_fold(&self) -> u8 {
unsafe { PyDateTime_DATE_GET_FOLD(self.as_ptr()) as u8 } unsafe { PyDateTime_DATE_GET_FOLD(self.as_ptr()) as u8 }
} }
@ -262,10 +262,8 @@ impl PyTime {
} }
} }
#[cfg(Py_3_6)] #[cfg(not(PyPy))]
/// Alternate constructor that takes a `fold` argument /// Alternate constructor that takes a `fold` argument
///
/// First available in Python 3.6.
pub fn new_with_fold<'p>( pub fn new_with_fold<'p>(
py: Python<'p>, py: Python<'p>,
hour: u8, hour: u8,
@ -307,7 +305,7 @@ impl PyTimeAccess for PyTime {
unsafe { PyDateTime_TIME_GET_MICROSECOND(self.as_ptr()) as u32 } unsafe { PyDateTime_TIME_GET_MICROSECOND(self.as_ptr()) as u32 }
} }
#[cfg(all(Py_3_6, not(PyPy)))] #[cfg(not(PyPy))]
fn get_fold(&self) -> u8 { fn get_fold(&self) -> u8 {
unsafe { PyDateTime_TIME_GET_FOLD(self.as_ptr()) as u8 } unsafe { PyDateTime_TIME_GET_FOLD(self.as_ptr()) as u8 }
} }

View File

@ -121,7 +121,6 @@ fn test_datetime_utc() {
assert_approx_eq!(offset, 0f32); assert_approx_eq!(offset, 0f32);
} }
#[cfg(Py_3_6)]
static INVALID_DATES: &[(i32, u8, u8)] = &[ static INVALID_DATES: &[(i32, u8, u8)] = &[
(-1, 1, 1), (-1, 1, 1),
(0, 1, 1), (0, 1, 1),
@ -134,16 +133,13 @@ static INVALID_DATES: &[(i32, u8, u8)] = &[
(2018, 1, 32), (2018, 1, 32),
]; ];
#[cfg(Py_3_6)]
static INVALID_TIMES: &[(u8, u8, u8, u32)] = static INVALID_TIMES: &[(u8, u8, u8, u32)] =
&[(25, 0, 0, 0), (255, 0, 0, 0), (0, 60, 0, 0), (0, 0, 61, 0)]; &[(25, 0, 0, 0), (255, 0, 0, 0), (0, 60, 0, 0), (0, 0, 61, 0)];
#[cfg(Py_3_6)]
#[test] #[test]
fn test_pydate_out_of_bounds() { fn test_pydate_out_of_bounds() {
use pyo3::types::PyDate; use pyo3::types::PyDate;
// This test is an XFAIL on Python < 3.6 until bounds checking is implemented
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let py = gil.python(); let py = gil.python();
for val in INVALID_DATES { for val in INVALID_DATES {
@ -153,12 +149,10 @@ fn test_pydate_out_of_bounds() {
} }
} }
#[cfg(Py_3_6)]
#[test] #[test]
fn test_pytime_out_of_bounds() { fn test_pytime_out_of_bounds() {
use pyo3::types::PyTime; use pyo3::types::PyTime;
// This test is an XFAIL on Python < 3.6 until bounds checking is implemented
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let py = gil.python(); let py = gil.python();
for val in INVALID_TIMES { for val in INVALID_TIMES {
@ -168,13 +162,11 @@ fn test_pytime_out_of_bounds() {
} }
} }
#[cfg(Py_3_6)]
#[test] #[test]
fn test_pydatetime_out_of_bounds() { fn test_pydatetime_out_of_bounds() {
use pyo3::types::PyDateTime; use pyo3::types::PyDateTime;
use std::iter; use std::iter;
// This test is an XFAIL on Python < 3.6 until bounds checking is implemented
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let py = gil.python(); let py = gil.python();
let valid_time = (0, 0, 0, 0); let valid_time = (0, 0, 0, 0);