Merge ~cjwatson/lazr.config:drop-py2 into lazr.config:main

Proposed by Colin Watson
Status: Merged
Merged at revision: e5cd66ae708ad90f3fc51ca405bd6aae52366758
Proposed branch: ~cjwatson/lazr.config:drop-py2
Merge into: lazr.config:main
Diff against target: 308 lines (+27/-50)
11 files modified
.pre-commit-config.yaml (+4/-0)
NEWS.rst (+3/-3)
pyproject.toml (+1/-0)
setup.py (+1/-1)
src/lazr/config/_config.py (+15/-25)
src/lazr/config/_version.py (+1/-1)
src/lazr/config/docs/conf.py (+0/-2)
src/lazr/config/interfaces.py (+1/-4)
src/lazr/config/tests/test_config.py (+0/-3)
src/lazr/config/tests/test_docs.py (+1/-10)
tox.ini (+0/-1)
Reviewer Review Type Date Requested Status
Guruprasad Approve
Review via email: mp+437444@code.launchpad.net

Commit message

Drop Python 2 support

To post a comment you must log in.
Revision history for this message
Guruprasad (lgp171188) wrote :

LGTM 👍

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 6382dc7..4753587 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -18,6 +18,10 @@ repos:
18 - id: black18 - id: black
19 # skip namespace package declaration19 # skip namespace package declaration
20 exclude: ^src/lazr/__init__\.py$20 exclude: ^src/lazr/__init__\.py$
21- repo: https://github.com/asottile/pyupgrade
22 rev: v3.3.1
23 hooks:
24 - id: pyupgrade
21- repo: https://github.com/PyCQA/isort25- repo: https://github.com/PyCQA/isort
22 rev: 5.12.026 rev: 5.12.0
23 hooks:27 hooks:
diff --git a/NEWS.rst b/NEWS.rst
index d298c85..ea61f16 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -2,14 +2,14 @@
2NEWS for lazr.config2NEWS for lazr.config
3====================3====================
44
52.2.453.0
6=====6===
7- Add basic pre-commit configuration.7- Add basic pre-commit configuration.
8- Publish Documentation on Read the Docs.8- Publish Documentation on Read the Docs.
9- Apply inclusive naming via the woke pre-commit hook.9- Apply inclusive naming via the woke pre-commit hook.
10- Test using ``zope.testrunner`` rather than ``nose``.10- Test using ``zope.testrunner`` rather than ``nose``.
11- Officially add support for Python 3.9 and 3.10.11- Officially add support for Python 3.9 and 3.10.
12- Drop support for Python 2.6 and 3.4.12- Drop support for Python 2.6, 2.7, and 3.4.
13- Apply ``black`` and ``isort``.13- Apply ``black`` and ``isort``.
1414
152.2.3 (2021-01-26)152.2.3 (2021-01-26)
diff --git a/pyproject.toml b/pyproject.toml
index a8f43fe..1eb96ee 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,2 +1,3 @@
1[tool.black]1[tool.black]
2line-length = 792line-length = 79
3target-version = ["py35"]
diff --git a/setup.py b/setup.py
index 5448a20..f5a5da9 100755
--- a/setup.py
+++ b/setup.py
@@ -61,7 +61,6 @@ files. The format supports schema validation.
61 "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", # noqa61 "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", # noqa
62 "Operating System :: OS Independent",62 "Operating System :: OS Independent",
63 "Programming Language :: Python",63 "Programming Language :: Python",
64 "Programming Language :: Python :: 2.7",
65 "Programming Language :: Python :: 3",64 "Programming Language :: Python :: 3",
66 "Programming Language :: Python :: 3.5",65 "Programming Language :: Python :: 3.5",
67 "Programming Language :: Python :: 3.6",66 "Programming Language :: Python :: 3.6",
@@ -73,4 +72,5 @@ files. The format supports schema validation.
73 extras_require=dict(72 extras_require=dict(
74 docs=["Sphinx"],73 docs=["Sphinx"],
75 ),74 ),
75 python_requires=">=3.5",
76)76)
diff --git a/src/lazr/config/_config.py b/src/lazr/config/_config.py
index 0f12bf7..b8a56a7 100644
--- a/src/lazr/config/_config.py
+++ b/src/lazr/config/_config.py
@@ -16,9 +16,6 @@
1616
17"""Implementation classes for config."""17"""Implementation classes for config."""
1818
19from __future__ import absolute_import, print_function, unicode_literals
20
21__metaclass__ = type
22__all__ = [19__all__ = [
23 "Config",20 "Config",
24 "ConfigData",21 "ConfigData",
@@ -41,7 +38,6 @@ import logging
41import os38import os
42import pwd39import pwd
43import re40import re
44import sys
45from os.path import abspath, basename, dirname41from os.path import abspath, basename, dirname
46from textwrap import dedent42from textwrap import dedent
4743
@@ -86,7 +82,7 @@ _missing = object()
8682
87def read_content(filename):83def read_content(filename):
88 """Return the content of a file at filename as a string."""84 """Return the content of a file at filename as a string."""
89 with open(filename, "rt") as fp:85 with open(filename) as fp:
90 return fp.read()86 return fp.read()
9187
9288
@@ -111,8 +107,7 @@ class SectionSchema:
111107
112 def __iter__(self):108 def __iter__(self):
113 """See `ISectionSchema`"""109 """See `ISectionSchema`"""
114 for key in self._options.keys():110 yield from self._options.keys()
115 yield key
116111
117 def __contains__(self, name):112 def __contains__(self, name):
118 """See `ISectionSchema`"""113 """See `ISectionSchema`"""
@@ -150,7 +145,7 @@ class Section:
150 # Use __dict__ because __getattr__ limits access to self.options.145 # Use __dict__ because __getattr__ limits access to self.options.
151 self.__dict__["schema"] = schema146 self.__dict__["schema"] = schema
152 if _options is None:147 if _options is None:
153 _options = dict((key, schema[key]) for key in schema)148 _options = {key: schema[key] for key in schema}
154 self.__dict__["_options"] = _options149 self.__dict__["_options"] = _options
155150
156 def __getitem__(self, key):151 def __getitem__(self, key):
@@ -184,7 +179,7 @@ class Section:
184 if key in self._options:179 if key in self._options:
185 self._options[key] = value180 self._options[key] = value
186 else:181 else:
187 msg = "%s does not have a %s key." % (self.name, key)182 msg = "{} does not have a {} key.".format(self.name, key)
188 errors.append(UnknownKeyError(msg))183 errors.append(UnknownKeyError(msg))
189 return errors184 return errors
190185
@@ -240,12 +235,12 @@ class ImplicitTypeSection(Section):
240235
241 def __getitem__(self, key):236 def __getitem__(self, key):
242 """See `ISection`."""237 """See `ISection`."""
243 value = super(ImplicitTypeSection, self).__getitem__(key)238 value = super().__getitem__(key)
244 return self._convert(value)239 return self._convert(value)
245240
246 def __getattr__(self, name):241 def __getattr__(self, name):
247 """See `ISection`."""242 """See `ISection`."""
248 value = super(ImplicitTypeSection, self).__getattr__(name)243 value = super().__getattr__(name)
249 return self._convert(value)244 return self._convert(value)
250245
251246
@@ -396,8 +391,7 @@ class ConfigSchema:
396391
397 def __iter__(self):392 def __iter__(self):
398 """See `IConfigSchema`."""393 """See `IConfigSchema`."""
399 for value in self._section_schemas.values():394 yield from self._section_schemas.values()
400 yield value
401395
402 def __contains__(self, name):396 def __contains__(self, name):
403 """See `IConfigSchema`."""397 """See `IConfigSchema`."""
@@ -500,8 +494,7 @@ class ConfigData:
500494
501 def __iter__(self):495 def __iter__(self):
502 """See `IConfigData`."""496 """See `IConfigData`."""
503 for value in self._sections.values():497 yield from self._sections.values()
504 yield value
505498
506 def __contains__(self, name):499 def __contains__(self, name):
507 """See `IConfigData`."""500 """See `IConfigData`."""
@@ -618,16 +611,13 @@ class Config:
618 # option and in Python 3.2, this argument changed its default from611 # option and in Python 3.2, this argument changed its default from
619 # False to True. This breaks behavior compatibility with Python 2, so612 # False to True. This breaks behavior compatibility with Python 2, so
620 # under Python 3, always force strict=False.613 # under Python 3, always force strict=False.
621 kws = {}614 parser = RawConfigParser(strict=False)
622 if sys.version_info >= (3,):
623 kws["strict"] = False
624 parser = RawConfigParser(**kws)
625 _parser_read_file(parser, StringIO(conf_data), conf_filename)615 _parser_read_file(parser, StringIO(conf_data), conf_filename)
626 confs.append((conf_filename, parser, encoding_errors))616 confs.append((conf_filename, parser, encoding_errors))
627 if parser.has_option("meta", "extends"):617 if parser.has_option("meta", "extends"):
628 base_path = dirname(conf_filename)618 base_path = dirname(conf_filename)
629 extends_name = parser.get("meta", "extends")619 extends_name = parser.get("meta", "extends")
630 extends_filename = abspath("%s/%s" % (base_path, extends_name))620 extends_filename = abspath("{}/{}".format(base_path, extends_name))
631 extends_data = read_content(extends_filename)621 extends_data = read_content(extends_filename)
632 self._getExtendedConfs(extends_filename, extends_data, confs)622 self._getExtendedConfs(extends_filename, extends_data, confs)
633 return confs623 return confs
@@ -676,7 +666,7 @@ class Config:
676 and master_name not in self.schema666 and master_name not in self.schema
677 ):667 ):
678 # Any section not in the the schema is an error.668 # Any section not in the the schema is an error.
679 msg = "%s does not have a %s section." % (669 msg = "{} does not have a {} section.".format(
680 self.schema.name,670 self.schema.name,
681 section_name,671 section_name,
682 )672 )
@@ -784,7 +774,7 @@ class Category:
784774
785 def __getattr__(self, name):775 def __getattr__(self, name):
786 """See `ICategory`."""776 """See `ICategory`."""
787 full_name = "%s.%s" % (self.name, name)777 full_name = "{}.{}".format(self.name, name)
788 if full_name in self._sections:778 if full_name in self._sections:
789 return self._sections[full_name]779 return self._sections[full_name]
790 raise AttributeError("No section named %s." % name)780 raise AttributeError("No section named %s." % name)
@@ -872,10 +862,10 @@ def as_timedelta(value):
872 # Complain if the components are out of order.862 # Complain if the components are out of order.
873 if "".join(components) != value:863 if "".join(components) != value:
874 raise ValueError864 raise ValueError
875 keywords = dict(865 keywords = {
876 (interval[0].lower(), interval)866 interval[0].lower(): interval
877 for interval in ("weeks", "days", "hours", "minutes", "seconds")867 for interval in ("weeks", "days", "hours", "minutes", "seconds")
878 )868 }
879 keyword_arguments = {}869 keyword_arguments = {}
880 for interval in components:870 for interval in components:
881 if len(interval) == 0:871 if len(interval) == 0:
diff --git a/src/lazr/config/_version.py b/src/lazr/config/_version.py
index f394e69..ecd0eec 100644
--- a/src/lazr/config/_version.py
+++ b/src/lazr/config/_version.py
@@ -1 +1 @@
1__version__ = "2.2.3"1__version__ = "3.0.dev0"
diff --git a/src/lazr/config/docs/conf.py b/src/lazr/config/docs/conf.py
index f9eabe9..160b12a 100644
--- a/src/lazr/config/docs/conf.py
+++ b/src/lazr/config/docs/conf.py
@@ -1,5 +1,3 @@
1# -*- coding: utf-8 -*-
2#
3# lazr.config documentation build configuration file, created by1# lazr.config documentation build configuration file, created by
4# sphinx-quickstart on Mon Jan 7 10:37:37 2013.2# sphinx-quickstart on Mon Jan 7 10:37:37 2013.
5#3#
diff --git a/src/lazr/config/interfaces.py b/src/lazr/config/interfaces.py
index 3c6527e..273c7c3 100644
--- a/src/lazr/config/interfaces.py
+++ b/src/lazr/config/interfaces.py
@@ -17,9 +17,6 @@
17# pylint: disable-msg=E0211,E0213,W023117# pylint: disable-msg=E0211,E0213,W0231
18"""Interfaces for process configuration.."""18"""Interfaces for process configuration.."""
1919
20from __future__ import absolute_import, print_function, unicode_literals
21
22__metaclass__ = type
23__all__ = [20__all__ = [
24 "ConfigErrors",21 "ConfigErrors",
25 "ConfigSchemaError",22 "ConfigSchemaError",
@@ -90,7 +87,7 @@ class ConfigErrors(ConfigSchemaError):
90 self.errors = errors87 self.errors = errors
9188
92 def __str__(self):89 def __str__(self):
93 return "%s: %s" % (self.__class__.__name__, self.message)90 return "{}: {}".format(self.__class__.__name__, self.message)
9491
9592
96class ISectionSchema(Interface):93class ISectionSchema(Interface):
diff --git a/src/lazr/config/tests/test_config.py b/src/lazr/config/tests/test_config.py
index 723e3e2..8817325 100644
--- a/src/lazr/config/tests/test_config.py
+++ b/src/lazr/config/tests/test_config.py
@@ -16,9 +16,6 @@
1616
17"""Tests of lazr.config."""17"""Tests of lazr.config."""
1818
19from __future__ import absolute_import, print_function, unicode_literals
20
21__metaclass__ = type
22__all__ = [19__all__ = [
23 "TestConfig",20 "TestConfig",
24]21]
diff --git a/src/lazr/config/tests/test_docs.py b/src/lazr/config/tests/test_docs.py
index 4c17208..698a94d 100644
--- a/src/lazr/config/tests/test_docs.py
+++ b/src/lazr/config/tests/test_docs.py
@@ -16,9 +16,6 @@
1616
17"""Test harness for doctests."""17"""Test harness for doctests."""
1818
19from __future__ import absolute_import, print_function, unicode_literals
20
21__metaclass__ = type
22__all__ = []19__all__ = []
2320
24import atexit21import atexit
@@ -49,18 +46,12 @@ def load_tests(loader, tests, pattern):
49 )46 )
50 )47 )
51 atexit.register(cleanup_resources)48 atexit.register(cleanup_resources)
52 globs = {
53 "absolute_import": absolute_import,
54 "print_function": print_function,
55 "unicode_literals": unicode_literals,
56 }
57 tests.addTest(49 tests.addTest(
58 doctest.DocFileSuite(50 doctest.DocFileSuite(
59 *doctest_files,51 *doctest_files,
60 module_relative=False,52 module_relative=False,
61 optionflags=DOCTEST_FLAGS,53 optionflags=DOCTEST_FLAGS,
62 globs=globs,54 encoding="UTF-8",
63 encoding="UTF-8"
64 )55 )
65 )56 )
66 return tests57 return tests
diff --git a/tox.ini b/tox.ini
index 186f2bd..4615990 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,6 @@
1[tox]1[tox]
2envlist =2envlist =
3 pre-commit3 pre-commit
4 py27
5 py354 py35
6 py365 py36
7 py376 py37

Subscribers

People subscribed via source and target branches