Python-checkins
Threads by month
- ----- 2025 -----
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
August 2016
- 2 participants
- 519 discussions

Aug. 31, 2016
https://hg.python.org/cpython/rev/caf547c9e589
changeset: 102969:caf547c9e589
branch: 3.5
parent: 102963:b8dd9ae08a91
user: Raymond Hettinger <python(a)rcn.com>
date: Wed Aug 31 08:44:11 2016 -0700
summary:
Issue #27909: Fix INCREF for possible NULL value
files:
Python/import.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/Python/import.c b/Python/import.c
--- a/Python/import.c
+++ b/Python/import.c
@@ -1056,7 +1056,7 @@
mod =…
[View More] _PyImport_FindExtensionObject(name, name);
if (mod || PyErr_Occurred()) {
Py_DECREF(name);
- Py_INCREF(mod);
+ Py_XINCREF(mod);
return mod;
}
--
Repository URL: https://hg.python.org/cpython
[View Less]
1
0
https://hg.python.org/cpython/rev/16bba5b49441
changeset: 102970:16bba5b49441
parent: 102968:5f6dac170b9b
parent: 102969:caf547c9e589
user: Raymond Hettinger <python(a)rcn.com>
date: Wed Aug 31 08:44:26 2016 -0700
summary:
Merge
files:
Python/import.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/Python/import.c b/Python/import.c
--- a/Python/import.c
+++ b/Python/import.c
@@ -1047,7 +1047,7 @@
mod = …
[View More]_PyImport_FindExtensionObject(name, name);
if (mod || PyErr_Occurred()) {
Py_DECREF(name);
- Py_INCREF(mod);
+ Py_XINCREF(mod);
return mod;
}
--
Repository URL: https://hg.python.org/cpython
[View Less]
1
0
https://hg.python.org/cpython/rev/5f6dac170b9b
changeset: 102968:5f6dac170b9b
user: R David Murray <rdmurray(a)bitdance.com>
date: Wed Aug 31 11:39:35 2016 -0400
summary:
#27904: fix distutils tests.
Patch by Ville Skyttä.
files:
Lib/distutils/tests/test_build_py.py | 3 ++-
Lib/distutils/tests/test_install_lib.py | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/Lib/distutils/tests/test_build_py.py b/Lib/distutils/tests/test_build_py.py
…
[View More]--- a/Lib/distutils/tests/test_build_py.py
+++ b/Lib/distutils/tests/test_build_py.py
@@ -168,7 +168,8 @@
finally:
sys.dont_write_bytecode = old_dont_write_bytecode
- self.assertIn('byte-compiling is disabled', self.logs[0][1])
+ self.assertIn('byte-compiling is disabled',
+ self.logs[0][1] % self.logs[0][2])
def test_suite():
diff --git a/Lib/distutils/tests/test_install_lib.py b/Lib/distutils/tests/test_install_lib.py
--- a/Lib/distutils/tests/test_install_lib.py
+++ b/Lib/distutils/tests/test_install_lib.py
@@ -104,7 +104,8 @@
finally:
sys.dont_write_bytecode = old_dont_write_bytecode
- self.assertIn('byte-compiling is disabled', self.logs[0][1])
+ self.assertIn('byte-compiling is disabled',
+ self.logs[0][1] % self.logs[0][2])
def test_suite():
--
Repository URL: https://hg.python.org/cpython
[View Less]
1
0

NEUTRAL Benchmark Results for Python Default 2016-08-31
by lp_benchmark_robot@intel.com Aug. 31, 2016
by lp_benchmark_robot@intel.com Aug. 31, 2016
Aug. 31, 2016
Results for project Python default, build date 2016-08-31 02:00:27 +0000
commit: 059f9f518834
previous commit: 7d73555c83ff
revision date: 2016-08-31 01:17:25 +0000
environment: Haswell-EP
cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB
mem: 128 GB
os: CentOS 7.1
kernel: Linux 3.10.0-229.4.2.el7.x86_64
Baseline results were generated using release v3.4.3, with hash b4cbecbc0781
from 2015-02-25 12:15:33+00:00
---------------------------------------------…
[View More]-------------------------------------
benchmark relative change since change since current rev run
std_dev* last run baseline with PGO
----------------------------------------------------------------------------------
:-) django_v2 0.24% 0.83% 10.07% 17.16%
:-) pybench 3.05% -0.03% 6.25% 6.96%
:-( regex_v8 2.76% -0.16% -3.99% 5.60%
:-| nbody 0.09% 0.00% -1.30% 11.97%
:-| json_dump_v2 0.38% 0.49% -1.97% 13.05%
:-) normal_startup 0.99% 0.13% 2.25% 5.57%
----------------------------------------------------------------------------------
* Relative Standard Deviation (Standard Deviation/Average)
If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/neutral-benchmark-results-for-python-…
Note: Benchmark results are measured in seconds.
Subject Label Legend:
Attributes are determined based on the performance evolution of the workloads
compared to the previous measurement iteration.
NEUTRAL: performance did not change by more than 1% for any workload
GOOD: performance improved by more than 1% for at least one workload and there
is no regression greater than 1%
BAD: performance dropped by more than 1% for at least one workload and there is
no improvement greater than 1%
UGLY: performance improved by more than 1% for at least one workload and also
dropped by more than 1% for at least one workload
Our lab does a nightly source pull and build of the Python project and measures
performance changes against the previous stable version and the previous nightly
measurement. This is provided as a service to the community so that quality
issues with current hardware can be identified quickly.
Intel technologies' features and benefits depend on system configuration and may
require enabled hardware, software or service activation. Performance varies
depending on system configuration.
[View Less]
1
0

Aug. 31, 2016
Results for project Python 2.7, build date 2016-08-31 02:47:12 +0000
commit: f478f9b88319
previous commit: 58ea646ef657
revision date: 2016-08-31 00:19:07 +0000
environment: Haswell-EP
cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB
mem: 128 GB
os: CentOS 7.1
kernel: Linux 3.10.0-229.4.2.el7.x86_64
Baseline results were generated using release v2.7.10, with hash 15c95b7d81dc
from 2015-05-23 16:02:14+00:00
------------------------------------------------…
[View More]----------------------------------
benchmark relative change since change since current rev run
std_dev* last run baseline with PGO
----------------------------------------------------------------------------------
:-) django_v2 0.13% 0.23% 5.06% 5.03%
:-) pybench 0.18% -0.06% 6.30% 3.74%
:-( regex_v8 0.61% 0.09% -2.26% 10.97%
:-) nbody 0.09% 0.10% 8.26% 2.29%
:-) json_dump_v2 0.65% 0.53% 2.18% 11.18%
:-| normal_startup 0.70% 0.05% -0.75% 2.19%
:-) ssbench 0.33% 0.34% 3.23% 0.71%
----------------------------------------------------------------------------------
* Relative Standard Deviation (Standard Deviation/Average)
If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/neutral-benchmark-results-for-python-…
Note: Benchmark results for ssbench are measured in requests/second while all
other are measured in seconds.
Subject Label Legend:
Attributes are determined based on the performance evolution of the workloads
compared to the previous measurement iteration.
NEUTRAL: performance did not change by more than 1% for any workload
GOOD: performance improved by more than 1% for at least one workload and there
is no regression greater than 1%
BAD: performance dropped by more than 1% for at least one workload and there is
no improvement greater than 1%
UGLY: performance improved by more than 1% for at least one workload and also
dropped by more than 1% for at least one workload
Our lab does a nightly source pull and build of the Python project and measures
performance changes against the previous stable version and the previous nightly
measurement. This is provided as a service to the community so that quality
issues with current hardware can be identified quickly.
Intel technologies' features and benefits depend on system configuration and may
require enabled hardware, software or service activation. Performance varies
depending on system configuration.
[View Less]
1
0

cpython: Closes #27904: Improved logging statements to defer formatting until needed.
by vinay.sajip Aug. 31, 2016
by vinay.sajip Aug. 31, 2016
Aug. 31, 2016
https://hg.python.org/cpython/rev/1340e298aa7e
changeset: 102967:1340e298aa7e
user: Vinay Sajip <vinay_sajip(a)yahoo.co.uk>
date: Wed Aug 31 08:22:29 2016 +0100
summary:
Closes #27904: Improved logging statements to defer formatting until needed.
files:
Doc/library/contextlib.rst | 4 ++--
Doc/library/shutil.rst | 2 +-
Doc/library/typing.rst | 2 +-
Doc/whatsnew/3.2.rst | 4 ++--
Lib/asyncio/base_events.py …
[View More] | 4 ++--
Lib/distutils/archive_util.py | 2 +-
Lib/distutils/cmd.py | 3 +--
Lib/distutils/command/bdist_dumb.py | 2 +-
Lib/distutils/command/build_ext.py | 6 +++---
Lib/distutils/command/config.py | 2 +-
Lib/distutils/command/install.py | 2 +-
Lib/distutils/command/register.py | 6 +++---
Lib/distutils/command/sdist.py | 2 +-
Tools/ssl/test_multiple_versions.py | 6 +++---
setup.py | 4 ++--
15 files changed, 25 insertions(+), 26 deletions(-)
diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst
--- a/Doc/library/contextlib.rst
+++ b/Doc/library/contextlib.rst
@@ -590,10 +590,10 @@
self.name = name
def __enter__(self):
- logging.info('Entering: {}'.format(self.name))
+ logging.info('Entering: %s', self.name)
def __exit__(self, exc_type, exc, exc_tb):
- logging.info('Exiting: {}'.format(self.name))
+ logging.info('Exiting: %s', self.name)
Instances of this class can be used as both a context manager::
diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst
--- a/Doc/library/shutil.rst
+++ b/Doc/library/shutil.rst
@@ -425,7 +425,7 @@
import logging
def _logpath(path, names):
- logging.info('Working in %s' % path)
+ logging.info('Working in %s', path)
return [] # nothing will be ignored
copytree(source, destination, ignore=_logpath)
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -204,7 +204,7 @@
return self.value
def log(self, message: str) -> None:
- self.logger.info('{}: {}'.format(self.name, message))
+ self.logger.info('%s: %s', self.name, message)
``Generic[T]`` as a base class defines that the class ``LoggedVar`` takes a
single type parameter ``T`` . This also makes ``T`` valid as a type within the
diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst
--- a/Doc/whatsnew/3.2.rst
+++ b/Doc/whatsnew/3.2.rst
@@ -1253,9 +1253,9 @@
@contextmanager
def track_entry_and_exit(name):
- logging.info('Entering: {}'.format(name))
+ logging.info('Entering: %s', name)
yield
- logging.info('Exiting: {}'.format(name))
+ logging.info('Exiting: %s', name)
Formerly, this would have only been usable as a context manager::
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -1069,7 +1069,7 @@
transport = yield from self._make_subprocess_transport(
protocol, cmd, True, stdin, stdout, stderr, bufsize, **kwargs)
if self._debug:
- logger.info('%s: %r' % (debug_log, transport))
+ logger.info('%s: %r', debug_log, transport)
return transport, protocol
@coroutine
@@ -1099,7 +1099,7 @@
protocol, popen_args, False, stdin, stdout, stderr,
bufsize, **kwargs)
if self._debug:
- logger.info('%s: %r' % (debug_log, transport))
+ logger.info('%s: %r', debug_log, transport)
return transport, protocol
def get_exception_handler(self):
diff --git a/Lib/distutils/archive_util.py b/Lib/distutils/archive_util.py
--- a/Lib/distutils/archive_util.py
+++ b/Lib/distutils/archive_util.py
@@ -171,7 +171,7 @@
path = os.path.normpath(os.path.join(dirpath, name))
if os.path.isfile(path):
zip.write(path, path)
- log.info("adding '%s'" % path)
+ log.info("adding '%s'", path)
zip.close()
return zip_filename
diff --git a/Lib/distutils/cmd.py b/Lib/distutils/cmd.py
--- a/Lib/distutils/cmd.py
+++ b/Lib/distutils/cmd.py
@@ -329,8 +329,7 @@
# -- External world manipulation -----------------------------------
def warn(self, msg):
- log.warn("warning: %s: %s\n" %
- (self.get_command_name(), msg))
+ log.warn("warning: %s: %s\n", self.get_command_name(), msg)
def execute(self, func, args, msg=None, level=1):
util.execute(func, args, msg, dry_run=self.dry_run)
diff --git a/Lib/distutils/command/bdist_dumb.py b/Lib/distutils/command/bdist_dumb.py
--- a/Lib/distutils/command/bdist_dumb.py
+++ b/Lib/distutils/command/bdist_dumb.py
@@ -85,7 +85,7 @@
install.skip_build = self.skip_build
install.warn_dir = 0
- log.info("installing to %s" % self.bdist_dir)
+ log.info("installing to %s", self.bdist_dir)
self.run_command('install')
# And make an archive relative to the root of the
diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py
--- a/Lib/distutils/command/build_ext.py
+++ b/Lib/distutils/command/build_ext.py
@@ -363,9 +363,9 @@
ext_name, build_info = ext
- log.warn(("old-style (ext_name, build_info) tuple found in "
- "ext_modules for extension '%s'"
- "-- please convert to Extension instance" % ext_name))
+ log.warn("old-style (ext_name, build_info) tuple found in "
+ "ext_modules for extension '%s'"
+ "-- please convert to Extension instance", ext_name)
if not (isinstance(ext_name, str) and
extension_name_re.match(ext_name)):
diff --git a/Lib/distutils/command/config.py b/Lib/distutils/command/config.py
--- a/Lib/distutils/command/config.py
+++ b/Lib/distutils/command/config.py
@@ -337,7 +337,7 @@
If head is not None, will be dumped before the file content.
"""
if head is None:
- log.info('%s' % filename)
+ log.info('%s', filename)
else:
log.info(head)
file = open(filename)
diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py
--- a/Lib/distutils/command/install.py
+++ b/Lib/distutils/command/install.py
@@ -385,7 +385,7 @@
else:
opt_name = opt_name.translate(longopt_xlate)
val = getattr(self, opt_name)
- log.debug(" %s: %s" % (opt_name, val))
+ log.debug(" %s: %s", opt_name, val)
def finalize_unix(self):
"""Finalizes options for posix platforms."""
diff --git a/Lib/distutils/command/register.py b/Lib/distutils/command/register.py
--- a/Lib/distutils/command/register.py
+++ b/Lib/distutils/command/register.py
@@ -94,7 +94,7 @@
'''
# send the info to the server and report the result
(code, result) = self.post_to_server(self.build_post_data('verify'))
- log.info('Server response (%s): %s' % (code, result))
+ log.info('Server response (%s): %s', code, result)
def send_metadata(self):
''' Send the metadata to the package index server.
@@ -205,7 +205,7 @@
data['email'] = input(' EMail: ')
code, result = self.post_to_server(data)
if code != 200:
- log.info('Server response (%s): %s' % (code, result))
+ log.info('Server response (%s): %s', code, result)
else:
log.info('You will receive an email shortly.')
log.info(('Follow the instructions in it to '
@@ -216,7 +216,7 @@
while not data['email']:
data['email'] = input('Your email address: ')
code, result = self.post_to_server(data)
- log.info('Server response (%s): %s' % (code, result))
+ log.info('Server response (%s): %s', code, result)
def build_post_data(self, action):
# figure the data to send - the metadata plus some additional
diff --git a/Lib/distutils/command/sdist.py b/Lib/distutils/command/sdist.py
--- a/Lib/distutils/command/sdist.py
+++ b/Lib/distutils/command/sdist.py
@@ -412,7 +412,7 @@
log.info(msg)
for file in files:
if not os.path.isfile(file):
- log.warn("'%s' not a regular file -- skipping" % file)
+ log.warn("'%s' not a regular file -- skipping", file)
else:
dest = os.path.join(base_dir, file)
self.copy_file(file, dest, link=link)
diff --git a/Tools/ssl/test_multiple_versions.py b/Tools/ssl/test_multiple_versions.py
--- a/Tools/ssl/test_multiple_versions.py
+++ b/Tools/ssl/test_multiple_versions.py
@@ -105,11 +105,11 @@
def _subprocess_call(self, cmd, stdout=subprocess.DEVNULL, env=None,
**kwargs):
- log.debug("Call '{}'".format(" ".join(cmd)))
+ log.debug("Call '%s'", " ".join(cmd))
return subprocess.check_call(cmd, stdout=stdout, env=env, **kwargs)
def _subprocess_output(self, cmd, env=None, **kwargs):
- log.debug("Call '{}'".format(" ".join(cmd)))
+ log.debug("Call '%s'", " ".join(cmd))
out = subprocess.check_output(cmd, env=env)
return out.strip().decode("utf-8")
@@ -168,7 +168,7 @@
if not self.has_src:
self._download_openssl()
else:
- log.debug("Already has src {}".format(self.src_file))
+ log.debug("Already has src %s", self.src_file)
self._unpack_openssl()
self._build_openssl()
self._install_openssl()
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -186,7 +186,7 @@
if not list:
return module
if len(list) > 1:
- log.info("WARNING: multiple copies of %s found"%module)
+ log.info("WARNING: multiple copies of %s found", module)
return os.path.join(list[0], module)
class PyBuildExt(build_ext):
@@ -2213,7 +2213,7 @@
newfilename = filename + fullversion
else:
newfilename = filename + minoronly
- log.info('renaming {} to {}'.format(filename, newfilename))
+ log.info('renaming %s to %s', filename, newfilename)
os.rename(filename, newfilename)
newoutfiles.append(newfilename)
if filename in updated_files:
--
Repository URL: https://hg.python.org/cpython
[View Less]
1
0
https://hg.python.org/cpython/rev/39661e2ff030
changeset: 102966:39661e2ff030
user: Ethan Furman <ethan(a)stoneleaf.us>
date: Wed Aug 31 00:12:15 2016 -0700
summary:
issue23591: add Flags, IntFlags, and tests
files:
Lib/enum.py | 227 ++++++++++++++-
Lib/test/test_enum.py | 452 +++++++++++++++++++++++++++++-
2 files changed, 668 insertions(+), 11 deletions(-)
diff --git a/Lib/enum.py b/Lib/enum.py
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -1,5 +1,7 @@
…
[View More]import sys
from types import MappingProxyType, DynamicClassAttribute
+from functools import reduce
+from operator import or_ as _or_
# try _collections first to reduce startup cost
try:
@@ -8,7 +10,7 @@
from collections import OrderedDict
-__all__ = ['EnumMeta', 'Enum', 'IntEnum', 'unique']
+__all__ = ['EnumMeta', 'Enum', 'IntEnum', 'Flags', 'IntFlags', 'unique']
def _is_descriptor(obj):
@@ -64,7 +66,10 @@
"""
if _is_sunder(key):
- if key not in ('_order_', ):
+ if key not in (
+ '_order_', '_create_pseudo_member_', '_decompose_',
+ '_generate_next_value_', '_missing_',
+ ):
raise ValueError('_names_ are reserved for future Enum use')
elif _is_dunder(key):
if key == '__order__':
@@ -75,7 +80,7 @@
elif not _is_descriptor(value):
if key in self:
# enum overwriting a descriptor?
- raise TypeError('Key already defined as: %r' % self[key])
+ raise TypeError('%r already defined as: %r' % (key, self[key]))
self._member_names.append(key)
super().__setitem__(key, value)
@@ -91,9 +96,15 @@
"""Metaclass for Enum"""
@classmethod
def __prepare__(metacls, cls, bases):
- return _EnumDict()
+ # create the namespace dict
+ enum_dict = _EnumDict()
+ # inherit previous flags and _generate_next_value_ function
+ member_type, first_enum = metacls._get_mixins_(bases)
+ if first_enum is not None:
+ enum_dict['_generate_next_value_'] = getattr(first_enum, '_generate_next_value_', None)
+ return enum_dict
- def __new__(metacls, cls, bases, classdict):
+ def __new__(metacls, cls, bases, classdict, **kwds):
# an Enum class is final once enumeration items have been defined; it
# cannot be mixed with other types (int, float, etc.) if it has an
# inherited __new__ unless a new __new__ is defined (or the resulting
@@ -104,7 +115,7 @@
# save enum items into separate mapping so they don't get baked into
# the new class
- members = {k: classdict[k] for k in classdict._member_names}
+ enum_members = {k: classdict[k] for k in classdict._member_names}
for name in classdict._member_names:
del classdict[name]
@@ -112,7 +123,7 @@
_order_ = classdict.pop('_order_', None)
# check for illegal enum names (any others?)
- invalid_names = set(members) & {'mro', }
+ invalid_names = set(enum_members) & {'mro', }
if invalid_names:
raise ValueError('Invalid enum member name: {0}'.format(
','.join(invalid_names)))
@@ -156,7 +167,7 @@
# a custom __new__ is doing something funky with the values -- such as
# auto-numbering ;)
for member_name in classdict._member_names:
- value = members[member_name]
+ value = enum_members[member_name]
if not isinstance(value, tuple):
args = (value, )
else:
@@ -170,7 +181,10 @@
else:
enum_member = __new__(enum_class, *args)
if not hasattr(enum_member, '_value_'):
- enum_member._value_ = member_type(*args)
+ if member_type is object:
+ enum_member._value_ = value
+ else:
+ enum_member._value_ = member_type(*args)
value = enum_member._value_
enum_member._name_ = member_name
enum_member.__objclass__ = enum_class
@@ -344,13 +358,18 @@
"""
metacls = cls.__class__
bases = (cls, ) if type is None else (type, cls)
+ _, first_enum = cls._get_mixins_(bases)
classdict = metacls.__prepare__(class_name, bases)
# special processing needed for names?
if isinstance(names, str):
names = names.replace(',', ' ').split()
if isinstance(names, (tuple, list)) and isinstance(names[0], str):
- names = [(e, i) for (i, e) in enumerate(names, start)]
+ original_names, names = names, []
+ last_value = None
+ for count, name in enumerate(original_names):
+ last_value = first_enum._generate_next_value_(name, start, count, last_value)
+ names.append((name, last_value))
# Here, names is either an iterable of (name, value) or a mapping.
for item in names:
@@ -492,6 +511,16 @@
for member in cls._member_map_.values():
if member._value_ == value:
return member
+ # still not found -- try _missing_ hook
+ return cls._missing_(value)
+
+ @staticmethod
+ def _generate_next_value_(name, start, count, last_value):
+ if not count:
+ return start
+ return last_value + 1
+ @classmethod
+ def _missing_(cls, value):
raise ValueError("%r is not a valid %s" % (value, cls.__name__))
def __repr__(self):
@@ -585,6 +614,184 @@
def _reduce_ex_by_name(self, proto):
return self.name
+class Flags(Enum):
+ """Support for flags"""
+ @staticmethod
+ def _generate_next_value_(name, start, count, last_value):
+ """
+ Generate the next value when not given.
+
+ name: the name of the member
+ start: the initital start value or None
+ count: the number of existing members
+ last_value: the last value assigned or None
+ """
+ if not count:
+ return start if start is not None else 1
+ high_bit = _high_bit(last_value)
+ return 2 ** (high_bit+1)
+
+ @classmethod
+ def _missing_(cls, value):
+ original_value = value
+ if value < 0:
+ value = ~value
+ possible_member = cls._create_pseudo_member_(value)
+ for member in possible_member._decompose_():
+ if member._name_ is None and member._value_ != 0:
+ raise ValueError('%r is not a valid %s' % (original_value, cls.__name__))
+ if original_value < 0:
+ possible_member = ~possible_member
+ return possible_member
+
+ @classmethod
+ def _create_pseudo_member_(cls, value):
+ pseudo_member = cls._value2member_map_.get(value, None)
+ if pseudo_member is None:
+ # construct a non-singleton enum pseudo-member
+ pseudo_member = object.__new__(cls)
+ pseudo_member._name_ = None
+ pseudo_member._value_ = value
+ cls._value2member_map_[value] = pseudo_member
+ return pseudo_member
+
+ def _decompose_(self):
+ """Extract all members from the value."""
+ value = self._value_
+ members = []
+ cls = self.__class__
+ for member in sorted(cls, key=lambda m: m._value_, reverse=True):
+ while _high_bit(value) > _high_bit(member._value_):
+ unknown = self._create_pseudo_member_(2 ** _high_bit(value))
+ members.append(unknown)
+ value &= ~unknown._value_
+ if (
+ (value & member._value_ == member._value_)
+ and (member._value_ or not members)
+ ):
+ value &= ~member._value_
+ members.append(member)
+ if not members or value:
+ members.append(self._create_pseudo_member_(value))
+ members = list(members)
+ return members
+
+ def __contains__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return other._value_ & self._value_ == other._value_
+
+ def __iter__(self):
+ if self.value == 0:
+ return iter([])
+ else:
+ return iter(self._decompose_())
+
+ def __repr__(self):
+ cls = self.__class__
+ if self._name_ is not None:
+ return '<%s.%s: %r>' % (cls.__name__, self._name_, self._value_)
+ members = self._decompose_()
+ if len(members) == 1 and members[0]._name_ is None:
+ return '<%s: %r>' % (cls.__name__, members[0]._value_)
+ else:
+ return '<%s.%s: %r>' % (
+ cls.__name__,
+ '|'.join([str(m._name_ or m._value_) for m in members]),
+ self._value_,
+ )
+
+ def __str__(self):
+ cls = self.__class__
+ if self._name_ is not None:
+ return '%s.%s' % (cls.__name__, self._name_)
+ members = self._decompose_()
+ if len(members) == 1 and members[0]._name_ is None:
+ return '%s.%r' % (cls.__name__, members[0]._value_)
+ else:
+ return '%s.%s' % (
+ cls.__name__,
+ '|'.join([str(m._name_ or m._value_) for m in members]),
+ )
+
+ def __or__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self.__class__(self._value_ | other._value_)
+
+ def __and__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self.__class__(self._value_ & other._value_)
+
+ def __xor__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self.__class__(self._value_ ^ other._value_)
+
+ def __invert__(self):
+ members = self._decompose_()
+ inverted_members = [m for m in self.__class__ if m not in members and not m._value_ & self._value_]
+ inverted = reduce(_or_, inverted_members, self.__class__(0))
+ return self.__class__(inverted)
+
+
+class IntFlags(int, Flags):
+ """Support for integer-based Flags"""
+
+ @classmethod
+ def _create_pseudo_member_(cls, value):
+ pseudo_member = cls._value2member_map_.get(value, None)
+ if pseudo_member is None:
+ # construct a non-singleton enum pseudo-member
+ pseudo_member = int.__new__(cls, value)
+ pseudo_member._name_ = None
+ pseudo_member._value_ = value
+ cls._value2member_map_[value] = pseudo_member
+ return pseudo_member
+
+ @classmethod
+ def _missing_(cls, value):
+ possible_member = cls._create_pseudo_member_(value)
+ return possible_member
+
+ def __or__(self, other):
+ if not isinstance(other, (self.__class__, int)):
+ return NotImplemented
+ return self.__class__(self._value_ | self.__class__(other)._value_)
+
+ def __and__(self, other):
+ if not isinstance(other, (self.__class__, int)):
+ return NotImplemented
+ return self.__class__(self._value_ & self.__class__(other)._value_)
+
+ def __xor__(self, other):
+ if not isinstance(other, (self.__class__, int)):
+ return NotImplemented
+ return self.__class__(self._value_ ^ self.__class__(other)._value_)
+
+ __ror__ = __or__
+ __rand__ = __and__
+ __rxor__ = __xor__
+
+ def __invert__(self):
+ # members = self._decompose_()
+ # inverted_members = [m for m in self.__class__ if m not in members and not m._value_ & self._value_]
+ # inverted = reduce(_or_, inverted_members, self.__class__(0))
+ return self.__class__(~self._value_)
+
+
+
+
+def _high_bit(value):
+ """return the highest bit set in value"""
+ bit = 0
+ while 'looking for the highest bit':
+ limit = 2 ** bit
+ if limit > value:
+ return bit - 1
+ bit += 1
+
def unique(enumeration):
"""Class decorator for enumerations ensuring unique member values."""
duplicates = []
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -3,7 +3,7 @@
import pydoc
import unittest
from collections import OrderedDict
-from enum import Enum, IntEnum, EnumMeta, unique
+from enum import Enum, IntEnum, EnumMeta, Flags, IntFlags, unique
from io import StringIO
from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL
from test import support
@@ -1633,6 +1633,456 @@
verde = green
+class TestFlags(unittest.TestCase):
+ """Tests of the Flags."""
+
+ class Perm(Flags):
+ R, W, X = 4, 2, 1
+
+ class Open(Flags):
+ RO = 0
+ WO = 1
+ RW = 2
+ AC = 3
+ CE = 1<<19
+
+ def test_str(self):
+ Perm = self.Perm
+ self.assertEqual(str(Perm.R), 'Perm.R')
+ self.assertEqual(str(Perm.W), 'Perm.W')
+ self.assertEqual(str(Perm.X), 'Perm.X')
+ self.assertEqual(str(Perm.R | Perm.W), 'Perm.R|W')
+ self.assertEqual(str(Perm.R | Perm.W | Perm.X), 'Perm.R|W|X')
+ self.assertEqual(str(Perm(0)), 'Perm.0')
+ self.assertEqual(str(~Perm.R), 'Perm.W|X')
+ self.assertEqual(str(~Perm.W), 'Perm.R|X')
+ self.assertEqual(str(~Perm.X), 'Perm.R|W')
+ self.assertEqual(str(~(Perm.R | Perm.W)), 'Perm.X')
+ self.assertEqual(str(~(Perm.R | Perm.W | Perm.X)), 'Perm.0')
+ self.assertEqual(str(Perm(~0)), 'Perm.R|W|X')
+
+ Open = self.Open
+ self.assertEqual(str(Open.RO), 'Open.RO')
+ self.assertEqual(str(Open.WO), 'Open.WO')
+ self.assertEqual(str(Open.AC), 'Open.AC')
+ self.assertEqual(str(Open.RO | Open.CE), 'Open.CE')
+ self.assertEqual(str(Open.WO | Open.CE), 'Open.CE|WO')
+ self.assertEqual(str(~Open.RO), 'Open.CE|AC')
+ self.assertEqual(str(~Open.WO), 'Open.CE|RW')
+ self.assertEqual(str(~Open.AC), 'Open.CE')
+ self.assertEqual(str(~(Open.RO | Open.CE)), 'Open.AC')
+ self.assertEqual(str(~(Open.WO | Open.CE)), 'Open.RW')
+
+ def test_repr(self):
+ Perm = self.Perm
+ self.assertEqual(repr(Perm.R), '<Perm.R: 4>')
+ self.assertEqual(repr(Perm.W), '<Perm.W: 2>')
+ self.assertEqual(repr(Perm.X), '<Perm.X: 1>')
+ self.assertEqual(repr(Perm.R | Perm.W), '<Perm.R|W: 6>')
+ self.assertEqual(repr(Perm.R | Perm.W | Perm.X), '<Perm.R|W|X: 7>')
+ self.assertEqual(repr(Perm(0)), '<Perm: 0>')
+ self.assertEqual(repr(~Perm.R), '<Perm.W|X: 3>')
+ self.assertEqual(repr(~Perm.W), '<Perm.R|X: 5>')
+ self.assertEqual(repr(~Perm.X), '<Perm.R|W: 6>')
+ self.assertEqual(repr(~(Perm.R | Perm.W)), '<Perm.X: 1>')
+ self.assertEqual(repr(~(Perm.R | Perm.W | Perm.X)), '<Perm: 0>')
+ self.assertEqual(repr(Perm(~0)), '<Perm.R|W|X: 7>')
+
+ Open = self.Open
+ self.assertEqual(repr(Open.RO), '<Open.RO: 0>')
+ self.assertEqual(repr(Open.WO), '<Open.WO: 1>')
+ self.assertEqual(repr(Open.AC), '<Open.AC: 3>')
+ self.assertEqual(repr(Open.RO | Open.CE), '<Open.CE: 524288>')
+ self.assertEqual(repr(Open.WO | Open.CE), '<Open.CE|WO: 524289>')
+ self.assertEqual(repr(~Open.RO), '<Open.CE|AC: 524291>')
+ self.assertEqual(repr(~Open.WO), '<Open.CE|RW: 524290>')
+ self.assertEqual(repr(~Open.AC), '<Open.CE: 524288>')
+ self.assertEqual(repr(~(Open.RO | Open.CE)), '<Open.AC: 3>')
+ self.assertEqual(repr(~(Open.WO | Open.CE)), '<Open.RW: 2>')
+
+ def test_or(self):
+ Perm = self.Perm
+ for i in Perm:
+ for j in Perm:
+ self.assertEqual((i | j), Perm(i.value | j.value))
+ self.assertEqual((i | j).value, i.value | j.value)
+ self.assertIs(type(i | j), Perm)
+ for i in Perm:
+ self.assertIs(i | i, i)
+ Open = self.Open
+ self.assertIs(Open.RO | Open.CE, Open.CE)
+
+ def test_and(self):
+ Perm = self.Perm
+ RW = Perm.R | Perm.W
+ RX = Perm.R | Perm.X
+ WX = Perm.W | Perm.X
+ RWX = Perm.R | Perm.W | Perm.X
+ values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
+ for i in values:
+ for j in values:
+ self.assertEqual((i & j).value, i.value & j.value)
+ self.assertIs(type(i & j), Perm)
+ for i in Perm:
+ self.assertIs(i & i, i)
+ self.assertIs(i & RWX, i)
+ self.assertIs(RWX & i, i)
+ Open = self.Open
+ self.assertIs(Open.RO & Open.CE, Open.RO)
+
+ def test_xor(self):
+ Perm = self.Perm
+ for i in Perm:
+ for j in Perm:
+ self.assertEqual((i ^ j).value, i.value ^ j.value)
+ self.assertIs(type(i ^ j), Perm)
+ for i in Perm:
+ self.assertIs(i ^ Perm(0), i)
+ self.assertIs(Perm(0) ^ i, i)
+ Open = self.Open
+ self.assertIs(Open.RO ^ Open.CE, Open.CE)
+ self.assertIs(Open.CE ^ Open.CE, Open.RO)
+
+ def test_invert(self):
+ Perm = self.Perm
+ RW = Perm.R | Perm.W
+ RX = Perm.R | Perm.X
+ WX = Perm.W | Perm.X
+ RWX = Perm.R | Perm.W | Perm.X
+ values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
+ for i in values:
+ self.assertIs(type(~i), Perm)
+ self.assertEqual(~~i, i)
+ for i in Perm:
+ self.assertIs(~~i, i)
+ Open = self.Open
+ self.assertIs(Open.WO & ~Open.WO, Open.RO)
+ self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE)
+
+ def test_programatic_function_string(self):
+ Perm = Flags('Perm', 'R W X')
+ lst = list(Perm)
+ self.assertEqual(len(lst), len(Perm))
+ self.assertEqual(len(Perm), 3, Perm)
+ self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
+ for i, n in enumerate('R W X'.split()):
+ v = 1<<i
+ e = Perm(v)
+ self.assertEqual(e.value, v)
+ self.assertEqual(type(e.value), int)
+ self.assertEqual(e.name, n)
+ self.assertIn(e, Perm)
+ self.assertIs(type(e), Perm)
+
+ def test_programatic_function_string_with_start(self):
+ Perm = Flags('Perm', 'R W X', start=8)
+ lst = list(Perm)
+ self.assertEqual(len(lst), len(Perm))
+ self.assertEqual(len(Perm), 3, Perm)
+ self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
+ for i, n in enumerate('R W X'.split()):
+ v = 8<<i
+ e = Perm(v)
+ self.assertEqual(e.value, v)
+ self.assertEqual(type(e.value), int)
+ self.assertEqual(e.name, n)
+ self.assertIn(e, Perm)
+ self.assertIs(type(e), Perm)
+
+ def test_programatic_function_string_list(self):
+ Perm = Flags('Perm', ['R', 'W', 'X'])
+ lst = list(Perm)
+ self.assertEqual(len(lst), len(Perm))
+ self.assertEqual(len(Perm), 3, Perm)
+ self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
+ for i, n in enumerate('R W X'.split()):
+ v = 1<<i
+ e = Perm(v)
+ self.assertEqual(e.value, v)
+ self.assertEqual(type(e.value), int)
+ self.assertEqual(e.name, n)
+ self.assertIn(e, Perm)
+ self.assertIs(type(e), Perm)
+
+ def test_programatic_function_iterable(self):
+ Perm = Flags('Perm', (('R', 2), ('W', 8), ('X', 32)))
+ lst = list(Perm)
+ self.assertEqual(len(lst), len(Perm))
+ self.assertEqual(len(Perm), 3, Perm)
+ self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
+ for i, n in enumerate('R W X'.split()):
+ v = 1<<(2*i+1)
+ e = Perm(v)
+ self.assertEqual(e.value, v)
+ self.assertEqual(type(e.value), int)
+ self.assertEqual(e.name, n)
+ self.assertIn(e, Perm)
+ self.assertIs(type(e), Perm)
+
+ def test_programatic_function_from_dict(self):
+ Perm = Flags('Perm', OrderedDict((('R', 2), ('W', 8), ('X', 32))))
+ lst = list(Perm)
+ self.assertEqual(len(lst), len(Perm))
+ self.assertEqual(len(Perm), 3, Perm)
+ self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
+ for i, n in enumerate('R W X'.split()):
+ v = 1<<(2*i+1)
+ e = Perm(v)
+ self.assertEqual(e.value, v)
+ self.assertEqual(type(e.value), int)
+ self.assertEqual(e.name, n)
+ self.assertIn(e, Perm)
+ self.assertIs(type(e), Perm)
+
+
+class TestIntFlags(unittest.TestCase):
+ """Tests of the IntFlags."""
+
+ class Perm(IntFlags):
+ X = 1 << 0
+ W = 1 << 1
+ R = 1 << 2
+
+ class Open(IntFlags):
+ RO = 0
+ WO = 1
+ RW = 2
+ AC = 3
+ CE = 1<<19
+
+ def test_str(self):
+ Perm = self.Perm
+ self.assertEqual(str(Perm.R), 'Perm.R')
+ self.assertEqual(str(Perm.W), 'Perm.W')
+ self.assertEqual(str(Perm.X), 'Perm.X')
+ self.assertEqual(str(Perm.R | Perm.W), 'Perm.R|W')
+ self.assertEqual(str(Perm.R | Perm.W | Perm.X), 'Perm.R|W|X')
+ self.assertEqual(str(Perm.R | 8), 'Perm.8|R')
+ self.assertEqual(str(Perm(0)), 'Perm.0')
+ self.assertEqual(str(Perm(8)), 'Perm.8')
+ self.assertEqual(str(~Perm.R), 'Perm.W|X|-8')
+ self.assertEqual(str(~Perm.W), 'Perm.R|X|-8')
+ self.assertEqual(str(~Perm.X), 'Perm.R|W|-8')
+ self.assertEqual(str(~(Perm.R | Perm.W)), 'Perm.X|-8')
+ self.assertEqual(str(~(Perm.R | Perm.W | Perm.X)), 'Perm.-8')
+ self.assertEqual(str(~(Perm.R | 8)), 'Perm.W|X|-16')
+ self.assertEqual(str(Perm(~0)), 'Perm.R|W|X|-8')
+ self.assertEqual(str(Perm(~8)), 'Perm.R|W|X|-16')
+
+ Open = self.Open
+ self.assertEqual(str(Open.RO), 'Open.RO')
+ self.assertEqual(str(Open.WO), 'Open.WO')
+ self.assertEqual(str(Open.AC), 'Open.AC')
+ self.assertEqual(str(Open.RO | Open.CE), 'Open.CE')
+ self.assertEqual(str(Open.WO | Open.CE), 'Open.CE|WO')
+ self.assertEqual(str(Open(4)), 'Open.4')
+ self.assertEqual(str(~Open.RO), 'Open.CE|AC|-524292')
+ self.assertEqual(str(~Open.WO), 'Open.CE|RW|-524292')
+ self.assertEqual(str(~Open.AC), 'Open.CE|-524292')
+ self.assertEqual(str(~(Open.RO | Open.CE)), 'Open.AC|-524292')
+ self.assertEqual(str(~(Open.WO | Open.CE)), 'Open.RW|-524292')
+ self.assertEqual(str(Open(~4)), 'Open.CE|AC|-524296')
+
+ def test_repr(self):
+ Perm = self.Perm
+ self.assertEqual(repr(Perm.R), '<Perm.R: 4>')
+ self.assertEqual(repr(Perm.W), '<Perm.W: 2>')
+ self.assertEqual(repr(Perm.X), '<Perm.X: 1>')
+ self.assertEqual(repr(Perm.R | Perm.W), '<Perm.R|W: 6>')
+ self.assertEqual(repr(Perm.R | Perm.W | Perm.X), '<Perm.R|W|X: 7>')
+ self.assertEqual(repr(Perm.R | 8), '<Perm.8|R: 12>')
+ self.assertEqual(repr(Perm(0)), '<Perm: 0>')
+ self.assertEqual(repr(Perm(8)), '<Perm: 8>')
+ self.assertEqual(repr(~Perm.R), '<Perm.W|X|-8: -5>')
+ self.assertEqual(repr(~Perm.W), '<Perm.R|X|-8: -3>')
+ self.assertEqual(repr(~Perm.X), '<Perm.R|W|-8: -2>')
+ self.assertEqual(repr(~(Perm.R | Perm.W)), '<Perm.X|-8: -7>')
+ self.assertEqual(repr(~(Perm.R | Perm.W | Perm.X)), '<Perm: -8>')
+ self.assertEqual(repr(~(Perm.R | 8)), '<Perm.W|X|-16: -13>')
+ self.assertEqual(repr(Perm(~0)), '<Perm.R|W|X|-8: -1>')
+ self.assertEqual(repr(Perm(~8)), '<Perm.R|W|X|-16: -9>')
+
+ Open = self.Open
+ self.assertEqual(repr(Open.RO), '<Open.RO: 0>')
+ self.assertEqual(repr(Open.WO), '<Open.WO: 1>')
+ self.assertEqual(repr(Open.AC), '<Open.AC: 3>')
+ self.assertEqual(repr(Open.RO | Open.CE), '<Open.CE: 524288>')
+ self.assertEqual(repr(Open.WO | Open.CE), '<Open.CE|WO: 524289>')
+ self.assertEqual(repr(Open(4)), '<Open: 4>')
+ self.assertEqual(repr(~Open.RO), '<Open.CE|AC|-524292: -1>')
+ self.assertEqual(repr(~Open.WO), '<Open.CE|RW|-524292: -2>')
+ self.assertEqual(repr(~Open.AC), '<Open.CE|-524292: -4>')
+ self.assertEqual(repr(~(Open.RO | Open.CE)), '<Open.AC|-524292: -524289>')
+ self.assertEqual(repr(~(Open.WO | Open.CE)), '<Open.RW|-524292: -524290>')
+ self.assertEqual(repr(Open(~4)), '<Open.CE|AC|-524296: -5>')
+
+ def test_or(self):
+ Perm = self.Perm
+ for i in Perm:
+ for j in Perm:
+ self.assertEqual(i | j, i.value | j.value)
+ self.assertEqual((i | j).value, i.value | j.value)
+ self.assertIs(type(i | j), Perm)
+ for j in range(8):
+ self.assertEqual(i | j, i.value | j)
+ self.assertEqual((i | j).value, i.value | j)
+ self.assertIs(type(i | j), Perm)
+ self.assertEqual(j | i, j | i.value)
+ self.assertEqual((j | i).value, j | i.value)
+ self.assertIs(type(j | i), Perm)
+ for i in Perm:
+ self.assertIs(i | i, i)
+ self.assertIs(i | 0, i)
+ self.assertIs(0 | i, i)
+ Open = self.Open
+ self.assertIs(Open.RO | Open.CE, Open.CE)
+
+ def test_and(self):
+ Perm = self.Perm
+ RW = Perm.R | Perm.W
+ RX = Perm.R | Perm.X
+ WX = Perm.W | Perm.X
+ RWX = Perm.R | Perm.W | Perm.X
+ values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
+ for i in values:
+ for j in values:
+ self.assertEqual(i & j, i.value & j.value, 'i is %r, j is %r' % (i, j))
+ self.assertEqual((i & j).value, i.value & j.value, 'i is %r, j is %r' % (i, j))
+ self.assertIs(type(i & j), Perm, 'i is %r, j is %r' % (i, j))
+ for j in range(8):
+ self.assertEqual(i & j, i.value & j)
+ self.assertEqual((i & j).value, i.value & j)
+ self.assertIs(type(i & j), Perm)
+ self.assertEqual(j & i, j & i.value)
+ self.assertEqual((j & i).value, j & i.value)
+ self.assertIs(type(j & i), Perm)
+ for i in Perm:
+ self.assertIs(i & i, i)
+ self.assertIs(i & 7, i)
+ self.assertIs(7 & i, i)
+ Open = self.Open
+ self.assertIs(Open.RO & Open.CE, Open.RO)
+
+ def test_xor(self):
+ Perm = self.Perm
+ for i in Perm:
+ for j in Perm:
+ self.assertEqual(i ^ j, i.value ^ j.value)
+ self.assertEqual((i ^ j).value, i.value ^ j.value)
+ self.assertIs(type(i ^ j), Perm)
+ for j in range(8):
+ self.assertEqual(i ^ j, i.value ^ j)
+ self.assertEqual((i ^ j).value, i.value ^ j)
+ self.assertIs(type(i ^ j), Perm)
+ self.assertEqual(j ^ i, j ^ i.value)
+ self.assertEqual((j ^ i).value, j ^ i.value)
+ self.assertIs(type(j ^ i), Perm)
+ for i in Perm:
+ self.assertIs(i ^ 0, i)
+ self.assertIs(0 ^ i, i)
+ Open = self.Open
+ self.assertIs(Open.RO ^ Open.CE, Open.CE)
+ self.assertIs(Open.CE ^ Open.CE, Open.RO)
+
+ def test_invert(self):
+ Perm = self.Perm
+ RW = Perm.R | Perm.W
+ RX = Perm.R | Perm.X
+ WX = Perm.W | Perm.X
+ RWX = Perm.R | Perm.W | Perm.X
+ values = list(Perm) + [RW, RX, WX, RWX, Perm(0)]
+ for i in values:
+ self.assertEqual(~i, ~i.value)
+ self.assertEqual((~i).value, ~i.value)
+ self.assertIs(type(~i), Perm)
+ self.assertEqual(~~i, i)
+ for i in Perm:
+ self.assertIs(~~i, i)
+ Open = self.Open
+ self.assertIs(Open.WO & ~Open.WO, Open.RO)
+ self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE)
+
+ def test_programatic_function_string(self):
+ Perm = IntFlags('Perm', 'R W X')
+ lst = list(Perm)
+ self.assertEqual(len(lst), len(Perm))
+ self.assertEqual(len(Perm), 3, Perm)
+ self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
+ for i, n in enumerate('R W X'.split()):
+ v = 1<<i
+ e = Perm(v)
+ self.assertEqual(e.value, v)
+ self.assertEqual(type(e.value), int)
+ self.assertEqual(e, v)
+ self.assertEqual(e.name, n)
+ self.assertIn(e, Perm)
+ self.assertIs(type(e), Perm)
+
+ def test_programatic_function_string_with_start(self):
+ Perm = IntFlags('Perm', 'R W X', start=8)
+ lst = list(Perm)
+ self.assertEqual(len(lst), len(Perm))
+ self.assertEqual(len(Perm), 3, Perm)
+ self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
+ for i, n in enumerate('R W X'.split()):
+ v = 8<<i
+ e = Perm(v)
+ self.assertEqual(e.value, v)
+ self.assertEqual(type(e.value), int)
+ self.assertEqual(e, v)
+ self.assertEqual(e.name, n)
+ self.assertIn(e, Perm)
+ self.assertIs(type(e), Perm)
+
+ def test_programatic_function_string_list(self):
+ Perm = IntFlags('Perm', ['R', 'W', 'X'])
+ lst = list(Perm)
+ self.assertEqual(len(lst), len(Perm))
+ self.assertEqual(len(Perm), 3, Perm)
+ self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
+ for i, n in enumerate('R W X'.split()):
+ v = 1<<i
+ e = Perm(v)
+ self.assertEqual(e.value, v)
+ self.assertEqual(type(e.value), int)
+ self.assertEqual(e, v)
+ self.assertEqual(e.name, n)
+ self.assertIn(e, Perm)
+ self.assertIs(type(e), Perm)
+
+ def test_programatic_function_iterable(self):
+ Perm = IntFlags('Perm', (('R', 2), ('W', 8), ('X', 32)))
+ lst = list(Perm)
+ self.assertEqual(len(lst), len(Perm))
+ self.assertEqual(len(Perm), 3, Perm)
+ self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
+ for i, n in enumerate('R W X'.split()):
+ v = 1<<(2*i+1)
+ e = Perm(v)
+ self.assertEqual(e.value, v)
+ self.assertEqual(type(e.value), int)
+ self.assertEqual(e, v)
+ self.assertEqual(e.name, n)
+ self.assertIn(e, Perm)
+ self.assertIs(type(e), Perm)
+
+ def test_programatic_function_from_dict(self):
+ Perm = IntFlags('Perm', OrderedDict((('R', 2), ('W', 8), ('X', 32))))
+ lst = list(Perm)
+ self.assertEqual(len(lst), len(Perm))
+ self.assertEqual(len(Perm), 3, Perm)
+ self.assertEqual(lst, [Perm.R, Perm.W, Perm.X])
+ for i, n in enumerate('R W X'.split()):
+ v = 1<<(2*i+1)
+ e = Perm(v)
+ self.assertEqual(e.value, v)
+ self.assertEqual(type(e.value), int)
+ self.assertEqual(e, v)
+ self.assertEqual(e.name, n)
+ self.assertIn(e, Perm)
+ self.assertIs(type(e), Perm)
+
+
class TestUnique(unittest.TestCase):
def test_unique_clean(self):
--
Repository URL: https://hg.python.org/cpython
[View Less]
1
0

cpython: Issue #27891: Consistently group and sort imports within idlelib modules.
by terry.reedy Aug. 31, 2016
by terry.reedy Aug. 31, 2016
Aug. 31, 2016
https://hg.python.org/cpython/rev/96ac4cd43a20
changeset: 102965:96ac4cd43a20
user: Terry Jan Reedy <tjreedy(a)udel.edu>
date: Wed Aug 31 00:50:55 2016 -0400
summary:
Issue #27891: Consistently group and sort imports within idlelib modules.
files:
Lib/idlelib/README.txt | 21 +++++++-
Lib/idlelib/autocomplete.py | 17 +++---
Lib/idlelib/autocomplete_w.py | 3 +-
Lib/idlelib/autoexpand.py | 3 +-
Lib/idlelib/browser.py …
[View More] | 6 +-
Lib/idlelib/calltips.py | 2 +-
Lib/idlelib/codecontext.py | 6 +-
Lib/idlelib/colorizer.py | 9 +-
Lib/idlelib/config.py | 2 +-
Lib/idlelib/configdialog.py | 6 +-
Lib/idlelib/debugger.py | 8 +-
Lib/idlelib/debugobj.py | 3 +-
Lib/idlelib/dynoption.py | 1 +
Lib/idlelib/editor.py | 41 ++++++++-------
Lib/idlelib/filelist.py | 1 +
Lib/idlelib/grep.py | 11 ++-
Lib/idlelib/help.py | 2 +
Lib/idlelib/help_about.py | 5 +-
Lib/idlelib/history.py | 4 +-
Lib/idlelib/hyperparser.py | 5 +-
Lib/idlelib/idle_test/test_iomenu.py | 5 +-
Lib/idlelib/macosx.py | 3 +-
Lib/idlelib/multicall.py | 4 +-
Lib/idlelib/outwin.py | 7 +-
Lib/idlelib/paragraph.py | 4 +-
Lib/idlelib/parenmatch.py | 1 -
Lib/idlelib/pathbrowser.py | 7 +-
Lib/idlelib/percolator.py | 2 +-
Lib/idlelib/pyparse.py | 2 +-
Lib/idlelib/pyshell.py | 28 +++++-----
Lib/idlelib/query.py | 3 +-
Lib/idlelib/replace.py | 6 +-
Lib/idlelib/rpc.py | 26 ++++++---
Lib/idlelib/run.py | 24 ++++----
Lib/idlelib/runscript.py | 3 +-
Lib/idlelib/scrolledlist.py | 4 +-
Lib/idlelib/search.py | 1 +
Lib/idlelib/searchbase.py | 1 +
Lib/idlelib/searchengine.py | 3 +
Lib/idlelib/stackviewer.py | 11 +++-
Lib/idlelib/statusbar.py | 2 +
Lib/idlelib/tabbedpages.py | 3 +
Lib/idlelib/textview.py | 2 +-
Lib/idlelib/tree.py | 4 +-
Lib/idlelib/undo.py | 7 +-
Lib/idlelib/windows.py | 2 +
Lib/idlelib/zoomheight.py | 2 +
47 files changed, 199 insertions(+), 124 deletions(-)
diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt
--- a/Lib/idlelib/README.txt
+++ b/Lib/idlelib/README.txt
@@ -228,4 +228,23 @@
<No menu>
Center Insert # eEW.center_insert_event
-
+
+
+CODE STYLE -- Generally PEP 8.
+
+import
+------
+Put import at the top, unless there is a good reason otherwise.
+PEP 8 says to group stdlib, 3rd-party dependencies, and package imports.
+For idlelib, the groups are general stdlib, tkinter, and idlelib.
+Sort modules within each group, except that tkinter.ttk follows tkinter.
+Sort 'from idlelib import mod1' and 'from idlelib.mod2 import object'
+together by module, ignoring within module objects.
+Put 'import __main__' after other idlelib imports.
+
+Imports only needed for testing are not at the top but are put in the
+htest function def or the "if __name__ == '__main__'" clause.
+
+Within module imports like "from idlelib.mod import class" may cause
+circular imports to deadlock. Even without this, circular imports may
+require at least one of the imports to be delayed until a function call.
diff --git a/Lib/idlelib/autocomplete.py b/Lib/idlelib/autocomplete.py
--- a/Lib/idlelib/autocomplete.py
+++ b/Lib/idlelib/autocomplete.py
@@ -4,26 +4,27 @@
a window with all available names, for the user to select from.
"""
import os
+import string
import sys
-import string
-from idlelib.config import idleConf
-
-# This string includes all chars that may be in an identifier
-ID_CHARS = string.ascii_letters + string.digits + "_"
-
-# These constants represent the two different types of completions
+# These constants represent the two different types of completions.
+# They must be defined here so autocomple_w can import them.
COMPLETE_ATTRIBUTES, COMPLETE_FILES = range(1, 2+1)
from idlelib import autocomplete_w
+from idlelib.config import idleConf
from idlelib.hyperparser import HyperParser
+import __main__
-import __main__
+# This string includes all chars that may be in an identifier.
+# TODO Update this here and elsewhere.
+ID_CHARS = string.ascii_letters + string.digits + "_"
SEPS = os.sep
if os.altsep: # e.g. '/' on Windows...
SEPS += os.altsep
+
class AutoComplete:
menudefs = [
diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py
--- a/Lib/idlelib/autocomplete_w.py
+++ b/Lib/idlelib/autocomplete_w.py
@@ -3,8 +3,9 @@
"""
from tkinter import *
from tkinter.ttk import Scrollbar
+
+from idlelib.autocomplete import COMPLETE_FILES, COMPLETE_ATTRIBUTES
from idlelib.multicall import MC_SHIFT
-from idlelib.autocomplete import COMPLETE_FILES, COMPLETE_ATTRIBUTES
HIDE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-hide>>"
HIDE_SEQUENCES = ("<FocusOut>", "<ButtonPress>")
diff --git a/Lib/idlelib/autoexpand.py b/Lib/idlelib/autoexpand.py
--- a/Lib/idlelib/autoexpand.py
+++ b/Lib/idlelib/autoexpand.py
@@ -12,8 +12,8 @@
This is an extension file and there is only one instance of AutoExpand.
'''
+import re
import string
-import re
###$ event <<expand-word>>
###$ win <Alt-slash>
@@ -100,7 +100,6 @@
i = i-1
return line[i:]
-
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_autoexpand', verbosity=2)
diff --git a/Lib/idlelib/browser.py b/Lib/idlelib/browser.py
--- a/Lib/idlelib/browser.py
+++ b/Lib/idlelib/browser.py
@@ -11,13 +11,13 @@
"""
import os
+import pyclbr
import sys
-import pyclbr
+from idlelib.config import idleConf
from idlelib import pyshell
+from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas
from idlelib.windows import ListedToplevel
-from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas
-from idlelib.config import idleConf
file_open = None # Method...Item and Class...Item use this.
# Normally pyshell.flist.open, but there is no pyshell.flist for htest.
diff --git a/Lib/idlelib/calltips.py b/Lib/idlelib/calltips.py
--- a/Lib/idlelib/calltips.py
+++ b/Lib/idlelib/calltips.py
@@ -5,7 +5,6 @@
which disappear when you type a closing parenthesis.
"""
-import __main__
import inspect
import re
import sys
@@ -14,6 +13,7 @@
from idlelib import calltip_w
from idlelib.hyperparser import HyperParser
+import __main__
class CallTips:
diff --git a/Lib/idlelib/codecontext.py b/Lib/idlelib/codecontext.py
--- a/Lib/idlelib/codecontext.py
+++ b/Lib/idlelib/codecontext.py
@@ -9,10 +9,12 @@
not open blocks are not shown in the context hints pane.
"""
+import re
+from sys import maxsize as INFINITY
+
import tkinter
from tkinter.constants import TOP, LEFT, X, W, SUNKEN
-import re
-from sys import maxsize as INFINITY
+
from idlelib.config import idleConf
BLOCKOPENERS = {"class", "def", "elif", "else", "except", "finally", "for",
diff --git a/Lib/idlelib/colorizer.py b/Lib/idlelib/colorizer.py
--- a/Lib/idlelib/colorizer.py
+++ b/Lib/idlelib/colorizer.py
@@ -1,9 +1,10 @@
+import builtins
+import keyword
+import re
import time
-import re
-import keyword
-import builtins
+
+from idlelib.config import idleConf
from idlelib.delegator import Delegator
-from idlelib.config import idleConf
DEBUG = False
diff --git a/Lib/idlelib/config.py b/Lib/idlelib/config.py
--- a/Lib/idlelib/config.py
+++ b/Lib/idlelib/config.py
@@ -18,10 +18,10 @@
"""
# TODOs added Oct 2014, tjr
+from configparser import ConfigParser
import os
import sys
-from configparser import ConfigParser
from tkinter.font import Font, nametofont
class InvalidConfigType(Exception): pass
diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py
--- a/Lib/idlelib/configdialog.py
+++ b/Lib/idlelib/configdialog.py
@@ -11,17 +11,17 @@
"""
from tkinter import *
from tkinter.ttk import Scrollbar
-import tkinter.messagebox as tkMessageBox
import tkinter.colorchooser as tkColorChooser
import tkinter.font as tkFont
+import tkinter.messagebox as tkMessageBox
from idlelib.config import idleConf
+from idlelib.config_key import GetKeysDialog
from idlelib.dynoption import DynOptionMenu
-from idlelib.config_key import GetKeysDialog
+from idlelib import macosx
from idlelib.query import SectionName, HelpSource
from idlelib.tabbedpages import TabbedPageSet
from idlelib.textview import view_text
-from idlelib import macosx
class ConfigDialog(Toplevel):
diff --git a/Lib/idlelib/debugger.py b/Lib/idlelib/debugger.py
--- a/Lib/idlelib/debugger.py
+++ b/Lib/idlelib/debugger.py
@@ -1,10 +1,12 @@
+import bdb
import os
-import bdb
+
from tkinter import *
from tkinter.ttk import Scrollbar
+
+from idlelib import macosx
+from idlelib.scrolledlist import ScrolledList
from idlelib.windows import ListedToplevel
-from idlelib.scrolledlist import ScrolledList
-from idlelib import macosx
class Idb(bdb.Bdb):
diff --git a/Lib/idlelib/debugobj.py b/Lib/idlelib/debugobj.py
--- a/Lib/idlelib/debugobj.py
+++ b/Lib/idlelib/debugobj.py
@@ -8,11 +8,10 @@
# XXX TO DO:
# - for classes/modules, add "open source" to object browser
+from reprlib import Repr
from idlelib.tree import TreeItem, TreeNode, ScrolledCanvas
-from reprlib import Repr
-
myrepr = Repr()
myrepr.maxstring = 100
myrepr.maxother = 100
diff --git a/Lib/idlelib/dynoption.py b/Lib/idlelib/dynoption.py
--- a/Lib/idlelib/dynoption.py
+++ b/Lib/idlelib/dynoption.py
@@ -3,6 +3,7 @@
and setting of highlightthickness
"""
import copy
+
from tkinter import OptionMenu, _setit, StringVar, Button
class DynOptionMenu(OptionMenu):
diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py
--- a/Lib/idlelib/editor.py
+++ b/Lib/idlelib/editor.py
@@ -6,24 +6,28 @@
import re
import string
import sys
+import tokenize
+import traceback
+import webbrowser
+
from tkinter import *
from tkinter.ttk import Scrollbar
import tkinter.simpledialog as tkSimpleDialog
import tkinter.messagebox as tkMessageBox
-import traceback
-import webbrowser
+from idlelib.config import idleConf
+from idlelib import configdialog
+from idlelib import grep
+from idlelib import help
+from idlelib import help_about
+from idlelib import macosx
from idlelib.multicall import MultiCallCreator
+from idlelib import pyparse
from idlelib import query
+from idlelib import replace
+from idlelib import search
+from idlelib import textview
from idlelib import windows
-from idlelib import search
-from idlelib import grep
-from idlelib import replace
-from idlelib import pyparse
-from idlelib.config import idleConf
-from idlelib import help_about, textview, configdialog
-from idlelib import macosx
-from idlelib import help
# The default tab setting for a Text widget, in average-width characters.
TK_TABWIDTH_DEFAULT = 8
@@ -1515,9 +1519,6 @@
break
return raw, effective
-import tokenize
-_tokenize = tokenize
-del tokenize
class IndentSearcher(object):
@@ -1542,8 +1543,8 @@
return self.text.get(mark, mark + " lineend+1c")
def tokeneater(self, type, token, start, end, line,
- INDENT=_tokenize.INDENT,
- NAME=_tokenize.NAME,
+ INDENT=tokenize.INDENT,
+ NAME=tokenize.NAME,
OPENERS=('class', 'def', 'for', 'if', 'try', 'while')):
if self.finished:
pass
@@ -1554,19 +1555,19 @@
self.finished = 1
def run(self):
- save_tabsize = _tokenize.tabsize
- _tokenize.tabsize = self.tabwidth
+ save_tabsize = tokenize.tabsize
+ tokenize.tabsize = self.tabwidth
try:
try:
- tokens = _tokenize.generate_tokens(self.readline)
+ tokens = tokenize.generate_tokens(self.readline)
for token in tokens:
self.tokeneater(*token)
- except (_tokenize.TokenError, SyntaxError):
+ except (tokenize.TokenError, SyntaxError):
# since we cut off the tokenizer early, we can trigger
# spurious errors
pass
finally:
- _tokenize.tabsize = save_tabsize
+ tokenize.tabsize = save_tabsize
return self.blkopenline, self.indentedline
### end autoindent code ###
diff --git a/Lib/idlelib/filelist.py b/Lib/idlelib/filelist.py
--- a/Lib/idlelib/filelist.py
+++ b/Lib/idlelib/filelist.py
@@ -1,4 +1,5 @@
import os
+
from tkinter import *
import tkinter.messagebox as tkMessageBox
diff --git a/Lib/idlelib/grep.py b/Lib/idlelib/grep.py
--- a/Lib/idlelib/grep.py
+++ b/Lib/idlelib/grep.py
@@ -1,11 +1,14 @@
+import fnmatch
import os
-import fnmatch
import sys
+
from tkinter import StringVar, BooleanVar
from tkinter.ttk import Checkbutton
+
+from idlelib.searchbase import SearchDialogBase
from idlelib import searchengine
-from idlelib.searchbase import SearchDialogBase
-# Importing OutputWindow fails due to import loop
+
+# Importing OutputWindow here fails due to import loop
# EditorWindow -> GrepDialop -> OutputWindow -> EditorWindow
def grep(text, io=None, flist=None):
@@ -127,9 +130,9 @@
def _grep_dialog(parent): # htest #
- from idlelib.pyshell import PyShellFileList
from tkinter import Toplevel, Text, SEL, END
from tkinter.ttk import Button
+ from idlelib.pyshell import PyShellFileList
top = Toplevel(parent)
top.title("Test GrepDialog")
x, y = map(int, parent.geometry().split('+')[1:])
diff --git a/Lib/idlelib/help.py b/Lib/idlelib/help.py
--- a/Lib/idlelib/help.py
+++ b/Lib/idlelib/help.py
@@ -27,9 +27,11 @@
from html.parser import HTMLParser
from os.path import abspath, dirname, isfile, join
from platform import python_version
+
from tkinter import Toplevel, Frame, Text, Menu
from tkinter.ttk import Menubutton, Scrollbar
from tkinter import font as tkfont
+
from idlelib.config import idleConf
## About IDLE ##
diff --git a/Lib/idlelib/help_about.py b/Lib/idlelib/help_about.py
--- a/Lib/idlelib/help_about.py
+++ b/Lib/idlelib/help_about.py
@@ -1,12 +1,14 @@
"""About Dialog for IDLE
"""
-
import os
from sys import version
+
from tkinter import *
+
from idlelib import textview
+
class AboutDialog(Toplevel):
"""Modal about dialog for idle
@@ -144,6 +146,7 @@
def Ok(self, event=None):
self.destroy()
+
if __name__ == '__main__':
import unittest
unittest.main('idlelib.idle_test.test_help_about', verbosity=2, exit=False)
diff --git a/Lib/idlelib/history.py b/Lib/idlelib/history.py
--- a/Lib/idlelib/history.py
+++ b/Lib/idlelib/history.py
@@ -2,6 +2,7 @@
from idlelib.config import idleConf
+
class History:
''' Implement Idle Shell history mechanism.
@@ -99,6 +100,7 @@
self.pointer = None
self.prefix = None
+
if __name__ == "__main__":
from unittest import main
- main('idlelib.idle_test.test_idlehistory', verbosity=2, exit=False)
+ main('idlelib.idle_test.test_history', verbosity=2, exit=False)
diff --git a/Lib/idlelib/hyperparser.py b/Lib/idlelib/hyperparser.py
--- a/Lib/idlelib/hyperparser.py
+++ b/Lib/idlelib/hyperparser.py
@@ -4,12 +4,11 @@
proper indentation of code. HyperParser gives additional information on
the structure of code.
"""
+from keyword import iskeyword
+import string
-import string
-from keyword import iskeyword
from idlelib import pyparse
-
# all ASCII chars that may be in an identifier
_ASCII_ID_CHARS = frozenset(string.ascii_letters + string.digits + "_")
# all ASCII chars that may be the first char of an identifier
diff --git a/Lib/idlelib/idle_test/test_iomenu.py b/Lib/idlelib/idle_test/test_iomenu.py
--- a/Lib/idlelib/idle_test/test_iomenu.py
+++ b/Lib/idlelib/idle_test/test_iomenu.py
@@ -1,6 +1,7 @@
import unittest
import io
-from idlelib.pyshell import PseudoInputFile, PseudoOutputFile
+
+from idlelib.run import PseudoInputFile, PseudoOutputFile
class S(str):
@@ -230,4 +231,4 @@
if __name__ == '__main__':
- unittest.main()
+ unittest.main(verbosity=2)
diff --git a/Lib/idlelib/macosx.py b/Lib/idlelib/macosx.py
--- a/Lib/idlelib/macosx.py
+++ b/Lib/idlelib/macosx.py
@@ -2,8 +2,9 @@
A number of functions that enhance IDLE on Mac OSX.
"""
from sys import platform # Used in _init_tk_type, changed by test.
+import warnings
+
import tkinter
-import warnings
## Define functions that query the Mac graphics type.
diff --git a/Lib/idlelib/multicall.py b/Lib/idlelib/multicall.py
--- a/Lib/idlelib/multicall.py
+++ b/Lib/idlelib/multicall.py
@@ -28,9 +28,9 @@
unless this conflicts with the first rule.
Each function will be called at most once for each event.
"""
+import re
+import sys
-import sys
-import re
import tkinter
# the event type constants, which define the meaning of mc_type
diff --git a/Lib/idlelib/outwin.py b/Lib/idlelib/outwin.py
--- a/Lib/idlelib/outwin.py
+++ b/Lib/idlelib/outwin.py
@@ -1,9 +1,12 @@
+import re
+
from tkinter import *
+import tkinter.messagebox as tkMessageBox
+
from idlelib.editor import EditorWindow
-import re
-import tkinter.messagebox as tkMessageBox
from idlelib import iomenu
+
class OutputWindow(EditorWindow):
"""An editor window that can serve as an output file.
diff --git a/Lib/idlelib/paragraph.py b/Lib/idlelib/paragraph.py
--- a/Lib/idlelib/paragraph.py
+++ b/Lib/idlelib/paragraph.py
@@ -14,10 +14,11 @@
spaces, they will not be considered part of the same block.
* Fancy comments, like this bulleted list, aren't handled :-)
"""
+import re
-import re
from idlelib.config import idleConf
+
class FormatParagraph:
menudefs = [
@@ -189,6 +190,7 @@
if m is None: return ""
return m.group(1)
+
if __name__ == "__main__":
import unittest
unittest.main('idlelib.idle_test.test_paragraph',
diff --git a/Lib/idlelib/parenmatch.py b/Lib/idlelib/parenmatch.py
--- a/Lib/idlelib/parenmatch.py
+++ b/Lib/idlelib/parenmatch.py
@@ -4,7 +4,6 @@
paren. Paren here is used generically; the matching applies to
parentheses, square brackets, and curly braces.
"""
-
from idlelib.hyperparser import HyperParser
from idlelib.config import idleConf
diff --git a/Lib/idlelib/pathbrowser.py b/Lib/idlelib/pathbrowser.py
--- a/Lib/idlelib/pathbrowser.py
+++ b/Lib/idlelib/pathbrowser.py
@@ -1,10 +1,10 @@
+import importlib.machinery
import os
import sys
-import importlib.machinery
-from idlelib.tree import TreeItem
from idlelib.browser import ClassBrowser, ModuleBrowserTreeItem
from idlelib.pyshell import PyShellFileList
+from idlelib.tree import TreeItem
class PathBrowser(ClassBrowser):
@@ -24,6 +24,7 @@
def rootnode(self):
return PathBrowserTreeItem()
+
class PathBrowserTreeItem(TreeItem):
def GetText(self):
@@ -36,6 +37,7 @@
sublist.append(item)
return sublist
+
class DirBrowserTreeItem(TreeItem):
def __init__(self, dir, packages=[]):
@@ -95,6 +97,7 @@
sorted.sort()
return sorted
+
def _path_browser(parent): # htest #
flist = PyShellFileList(parent)
PathBrowser(flist, _htest=True)
diff --git a/Lib/idlelib/percolator.py b/Lib/idlelib/percolator.py
--- a/Lib/idlelib/percolator.py
+++ b/Lib/idlelib/percolator.py
@@ -1,5 +1,5 @@
+from idlelib.delegator import Delegator
from idlelib.redirector import WidgetRedirector
-from idlelib.delegator import Delegator
class Percolator:
diff --git a/Lib/idlelib/pyparse.py b/Lib/idlelib/pyparse.py
--- a/Lib/idlelib/pyparse.py
+++ b/Lib/idlelib/pyparse.py
@@ -1,6 +1,6 @@
+from collections import Mapping
import re
import sys
-from collections import Mapping
# Reason last stmt is continued (or C_NONE if it's not).
(C_NONE, C_BACKSLASH, C_STRING_FIRST_LINE,
diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py
--- a/Lib/idlelib/pyshell.py
+++ b/Lib/idlelib/pyshell.py
@@ -15,9 +15,13 @@
parent=root)
sys.exit(1)
+from code import InteractiveInterpreter
import getopt
+import io
+import linecache
import os
import os.path
+from platform import python_version, system
import re
import socket
import subprocess
@@ -25,23 +29,20 @@
import threading
import time
import tokenize
+import warnings
-import linecache
-from code import InteractiveInterpreter
-from platform import python_version, system
-
-from idlelib import testing
+from idlelib import testing # bool value
+from idlelib.colorizer import ColorDelegator
+from idlelib.config import idleConf
+from idlelib import debugger
+from idlelib import debugger_r
from idlelib.editor import EditorWindow, fixwordbreaks
from idlelib.filelist import FileList
-from idlelib.colorizer import ColorDelegator
+from idlelib import macosx
+from idlelib.outwin import OutputWindow
+from idlelib import rpc
+from idlelib.run import idle_formatwarning, PseudoInputFile, PseudoOutputFile
from idlelib.undo import UndoDelegator
-from idlelib.outwin import OutputWindow
-from idlelib.config import idleConf
-from idlelib.run import idle_formatwarning, PseudoInputFile, PseudoOutputFile
-from idlelib import rpc
-from idlelib import debugger
-from idlelib import debugger_r
-from idlelib import macosx
HOST = '127.0.0.1' # python execution server on localhost loopback
PORT = 0 # someday pass in host, port for remote debug capability
@@ -51,7 +52,6 @@
# temporarily redirect the stream to the shell window to display warnings when
# checking user's code.
warning_stream = sys.__stderr__ # None, at least on Windows, if no console.
-import warnings
def idle_showwarning(
message, category, filename, lineno, file=None, line=None):
diff --git a/Lib/idlelib/query.py b/Lib/idlelib/query.py
--- a/Lib/idlelib/query.py
+++ b/Lib/idlelib/query.py
@@ -23,9 +23,10 @@
import importlib
import os
from sys import executable, platform # Platform is set for one test.
+
from tkinter import Toplevel, StringVar, W, E, N, S
+from tkinter.ttk import Frame, Button, Entry, Label
from tkinter import filedialog
-from tkinter.ttk import Frame, Button, Entry, Label
from tkinter.font import Font
class Query(Toplevel):
diff --git a/Lib/idlelib/replace.py b/Lib/idlelib/replace.py
--- a/Lib/idlelib/replace.py
+++ b/Lib/idlelib/replace.py
@@ -3,12 +3,12 @@
Defines various replace related functions like replace, replace all,
replace+find.
"""
+import re
+
from tkinter import StringVar, TclError
+from idlelib.searchbase import SearchDialogBase
from idlelib import searchengine
-from idlelib.searchbase import SearchDialogBase
-import re
-
def replace(text):
"""Returns a singleton ReplaceDialog instance.The single dialog
diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py
--- a/Lib/idlelib/rpc.py
+++ b/Lib/idlelib/rpc.py
@@ -26,23 +26,21 @@
accomplished in Idle.
"""
-
-import sys
+import builtins
+import copyreg
+import io
+import marshal
import os
-import io
+import pickle
+import queue
+import select
import socket
-import select
import socketserver
import struct
-import pickle
+import sys
import threading
-import queue
import traceback
-import copyreg
import types
-import marshal
-import builtins
-
def unpickle_code(ms):
co = marshal.loads(ms)
@@ -60,10 +58,12 @@
p.dump(obj)
return f.getvalue()
+
class CodePickler(pickle.Pickler):
dispatch_table = {types.CodeType: pickle_code}
dispatch_table.update(copyreg.dispatch_table)
+
BUFSIZE = 8*1024
LOCALHOST = '127.0.0.1'
@@ -487,16 +487,19 @@
# Token mix-in class
pass
+
def remoteref(obj):
oid = id(obj)
objecttable[oid] = obj
return RemoteProxy(oid)
+
class RemoteProxy(object):
def __init__(self, oid):
self.oid = oid
+
class RPCHandler(socketserver.BaseRequestHandler, SocketIO):
debugging = False
@@ -514,6 +517,7 @@
def get_remote_proxy(self, oid):
return RPCProxy(self, oid)
+
class RPCClient(SocketIO):
debugging = False
@@ -539,6 +543,7 @@
def get_remote_proxy(self, oid):
return RPCProxy(self, oid)
+
class RPCProxy(object):
__methods = None
@@ -587,6 +592,7 @@
if not callable(attr):
attributes[name] = 1
+
class MethodProxy(object):
def __init__(self, sockio, oid, name):
diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py
--- a/Lib/idlelib/run.py
+++ b/Lib/idlelib/run.py
@@ -2,21 +2,21 @@
import linecache
import queue
import sys
+import time
+import traceback
import _thread as thread
import threading
-import time
-import traceback
-import tkinter
+import warnings
-from idlelib import calltips
-from idlelib import autocomplete
+import tkinter # Tcl, deletions, messagebox if startup fails
-from idlelib import debugger_r
-from idlelib import debugobj_r
-from idlelib import stackviewer
-from idlelib import rpc
-from idlelib import iomenu
-
+from idlelib import autocomplete # AutoComplete, fetch_encodings
+from idlelib import calltips # CallTips
+from idlelib import debugger_r # start_debugger
+from idlelib import debugobj_r # remote_object_tree_item
+from idlelib import iomenu # encoding
+from idlelib import rpc # multiple objects
+from idlelib import stackviewer # StackTreeItem
import __main__
for mod in ('simpledialog', 'messagebox', 'font',
@@ -27,7 +27,6 @@
LOCALHOST = '127.0.0.1'
-import warnings
def idle_formatwarning(message, category, filename, lineno, line=None):
"""Format warnings the IDLE way."""
@@ -280,6 +279,7 @@
capture_warnings(False)
sys.exit(0)
+
class MyRPCServer(rpc.RPCServer):
def handle_error(self, request, client_address):
diff --git a/Lib/idlelib/runscript.py b/Lib/idlelib/runscript.py
--- a/Lib/idlelib/runscript.py
+++ b/Lib/idlelib/runscript.py
@@ -20,11 +20,12 @@
import os
import tabnanny
import tokenize
+
import tkinter.messagebox as tkMessageBox
-from idlelib import pyshell
from idlelib.config import idleConf
from idlelib import macosx
+from idlelib import pyshell
indent_message = """Error: Inconsistent indentation detected!
diff --git a/Lib/idlelib/scrolledlist.py b/Lib/idlelib/scrolledlist.py
--- a/Lib/idlelib/scrolledlist.py
+++ b/Lib/idlelib/scrolledlist.py
@@ -1,6 +1,8 @@
from tkinter import *
+from tkinter.ttk import Scrollbar
+
from idlelib import macosx
-from tkinter.ttk import Scrollbar
+
class ScrolledList:
diff --git a/Lib/idlelib/search.py b/Lib/idlelib/search.py
--- a/Lib/idlelib/search.py
+++ b/Lib/idlelib/search.py
@@ -24,6 +24,7 @@
"Handle the editor edit menu item and corresponding event."
return _setup(text).find_selection(text)
+
class SearchDialog(SearchDialogBase):
def create_widgets(self):
diff --git a/Lib/idlelib/searchbase.py b/Lib/idlelib/searchbase.py
--- a/Lib/idlelib/searchbase.py
+++ b/Lib/idlelib/searchbase.py
@@ -3,6 +3,7 @@
from tkinter import Toplevel, Frame
from tkinter.ttk import Entry, Label, Button, Checkbutton, Radiobutton
+
class SearchDialogBase:
'''Create most of a 3 or 4 row, 3 column search dialog.
diff --git a/Lib/idlelib/searchengine.py b/Lib/idlelib/searchengine.py
--- a/Lib/idlelib/searchengine.py
+++ b/Lib/idlelib/searchengine.py
@@ -1,5 +1,6 @@
'''Define SearchEngine for search dialogs.'''
import re
+
from tkinter import StringVar, BooleanVar, TclError
import tkinter.messagebox as tkMessageBox
@@ -14,6 +15,7 @@
# This creates a cycle that persists until root is deleted.
return root._searchengine
+
class SearchEngine:
"""Handles searching a text widget for Find, Replace, and Grep."""
@@ -186,6 +188,7 @@
col = len(chars) - 1
return None
+
def search_reverse(prog, chars, col):
'''Search backwards and return an re match object or None.
diff --git a/Lib/idlelib/stackviewer.py b/Lib/idlelib/stackviewer.py
--- a/Lib/idlelib/stackviewer.py
+++ b/Lib/idlelib/stackviewer.py
@@ -1,11 +1,12 @@
+import linecache
import os
+import re
import sys
-import linecache
-import re
+
import tkinter as tk
+from idlelib.debugobj import ObjectTreeItem, make_objecttreeitem
from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas
-from idlelib.debugobj import ObjectTreeItem, make_objecttreeitem
def StackBrowser(root, flist=None, tb=None, top=None):
if top is None:
@@ -16,6 +17,7 @@
node = TreeNode(sc.canvas, None, item)
node.expand()
+
class StackTreeItem(TreeItem):
def __init__(self, flist=None, tb=None):
@@ -54,6 +56,7 @@
sublist.append(item)
return sublist
+
class FrameTreeItem(TreeItem):
def __init__(self, info, flist):
@@ -95,6 +98,7 @@
if os.path.isfile(filename):
self.flist.gotofileline(filename, lineno)
+
class VariablesTreeItem(ObjectTreeItem):
def GetText(self):
@@ -119,6 +123,7 @@
sublist.append(item)
return sublist
+
def _stack_viewer(parent): # htest #
from idlelib.pyshell import PyShellFileList
top = tk.Toplevel(parent)
diff --git a/Lib/idlelib/statusbar.py b/Lib/idlelib/statusbar.py
--- a/Lib/idlelib/statusbar.py
+++ b/Lib/idlelib/statusbar.py
@@ -1,5 +1,6 @@
from tkinter import Frame, Label
+
class MultiStatusBar(Frame):
def __init__(self, master, **kw):
@@ -17,6 +18,7 @@
label.config(width=width)
label.config(text=text)
+
def _multistatus_bar(parent): # htest #
from tkinter import Toplevel, Frame, Text, Button
top = Toplevel(parent)
diff --git a/Lib/idlelib/tabbedpages.py b/Lib/idlelib/tabbedpages.py
--- a/Lib/idlelib/tabbedpages.py
+++ b/Lib/idlelib/tabbedpages.py
@@ -285,6 +285,7 @@
# placed hide it
self.tab_set.lower()
+
class TabbedPageSet(Frame):
"""A Tkinter tabbed-pane widget.
@@ -302,6 +303,7 @@
remove_page() methods.
"""
+
class Page(object):
"""Abstract base class for TabbedPageSet's pages.
@@ -467,6 +469,7 @@
self._tab_set.set_selected_tab(page_name)
+
def _tabbed_pages(parent): # htest #
top=Toplevel(parent)
x, y = map(int, parent.geometry().split('+')[1:])
diff --git a/Lib/idlelib/textview.py b/Lib/idlelib/textview.py
--- a/Lib/idlelib/textview.py
+++ b/Lib/idlelib/textview.py
@@ -1,11 +1,11 @@
"""Simple text browser for IDLE
"""
-
from tkinter import *
from tkinter.ttk import Scrollbar
from tkinter.messagebox import showerror
+
class TextViewer(Toplevel):
"""A simple text viewer dialog for IDLE
diff --git a/Lib/idlelib/tree.py b/Lib/idlelib/tree.py
--- a/Lib/idlelib/tree.py
+++ b/Lib/idlelib/tree.py
@@ -15,10 +15,12 @@
# - optimize tree redraw after expand of subnode
import os
+
from tkinter import *
from tkinter.ttk import Scrollbar
+
+from idlelib.config import idleConf
from idlelib import zoomheight
-from idlelib.config import idleConf
ICONDIR = "Icons"
diff --git a/Lib/idlelib/undo.py b/Lib/idlelib/undo.py
--- a/Lib/idlelib/undo.py
+++ b/Lib/idlelib/undo.py
@@ -1,5 +1,7 @@
import string
+
from idlelib.delegator import Delegator
+
# tkintter import not needed because module does not create widgets,
# although many methods operate on text widget arguments.
@@ -158,7 +160,6 @@
class Command:
-
# Base class for Undoable commands
tags = None
@@ -204,7 +205,6 @@
class InsertCommand(Command):
-
# Undoable insert command
def __init__(self, index1, chars, tags=None):
@@ -262,7 +262,6 @@
class DeleteCommand(Command):
-
# Undoable delete command
def __init__(self, index1, index2=None):
@@ -297,8 +296,8 @@
text.see('insert')
##sys.__stderr__.write("undo: %s\n" % self)
+
class CommandSequence(Command):
-
# Wrapper for a sequence of undoable cmds to be undone/redone
# as a unit
diff --git a/Lib/idlelib/windows.py b/Lib/idlelib/windows.py
--- a/Lib/idlelib/windows.py
+++ b/Lib/idlelib/windows.py
@@ -1,5 +1,6 @@
from tkinter import *
+
class WindowList:
def __init__(self):
@@ -48,6 +49,7 @@
t, v, tb = sys.exc_info()
print("warning: callback failed in WindowList", t, ":", v)
+
registry = WindowList()
add_windows_to_menu = registry.add_windows_to_menu
diff --git a/Lib/idlelib/zoomheight.py b/Lib/idlelib/zoomheight.py
--- a/Lib/idlelib/zoomheight.py
+++ b/Lib/idlelib/zoomheight.py
@@ -5,6 +5,7 @@
from idlelib import macosx
+
class ZoomHeight:
menudefs = [
@@ -20,6 +21,7 @@
top = self.editwin.top
zoom_height(top)
+
def zoom_height(top):
geom = top.wm_geometry()
m = re.match(r"(\d+)x(\d+)\+(-?\d+)\+(-?\d+)", geom)
--
Repository URL: https://hg.python.org/cpython
[View Less]
1
0

cpython (merge 3.5 -> default): Merge #27893: arg name and bytes references in email.parser docs.
by r.david.murray Aug. 31, 2016
by r.david.murray Aug. 31, 2016
Aug. 31, 2016
https://hg.python.org/cpython/rev/059f9f518834
changeset: 102964:059f9f518834
parent: 102962:c9d59e6cc1e4
parent: 102963:b8dd9ae08a91
user: R David Murray <rdmurray(a)bitdance.com>
date: Tue Aug 30 21:17:25 2016 -0400
summary:
Merge #27893: arg name and bytes references in email.parser docs.
files:
Doc/library/email.parser.rst | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Doc/library/email.parser.rst b/Doc/library/email.…
[View More]parser.rst
--- a/Doc/library/email.parser.rst
+++ b/Doc/library/email.parser.rst
@@ -202,12 +202,12 @@
reading the headers or not. The default is ``False``, meaning it parses
the entire contents of the file.
- .. method:: parsebytes(bytes, headersonly=False)
+ .. method:: parsebytes(text, headersonly=False)
- Similar to the :meth:`parse` method, except it takes a byte string object
- instead of a file-like object. Calling this method on a byte string is
- exactly equivalent to wrapping *text* in a :class:`~io.BytesIO` instance
- first and calling :meth:`parse`.
+ Similar to the :meth:`parse` method, except it takes a :term:`bytes-like
+ object` instead of a file-like object. Calling this method is equivalent
+ to wrapping *text* in a :class:`~io.BytesIO` instance first and calling
+ :meth:`parse`.
Optional *headersonly* is as with the :meth:`parse` method.
@@ -233,7 +233,7 @@
.. function:: message_from_bytes(s, _class=email.message.Message, *, \
policy=policy.compat32)
- Return a message object structure from a byte string. This is exactly
+ Return a message object structure from a :term:`bytes-like object`. This is exactly
equivalent to ``BytesParser().parsebytes(s)``. Optional *_class* and
*strict* are interpreted as with the :class:`~email.parser.Parser` class
constructor.
--
Repository URL: https://hg.python.org/cpython
[View Less]
1
0

cpython (3.5): #27893: arg name and bytes references in email.parser docs.
by r.david.murray Aug. 31, 2016
by r.david.murray Aug. 31, 2016
Aug. 31, 2016
https://hg.python.org/cpython/rev/b8dd9ae08a91
changeset: 102963:b8dd9ae08a91
branch: 3.5
parent: 102959:d048df7efe0b
user: R David Murray <rdmurray(a)bitdance.com>
date: Tue Aug 30 21:17:02 2016 -0400
summary:
#27893: arg name and bytes references in email.parser docs.
Perhaps the BytesParser 'text' argument should really be bytes, but
it hasn't been, it has been text, so for backward compatibility
and for consistency with the regular Parser class, I'm …
[View More]keeping it
as 'text'.
files:
Doc/library/email.parser.rst | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst
--- a/Doc/library/email.parser.rst
+++ b/Doc/library/email.parser.rst
@@ -202,12 +202,12 @@
reading the headers or not. The default is ``False``, meaning it parses
the entire contents of the file.
- .. method:: parsebytes(bytes, headersonly=False)
+ .. method:: parsebytes(text, headersonly=False)
- Similar to the :meth:`parse` method, except it takes a byte string object
- instead of a file-like object. Calling this method on a byte string is
- exactly equivalent to wrapping *text* in a :class:`~io.BytesIO` instance
- first and calling :meth:`parse`.
+ Similar to the :meth:`parse` method, except it takes a :term:`bytes-like
+ object` instead of a file-like object. Calling this method is equivalent
+ to wrapping *text* in a :class:`~io.BytesIO` instance first and calling
+ :meth:`parse`.
Optional *headersonly* is as with the :meth:`parse` method.
@@ -233,7 +233,7 @@
.. function:: message_from_bytes(s, _class=email.message.Message, *, \
policy=policy.compat32)
- Return a message object structure from a byte string. This is exactly
+ Return a message object structure from a :term:`bytes-like object`. This is exactly
equivalent to ``BytesParser().parsebytes(s)``. Optional *_class* and
*strict* are interpreted as with the :class:`~email.parser.Parser` class
constructor.
--
Repository URL: https://hg.python.org/cpython
[View Less]
1
0