Skip to content

Commit

Permalink
Merge pull request #16 from SethMMorton/3.7-support
Browse files Browse the repository at this point in the history
3.7 support
  • Loading branch information
SethMMorton authored Aug 2, 2018
2 parents 4dd0ac7 + 4adb85d commit a159a03
Show file tree
Hide file tree
Showing 38 changed files with 3,497 additions and 3,291 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
*.py[co]
.venv

# Packages
*.egg
Expand Down
65 changes: 51 additions & 14 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,65 @@
language: python
python:
- "2.7"
- "3.4"
- "3.5"
- "3.6"
os: linux

sudo: false
os:
- linux
matrix:
include:
- python: 2.7
dist: trusty
sudo: false
env: CC=clang
- python: 2.7
dist: trusty
sudo: false
env: CC=gcc CFLAGS="--coverage -O0"
- python: 3.4
dist: trusty
sudo: false
env: CC=clang
- python: 3.4
dist: trusty
sudo: false
env: CC=gcc CFLAGS="--coverage -O0"
- python: 3.5
dist: trusty
sudo: false
env: CC=clang
- python: 3.5
dist: trusty
sudo: false
env: CC=gcc CFLAGS="--coverage -O0"
- python: 3.6
dist: trusty
sudo: false
env: CC=clang
- python: 3.6
dist: trusty
sudo: false
env: CC=gcc CFLAGS="--coverage -O0"
- python: 3.7
dist: xenial
sudo: true
env: CC=clang
- python: 3.7
dist: xenial
sudo: true
env: CC=gcc CFLAGS="--coverage -O0"

branches:
except:
- /^appveyor-.*$/

env:
- CC=clang
- CC=gcc CFLAGS="--coverage -O0"

install:
- pip install -U pip
- pip install tox-travis codecov
- pip install codecov pipenv
- pipenv install --dev --skip-lock

before_script:
- python dev/patch_doctest.py

script:
- tox
- python setup.py install
- python -m doctest fastnumbers
- pytest --doctest-glob=README.rst

after_success:
- (test "$CC" == "gcc" && codecov --gcov-args '-o build/temp.*/src') || echo "skipping coverage for $CC"
14 changes: 8 additions & 6 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@ environment:
- PYTHON: "C:\\Python34"
- PYTHON: "C:\\Python35"
- PYTHON: "C:\\Python36"
- PYTHON: "C:\\Python37"
- PYTHON: "C:\\Python27-x64"
- PYTHON: "C:\\Python34-x64"
DISTUTILS_USE_SDK: "1"
- PYTHON: "C:\\Python35-x64"
- PYTHON: "C:\\Python36-x64"
- PYTHON: "C:\\Python37-x64"

install:
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
- "python -m pip install -U pip"
- "python -m pip install tox"
- "python -m pip install pipenv"
- "pipenv install --dev --skip-lock"
- "pipenv run python dev/patch_doctest.py"

build: false

Expand All @@ -27,11 +31,9 @@ test_script:
# If you don't need to build C extensions on 64-bit Python 3.3 or 3.4,
# you can remove "build.cmd" from the front of the command, as it's
# only needed to support those cases.
# Note that you must use the environment variable %PYTHON% to refer to
# the interpreter you're using - Appveyor does not do anything special
# to put the Python evrsion you want to use on PATH.
# tox will build for us as well.
- "dev\\build.cmd %PYTHON%\\Scripts\\tox.exe -e pywin"
- "dev\\build.cmd pipenv run python setup.py install"
- "pipenv run python -m doctest fastnumbers"
- "pipenv run pytest --doctest-glob=README.rst"

#on_success:
# You can use this step to upload your artifacts to a public website.
Expand Down
20 changes: 20 additions & 0 deletions dev/astyle.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# PEP7 formatting style.
--break-closing-braces
--break-one-line-headers
--attach-closing-while
--add-braces
--break-return-type
--indent=spaces=4
--attach-extern-c
--max-code-length=79
--max-continuation-indent=70
--break-after-logical
--mode=c

# Personal preferences.
--indent-preproc-define
--pad-comma
--pad-header
--pad-oper
--unpad-paren
--align-pointer=name
4 changes: 4 additions & 0 deletions dev/fmt.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#! /bin/bash

find src include -type f | grep -E -v "(pstdint|docstrings|fn_bool).h" | xargs astyle --options=dev/astyle.cfg --suffix=none
black --exclude builtin_tests tests
19 changes: 6 additions & 13 deletions include/number_handling.h → include/numbers.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
#include <Python.h>
#include <limits.h>
#include "fn_bool.h"
#include "parsing.h"
#include "object_handling.h"
#include "options.h"

#ifdef __cplusplus
Expand All @@ -35,8 +33,8 @@ extern "C" {
#if PY_MAJOR_VERSION >= 3 && !defined(PY_NO_SHORT_FLOAT_REPR)
#define PyFloat_from_NaN(negative) PyFloat_FromDouble(_Py_dg_stdnan(negative));
#else
#define PyFloat_from_NaN(negative) (negative) ? PyFloat_FromDouble(-Py_NAN) \
: PyFloat_FromDouble(Py_NAN);
#define PyFloat_from_NaN(negative) \
(negative) ? PyFloat_FromDouble(-Py_NAN) : PyFloat_FromDouble(Py_NAN);
#endif

/* Quickies for raising errors. Try to mimic what Python would say. */
Expand Down Expand Up @@ -77,20 +75,15 @@ extern "C" {

/* Declarations */

PyObject*
PyFloat_to_PyInt(PyObject *fobj, const struct Options *options);
PyObject *
PyFloat_to_PyInt(PyObject *fobj, const Options *options);

bool
PyFloat_is_Intlike(PyObject *obj);

/* Not actually used... keeping in code for posterity's sake.
bool
double_is_intlike(const double val);
*/

PyObject*
PyObject *
PyNumber_to_PyNumber(PyObject *obj, const PyNumberType type,
const struct Options *options);
const Options *options);

bool
PyNumber_is_type(PyObject *obj, const PyNumberType type);
Expand Down
16 changes: 4 additions & 12 deletions include/object_handling.h → include/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,21 @@
*/

#include <Python.h>
#include "fn_bool.h"
#include "options.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef enum PyNumberType { REAL, FLOAT, INT, INTLIKE, FORCEINT } PyNumberType;

/* All the awesome MACROS */

#define PyBool_from_bool(b) ((b) ? (Py_INCREF(Py_True), Py_True) \
: (Py_INCREF(Py_False), Py_False))

/* Declarations */

PyObject*
PyObject *
PyObject_to_PyNumber(PyObject *obj, const PyNumberType type,
const struct Options *options);
const Options *options);

PyObject*
PyObject *
PyObject_is_number(PyObject *obj, const PyNumberType type,
const struct Options *options);
const Options *options);

#ifdef __cplusplus
} /* extern "C" */
Expand Down
93 changes: 49 additions & 44 deletions include/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,52 @@
#include <limits.h>
#include "fn_bool.h"

/* Selector for the type of number to check/convert. */
typedef enum PyNumberType { REAL, FLOAT, INT, INTLIKE, FORCEINT } PyNumberType;

/* This struct holds all the user options.
* Makes adding new future options easier to manage.
*/
struct Options {
PyObject* retval;
PyObject* input;
PyObject* key;
PyObject* handle_inf;
PyObject* handle_nan;
PyObject* coerce;
PyObject* num_only;
PyObject* str_only;
typedef struct Options {
PyObject *retval;
PyObject *input;
PyObject *key;
PyObject *handle_inf;
PyObject *handle_nan;
PyObject *coerce;
PyObject *num_only;
PyObject *str_only;
bool allow_uni;
int base;
};
} Options;

/* Convenience for initializing.
* Older MSVC does not like designated initializers.
*/
#define init_Options_convert { /*.retval =*/ NULL, \
/*.input =*/ NULL, \
/*.key =*/ NULL, \
/*.handle_inf =*/ NULL, \
/*.handle_nan =*/ NULL, \
/*.coerce =*/ Py_True, \
/*.num_only =*/ NULL, \
/*.str_only =*/ NULL, \
/*.allow_uni =*/ true, \
/*.base =*/ INT_MIN, \
}
#define init_Options_check { /*.retval =*/ Py_None, \
/*.input =*/ NULL, \
/*.key =*/ NULL, \
/*.handle_inf =*/ Py_False, \
/*.handle_nan =*/ Py_False, \
/*.coerce =*/ NULL, \
/*.num_only =*/ Py_False, \
/*.str_only =*/ Py_False, \
/*.allow_uni =*/ true, \
/*.base =*/ INT_MIN, \
}
#define init_Options_convert { \
/*.retval =*/ NULL, \
/*.input =*/ NULL, \
/*.key =*/ NULL, \
/*.handle_inf =*/ NULL, \
/*.handle_nan =*/ NULL, \
/*.coerce =*/ Py_True, \
/*.num_only =*/ NULL, \
/*.str_only =*/ NULL, \
/*.allow_uni =*/ true, \
/*.base =*/ INT_MIN, \
}
#define init_Options_check { \
/*.retval =*/ Py_None, \
/*.input =*/ NULL, \
/*.key =*/ NULL, \
/*.handle_inf =*/ Py_False, \
/*.handle_nan =*/ Py_False, \
/*.coerce =*/ NULL, \
/*.num_only =*/ Py_False, \
/*.str_only =*/ Py_False, \
/*.allow_uni =*/ true, \
/*.base =*/ INT_MIN, \
}

/* Some query MACROs. Each expects a pointer. */
#define Options_Coerce_True(o) PyObject_IsTrue((o)->coerce)
Expand All @@ -63,29 +68,29 @@ struct Options {

/* Set allow unicode. */
#define Options_Set_Disallow_UnicodeCharacter(o) \
do { \
(o)->retval = NULL; \
(o)->allow_uni = false; \
do { \
(o)->retval = NULL; \
(o)->allow_uni = false; \
} while (0)

/* MACRO to return the correct result based on user-input.
* Expects the Options struct as a pointer.
*/
#define Options_Return_Correct_Result_On_Error(o) \
(Options_Should_Raise(o) ? \
NULL : \
((o)->key != NULL ? \
PyObject_CallFunctionObjArgs((o)->key, (o)->retval, NULL) : \
(Py_INCREF((o)->retval), (o)->retval) \
))
#define Options_Return_Correct_Result_On_Error(o) \
(Options_Should_Raise(o) ? \
NULL : \
((o)->key != NULL ? \
PyObject_CallFunctionObjArgs((o)->key, (o)->retval, NULL) : \
(Py_INCREF((o)->retval), (o)->retval) \
))

/* MACRO to set the correct return value based on given input.
* Expects the Options struct NOT as a pointer.
*/
#define Options_Set_Return_Value(o, input, default_value, raise) \
(o).input = input; \
(o).retval = PyObject_IsTrue(raise) \
? NULL \
: (((o).key != NULL || default_value == NULL) ? input : default_value)
? NULL \
: (((o).key != NULL || default_value == NULL) ? input : default_value)

#endif /* FN_OPTIONS */
Loading

0 comments on commit a159a03

Please sign in to comment.