Skip to content

Commit 1b06fc7

Browse files
hugovkc4urself
authored andcommitted
Drop support for EOL Python 2.7 (#108)
* Drop support for legacy Python 2.7 * Drop the dot https://twitter.com/pytestdotorg/status/753767547866972160 * Mock is part of stdlib in Python 3 * Upgrade Python syntax with pyupgrade --py3-plus * Drop support for legacy Python 2.7 * Remove redundant compat.py * Drop support for legacy Python 2.7 * pylint fixes * Drop support for legacy Python 2.7 * Add note for Python 2 users * Sort imports * Remove py3x-configparser
1 parent 7dda220 commit 1b06fc7

14 files changed

+61
-144
lines changed

.travis.yml

+1-11
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,11 @@
11
language: python
2-
dist: xenial
32

43
python:
5-
- "2.7"
64
- "3.5"
75
- "3.6"
86
- "3.7"
97
- "3.8"
10-
11-
# also test PyPy; do this on Trusty due to
12-
# https://travis-ci.community/t/pypy-2-7-on-xenial/889
13-
matrix:
14-
include:
15-
- python: "pypy"
16-
dist: trusty
17-
- python: "pypy3"
18-
dist: trusty
8+
- "pypy3"
199

2010
install:
2111
- git config --global user.email "[email protected]"

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ RUN cd /.pyenv \
99

1010
# only install certain versions for tox to use
1111
RUN pyenv versions
12-
RUN pyenv global system 2.7.15 3.5.7 3.6.9 3.7.5 3.8.0 pypy2.7-7.2.0 pypy3.6-7.2.0
12+
RUN pyenv global system 3.5.7 3.6.9 3.7.5 3.8.0 pypy3.6-7.2.0
1313

1414
RUN git config --global user.email "[email protected]"
1515
RUN git config --global user.name "Bumpversion Test"

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ test:
33
docker-compose run test
44

55
local_test:
6-
PYTHONPATH=. py.test tests/
6+
PYTHONPATH=. pytest tests/
77

88
lint:
99
pip install pylint

README.md

+12-7
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ commits and tags:
2727
* works without any VCS, but happily reads tag information from and writes
2828
commits and tags to Git and Mercurial if available
2929
* just handles text files, so it's not specific to any programming language
30-
* supports Python2, Python3 and Pypy
30+
* supports Python 3 and PyPy3
31+
32+
If you want to use Python 2, use `pip>=9` and you'll get the last supported version,
33+
or pin `bump2version<1`.
34+
35+
3136

3237
<!---
3338
## Screencast
@@ -150,7 +155,7 @@ General configuration is grouped in a `[bumpversion]` section.
150155

151156
The name of the tag that will be created. Only valid when using `--tag` / `tag = True`.
152157

153-
This is templated using the [Python Format String Syntax](http://docs.python.org/2/library/string.html#format-string-syntax).
158+
This is templated using the [Python Format String Syntax](https://docs.python.org/3/library/string.html#format-string-syntax).
154159
Available in the template context are `current_version` and `new_version`
155160
as well as `current_[part]` and `new_[part]` (e.g. '`current_major`'
156161
or '`new_patch`').
@@ -184,7 +189,7 @@ General configuration is grouped in a `[bumpversion]` section.
184189

185190
The commit message to use when creating a commit. Only valid when using `--commit` / `commit = True`.
186191

187-
This is templated using the [Python Format String Syntax](http://docs.python.org/2/library/string.html#format-string-syntax).
192+
This is templated using the [Python Format String Syntax](https://docs.python.org/3/library/string.html#format-string-syntax).
188193
Available in the template context are `current_version` and `new_version`
189194
as well as `current_[part]` and `new_[part]` (e.g. '`current_major`'
190195
or '`new_patch`').
@@ -288,7 +293,7 @@ This configuration is in the section: `[bumpversion:file:…]`
288293
#### `parse =`
289294
**default:** `(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)`
290295

291-
Regular expression (using [Python regular expression syntax](http://docs.python.org/2/library/re.html#regular-expression-syntax)) on
296+
Regular expression (using [Python regular expression syntax](https://docs.python.org/3/library/re.html#regular-expression-syntax)) on
292297
how to find and parse the version string.
293298

294299
Is required to parse all strings produced by `serialize =`. Named matching
@@ -302,7 +307,7 @@ This configuration is in the section: `[bumpversion:file:…]`
302307
Template specifying how to serialize the version parts back to a version
303308
string.
304309

305-
This is templated using the [Python Format String Syntax](http://docs.python.org/2/library/string.html#format-string-syntax).
310+
This is templated using the [Python Format String Syntax](https://docs.python.org/3/library/string.html#format-string-syntax).
306311
Available in the template context are parsed values of the named groups
307312
specified in `parse =` as well as all environment variables (prefixed with
308313
`$`).
@@ -329,7 +334,7 @@ serialize =
329334
Template string how to search for the string to be replaced in the file.
330335
Useful if the remotest possibility exists that the current version number
331336
might be present multiple times in the file and you mean to only bump one of the
332-
occurences. Can be multiple lines, templated using [Python Format String Syntax](http://docs.python.org/2/library/string.html#format-string-syntax)
337+
occurrences. Can be multiple lines, templated using [Python Format String Syntax](https://docs.python.org/3/library/string.html#format-string-syntax)
333338

334339
#### `replace =`
335340
**default:** `{new_version}`
@@ -354,7 +359,7 @@ search = MyProject=={current_version}
354359
replace = MyProject=={new_version}
355360
```
356361

357-
Can be multiple lines, templated using [Python Format String Syntax](http://docs.python.org/2/library/string.html#format-string-syntax).
362+
Can be multiple lines, templated using [Python Format String Syntax](https://docs.python.org/3/library/string.html#format-string-syntax).
358363

359364
## Command-line Options
360365

appveyor.yml

-6
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,6 @@ build: off
55

66
environment:
77
matrix:
8-
- PYTHON: "C:/Python27"
9-
TOXENV: "py27"
10-
11-
- PYTHON: "C:/Python27"
12-
TOXENV: "py27-configparser"
13-
148
- PYTHON: "C:/Python35"
159
TOXENV: "py35"
1610

bumpversion/cli.py

+16-25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# -*- coding: utf-8 -*-
2-
from __future__ import unicode_literals
3-
41
import argparse
52
from datetime import datetime
63
import io
@@ -11,19 +8,18 @@
118
import sre_constants
129
import sys
1310
import warnings
11+
from configparser import (
12+
ConfigParser,
13+
RawConfigParser,
14+
NoOptionError,
15+
)
1416

1517
from bumpversion import __version__, __title__
1618
from bumpversion.version_part import (
1719
VersionConfig,
1820
NumericVersionPartConfiguration,
1921
ConfiguredVersionPartConfiguration,
2022
)
21-
from bumpversion.compat import (
22-
ConfigParser,
23-
StringIO,
24-
RawConfigParser,
25-
NoOptionError,
26-
)
2723
from bumpversion.exceptions import (
2824
IncompleteVersionRepresentationException,
2925
MissingValueForSerializationException,
@@ -115,7 +111,8 @@ def main(original_args=None):
115111

116112
# commit and tag
117113
if vcs:
118-
context = _commit_to_vcs(files, context, config_file, config_file_exists, vcs, args, current_version, new_version)
114+
context = _commit_to_vcs(files, context, config_file, config_file_exists, vcs,
115+
args, current_version, new_version)
119116
_tag_in_vcs(vcs, context, args)
120117

121118

@@ -245,21 +242,14 @@ def _load_configuration(config_file, explicit_config, defaults):
245242

246243
logger.info("Reading config file %s:", config_file)
247244

248-
with io.open(config_file, "rt", encoding="utf-8") as config_fp:
245+
with open(config_file, "rt", encoding="utf-8") as config_fp:
249246
config_content = config_fp.read()
250247
config_newlines = config_fp.newlines
251248

252249
# TODO: this is a DEBUG level log
253250
logger.info(config_content)
254-
255-
try:
256-
config.read_string(config_content)
257-
except AttributeError:
258-
# python 2 standard ConfigParser doesn't have read_string,
259-
# only deprecated readfp
260-
config.readfp(io.open(config_file, "rt", encoding="utf-8"))
261-
262-
log_config = StringIO()
251+
config.read_string(config_content)
252+
log_config = io.StringIO()
263253
config.write(log_config)
264254

265255
if config.has_option("bumpversion", "files"):
@@ -339,7 +329,7 @@ def _load_configuration(config_file, explicit_config, defaults):
339329

340330
if "serialize" not in section_config:
341331
section_config["serialize"] = defaults.get(
342-
"serialize", [str("{major}.{minor}.{patch}")]
332+
"serialize", ["{major}.{minor}.{patch}"]
343333
)
344334

345335
if "search" not in section_config:
@@ -379,7 +369,7 @@ def _parse_arguments_phase_2(args, known_args, defaults, root_parser):
379369
metavar="FORMAT",
380370
action=DiscardDefaultIfSpecifiedAppendAction,
381371
help="How to format what is parsed back to a version",
382-
default=defaults.get("serialize", [str("{major}.{minor}.{patch}")]),
372+
default=defaults.get("serialize", ["{major}.{minor}.{patch}"]),
383373
)
384374
parser2.add_argument(
385375
"--search",
@@ -610,7 +600,7 @@ def _update_config_file(
610600
config, config_file, config_newlines, config_file_exists, new_version, dry_run,
611601
):
612602
config.set("bumpversion", "current_version", new_version)
613-
new_config = StringIO()
603+
new_config = io.StringIO()
614604
try:
615605
write_to_config_file = (not dry_run) and config_file_exists
616606

@@ -624,7 +614,7 @@ def _update_config_file(
624614
logger.info(new_config.getvalue())
625615

626616
if write_to_config_file:
627-
with io.open(config_file, "wt", encoding="utf-8", newline=config_newlines) as f:
617+
with open(config_file, "wt", encoding="utf-8", newline=config_newlines) as f:
628618
f.write(new_config.getvalue())
629619

630620
except UnicodeEncodeError:
@@ -634,7 +624,8 @@ def _update_config_file(
634624
)
635625

636626

637-
def _commit_to_vcs(files, context, config_file, config_file_exists, vcs, args, current_version, new_version):
627+
def _commit_to_vcs(files, context, config_file, config_file_exists, vcs, args,
628+
current_version, new_version):
638629
commit_files = [f.path for f in files]
639630
if config_file_exists:
640631
commit_files.append(config_file)

bumpversion/compat.py

-34
This file was deleted.

bumpversion/functions.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import re
22

33

4-
class NumericFunction(object):
4+
class NumericFunction:
55

66
"""
77
This is a class that provides a numeric function for version parts.
@@ -43,7 +43,7 @@ def bump(self, value):
4343
return "".join([part_prefix, str(bumped_numeric), part_suffix])
4444

4545

46-
class ValuesFunction(object):
46+
class ValuesFunction:
4747

4848
"""
4949
This is a class that provides a values list based function for version parts.
@@ -69,7 +69,7 @@ def __init__(self, values, optional_value=None, first_value=None):
6969

7070
if optional_value not in values:
7171
raise ValueError(
72-
"Optional value {0} must be included in values {1}".format(
72+
"Optional value {} must be included in values {}".format(
7373
optional_value, values
7474
)
7575
)
@@ -81,7 +81,7 @@ def __init__(self, values, optional_value=None, first_value=None):
8181

8282
if first_value not in values:
8383
raise ValueError(
84-
"First value {0} must be included in values {1}".format(
84+
"First value {} must be included in values {}".format(
8585
first_value, values
8686
)
8787
)

bumpversion/utils.py

+5-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# -*- coding: utf-8 -*-
2-
3-
from __future__ import unicode_literals, print_function
4-
51
from argparse import _AppendAction
62
from difflib import unified_diff
73
import io
@@ -23,7 +19,7 @@ def __call__(self, parser, namespace, values, option_string=None):
2319
setattr(namespace, self.dest, [])
2420
self._discarded_default = True # pylint: disable=attribute-defined-outside-init
2521

26-
super(DiscardDefaultIfSpecifiedAppendAction, self).__call__(
22+
super().__call__(
2723
parser, namespace, values, option_string=None
2824
)
2925

@@ -36,7 +32,7 @@ def prefixed_environ():
3632
return {"${}".format(key): value for key, value in os.environ.items()}
3733

3834

39-
class ConfiguredFile(object):
35+
class ConfiguredFile:
4036
def __init__(self, path, versionconfig):
4137
self.path = path
4238
self._versionconfig = versionconfig
@@ -61,7 +57,7 @@ def should_contain_version(self, version, context):
6157
assert False, msg
6258

6359
def contains(self, search):
64-
with io.open(self.path, "rt", encoding="utf-8") as f:
60+
with open(self.path, "rt", encoding="utf-8") as f:
6561
search_lines = search.splitlines()
6662
lookbehind = []
6763

@@ -88,7 +84,7 @@ def contains(self, search):
8884

8985
def replace(self, current_version, new_version, context, dry_run):
9086

91-
with io.open(self.path, "rt", encoding="utf-8") as f:
87+
with open(self.path, "rt", encoding="utf-8") as f:
9288
file_content_before = f.read()
9389
file_new_lines = f.newlines
9490

@@ -127,7 +123,7 @@ def replace(self, current_version, new_version, context, dry_run):
127123
logger.info("%s file %s", "Would not change" if dry_run else "Not changing", self.path)
128124

129125
if not dry_run:
130-
with io.open(self.path, "wt", encoding="utf-8", newline=file_new_lines) as f:
126+
with open(self.path, "wt", encoding="utf-8", newline=file_new_lines) as f:
131127
f.write(file_content_after)
132128

133129
def __str__(self):

0 commit comments

Comments
 (0)