Skip to content

Commit

Permalink
Merge pull request #411 from brian-team/remove_python26_support
Browse files Browse the repository at this point in the history
Remove Python 2.6 support
  • Loading branch information
thesamovar committed Feb 25, 2015
2 parents 716547f + e33e008 commit e87111a
Show file tree
Hide file tree
Showing 21 changed files with 63 additions and 360 deletions.
20 changes: 9 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
language: python
matrix:
include:
- python: "2.6"
env: STANDALONE=no CYTHON=yes MINIMAL_VERSIONS=no
include:
- python: "2.7"
env: STANDALONE=no CYTHON=yes MINIMAL_VERSIONS=no
env: STANDALONE=no CYTHON=yes MINIMAL_VERSIONS=no REPORT_COVERAGE=yes
- python: "2.7"
env: STANDALONE=no CYTHON=yes MINIMAL_VERSIONS=yes
env: STANDALONE=no CYTHON=yes MINIMAL_VERSIONS=yes REPORT_COVERAGE=no
- python: "3.3"
env: STANDALONE=no CYTHON=yes MINIMAL_VERSIONS=no
env: STANDALONE=no CYTHON=yes MINIMAL_VERSIONS=no REPORT_COVERAGE=no
- python: "3.3"
env: STANDALONE=no CYTHON=yes MINIMAL_VERSIONS=yes
env: STANDALONE=no CYTHON=yes MINIMAL_VERSIONS=yes REPORT_COVERAGE=no
- python: "3.4"
env: STANDALONE=no CYTHON=yes MINIMAL_VERSIONS=no
env: STANDALONE=no CYTHON=yes MINIMAL_VERSIONS=no REPORT_COVERAGE=no
- python: "2.7"
env: STANDALONE=yes CYTHON=no MINIMAL_VERSIONS=no
env: STANDALONE=yes CYTHON=no MINIMAL_VERSIONS=no REPORT_COVERAGE=no
- python: "2.7" # test without installed cython
env: STANDALONE=no CYTHON=no MINIMAL_VERSIONS=no
env: STANDALONE=no CYTHON=no MINIMAL_VERSIONS=no REPORT_COVERAGE=no

# Use miniconda to install binary versions of numpy etc. from continuum
# analytic's repository. Follows an approach described by Dan Blanchard:
Expand Down Expand Up @@ -47,6 +45,6 @@ script:
- if [[ $STANDALONE == 'yes' ]]; then SCRIPTFILE=$SRCDIR/dev/tools/run_nose_tests_standalone.py; else SCRIPTFILE=$SRCDIR/dev/tools/run_nose_tests.py; fi
- cd ~;coverage run --rcfile=$SRCDIR/.coveragerc $SCRIPTFILE
# We only report coverage for one Python version
after_success: if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then cp .coverage $SRCDIR; cd $SRCDIR; coveralls; fi
after_success: if [[ $REPORT_COVERAGE == 'yes' ]]; then cp .coverage $SRCDIR; cd $SRCDIR; coveralls; fi
notifications:
email: false
28 changes: 0 additions & 28 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -594,34 +594,6 @@ POSSIBILITY OF SUCH DAMAGE.

-------------------------------------------------------------------------------

The code in brian2.utils.collections is based on the ActiveState Code Recipe
by Raymond Hettinger, available at: http://code.activestate.com/recipes/576693/
It is published under the MIT license:

Copyright (c) 2009 Raymond Hettinger

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.

-------------------------------------------------------------------------------

The spelling corrector code in brian2.utils.stringtools is based on the spelling
corrector by Peter Norvig, available at: http://norvig.com/spell.py
It is published under the MIT license:
Expand Down
9 changes: 3 additions & 6 deletions brian2/codegen/translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@
import ast
import re
import collections
try:
from collections import OrderedDict
except ImportError:
from brian2.utils.ordereddict import OrderedDict
from collections import OrderedDict

import numpy as np

Expand Down Expand Up @@ -52,7 +49,7 @@ def __init__(self, **kwds):
setattr(self, k, v)

# TODO: This information should go somewhere else, I guess
STANDARD_IDENTIFIERS = set(['and', 'or', 'not', 'True', 'False'])
STANDARD_IDENTIFIERS = {'and', 'or', 'not', 'True', 'False'}


def analyse_identifiers(code, variables, recursive=False):
Expand Down Expand Up @@ -447,7 +444,7 @@ def make_statements(code, variables, dtype):
# find that have a dependency on something in the invalid set. We
# go through in sorted subexpression order so that the invalid set
# is increased in the right order
invalid = set([var])
invalid = {var}
for subvar in sorted_subexpr_vars:
spec = subexpressions[subvar]
spec_ids = set(spec.identifiers)
Expand Down
6 changes: 2 additions & 4 deletions brian2/equations/equations.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,10 +584,8 @@ def __add__(self, other_eqns):
#: Functions can be registered with the static method
#: `Equations.register_identifier_check` and will be automatically
#: used when checking identifiers
identifier_checks = set([check_identifier_basic,
check_identifier_reserved,
check_identifier_functions,
check_identifier_units])
identifier_checks = {check_identifier_basic, check_identifier_reserved,
check_identifier_functions, check_identifier_units}

@staticmethod
def register_identifier_check(func):
Expand Down
6 changes: 1 addition & 5 deletions brian2/groups/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
saves state variables, e.g. `NeuronGroup` or `StateMonitor`.
'''
import collections
from collections import OrderedDict
import weakref
try:
from collections import OrderedDict
except ImportError:
# OrderedDict was added in Python 2.7, use backport for Python 2.6
from brian2.utils.ordereddict import OrderedDict

import numpy as np

Expand Down
2 changes: 1 addition & 1 deletion brian2/groups/neurongroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def update_abstract_code(self, run_namespace=None, level=0):

# Get all names used in the equations (and always get "dt")
names = self.group.equations.names
external_names = self.group.equations.identifiers | set(['dt'])
external_names = self.group.equations.identifiers | {'dt'}

variables = self.group.resolve_all(used_known | unknown | names | external_names,
# we don't need to raise any warnings
Expand Down
2 changes: 1 addition & 1 deletion brian2/hears.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def reinit(self):
self.buffer_pointer = self.buffersize
self.buffer_start = -self.buffersize

handled_explicitly = set(['Sound', 'FilterbankGroup'])
handled_explicitly = {'Sound', 'FilterbankGroup'}

__all__ = [k for k in b1h.__dict__.keys() if not k.startswith('_')]
for k in __all__:
Expand Down
2 changes: 1 addition & 1 deletion brian2/parsing/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def abstract_code_dependencies(code, known_vars=None, known_funcs=None):
x = y+z
a = f(b)
'''
known_vars = set(['y', 'z'])
known_vars = {'y', 'z'}
print deindent(code)
print 'known_vars:', known_vars
print
Expand Down
7 changes: 4 additions & 3 deletions brian2/stateupdaters/exact.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def _non_constant_symbols(symbols, variables, t_symbol):
for symbol in symbols:
if symbol in variables and not getattr(variables[symbol],
'constant', False):
non_constant |= set([symbol])
non_constant |= {symbol}

return non_constant

Expand Down Expand Up @@ -148,7 +148,8 @@ def __call__(self, equations, variables=None):
code = []
for name, expression in diff_eqs:
rhs = expression.sympy_expr
non_constant = _non_constant_symbols(rhs.atoms(), variables, t) - set([name])
non_constant = _non_constant_symbols(rhs.atoms(), variables, t) - {
name}
if len(non_constant):
raise ValueError(('Equation for %s referred to non-constant '
'variables %s') % (name, str(non_constant)))
Expand All @@ -164,7 +165,7 @@ def __call__(self, equations, variables=None):
# https://github.com/sympy/sympy/issues/2666
try:
general_solution = sp.dsolve(diff_eq, f(t), simplify=True)
except (RuntimeError, AttributeError): #AttributeError seems to be raised on Python 2.6
except RuntimeError:
general_solution = sp.dsolve(diff_eq, f(t), simplify=False)
# Check whether this is an explicit solution
if not getattr(general_solution, 'lhs', None) == f(t):
Expand Down
5 changes: 2 additions & 3 deletions brian2/synapses/synapses.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,8 @@ def initialise_queue(self):
self.queue.prepare(self._delays.get_value(), self.source.clock.dt_,
self.synapse_sources.get_value())

if len(set([self.source.clock.dt_,
self.synapses.clock.dt_,
self.target.clock.dt_])) > 1:
if len({self.source.clock.dt_, self.synapses.clock.dt_,
self.target.clock.dt_}) > 1:
logger.warn(("Note that the synaptic pathway '{pathway}' will run on the "
"clock of the group '{source}' using a dt of {dt}. Either "
"the Synapses object '{synapses}' or the target '{target}' "
Expand Down
6 changes: 3 additions & 3 deletions brian2/tests/test_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ def test_analyse_identifiers():
defined, used_known, dependent = analyse_identifiers(code, known)
assert 'a' in defined # There might be an additional constant added by the
# loop-invariant optimisation
assert used_known==set(['b', 'c', 'd'])
assert dependent==set(['e', 'f'])
assert used_known == {'b', 'c', 'd'}
assert dependent == {'e', 'f'}


@attr('codegen-independent')
Expand All @@ -62,7 +62,7 @@ def test_get_identifiers_recursively():
'x': Variable(unit=None, name='x')}
identifiers = get_identifiers_recursively(['_x = sub1 + x'],
variables)
assert identifiers == set(['x', '_x', 'y', 'z', 'sub1', 'sub2'])
assert identifiers == {'x', '_x', 'y', 'z', 'sub1', 'sub2'}


@attr('codegen-independent')
Expand Down
2 changes: 1 addition & 1 deletion brian2/tests/test_codestrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def test_split_stochastic():

expr = Expression('(-v + I) / tau + sigma*xi_1/tau**.5 + xi_2*sigma2/sqrt(tau_2)')
non_stochastic, stochastic = expr.split_stochastic()
assert set(stochastic.keys()) == set(['xi_1', 'xi_2'])
assert set(stochastic.keys()) == {'xi_1', 'xi_2'}
assert sympy_equals(non_stochastic.code, '(-v + I) / tau')
assert sympy_equals(stochastic['xi_1'].code, 'sigma/tau**.5')
assert sympy_equals(stochastic['xi_2'].code, 'sigma2/tau_2**.5')
Expand Down
22 changes: 11 additions & 11 deletions brian2/tests/test_equations.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,40 +326,40 @@ def test_properties():
assert (len(eqs.diff_eq_expressions) == 1 and
eqs.diff_eq_expressions[0][0] == 'v' and
isinstance(eqs.diff_eq_expressions[0][1], Expression))
assert eqs.diff_eq_names == set(['v'])
assert eqs.diff_eq_names == {'v'}
assert (len(eqs.eq_expressions) == 3 and
set([name for name, _ in eqs.eq_expressions]) == set(['v', 'I', 'f']) and
set([name for name, _ in eqs.eq_expressions]) == {'v', 'I', 'f'} and
all((isinstance(expr, Expression) for _, expr in eqs.eq_expressions)))
assert len(eqs.eq_names) == 3 and eqs.eq_names == set(['v', 'I', 'f'])
assert set(eqs.keys()) == set(['v', 'I', 'f', 'freq'])
assert len(eqs.eq_names) == 3 and eqs.eq_names == {'v', 'I', 'f'}
assert set(eqs.keys()) == {'v', 'I', 'f', 'freq'}
# test that the equations object is iterable itself
assert all((isinstance(eq, SingleEquation) for eq in eqs.itervalues()))
assert all((isinstance(eq, basestring) for eq in eqs))
assert (len(eqs.ordered) == 4 and
all((isinstance(eq, SingleEquation) for eq in eqs.ordered)) and
[eq.varname for eq in eqs.ordered] == ['f', 'I', 'v', 'freq'])
assert eqs.names == set(['v', 'I', 'f', 'freq'])
assert eqs.parameter_names == set(['freq'])
assert eqs.subexpr_names == set(['I', 'f'])
assert eqs.names == {'v', 'I', 'f', 'freq'}
assert eqs.parameter_names == {'freq'}
assert eqs.subexpr_names == {'I', 'f'}
units = eqs.units
assert set(units.keys()) == set(['v', 'I', 'f', 'freq'])
assert set(units.keys()) == {'v', 'I', 'f', 'freq'}
assert units['v'] == volt
assert units['I'] == volt
assert units['f'] == Hz
assert have_same_dimensions(units['freq'], 1)
assert eqs.names == set(eqs.units.keys())
assert eqs.identifiers == set(['tau', 'volt', 'Hz', 'sin', 't'])
assert eqs.identifiers == {'tau', 'volt', 'Hz', 'sin', 't'}

# stochastic equations
assert len(eqs.stochastic_variables) == 0
assert eqs.stochastic_type is None

eqs = Equations('''dv/dt = -v / tau + 0.1*second**-.5*xi : 1''')
assert eqs.stochastic_variables == set(['xi'])
assert eqs.stochastic_variables == {'xi'}
assert eqs.stochastic_type == 'additive'

eqs = Equations('''dv/dt = -v / tau + 0.1*second**-.5*xi_1 + 0.1*second**-.5*xi_2: 1''')
assert eqs.stochastic_variables == set(['xi_1', 'xi_2'])
assert eqs.stochastic_variables == {'xi_1', 'xi_2'}
assert eqs.stochastic_type == 'additive'

eqs = Equations('''dv/dt = -v / tau + 0.1*second**-1.5*xi*t : 1''')
Expand Down
6 changes: 3 additions & 3 deletions brian2/tests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ class BCodeObject(CodeObject):

# Register the code generation targets
_previous_codegen_targets = set(targets.codegen_targets)
targets.codegen_targets = set([ACodeObject, BCodeObject])
targets.codegen_targets = {ACodeObject, BCodeObject}

@check_units(x=volt, result=volt)
def foo(x):
Expand Down Expand Up @@ -406,8 +406,8 @@ def foo(x):

# some basic dictionary properties
assert len(container) == 4
assert set((key for key in container)) == set(['A Language', 'B',
ACodeObject, BCodeGenerator])
assert set((key for key in container)) == {'A Language', 'B', ACodeObject,
BCodeGenerator}

# Restore the previous codegeneration targets
targets.codegen_targets = _previous_codegen_targets
Expand Down
4 changes: 2 additions & 2 deletions brian2/tests/test_neurongroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -1084,8 +1084,8 @@ def test_get_states():
assert_equal(states['subexpr2'], 11*np.arange(10))

all_states = G.get_states(units=True)
assert set(all_states.keys()) == set(['v', 'x', 'subexpr', 'subexpr2',
'N', 't', 'dt', 'i'])
assert set(all_states.keys()) == {'v', 'x', 'subexpr', 'subexpr2', 'N', 't',
'dt', 'i'}


def test_random_vector_values():
Expand Down
4 changes: 2 additions & 2 deletions brian2/tests/test_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ def test_abstract_code_dependencies():
a = func_b()
a = x+d
'''
known_vars = set(['a', 'b', 'c'])
known_funcs = set(['func_a'])
known_vars = {'a', 'b', 'c'}
known_funcs = {'func_a'}
res = abstract_code_dependencies(code, known_vars, known_funcs)
expected_res = dict(
all=['a', 'b', 'c', 'd', 'x',
Expand Down
6 changes: 3 additions & 3 deletions brian2/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ def test_environment():

def test_spell_check():
checker = SpellChecker(['vm', 'alpha', 'beta'])
assert checker.suggest('Vm') == set(['vm'])
assert checker.suggest('alphas') == set(['alpha'])
assert checker.suggest('bta') == set(['beta'])
assert checker.suggest('Vm') == {'vm'}
assert checker.suggest('alphas') == {'alpha'}
assert checker.suggest('bta') == {'beta'}
assert checker.suggest('gamma') == set()


Expand Down
21 changes: 10 additions & 11 deletions brian2/utils/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,16 @@ def _encode(text):
logger.addHandler(CONSOLE_HANDLER)

# We want to log all warnings
if hasattr(logging, 'captureWarnings'): # This function was added in Python 2.7
logging.captureWarnings(True) # pylint: disable=E1101
# Manually connect to the warnings logger so that the warnings end up in
# the log file. Note that connecting to the console handler here means
# duplicated warning messages in the ipython notebook, but not doing so
# would mean that they are not displayed at all in the standard ipython
# interface...
warn_logger = logging.getLogger('py.warnings')
warn_logger.addHandler(CONSOLE_HANDLER)
if FILE_HANDLER is not None:
warn_logger.addHandler(FILE_HANDLER)
logging.captureWarnings(True) # pylint: disable=E1101
# Manually connect to the warnings logger so that the warnings end up in
# the log file. Note that connecting to the console handler here means
# duplicated warning messages in the ipython notebook, but not doing so
# would mean that they are not displayed at all in the standard ipython
# interface...
warn_logger = logging.getLogger('py.warnings')
warn_logger.addHandler(CONSOLE_HANDLER)
if FILE_HANDLER is not None:
warn_logger.addHandler(FILE_HANDLER)

# Put some standard info into the log file
logger.debug('Logging to file: %s, copy of main script saved as: %s' %
Expand Down

0 comments on commit e87111a

Please sign in to comment.