Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

Python 3 support #163

Merged
merged 55 commits into from Jul 8, 2016
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
6410400
get tox green for py26,py27
escapewindow Jun 25, 2015
7cdd996
start porting to py3. green on py27, already dropped py26 support
escapewindow Jun 25, 2015
86dec44
future statement through config_manager
escapewindow Jun 25, 2015
aabff59
re-add py26 support. argparse help output will need to be regexed or
escapewindow Jun 25, 2015
5407ff0
works in py27, tox seems a bit busted?
escapewindow Jun 25, 2015
45b4bd0
fix tox
escapewindow Jun 25, 2015
3f1c92d
move the first py3 error to dotdict
escapewindow Jun 25, 2015
197f698
python 3 < 3.3 not supported
escapewindow Jun 25, 2015
68dfb84
move py3 error to def_sources/__init__.py
escapewindow Jun 25, 2015
8dcf054
move py3 error to value_sources/for_conf.py
escapewindow Jun 25, 2015
817350d
move py3 error to value_sources/for_modules.py
escapewindow Jun 25, 2015
7694333
first py3 error in test_val_for_modules.py!
escapewindow Jun 25, 2015
f47ae77
port a bunch more files
escapewindow Jun 25, 2015
120c9b3
a lot more files
escapewindow Jun 25, 2015
d31b3d2
more files, still green on py2
escapewindow Jun 25, 2015
38da698
four more files to go, then more py3 fixes
escapewindow Jun 25, 2015
41a2f54
down to 57 errors, 1 failure
escapewindow Jun 25, 2015
105346c
down to 53 errors, 1 failure
escapewindow Jun 25, 2015
0042c66
47 errors, 1 failure
escapewindow Jun 25, 2015
5bb3e28
errors=40, failures=1
escapewindow Jun 25, 2015
3e6c864
errors=13, failures=1
escapewindow Jun 25, 2015
5698eaa
20 errors, 4 failures now that i fixed some broken python =\
escapewindow Jun 25, 2015
5f72e1e
all ints in py3 are long. also, 31 errors, 4 failures =\
escapewindow Jun 25, 2015
72f3510
30 errors, 4 failures
escapewindow Jun 25, 2015
8b4dc5e
comment out ArgumentParser.version; errors-18, failures=4
escapewindow Jun 25, 2015
81f87f5
the sorted()/cmp and getattr hacks are killing me
escapewindow Jun 25, 2015
34dd795
back down to errors=18, failures=4
escapewindow Jun 25, 2015
c9902bd
errors=18 failures=1
escapewindow Jun 25, 2015
3e5f909
errors=15, failures=3
escapewindow Jun 25, 2015
aa44d1c
errors=15, failures=1
escapewindow Jun 25, 2015
dae6dd6
errors=15, failures=0
escapewindow Jun 25, 2015
37d1432
i think i've moved on to other errors in the same tests? 15 errors
escapewindow Jun 25, 2015
7a41e46
Merge branch 'master' into python3
escapewindow Jul 1, 2016
cb7ec8e
errors = 12
escapewindow Jul 1, 2016
2df1e57
11 errors
escapewindow Jul 1, 2016
9246b28
5 errors
escapewindow Jul 1, 2016
2ba6b1e
add py3{3,4,5} to travis
escapewindow Jul 1, 2016
74e9dc9
get converters more sane
escapewindow Jul 1, 2016
56daba1
to_str ize more things, get rid of unicode_literals
escapewindow Jul 1, 2016
3a52053
finish to_str
escapewindow Jul 1, 2016
2b72cdb
2 errors
escapewindow Jul 1, 2016
e2ffa05
omg, green tests py26,py27,py33,py34,py35
escapewindow Jul 1, 2016
17e8777
reenable commented-out test after fixing
escapewindow Jul 1, 2016
70e5433
update packaging files for py3
escapewindow Jul 1, 2016
51cf7f9
python3 support for demo/
escapewindow Jul 1, 2016
20794b5
python3 compatible docs
escapewindow Jul 1, 2016
91b0fcc
use range instead of xrange
escapewindow Jul 1, 2016
0633d30
clean up debugging print()
escapewindow Jul 1, 2016
13e99ae
add some additional test fixes
escapewindow Jul 1, 2016
f8c3078
add version back into ArgumentParser
escapewindow Jul 5, 2016
34265f8
update setup.py to include version 2 & 3
escapewindow Jul 5, 2016
8b2223a
also uncomment the other version
escapewindow Jul 5, 2016
2c2210f
add Orderable{Obj,Tuple} tests and fixes
escapewindow Jul 5, 2016
5057709
add total_ordering
escapewindow Jul 5, 2016
5952296
fix py26 total_ordering
escapewindow Jul 6, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .travis.yml
Expand Up @@ -24,6 +24,9 @@ env:
python:
- 2.6
- 2.7
- 3.3
- 3.4
- 3.5


install:
Expand Down
2 changes: 1 addition & 1 deletion configman/__init__.py
@@ -1,7 +1,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

from __future__ import absolute_import, division, print_function
from os import path
with open(path.join(path.dirname(__file__), 'version.txt')) as f:
__version__ = f.read().strip()
Expand Down
1 change: 1 addition & 0 deletions configman/commandline.py
Expand Up @@ -7,6 +7,7 @@

# at which point we want to make argparse the default, we will eliminate
# this line
from __future__ import absolute_import, division, print_function
import getopt as command_line

try:
Expand Down
1 change: 1 addition & 0 deletions configman/config_exceptions.py
@@ -1,6 +1,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import, division, print_function


class ConfigmanException(Exception):
Expand Down
1 change: 1 addition & 0 deletions configman/config_file_future_proxy.py
@@ -1,6 +1,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import, division, print_function


#==============================================================================
Expand Down
55 changes: 33 additions & 22 deletions configman/config_manager.py
@@ -1,7 +1,9 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import absolute_import, division, print_function

import six
import sys
import os
import collections
Expand All @@ -20,6 +22,7 @@
)
from configman.converters import (
to_string_converters,
to_str
)
from configman.config_exceptions import (
NotAnOptionError,
Expand Down Expand Up @@ -133,10 +136,12 @@ def __init__(
definition_source_list = []
elif (
isinstance(definition_source, collections.Sequence) and
not isinstance(definition_source, basestring)
not isinstance(definition_source, (six.binary_type, six.text_type))
):
definition_source_list = list(definition_source)
else:
if isinstance(definition_source, (six.binary_type, six.text_type)):
definition_source = to_str(definition_source)
definition_source_list = [definition_source]

if argv_source is None:
Expand Down Expand Up @@ -339,28 +344,30 @@ def output_summary(self, output_stream=sys.stdout):

parameters:
output_stream - an open file-like object suitable for use as the
target of a print statement
target of a print function
"""
if self.app_name or self.app_description:
print >> output_stream, 'Application:',
print('Application: ', end='', file=output_stream)
if self.app_name:
print >> output_stream, self.app_name, self.app_version
print(self.app_name, self.app_version, file=output_stream)
if self.app_description:
print >> output_stream, self.app_description
print(self.app_description, file=output_stream)
if self.app_name or self.app_description:
print >> output_stream, ''
print('', file=output_stream)

names_list = self.get_option_names()
print >> output_stream, \
print(
"usage:\n%s [OPTIONS]... " % self.app_invocation_name,
end='', file=output_stream
)
bracket_count = 0
# this section prints the non-switch command line arguments
for key in names_list:
an_option = self.option_definitions[key]
if an_option.is_argument:
if an_option.default is None:
# there's no option, assume the user must set this
print >> output_stream, an_option.name,
print(an_option.name, end='', file=output_stream)
elif (
inspect.isclass(an_option.value)
or inspect.ismodule(an_option.value)
Expand All @@ -370,17 +377,17 @@ def output_summary(self, output_stream=sys.stdout):
# loaded and we're looking to show the help for it.
# display show it as a constant already provided rather
# than as an option the user must provide
print >> output_stream, an_option.default,
print(an_option.default, end='', file=output_stream)
else:
# this is an argument that the user may alternatively
# provide
print >> output_stream, "[ %s" % an_option.name,
print("[ %s" % an_option.name, end='', file=output_stream)
bracket_count += 1
print >> output_stream, ']' * bracket_count, '\n'
print(']' * bracket_count, '\n', file=output_stream)

names_list.sort()
if names_list:
print >> output_stream, 'OPTIONS:'
print('OPTIONS:', file=output_stream)

pad = ' ' * 4

Expand Down Expand Up @@ -415,7 +422,7 @@ def output_summary(self, output_stream=sys.stdout):
# don't bother with certain dead obvious ones
line += '%s(default: %s)\n' % (pad, default)

print >> output_stream, line
print(line, file=output_stream)

#--------------------------------------------------------------------------
def print_conf(self):
Expand All @@ -435,7 +442,7 @@ def stdout_opener():

skip_keys = [
k for (k, v)
in self.option_definitions.iteritems()
in six.iteritems(self.option_definitions)
if isinstance(v, Option) and v.exclude_from_print_conf
]
self.write_conf(config_file_type, stdout_opener, skip_keys=skip_keys)
Expand All @@ -458,7 +465,7 @@ def dump_conf(self, config_pathname=None):

skip_keys = [
k for (k, v)
in self.option_definitions.iteritems()
in six.iteritems(self.option_definitions)
if isinstance(v, Option) and v.exclude_from_dump_conf
]

Expand Down Expand Up @@ -706,7 +713,7 @@ def _overlay_expand(self):
finished_keys -= set(
all_reference_values[key]
)
except KeyError, x:
except KeyError as x:
pass # okay, that source doesn't have this value

# expansion process:
Expand Down Expand Up @@ -784,7 +791,7 @@ def _overlay_expand(self):
for new_key in new_namespace.keys_breadth_first():
if new_key not in current_namespace:
current_namespace[new_key] = new_namespace[new_key]
except AttributeError, x:
except AttributeError as x:
# there are apparently no new Options to bring in from
# this option's value
pass
Expand Down Expand Up @@ -831,7 +838,7 @@ def _check_for_mismatches(self, known_keys):
# remove keys of the form 'y.z' if they match a known key of the
# form 'x.y.z'
for key in unmatched_keys.copy():
key_is_okay = reduce(
key_is_okay = six.moves.reduce(
lambda x, y: x or y,
(known_key.endswith(key) for known_key in known_keys)
)
Expand All @@ -852,17 +859,21 @@ def _check_for_mismatches(self, known_keys):
)
else:
warnings.warn(
'Invalid options: %s' % ', '.join(unmatched_keys)
'Invalid options: %s' % ', '.join(sorted(unmatched_keys))
)

#--------------------------------------------------------------------------
@staticmethod
def _walk_and_close(a_dict):
for val in a_dict.itervalues():
for val in six.itervalues(a_dict):
if isinstance(val, collections.Mapping):
ConfigurationManager._walk_and_close(val)
if hasattr(val, 'close') and not inspect.isclass(val):
val.close()
try:
if hasattr(val, 'close') and not inspect.isclass(val):
val.close()
except KeyError:
# py3 will sometimes hit KeyError from the hasattr()
pass

#--------------------------------------------------------------------------
def _generate_config(self, mapping_class):
Expand Down