Skip to content

Commit 97fbf48

Browse files
committedJan 4, 2022
add testing on Python 3.11
Also update versioneer to 0.21 (with modifications to make it work with 2.6)
1 parent 8eb0731 commit 97fbf48

File tree

5 files changed

+709
-261
lines changed

5 files changed

+709
-261
lines changed
 

‎.github/workflows/ci.yml

+4
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ jobs:
8282
os: ubuntu-latest
8383
python-version: '3.10'
8484
tox-env: gmpy2py310
85+
- name: py3.11
86+
os: ubuntu-latest
87+
python-version: '3.11.0-alpha.3'
88+
tox-env: py311
8589
- name: pypy
8690
os: ubuntu-latest
8791
python-version: pypy-2.7

‎src/ecdsa/__init__.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,9 @@
3737
InvalidSharedSecretError,
3838
)
3939
from .der import UnexpectedDER
40+
from . import _version
4041

4142
# This code comes from http://github.com/tlsfuzzer/python-ecdsa
42-
from ._version import get_versions
43-
44-
__version__ = get_versions()["version"]
45-
del get_versions
46-
4743
__all__ = [
4844
"curves",
4945
"der",
@@ -90,3 +86,5 @@
9086
six.b(""),
9187
]
9288
del _hush_pyflakes
89+
90+
__version__ = _version.get_versions()["version"]

‎src/ecdsa/_version.py

+182-53
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# that just contains the computed version number.
66

77
# This file is released into the public domain. Generated by
8-
# versioneer-0.17 (https://github.com/warner/python-versioneer)
8+
# versioneer-0.21 (https://github.com/python-versioneer/python-versioneer)
99

1010
"""Git implementation of _version.py."""
1111

@@ -56,7 +56,7 @@ class NotThisMethod(Exception):
5656

5757

5858
def register_vcs_handler(vcs, method): # decorator
59-
"""Decorator to mark a method as the handler for a particular VCS."""
59+
"""Create decorator to mark a method as the handler of a VCS."""
6060

6161
def decorate(f):
6262
"""Store f in HANDLERS[vcs][method]."""
@@ -73,20 +73,20 @@ def run_command(
7373
):
7474
"""Call the given command(s)."""
7575
assert isinstance(commands, list)
76-
p = None
77-
for c in commands:
76+
process = None
77+
for command in commands:
7878
try:
79-
dispcmd = str([c] + args)
79+
dispcmd = str([command] + args)
8080
# remember shell=False, so use git.cmd on windows, not just git
81-
p = subprocess.Popen(
82-
[c] + args,
81+
process = subprocess.Popen(
82+
[command] + args,
8383
cwd=cwd,
8484
env=env,
8585
stdout=subprocess.PIPE,
8686
stderr=(subprocess.PIPE if hide_stderr else None),
8787
)
8888
break
89-
except EnvironmentError:
89+
except OSError:
9090
e = sys.exc_info()[1]
9191
if e.errno == errno.ENOENT:
9292
continue
@@ -98,15 +98,15 @@ def run_command(
9898
if verbose:
9999
print("unable to find command, tried %s" % (commands,))
100100
return None, None
101-
stdout = p.communicate()[0].strip()
101+
stdout = process.communicate()[0].strip()
102102
if sys.version_info[0] >= 3:
103103
stdout = stdout.decode()
104-
if p.returncode != 0:
104+
if process.returncode != 0:
105105
if verbose:
106106
print("unable to run %s (error)" % dispcmd)
107107
print("stdout was %s" % stdout)
108-
return None, p.returncode
109-
return stdout, p.returncode
108+
return None, process.returncode
109+
return stdout, process.returncode
110110

111111

112112
def versions_from_parentdir(parentdir_prefix, root, verbose):
@@ -118,7 +118,7 @@ def versions_from_parentdir(parentdir_prefix, root, verbose):
118118
"""
119119
rootdirs = []
120120

121-
for i in range(3):
121+
for _ in range(3):
122122
dirname = os.path.basename(root)
123123
if dirname.startswith(parentdir_prefix):
124124
return {
@@ -128,9 +128,8 @@ def versions_from_parentdir(parentdir_prefix, root, verbose):
128128
"error": None,
129129
"date": None,
130130
}
131-
else:
132-
rootdirs.append(root)
133-
root = os.path.dirname(root) # up a level
131+
rootdirs.append(root)
132+
root = os.path.dirname(root) # up a level
134133

135134
if verbose:
136135
print(
@@ -149,33 +148,36 @@ def git_get_keywords(versionfile_abs):
149148
# _version.py.
150149
keywords = {}
151150
try:
152-
f = open(versionfile_abs, "r")
153-
for line in f.readlines():
154-
if line.strip().startswith("git_refnames ="):
155-
mo = re.search(r'=\s*"(.*)"', line)
156-
if mo:
157-
keywords["refnames"] = mo.group(1)
158-
if line.strip().startswith("git_full ="):
159-
mo = re.search(r'=\s*"(.*)"', line)
160-
if mo:
161-
keywords["full"] = mo.group(1)
162-
if line.strip().startswith("git_date ="):
163-
mo = re.search(r'=\s*"(.*)"', line)
164-
if mo:
165-
keywords["date"] = mo.group(1)
166-
f.close()
167-
except EnvironmentError:
151+
with open(versionfile_abs, "r") as fobj:
152+
for line in fobj:
153+
if line.strip().startswith("git_refnames ="):
154+
mo = re.search(r'=\s*"(.*)"', line)
155+
if mo:
156+
keywords["refnames"] = mo.group(1)
157+
if line.strip().startswith("git_full ="):
158+
mo = re.search(r'=\s*"(.*)"', line)
159+
if mo:
160+
keywords["full"] = mo.group(1)
161+
if line.strip().startswith("git_date ="):
162+
mo = re.search(r'=\s*"(.*)"', line)
163+
if mo:
164+
keywords["date"] = mo.group(1)
165+
except OSError:
168166
pass
169167
return keywords
170168

171169

172170
@register_vcs_handler("git", "keywords")
173171
def git_versions_from_keywords(keywords, tag_prefix, verbose):
174172
"""Get version information from git keywords."""
175-
if not keywords:
176-
raise NotThisMethod("no keywords at all, weird")
173+
if "refnames" not in keywords:
174+
raise NotThisMethod("Short version file found")
177175
date = keywords.get("date")
178176
if date is not None:
177+
# Use only the last line. Previous lines may contain GPG signature
178+
# information.
179+
date = date.splitlines()[-1]
180+
179181
# git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant
180182
# datestamp. However we prefer "%ci" (which expands to an "ISO-8601
181183
# -like" string, which we must then edit to make compliant), because
@@ -188,11 +190,11 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose):
188190
if verbose:
189191
print("keywords are unexpanded, not using")
190192
raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
191-
refs = set([r.strip() for r in refnames.strip("()").split(",")])
193+
refs = set(r.strip() for r in refnames.strip("()").split(","))
192194
# starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
193195
# just "foo-1.0". If we see a "tag: " prefix, prefer those.
194196
TAG = "tag: "
195-
tags = set([r[len(TAG) :] for r in refs if r.startswith(TAG)])
197+
tags = set(r[len(TAG) :] for r in refs if r.startswith(TAG))
196198
if not tags:
197199
# Either we're using git < 1.8.3, or there really are no tags. We use
198200
# a heuristic: assume all version tags have a digit. The old git %d
@@ -201,7 +203,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose):
201203
# between branches and tags. By ignoring refnames without digits, we
202204
# filter out many common branch names like "release" and
203205
# "stabilization", as well as "HEAD" and "master".
204-
tags = set([r for r in refs if re.search(r"\d", r)])
206+
tags = set(r for r in refs if re.search(r"\d", r))
205207
if verbose:
206208
print("discarding '%s', no digits" % ",".join(refs - tags))
207209
if verbose:
@@ -210,6 +212,11 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose):
210212
# sorting will prefer e.g. "2.0" over "2.0rc1"
211213
if ref.startswith(tag_prefix):
212214
r = ref[len(tag_prefix) :]
215+
# Filter out refs that exactly match prefix or that don't start
216+
# with a number once the prefix is stripped (mostly a concern
217+
# when prefix is '')
218+
if not re.match(r"\d", r):
219+
continue
213220
if verbose:
214221
print("picking %s" % r)
215222
return {
@@ -232,18 +239,20 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose):
232239

233240

234241
@register_vcs_handler("git", "pieces_from_vcs")
235-
def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
242+
def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
236243
"""Get version from 'git describe' in the root of the source tree.
237244
238245
This only gets called if the git-archive 'subst' keywords were *not*
239246
expanded, and _version.py hasn't already been rewritten with a short
240247
version string, meaning we're inside a checked out source tree.
241248
"""
242249
GITS = ["git"]
250+
TAG_PREFIX_REGEX = "*"
243251
if sys.platform == "win32":
244252
GITS = ["git.cmd", "git.exe"]
253+
TAG_PREFIX_REGEX = r"\*"
245254

246-
out, rc = run_command(
255+
_, rc = runner(
247256
GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True
248257
)
249258
if rc != 0:
@@ -253,7 +262,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
253262

254263
# if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
255264
# if there isn't one, this yields HEX[-dirty] (no NUM)
256-
describe_out, rc = run_command(
265+
describe_out, rc = runner(
257266
GITS,
258267
[
259268
"describe",
@@ -262,15 +271,15 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
262271
"--always",
263272
"--long",
264273
"--match",
265-
"%s*" % tag_prefix,
274+
"%s%s" % (tag_prefix, TAG_PREFIX_REGEX),
266275
],
267276
cwd=root,
268277
)
269278
# --long was added in git-1.5.5
270279
if describe_out is None:
271280
raise NotThisMethod("'git describe' failed")
272281
describe_out = describe_out.strip()
273-
full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
282+
full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root)
274283
if full_out is None:
275284
raise NotThisMethod("'git rev-parse' failed")
276285
full_out = full_out.strip()
@@ -280,6 +289,40 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
280289
pieces["short"] = full_out[:7] # maybe improved later
281290
pieces["error"] = None
282291

292+
branch_name, rc = runner(
293+
GITS, ["rev-parse", "--abbrev-ref", "HEAD"], cwd=root
294+
)
295+
# --abbrev-ref was added in git-1.6.3
296+
if rc != 0 or branch_name is None:
297+
raise NotThisMethod("'git rev-parse --abbrev-ref' returned error")
298+
branch_name = branch_name.strip()
299+
300+
if branch_name == "HEAD":
301+
# If we aren't exactly on a branch, pick a branch which represents
302+
# the current commit. If all else fails, we are on a branchless
303+
# commit.
304+
branches, rc = runner(GITS, ["branch", "--contains"], cwd=root)
305+
# --contains was added in git-1.5.4
306+
if rc != 0 or branches is None:
307+
raise NotThisMethod("'git branch --contains' returned error")
308+
branches = branches.split("\n")
309+
310+
# Remove the first line if we're running detached
311+
if "(" in branches[0]:
312+
branches.pop(0)
313+
314+
# Strip off the leading "* " from the list of branches.
315+
branches = [branch[2:] for branch in branches]
316+
if "master" in branches:
317+
branch_name = "master"
318+
elif not branches:
319+
branch_name = None
320+
else:
321+
# Pick the first branch that is returned. Good or bad.
322+
branch_name = branches[0]
323+
324+
pieces["branch"] = branch_name
325+
283326
# parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
284327
# TAG might have hyphens.
285328
git_describe = describe_out
@@ -324,15 +367,16 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
324367
else:
325368
# HEX: no tags
326369
pieces["closest-tag"] = None
327-
count_out, rc = run_command(
328-
GITS, ["rev-list", "HEAD", "--count"], cwd=root
329-
)
370+
count_out, rc = runner(GITS, ["rev-list", "HEAD", "--count"], cwd=root)
330371
pieces["distance"] = int(count_out) # total number of commits
331372

332373
# commit date: see ISO-8601 comment in git_versions_from_keywords()
333-
date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[
374+
date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[
334375
0
335376
].strip()
377+
# Use only the last line. Previous lines may contain GPG signature
378+
# information.
379+
date = date.splitlines()[-1]
336380
pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
337381

338382
return pieces
@@ -369,19 +413,71 @@ def render_pep440(pieces):
369413
return rendered
370414

371415

372-
def render_pep440_pre(pieces):
373-
"""TAG[.post.devDISTANCE] -- No -dirty.
416+
def render_pep440_branch(pieces):
417+
"""TAG[[.dev0]+DISTANCE.gHEX[.dirty]] .
418+
419+
The ".dev0" means not master branch. Note that .dev0 sorts backwards
420+
(a feature branch will appear "older" than the master branch).
374421
375422
Exceptions:
376-
1: no tags. 0.post.devDISTANCE
423+
1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty]
377424
"""
378425
if pieces["closest-tag"]:
379426
rendered = pieces["closest-tag"]
427+
if pieces["distance"] or pieces["dirty"]:
428+
if pieces["branch"] != "master":
429+
rendered += ".dev0"
430+
rendered += plus_or_dot(pieces)
431+
rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
432+
if pieces["dirty"]:
433+
rendered += ".dirty"
434+
else:
435+
# exception #1
436+
rendered = "0"
437+
if pieces["branch"] != "master":
438+
rendered += ".dev0"
439+
rendered += "+untagged.%d.g%s" % (pieces["distance"], pieces["short"])
440+
if pieces["dirty"]:
441+
rendered += ".dirty"
442+
return rendered
443+
444+
445+
def pep440_split_post(ver):
446+
"""Split pep440 version string at the post-release segment.
447+
448+
Returns the release segments before the post-release and the
449+
post-release version number (or -1 if no post-release segment is present).
450+
"""
451+
vc = str.split(ver, ".post")
452+
return vc[0], int(vc[1] or 0) if len(vc) == 2 else None
453+
454+
455+
def render_pep440_pre(pieces):
456+
"""TAG[.postN.devDISTANCE] -- No -dirty.
457+
458+
Exceptions:
459+
1: no tags. 0.post0.devDISTANCE
460+
"""
461+
if pieces["closest-tag"]:
380462
if pieces["distance"]:
381-
rendered += ".post.dev%d" % pieces["distance"]
463+
# update the post release segment
464+
tag_version, post_version = pep440_split_post(
465+
pieces["closest-tag"]
466+
)
467+
rendered = tag_version
468+
if post_version is not None:
469+
rendered += ".post%d.dev%d" % (
470+
post_version + 1,
471+
pieces["distance"],
472+
)
473+
else:
474+
rendered += ".post0.dev%d" % (pieces["distance"])
475+
else:
476+
# no commits, use the tag as the version
477+
rendered = pieces["closest-tag"]
382478
else:
383479
# exception #1
384-
rendered = "0.post.dev%d" % pieces["distance"]
480+
rendered = "0.post0.dev%d" % pieces["distance"]
385481
return rendered
386482

387483

@@ -412,12 +508,41 @@ def render_pep440_post(pieces):
412508
return rendered
413509

414510

511+
def render_pep440_post_branch(pieces):
512+
"""TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] .
513+
514+
The ".dev0" means not master branch.
515+
516+
Exceptions:
517+
1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty]
518+
"""
519+
if pieces["closest-tag"]:
520+
rendered = pieces["closest-tag"]
521+
if pieces["distance"] or pieces["dirty"]:
522+
rendered += ".post%d" % pieces["distance"]
523+
if pieces["branch"] != "master":
524+
rendered += ".dev0"
525+
rendered += plus_or_dot(pieces)
526+
rendered += "g%s" % pieces["short"]
527+
if pieces["dirty"]:
528+
rendered += ".dirty"
529+
else:
530+
# exception #1
531+
rendered = "0.post%d" % pieces["distance"]
532+
if pieces["branch"] != "master":
533+
rendered += ".dev0"
534+
rendered += "+g%s" % pieces["short"]
535+
if pieces["dirty"]:
536+
rendered += ".dirty"
537+
return rendered
538+
539+
415540
def render_pep440_old(pieces):
416541
"""TAG[.postDISTANCE[.dev0]] .
417542
418543
The ".dev0" means dirty.
419544
420-
Eexceptions:
545+
Exceptions:
421546
1: no tags. 0.postDISTANCE[.dev0]
422547
"""
423548
if pieces["closest-tag"]:
@@ -490,10 +615,14 @@ def render(pieces, style):
490615

491616
if style == "pep440":
492617
rendered = render_pep440(pieces)
618+
elif style == "pep440-branch":
619+
rendered = render_pep440_branch(pieces)
493620
elif style == "pep440-pre":
494621
rendered = render_pep440_pre(pieces)
495622
elif style == "pep440-post":
496623
rendered = render_pep440_post(pieces)
624+
elif style == "pep440-post-branch":
625+
rendered = render_pep440_post_branch(pieces)
497626
elif style == "pep440-old":
498627
rendered = render_pep440_old(pieces)
499628
elif style == "git-describe":
@@ -534,7 +663,7 @@ def get_versions():
534663
# versionfile_source is the relative path from the top of the source
535664
# tree (where the .git directory might live) to this file. Invert
536665
# this to find the root from __file__.
537-
for i in cfg.versionfile_source.split("/"):
666+
for _ in cfg.versionfile_source.split("/"):
538667
root = os.path.dirname(root)
539668
except NameError:
540669
return {

‎tox.ini

+13-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
[tox]
3-
envlist = py26, py27, py33, py34, py35, py36, py37, py38, py39, py310, py, pypy, pypy3, gmpy2py27, gmpy2py39, gmpy2py310, gmpypy27, gmpypy39, gmpypy310, codechecks
3+
envlist = py26, py27, py33, py34, py35, py36, py37, py38, py39, py310, py311, py, pypy, pypy3, gmpy2py27, gmpy2py39, gmpy2py310, gmpypy27, gmpypy39, gmpypy310, codechecks
44

55
[testenv]
66
deps =
@@ -11,12 +11,12 @@ deps =
1111
py{26}: unittest2
1212
py{26}: hypothesis<3
1313
py{34}: attrs<21
14-
py{26,27,34,35,36,37,38,39,310,py,py3}: pytest
15-
py{27,34,35,36,37,38,39,310,py,py3}: hypothesis
16-
gmpy2py{27,39,310}: gmpy2
17-
gmpypy{27,39,310}: gmpy
18-
gmpy{2py27,2py39,2py310,py27,py39,py310}: pytest
19-
gmpy{2py27,2py39,2py310,py27,py39,py310}: hypothesis
14+
py{26,27,34,35,36,37,38,39,310,311,py,py3}: pytest
15+
py{27,34,35,36,37,38,39,310,311,py,py3}: hypothesis
16+
gmpy2py{27,39,310,311}: gmpy2
17+
gmpypy{27,39,310,311}: gmpy
18+
gmpy{2py27,2py39,2py310,2py311,py27,py39,py310,py311}: pytest
19+
gmpy{2py27,2py39,2py310,2py311,py27,py39,py310,py311}: hypothesis
2020
# six==1.9.0 comes from setup.py install_requires
2121
py27_old_six: six==1.9.0
2222
py27_old_six: pytest
@@ -53,6 +53,9 @@ basepython=python3.9
5353
[testenv:gmpypy310]
5454
basepython=python3.10
5555

56+
[testenv:gmpypy311]
57+
basepython=python3.11
58+
5659
[testenv:gmpy2py27]
5760
basepython=python2.7
5861

@@ -62,6 +65,9 @@ basepython=python3.9
6265
[testenv:gmpy2py310]
6366
basepython=python3.10
6467

68+
[testenv:gmpy2py311]
69+
basepython=python3.11
70+
6571
[testenv:instrumental]
6672
basepython = python2.7
6773
deps =

‎versioneer.py

+507-196
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.