Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Python3 support #317

Merged
merged 52 commits into from
Feb 17, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
fc9162f
update setup.py version restrictions and add Py3 to travis
sn6uv Aug 3, 2015
e699d6a
2to3 of setup.py and cleanup
sn6uv Aug 3, 2015
b0dfba9
remove old style exceptions
sn6uv Aug 3, 2015
7b95c68
fix PEP 0263 headers
sn6uv Aug 3, 2015
d92fc29
remove __future__.with_statement since we no longer support 2.6
sn6uv Aug 3, 2015
a78c41b
update license headers
sn6uv Aug 3, 2015
2d36d77
fixup core/convert header
sn6uv Feb 10, 2016
d7746b5
replace print statements with print function
sn6uv Feb 10, 2016
87e242d
remove cmp for rich comparisons
sn6uv Feb 11, 2016
fba407f
cleanup Import comparisons
sn6uv Feb 11, 2016
0b478e4
add __future__.unicode_literals imports
sn6uv Feb 11, 2016
d6b8beb
workaround cPickle -> pickle rename
sn6uv Feb 11, 2016
f7fbf28
cleanup __future__ imports
sn6uv Feb 11, 2016
9c53a7f
(str, unicode) -> basetring
sn6uv Feb 11, 2016
1b6f936
bytecount should count bytes not str
sn6uv Feb 11, 2016
bcceda3
fix failed byte tests
sn6uv Feb 11, 2016
4195e0b
towards Py3 with python-modernize plus some manual touchups
sn6uv Feb 11, 2016
a5cee0f
signal based timeout to replace interruptingcow
sn6uv Feb 11, 2016
27b8ca8
fixup pickle binary read/write
sn6uv Feb 11, 2016
b832114
fix sympy conversion encoding bug
sn6uv Feb 11, 2016
bb647e5
require six in setup.py
sn6uv Feb 12, 2016
f9fcff7
fix Power precision bug
sn6uv Feb 13, 2016
cb10a2f
fix FixedPointList test result
sn6uv Feb 13, 2016
f0d0f5a
cleanup ParseError and ScanError
sn6uv Feb 13, 2016
b1c1651
Min/Max without hashing
sn6uv Feb 13, 2016
9fec38f
fix StringReplace None int comparison
sn6uv Feb 13, 2016
f790898
fix subtle RSolve bug
sn6uv Feb 13, 2016
0dc1d2c
DateTime division bugs
sn6uv Feb 13, 2016
674c5d7
fixup Read/Write Binary byte/str bugs
sn6uv Feb 13, 2016
fdc09ee
Compress/Uncompress encoding
sn6uv Feb 13, 2016
527a1b9
fixup asy output number precision
sn6uv Feb 13, 2016
c47a3bf
random.seed is backwards incompatible in Py3
sn6uv Feb 13, 2016
7f53567
FromCharacterCodes int/long bug
sn6uv Feb 13, 2016
f6d6d29
fix ascii_lowercase BaseForm
sn6uv Feb 13, 2016
16367dc
patch unittest encoding
sn6uv Feb 14, 2016
0348bf1
replace unichr hack with six
sn6uv Feb 14, 2016
167efbc
import code formatting tweaks
sn6uv Feb 14, 2016
c0f7076
Py3 division bugs in plot
sn6uv Feb 14, 2016
f690c38
implement Real.__hash__ (ignoring last 7 bits)
sn6uv Feb 13, 2016
f5d2676
proper hashes for all BaseExpressions
sn6uv Feb 14, 2016
41dc9b7
patch pymimesniffer for Py3
sn6uv Feb 14, 2016
f36ee50
cleanup version strings
sn6uv Feb 16, 2016
16c17ab
update PyPI classifiers and keywords
sn6uv Feb 13, 2016
017fd48
fix Py2/Py3 django views bytes/str
sn6uv Feb 16, 2016
08834ab
conditional python2 unicode input handling with codecs
sn6uv Feb 13, 2016
7126c3c
add unicode Print tests
sn6uv Feb 16, 2016
301ac62
workaround asymptote three.asy zero division bug
sn6uv Feb 16, 2016
eec24f5
update docs: new homepage and Py3
sn6uv Feb 16, 2016
0b78449
fix axes label formatting bug in Py3
sn6uv Feb 16, 2016
6ef2a8a
remove deprecated constant function handling code (never called)
sn6uv Feb 13, 2016
d4cbb45
remove old style man pages
sn6uv Feb 17, 2016
6814bcb
pep8 changes
sn6uv Feb 17, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pep8
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[pep8]
ignore = E501,W291
exclude = parsetab.py,magic.py
exclude = parsetab.py,magic.py,build/,.tox/
57 changes: 35 additions & 22 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,44 @@ language: python
python:
- 2.7
- pypy
- 3.5
- 3.4
- 3.3
- 3.2
- pypy3
env:
- SYMPY_SRC=sympy-0.7.5
- SYMPY_SRC=sympy-0.7.6
- SYMPY_SRC=master
global:
- SYMPY_SRC=sympy-0.7.6
- DOC="false"
matrix:
- CYTHON="false"
- CYTHON="true"
matrix:
fast_finish: true
include:
- python: 2.7
env:
- SYMPY_SRC=sympy-0.7.6
- TEST_DOC="true"
- python: 2.7
env:
- SYMPY_SRC=sympy-0.7.6
- CYTHON="true"
allow_failures:
- env: SYMPY_SRC=sympy-0.7.5
- env: SYMPY_SRC=master
- env:
- SYMPY_SRC=sympy-0.7.6
- TEST_DOC="true"
fast_finish: true
include:
- python: 2.7
env: DOC="true" CYTHON="false"
- python: 3.5
env: DOC="true" CYTHON="false"
- python: 2.7
env: SYMPY_SRC=master CYTHON="false"
- python: 3.5
env: SYMPY_SRC=master CYTHON="false"
exclude:
# PyPy is not compatible with Cython
- python: pypy
env: CYTHON="true"
- python: pypy3
env: CYTHON="true"
allow_failures:
- python: 3.2
- python: pypy3
- env: SYMPY_SRC=master CYTHON="false"
- env: DOC="true" CYTHON="false"
before_install:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- if [[ "$TEST_DOC" == "true" ]]; then
- if [[ "$DOC" == "true" ]]; then
sudo apt-get update -qq &&
sudo apt-get install -qq asymptote imagemagick texlive-latex-extra texlive-latex3 texlive-fonts-recommended latexmk;
fi
Expand All @@ -38,10 +51,10 @@ before_install:
- pip install git+https://github.com/sympy/sympy.git@$SYMPY_SRC
install:
- sed -i "s/'sympy==[0-9]\.[0-9]\.[0-9]', //" setup.py
- if [[ "$TEST_DOC" == "true" ]]; then python setup.py develop; else python setup.py install; fi
- if [[ "$DOC" == "true" ]]; then python setup.py develop; else python setup.py install; fi
script:
- python setup.py test
- if [[ "$TEST_DOC" == "true" ]]; then
- if [[ "$DOC" == "true" ]]; then
python mathics/test.py -o &&
python mathics/test.py -t &&
cd mathics/doc/ &&
Expand Down
73 changes: 32 additions & 41 deletions mathics/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# -*- coding: utf8 -*-
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import

# force utf8 encoding
import sys
import codecs
writer = codecs.getwriter("utf-8")
sys.stdout = writer(sys.stdout)
import platform
import sympy
import mpmath
import django
import six

from mathics.version import __version__
from mathics.core.expression import (
Expand All @@ -13,51 +19,36 @@
from mathics.core.convert import from_sympy


def get_version():
version = {}

import sympy
import mpmath
if six.PY2:
import codecs
writer = codecs.getwriter("utf-8")
sys.stdout = writer(sys.stdout)

from django.core.exceptions import ImproperlyConfigured

try:
import django
from django.conf import settings
version['django'] = django.get_version()
except (ImportError, ImproperlyConfigured):
pass
version['mathics'] = __version__
version['sympy'] = sympy.__version__
version['mpmath'] = mpmath.__version__
version['python'] = sys.subversion[0] + " " + sys.version.split('\n')[0]
return version
version_info = {
'mathics': __version__,
'sympy': sympy.__version__,
'mpmath': mpmath.__version__,
'python': platform.python_implementation() + " " + sys.version.split('\n')[0],
'django': django.__version__,
}


def get_version_string(is_server, newlines=False):
version = get_version()
result = []
result.append(u"Mathics %s" % version['mathics'])
result.append(u"on %s" % version['python'])
libs = []
if 'django' in version and is_server:
libs.append("Django %s" % version['django'])
libs += ["SymPy %s" % version['sympy'], "mpmath %s" % version['mpmath']]
result.append(u"using %s" % ", ".join(libs))
return ("\n" if newlines else " ").join(result)
version_string = '''Mathics {mathics}
on {python}
using SymPy {sympy}, mpmath {mpmath}'''.format(**version_info)


def print_version(is_server):
print "\n" + get_version_string(is_server, newlines=True)
server_version_string = version_string + ', django {django}'.format(**version_info)


def print_license():
print u"""
Copyright (C) 2011-2013 The Mathics Team.
license_string = '''\
Copyright (C) 2011-2016 The Mathics Team.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.
See the documentation for the full license.
"""
See the documentation for the full license.'''


from mathics.core.parser import parse, ScanError, ParseError
# this import is last to handle a circlular dependency on version_string
from mathics.core.parser import parse, ScanError, ParseError # nopep8
65 changes: 28 additions & 37 deletions mathics/benchmark.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
# -*- coding: utf8 -*-
#!/usr/bin/env python
# -*- coding: utf-8 -*-

u"""
Mathics: a general-purpose computer algebra system
Copyright (C) 2011-2013 The Mathics Team
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
import sys
import time
from argparse import ArgumentParser

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
import mathics
from mathics.core.parser import parse
from mathics.core.definitions import Definitions
from mathics.core.evaluation import Evaluation

from six.moves import map
from six.moves import range

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""

# Default number of times to repeat each benchmark. None -> Automatic
TESTS_PER_BENCHMARK = None
Expand Down Expand Up @@ -64,15 +64,6 @@
"Sin[" * 1000 + '0.5' + "]" * 1000,
]

import sys
import time
from argparse import ArgumentParser

import mathics
from mathics.core.parser import parse
from mathics.core.definitions import Definitions
from mathics.core.evaluation import Evaluation

definitions = Definitions(add_builtin=True)
evaluation = None

Expand All @@ -96,13 +87,13 @@ def timeit(func, repeats=None):
times = []
if repeats is not None:
# Fixed number of repeats
for i in xrange(repeats):
for i in range(repeats):
times.append(time.clock())
func()
else:
# Automatic number of repeats
repeats = 10000
for i in xrange(repeats):
for i in range(repeats):
times.append(time.clock())
func()
if any(i == j for j in (5, 10, 100, 1000, 5000)):
Expand All @@ -115,8 +106,8 @@ def timeit(func, repeats=None):
average_time = format_time_units((times[-1] - times[0]) / repeats)
best_time = format_time_units(
min([times[i + 1] - times[i] for i in range(repeats)]))
print " {0:5n} loops, avg: {1} per loop, best: {2} per loop".format(
repeats, average_time, best_time)
print(" {0:5n} loops, avg: {1} per loop, best: {2} per loop".format(
repeats, average_time, best_time))


def truncate_line(string):
Expand All @@ -126,34 +117,34 @@ def truncate_line(string):


def benchmark_parse(expression_string):
print " '{0}'".format(truncate_line(expression_string))
print(" '{0}'".format(truncate_line(expression_string)))
timeit(lambda: parse(expression_string, definitions))


def benchmark_format(expression_string):
print " '{0}'".format(expression_string)
print(" '{0}'".format(expression_string))
expr = parse(expression_string, definitions)
timeit(lambda: expr.default_format(evaluation, "FullForm"))


def benchmark_expression(expression_string):
print " '{0}'".format(expression_string)
print(" '{0}'".format(expression_string))
expr = parse(expression_string, definitions)
timeit(lambda: expr.evaluate(evaluation))


def benchmark_section(section_name):
print section_name
print(section_name)
for benchmark in BENCHMARKS.get(section_name):
benchmark_expression(benchmark)
print ""
print()


def benchmark_all():
print "EVALUATION BENCHMARKS:"
print("EVALUATION BENCHMARKS:")
for section_name in sorted(BENCHMARKS.keys()):
benchmark_section(section_name)
print "PARSING BENCHMARKS:"
print("PARSING BENCHMARKS:")
for expression_string in PARSING_BENCHMARKS:
benchmark_parse(expression_string)

Expand Down Expand Up @@ -186,8 +177,8 @@ def main():

try:
evaluation = Evaluation("", definitions, catch_interrupt=False)
except Exception, exc:
print "Exception {0}".format(exc)
except Exception as exc:
print("Exception {0}".format(exc))
info = sys.exc_info()
sys.excepthook(*info)
sys.exit(-1)
Expand Down
32 changes: 9 additions & 23 deletions mathics/builtin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,8 @@
# -*- coding: utf8 -*-
#!/usr/bin/env python
# -*- coding: utf-8 -*-

u"""
Mathics: a general-purpose computer algebra system
Copyright (C) 2011-2013 The Mathics Team

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from __future__ import unicode_literals
from __future__ import absolute_import

from mathics.builtin import (
algebra, arithmetic, assignment, attributes, calculus, combinatorial,
Expand Down Expand Up @@ -57,11 +43,11 @@ def is_builtin(var):
vars = dir(module)
for name in vars:
var = getattr(module, name)
if (hasattr(var, '__module__')
and var.__module__.startswith('mathics.builtin.')
and var.__module__ != 'mathics.builtin.base'
and is_builtin(var) and not name.startswith('_')
and var.__module__ == module.__name__):
if (hasattr(var, '__module__') and
var.__module__.startswith('mathics.builtin.') and
var.__module__ != 'mathics.builtin.base' and
is_builtin(var) and not name.startswith('_') and
var.__module__ == module.__name__): # nopep8

instance = var(expression=False)

Expand Down
7 changes: 6 additions & 1 deletion mathics/builtin/algebra.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# -*- coding: utf8 -*-
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import unicode_literals
from __future__ import absolute_import

from mathics.builtin.base import Builtin
from mathics.core.expression import Expression, Integer
from mathics.core.convert import from_sympy

import sympy
import mpmath
from six.moves import range


def sympy_factor(expr_sympy):
Expand Down
Loading