Commit 29c32645 authored by Wei Shoulin's avatar Wei Shoulin
Browse files

remove .eggs

parent 1773491b
"""
utils
"""
from __future__ import print_function, unicode_literals
import inspect
import warnings
import sys
import shlex
import subprocess
import os
import io
import platform
import traceback
DEBUG = bool(os.environ.get("SETUPTOOLS_SCM_DEBUG"))
IS_WINDOWS = platform.system() == "Windows"
PY2 = sys.version_info < (3,)
PY3 = sys.version_info > (3,)
string_types = (str,) if PY3 else (str, unicode) # noqa
def no_git_env(env):
# adapted from pre-commit
# Too many bugs dealing with environment variables and GIT:
# https://github.com/pre-commit/pre-commit/issues/300
# In git 2.6.3 (maybe others), git exports GIT_WORK_TREE while running
# pre-commit hooks
# In git 1.9.1 (maybe others), git exports GIT_DIR and GIT_INDEX_FILE
# while running pre-commit hooks in submodules.
# GIT_DIR: Causes git clone to clone wrong thing
# GIT_INDEX_FILE: Causes 'error invalid object ...' during commit
for k, v in env.items():
if k.startswith("GIT_"):
trace(k, v)
return {
k: v
for k, v in env.items()
if not k.startswith("GIT_")
or k in ("GIT_EXEC_PATH", "GIT_SSH", "GIT_SSH_COMMAND")
}
def trace(*k):
if DEBUG:
print(*k)
sys.stdout.flush()
def trace_exception():
DEBUG and traceback.print_exc()
def ensure_stripped_str(str_or_bytes):
if isinstance(str_or_bytes, str):
return str_or_bytes.strip()
else:
return str_or_bytes.decode("utf-8", "surrogateescape").strip()
def _always_strings(env_dict):
"""
On Windows and Python 2, environment dictionaries must be strings
and not unicode.
"""
if IS_WINDOWS or PY2:
env_dict.update((key, str(value)) for (key, value) in env_dict.items())
return env_dict
def _popen_pipes(cmd, cwd):
return subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=str(cwd),
env=_always_strings(
dict(
no_git_env(os.environ),
# os.environ,
# try to disable i18n
LC_ALL="C",
LANGUAGE="",
HGPLAIN="1",
)
),
)
def do_ex(cmd, cwd="."):
trace("cmd", repr(cmd))
if os.name == "posix" and not isinstance(cmd, (list, tuple)):
cmd = shlex.split(cmd)
p = _popen_pipes(cmd, cwd)
out, err = p.communicate()
if out:
trace("out", repr(out))
if err:
trace("err", repr(err))
if p.returncode:
trace("ret", p.returncode)
return ensure_stripped_str(out), ensure_stripped_str(err), p.returncode
def do(cmd, cwd="."):
out, err, ret = do_ex(cmd, cwd)
if ret:
print(err)
return out
def data_from_mime(path):
with io.open(path, encoding="utf-8") as fp:
content = fp.read()
trace("content", repr(content))
# the complex conditions come from reading pseudo-mime-messages
data = dict(x.split(": ", 1) for x in content.splitlines() if ": " in x)
trace("data", data)
return data
def function_has_arg(fn, argname):
assert inspect.isfunction(fn)
if PY2:
argspec = inspect.getargspec(fn).args
else:
argspec = inspect.signature(fn).parameters
return argname in argspec
def has_command(name, warn=True):
try:
p = _popen_pipes([name, "help"], ".")
except OSError:
trace(*sys.exc_info())
res = False
else:
p.communicate()
res = not p.returncode
if not res and warn:
warnings.warn("%r was not found" % name, category=RuntimeWarning)
return res
def require_command(name):
if not has_command(name, warn=False):
raise EnvironmentError("%r was not found" % name)
from __future__ import print_function
import datetime
import warnings
import re
import time
import os
from .config import Configuration
from .utils import trace, string_types
from pkg_resources import iter_entry_points
from pkg_resources import parse_version as pkg_parse_version
SEMVER_MINOR = 2
SEMVER_PATCH = 3
SEMVER_LEN = 3
def _parse_version_tag(tag, config):
tagstring = tag if not isinstance(tag, string_types) else str(tag)
match = config.tag_regex.match(tagstring)
result = None
if match:
if len(match.groups()) == 1:
key = 1
else:
key = "version"
result = {
"version": match.group(key),
"prefix": match.group(0)[: match.start(key)],
"suffix": match.group(0)[match.end(key) :],
}
trace("tag '{}' parsed to {}".format(tag, result))
return result
def _get_version_class():
modern_version = pkg_parse_version("1.0")
if isinstance(modern_version, tuple):
return None
else:
return type(modern_version)
VERSION_CLASS = _get_version_class()
class SetuptoolsOutdatedWarning(Warning):
pass
# append so integrators can disable the warning
warnings.simplefilter("error", SetuptoolsOutdatedWarning, append=True)
def _warn_if_setuptools_outdated():
if VERSION_CLASS is None:
warnings.warn("your setuptools is too old (<12)", SetuptoolsOutdatedWarning)
def callable_or_entrypoint(group, callable_or_name):
trace("ep", (group, callable_or_name))
if callable(callable_or_name):
return callable_or_name
for ep in iter_entry_points(group, callable_or_name):
trace("ep found:", ep.name)
return ep.load()
def tag_to_version(tag, config=None):
"""
take a tag that might be prefixed with a keyword and return only the version part
:param config: optional configuration object
"""
trace("tag", tag)
if not config:
config = Configuration()
tagdict = _parse_version_tag(tag, config)
if not isinstance(tagdict, dict) or not tagdict.get("version", None):
warnings.warn("tag {!r} no version found".format(tag))
return None
version = tagdict["version"]
trace("version pre parse", version)
if tagdict.get("suffix", ""):
warnings.warn(
"tag {!r} will be stripped of its suffix '{}'".format(
tag, tagdict["suffix"]
)
)
if VERSION_CLASS is not None:
version = pkg_parse_version(version)
trace("version", repr(version))
return version
def tags_to_versions(tags, config=None):
"""
take tags that might be prefixed with a keyword and return only the version part
:param tags: an iterable of tags
:param config: optional configuration object
"""
result = []
for tag in tags:
tag = tag_to_version(tag, config=config)
if tag:
result.append(tag)
return result
class ScmVersion(object):
def __init__(
self,
tag_version,
distance=None,
node=None,
dirty=False,
preformatted=False,
branch=None,
config=None,
**kw
):
if kw:
trace("unknown args", kw)
self.tag = tag_version
if dirty and distance is None:
distance = 0
self.distance = distance
self.node = node
self.time = datetime.datetime.utcfromtimestamp(
int(os.environ.get("SOURCE_DATE_EPOCH", time.time()))
)
self._extra = kw
self.dirty = dirty
self.preformatted = preformatted
self.branch = branch
self.config = config
@property
def extra(self):
warnings.warn(
"ScmVersion.extra is deprecated and will be removed in future",
category=DeprecationWarning,
stacklevel=2,
)
return self._extra
@property
def exact(self):
return self.distance is None
def __repr__(self):
return self.format_with(
"<ScmVersion {tag} d={distance} n={node} d={dirty} b={branch}>"
)
def format_with(self, fmt, **kw):
return fmt.format(
time=self.time,
tag=self.tag,
distance=self.distance,
node=self.node,
dirty=self.dirty,
branch=self.branch,
**kw
)
def format_choice(self, clean_format, dirty_format, **kw):
return self.format_with(dirty_format if self.dirty else clean_format, **kw)
def format_next_version(self, guess_next, fmt="{guessed}.dev{distance}", **kw):
guessed = guess_next(self.tag, **kw)
return self.format_with(fmt, guessed=guessed)
def _parse_tag(tag, preformatted, config):
if preformatted:
return tag
if VERSION_CLASS is None or not isinstance(tag, VERSION_CLASS):
tag = tag_to_version(tag, config)
return tag
def meta(
tag,
distance=None,
dirty=False,
node=None,
preformatted=False,
branch=None,
config=None,
**kw
):
if not config:
warnings.warn(
"meta invoked without explicit configuration,"
" will use defaults where required."
)
parsed_version = _parse_tag(tag, preformatted, config)
trace("version", tag, "->", parsed_version)
assert parsed_version is not None, "Can't parse version %s" % tag
return ScmVersion(
parsed_version, distance, node, dirty, preformatted, branch, config, **kw
)
def guess_next_version(tag_version):
version = _strip_local(str(tag_version))
return _bump_dev(version) or _bump_regex(version)
def _strip_local(version_string):
public, sep, local = version_string.partition("+")
return public
def _bump_dev(version):
if ".dev" not in version:
return
prefix, tail = version.rsplit(".dev", 1)
if tail != "0":
raise ValueError(
"choosing custom numbers for the `.devX` distance "
"is not supported.\n "
"The {version} can't be bumped\n"
"Please drop the tag or create a new supported one".format(version=version)
)
return prefix
def _bump_regex(version):
match = re.match(r"(.*?)(\d+)$", version)
if match is None:
raise ValueError(
"{version} does not end with a number to bump, "
"please correct or use a custom version scheme".format(version=version)
)
else:
prefix, tail = match.groups()
return "%s%d" % (prefix, int(tail) + 1)
def guess_next_dev_version(version):
if version.exact:
return version.format_with("{tag}")
else:
return version.format_next_version(guess_next_version)
def guess_next_simple_semver(version, retain, increment=True):
try:
parts = [int(i) for i in str(version).split(".")[:retain]]
except ValueError:
raise ValueError(
"{version} can't be parsed as numeric version".format(version=version)
)
while len(parts) < retain:
parts.append(0)
if increment:
parts[-1] += 1
while len(parts) < SEMVER_LEN:
parts.append(0)
return ".".join(str(i) for i in parts)
def simplified_semver_version(version):
if version.exact:
return guess_next_simple_semver(version.tag, retain=SEMVER_LEN, increment=False)
else:
if version.branch is not None and "feature" in version.branch:
return version.format_next_version(
guess_next_simple_semver, retain=SEMVER_MINOR
)
else:
return version.format_next_version(
guess_next_simple_semver, retain=SEMVER_PATCH
)
def release_branch_semver_version(version):
if version.exact:
return version.format_with("{tag}")
if version.branch is not None:
# Does the branch name (stripped of namespace) parse as a version?
branch_ver = _parse_version_tag(version.branch.split("/")[-1], version.config)
if branch_ver is not None:
# Does the branch version up to the minor part match the tag? If not it
# might be like, an issue number or something and not a version number, so
# we only want to use it if it matches.
tag_ver_up_to_minor = str(version.tag).split(".")[:SEMVER_MINOR]
branch_ver_up_to_minor = branch_ver["version"].split(".")[:SEMVER_MINOR]
if branch_ver_up_to_minor == tag_ver_up_to_minor:
# We're in a release/maintenance branch, next is a patch/rc/beta bump:
return version.format_next_version(guess_next_version)
# We're in a development branch, next is a minor bump:
return version.format_next_version(guess_next_simple_semver, retain=SEMVER_MINOR)
def release_branch_semver(version):
warnings.warn(
"release_branch_semver is deprecated and will be removed in future. "
+ "Use release_branch_semver_version instead",
category=DeprecationWarning,
stacklevel=2,
)
return release_branch_semver_version(version)
def no_guess_dev_version(version):
if version.exact:
return version.format_with("{tag}")
else:
return version.format_with("{tag}.post1.dev{distance}")
def _format_local_with_time(version, time_format):
if version.exact or version.node is None:
return version.format_choice(
"", "+d{time:{time_format}}", time_format=time_format
)
else:
return version.format_choice(
"+{node}", "+{node}.d{time:{time_format}}", time_format=time_format
)
def get_local_node_and_date(version):
return _format_local_with_time(version, time_format="%Y%m%d")
def get_local_node_and_timestamp(version, fmt="%Y%m%d%H%M%S"):
return _format_local_with_time(version, time_format=fmt)
def get_local_dirty_tag(version):
return version.format_choice("", "+dirty")
def get_no_local_node(_):
return ""
def postrelease_version(version):
if version.exact:
return version.format_with("{tag}")
else:
return version.format_with("{tag}.post{distance}")
def format_version(version, **config):
trace("scm version", version)
trace("config", config)
if version.preformatted:
return version.tag
version_scheme = callable_or_entrypoint(
"setuptools_scm.version_scheme", config["version_scheme"]
)
local_scheme = callable_or_entrypoint(
"setuptools_scm.local_scheme", config["local_scheme"]
)
main_version = version_scheme(version)
trace("version", main_version)
local_version = local_scheme(version)
trace("local_version", local_version)
return version_scheme(version) + local_scheme(version)
"""
Backport of os.path.samefile for Python prior to 3.2
on Windows from jaraco.windows 3.8.
DON'T EDIT THIS FILE!
Instead, file tickets and PR's with `jaraco.windows
<https://github.com/jaraco/jaraco.windows>`_ and request
a port to setuptools_scm.
"""
import os
import nt
import posixpath
import ctypes.wintypes
import sys
import __builtin__ as builtins
##
# From jaraco.windows.error
def format_system_message(errno):
"""
Call FormatMessage with a system error number to retrieve
the descriptive error message.
"""
# first some flags used by FormatMessageW
ALLOCATE_BUFFER = 0x100
FROM_SYSTEM = 0x1000
# Let FormatMessageW allocate the buffer (we'll free it below)
# Also, let it know we want a system error message.
flags = ALLOCATE_BUFFER | FROM_SYSTEM
source = None
message_id = errno
language_id = 0
result_buffer = ctypes.wintypes.LPWSTR()
buffer_size = 0
arguments = None
bytes = ctypes.windll.kernel32.FormatMessageW(
flags,
source,
message_id,
language_id,
ctypes.byref(result_buffer),
buffer_size,
arguments,
)
# note the following will cause an infinite loop if GetLastError
# repeatedly returns an error that cannot be formatted, although
# this should not happen.
handle_nonzero_success(bytes)
message = result_buffer.value
ctypes.windll.kernel32.LocalFree(result_buffer)
return message
class WindowsError(builtins.WindowsError):
"""
More info about errors at
http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx
"""
def __init__(self, value=None):
if value is None:
value = ctypes.windll.kernel32.GetLastError()
strerror = format_system_message(value)
if sys.version_info > (3, 3):
args = 0, strerror, None, value
else:
args = value, strerror
super(WindowsError, self).__init__(*args)
@property
def message(self):
return self.strerror
@property
def code(self):
return self.winerror
def __str__(self):
return self.message
def __repr__(self):
return '{self.__class__.__name__}({self.winerror})'.format(**vars())
def handle_nonzero_success(result):
if result == 0:
raise WindowsError()
##
# From jaraco.windows.api.filesystem
FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000
FILE_FLAG_BACKUP_SEMANTICS = 0x2000000
OPEN_EXISTING = 3
FILE_ATTRIBUTE_NORMAL = 0x80
FILE_READ_ATTRIBUTES = 0x80
INVALID_HANDLE_VALUE = ctypes.wintypes.HANDLE(-1).value
class BY_HANDLE_FILE_INFORMATION(ctypes.Structure):
_fields_ = [
('file_attributes', ctypes.wintypes.DWORD),
('creation_time', ctypes.wintypes.FILETIME),
('last_access_time', ctypes.wintypes.FILETIME),
('last_write_time', ctypes.wintypes.FILETIME),
('volume_serial_number', ctypes.wintypes.DWORD),
('file_size_high', ctypes.wintypes.DWORD),
('file_size_low', ctypes.wintypes.DWORD),
('number_of_links', ctypes.wintypes.DWORD),
('file_index_high', ctypes.wintypes.DWORD),
('file_index_low', ctypes.wintypes.DWORD),
]
@property
def file_size(self):
return (self.file_size_high << 32) + self.file_size_low
@property
def file_index(self):
return (self.file_index_high << 32) + self.file_index_low
class SECURITY_ATTRIBUTES(ctypes.Structure):
_fields_ = (
('length', ctypes.wintypes.DWORD),
('p_security_descriptor', ctypes.wintypes.LPVOID),
('inherit_handle', ctypes.wintypes.BOOLEAN),
)
LPSECURITY_ATTRIBUTES = ctypes.POINTER(SECURITY_ATTRIBUTES)
CreateFile = ctypes.windll.kernel32.CreateFileW
CreateFile.argtypes = (
ctypes.wintypes.LPWSTR,
ctypes.wintypes.DWORD,
ctypes.wintypes.DWORD,
LPSECURITY_ATTRIBUTES,
ctypes.wintypes.DWORD,
ctypes.wintypes.DWORD,
ctypes.wintypes.HANDLE,
)
CreateFile.restype = ctypes.wintypes.HANDLE
GetFileInformationByHandle = ctypes.windll.kernel32.GetFileInformationByHandle
GetFileInformationByHandle.restype = ctypes.wintypes.BOOL
GetFileInformationByHandle.argtypes = (
ctypes.wintypes.HANDLE,
ctypes.POINTER(BY_HANDLE_FILE_INFORMATION),
)
##
# From jaraco.windows.filesystem
def compat_stat(path):
"""
Generate stat as found on Python 3.2 and later.
"""
stat = os.stat(path)
info = get_file_info(path)
# rewrite st_ino, st_dev, and st_nlink based on file info
return nt.stat_result(
(stat.st_mode,) +
(info.file_index, info.volume_serial_number, info.number_of_links) +
stat[4:]
)
def samefile(f1, f2):
"""
Backport of samefile from Python 3.2 with support for Windows.
"""
return posixpath.samestat(compat_stat(f1), compat_stat(f2))
def get_file_info(path):
# open the file the same way CPython does in posixmodule.c
desired_access = FILE_READ_ATTRIBUTES
share_mode = 0
security_attributes = None
creation_disposition = OPEN_EXISTING
flags_and_attributes = (
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_BACKUP_SEMANTICS |
FILE_FLAG_OPEN_REPARSE_POINT
)
template_file = None
handle = CreateFile(
path,
desired_access,
share_mode,
security_attributes,
creation_disposition,
flags_and_attributes,
template_file,
)
if handle == INVALID_HANDLE_VALUE:
raise WindowsError()
info = BY_HANDLE_FILE_INFORMATION()
res = GetFileInformationByHandle(handle, info)
handle_nonzero_success(res)
return info
......@@ -36,3 +36,5 @@ test_reports.xml
# Python egg metadata, regenerated from source files by setuptools.
**/*.egg-info
**/*.rdb
**/.eggs
**/_version.py
\ No newline at end of file
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = '0.1.dev1+gd5fcbad.d20210224'
version_tuple = (0, 1, 'dev1+gd5fcbad', 'd20210224')
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment