Commit 1e5cb887 authored by Ondřej Nový's avatar Ondřej Nový

New upstream version 1.8.0

parent 5bae8066
sudo: false
dist: xenial
language: python
python:
- '2.7'
- '3.4'
- '3.5'
- '3.6'
- 'pypy-5.4'
- '2.7'
- '3.4'
- '3.5'
- '3.6'
- '3.7'
# - 'pypy2.7-6.0'
- 'pypy3.5-6.0'
env:
- DEPS="pytest~=2.9.0"
- DEPS="pytest~=3.0.0"
#- DEPS="pytest~=3.1.0"
global:
- COVERAGE_PROCESS_START=$PWD/tox.ini
matrix:
- DEPS="pytest~=2.9.0"
- DEPS="pytest~=3.0.0"
#- DEPS="pytest~=3.1.0"
matrix:
stages:
- name: deploy
if: tag IS present
matrix:
include:
- python: '2.7'
# using a different option due to pytest-addopts pytester issues
env: PYTEST_XADDOPTS="-n 3 --runslowtests" DEPS="pytest~=3.0.0 pytest-xdist"
- stage: deploy
python: '3.6'
env:
install: pip install -U setuptools setuptools_scm
script: skip
deploy:
provider: pypi
user: nicoddemus
distributions: sdist bdist_wheel
skip_upload_docs: true
password:
secure: VNYW/sZoD+9DzKCe6vANNXXJR7jP7rwySafQ33N1jAnCrdylQjEN/p6tSfUe8jDi3wDpLPL9h8pwfxuUT7CRxglHov3Qe7zSeywixvHan5aFahQiQ8+gucYIM7wITHH3oQs7jN35pnhdnF+QlW2+eDCL6qOLU5XwuRhsDKXjQ/hUWR5hlX5EniD1gzyKEf6j1YCpST87tKpeLwVEYEmsucdkUZuXhxDtyaWQHWiPsLWwh/slQtUJEHeLF26r8UxFy0RiGne9jR+CzRfH5ktcA9/pArvp4VuwOii+1TDxVSYP7+I8Z+eUKN9JBg12QLaHwoIN/8J+MvHCkuf+OGSLM3sEyNRJGDev372xg3K7ylIkeeK4WXirKEp2ojgN8tniloDjnwdu/gPWBnrXuooA60tNoByHFa8KbMZAr2B2sQeMxD4VZGr1N8l0rX4gRTrwvdk3i3ulLKVSwkXaGn+GrfZTTboa7dEnpuma8tv1niNCSpStYIy7atS8129+5ijV3OC8DzOMh/rVbO9WsDb/RPG3yjFiDvEJPIPeE0l/m5u42QBqtdZSS2ia7UWTJBiEY09uFMTRmH5hhE/1aiYBbvAztf5CReUbeKdSQz3L8TTSZqewtFZmXTkX97/xQnrEpsnGezIM2DNuMEuQG3MxGkNCxwbQKpx/bkHdrD75yMk=
on:
tags: true
repo: pytest-dev/py
- python: '2.7'
# using a different option due to pytest-addopts pytester issues
env: PYTEST_XADDOPTS="-n auto --runslowtests" DEPS="pytest~=3.0.0 pytest-xdist<1.25 pytest-forked<0.3"
- stage: deploy
python: '3.6'
env:
install: pip install -U setuptools setuptools_scm
script: skip
deploy:
provider: pypi
user: nicoddemus
distributions: sdist bdist_wheel
skip_upload_docs: true
password:
secure: VNYW/sZoD+9DzKCe6vANNXXJR7jP7rwySafQ33N1jAnCrdylQjEN/p6tSfUe8jDi3wDpLPL9h8pwfxuUT7CRxglHov3Qe7zSeywixvHan5aFahQiQ8+gucYIM7wITHH3oQs7jN35pnhdnF+QlW2+eDCL6qOLU5XwuRhsDKXjQ/hUWR5hlX5EniD1gzyKEf6j1YCpST87tKpeLwVEYEmsucdkUZuXhxDtyaWQHWiPsLWwh/slQtUJEHeLF26r8UxFy0RiGne9jR+CzRfH5ktcA9/pArvp4VuwOii+1TDxVSYP7+I8Z+eUKN9JBg12QLaHwoIN/8J+MvHCkuf+OGSLM3sEyNRJGDev372xg3K7ylIkeeK4WXirKEp2ojgN8tniloDjnwdu/gPWBnrXuooA60tNoByHFa8KbMZAr2B2sQeMxD4VZGr1N8l0rX4gRTrwvdk3i3ulLKVSwkXaGn+GrfZTTboa7dEnpuma8tv1niNCSpStYIy7atS8129+5ijV3OC8DzOMh/rVbO9WsDb/RPG3yjFiDvEJPIPeE0l/m5u42QBqtdZSS2ia7UWTJBiEY09uFMTRmH5hhE/1aiYBbvAztf5CReUbeKdSQz3L8TTSZqewtFZmXTkX97/xQnrEpsnGezIM2DNuMEuQG3MxGkNCxwbQKpx/bkHdrD75yMk=
on:
tags: true
repo: pytest-dev/py
exclude:
- python: '3.7'
env: DEPS="pytest~=2.9.0"
allow_failures:
- python: 'pypy-5.4'
- python: 'pypy2.7-6.0'
- python: 'pypy3.5-6.0'
install:
- pip install -U setuptools setuptools_scm
- pip install $DEPS
- pip install -U . --force-reinstall
- pip install -U coverage coverage-enable-subprocess pip setuptools setuptools_scm
- pip install $DEPS
- pip install -U . --force-reinstall
script:
- py.test --lsof $PYTEST_XADDOPTS
- coverage run -m pytest --lsof $PYTEST_XADDOPTS
after_success:
- coverage combine
- coverage report -m
- coverage xml
- bash <(curl -s https://codecov.io/bash) -Z -X gcov -X coveragepy -X search -X xcode -X gcovout -X fix -f coverage.xml -e TRAVIS_PYTHON_VERSION
1.8.0 (2019-02-21)
==================
- add ``"importlib"`` pyimport mode for python3.5+, allowing unimportable test suites
to contain identically named modules.
- fix ``LocalPath.as_cwd()`` not calling ``os.chdir()`` with ``None``, when
being invoked from a non-existing directory.
1.7.0 (2018-10-11)
==================
......
Metadata-Version: 1.2
Name: py
Version: 1.7.0
Version: 1.8.0
Summary: library with cross-python path, ini-parsing, io, code, log facilities
Home-page: http://py.readthedocs.io/
Author: holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others
......
coverage:
status:
project: true
patch: true
changes: true
comment:
layout: "diff"
Metadata-Version: 1.2
Name: py
Version: 1.7.0
Version: 1.8.0
Summary: library with cross-python path, ini-parsing, io, code, log facilities
Home-page: http://py.readthedocs.io/
Author: holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others
......
......@@ -8,6 +8,7 @@ LICENSE
MANIFEST.in
README.rst
appveyor.yml
codecov.yml
conftest.py
setup.cfg
setup.py
......
import sys
try:
reversed = reversed
except NameError:
def reversed(sequence):
"""reversed(sequence) -> reverse iterator over values of the sequence
Return a reverse iterator
"""
if hasattr(sequence, '__reversed__'):
return sequence.__reversed__()
if not hasattr(sequence, '__getitem__'):
raise TypeError("argument to reversed() must be a sequence")
return reversed_iterator(sequence)
class reversed_iterator(object):
def __init__(self, seq):
self.seq = seq
self.remaining = len(seq)
def __iter__(self):
return self
def next(self):
i = self.remaining
if i > 0:
i -= 1
item = self.seq[i]
self.remaining = i
return item
raise StopIteration
def __length_hint__(self):
return self.remaining
try:
any = any
except NameError:
def any(iterable):
for x in iterable:
if x:
return True
return False
try:
all = all
except NameError:
def all(iterable):
for x in iterable:
if not x:
return False
return True
try:
sorted = sorted
except NameError:
builtin_cmp = cmp # need to use cmp as keyword arg
def sorted(iterable, cmp=None, key=None, reverse=0):
use_cmp = None
if key is not None:
if cmp is None:
def use_cmp(x, y):
return builtin_cmp(x[0], y[0])
else:
def use_cmp(x, y):
return cmp(x[0], y[0])
l = [(key(element), element) for element in iterable]
else:
if cmp is not None:
use_cmp = cmp
l = list(iterable)
if use_cmp is not None:
l.sort(use_cmp)
else:
l.sort()
if reverse:
l.reverse()
if key is not None:
return [element for (_, element) in l]
return l
try:
set, frozenset = set, frozenset
except NameError:
from sets import set, frozenset
# pass through
enumerate = enumerate
try:
BaseException = BaseException
except NameError:
BaseException = Exception
try:
GeneratorExit = GeneratorExit
except NameError:
class GeneratorExit(Exception):
""" This exception is never raised, it is there to make it possible to
write code compatible with CPython 2.5 even in lower CPython
versions."""
pass
GeneratorExit.__module__ = 'exceptions'
# Passthrough for builtins supported with py27.
BaseException = BaseException
GeneratorExit = GeneratorExit
_sysex = (KeyboardInterrupt, SystemExit, MemoryError, GeneratorExit)
all = all
any = any
callable = callable
enumerate = enumerate
reversed = reversed
set, frozenset = set, frozenset
sorted = sorted
try:
callable = callable
except NameError:
def callable(obj):
return hasattr(obj, "__call__")
if sys.version_info >= (3, 0):
exec ("print_ = print ; exec_=exec")
exec("print_ = print ; exec_=exec")
import builtins
# some backward compatibility helpers
......@@ -131,13 +32,13 @@ if sys.version_info >= (3, 0):
def _isbytes(x):
return isinstance(x, bytes)
def _istext(x):
return isinstance(x, str)
text = str
bytes = bytes
def _getimself(function):
return getattr(function, '__self__', None)
......
......@@ -227,7 +227,7 @@ class TerminalWriter(object):
# i.e. 2 + 2*len(sepchar)*N + len(title) <= fullwidth
# 2*len(sepchar)*N <= fullwidth - len(title) - 2
# N <= (fullwidth - len(title) - 2) // (2*len(sepchar))
N = (fullwidth - len(title) - 2) // (2*len(sepchar))
N = max((fullwidth - len(title) - 2) // (2*len(sepchar)), 1)
fill = sepchar * N
line = "%s %s %s" % (fill, title, fill)
else:
......
......@@ -18,6 +18,11 @@ if sys.version_info > (3,0):
else:
map_as_list = map
ALLOW_IMPORTLIB_MODE = sys.version_info > (3,5)
if ALLOW_IMPORTLIB_MODE:
import importlib
class Stat(object):
def __getattr__(self, name):
return getattr(self._osstatresult, "st_" + name)
......@@ -574,14 +579,17 @@ class LocalPath(FSBase):
@contextmanager
def as_cwd(self):
""" return context manager which changes to current dir during the
managed "with" context. On __enter__ it returns the old dir.
"""
Return a context manager, which changes to the path's dir during the
managed "with" context.
On __enter__ it returns the old dir, which might be ``None``.
"""
old = self.chdir()
try:
yield old
finally:
old.chdir()
if old is not None:
old.chdir()
def realpath(self):
""" return a new path which contains no symbolic links."""
......@@ -647,10 +655,35 @@ class LocalPath(FSBase):
If ensuresyspath=="append" the root dir will be appended
if it isn't already contained in sys.path.
if ensuresyspath is False no modification of syspath happens.
Special value of ensuresyspath=="importlib" is intended
purely for using in pytest, it is capable only of importing
separate .py files outside packages, e.g. for test suite
without any __init__.py file. It effectively allows having
same-named test modules in different places and offers
mild opt-in via this option. Note that it works only in
recent versions of python.
"""
if not self.check():
raise py.error.ENOENT(self)
if ensuresyspath == 'importlib':
if modname is None:
modname = self.purebasename
if not ALLOW_IMPORTLIB_MODE:
raise ImportError(
"Can't use importlib due to old version of Python")
spec = importlib.util.spec_from_file_location(
modname, str(self))
if spec is None:
raise ImportError(
"Can't find module %s at location %s" %
(modname, str(self))
)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
pkgpath = None
if modname is None:
pkgpath = self.pypkgpath()
......
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = '1.7.0'
version = '1.8.0'
......@@ -165,6 +165,12 @@ class TestTerminalWriter:
assert len(l) == 1
assert l[0] == "-" * 26 + " hello " + "-" * (27-win32) + "\n"
def test_sep_longer_than_width(self, tw):
tw.sep('-', 'a' * 10, fullwidth=5)
line, = tw.getlines()
# even though the string is wider than the line, still have a separator
assert line == '- aaaaaaaaaa -\n'
@py.test.mark.skipif("sys.platform == 'win32'")
def test__escaped(self, tw):
text2 = tw._escaped("hello", (31))
......
......@@ -125,6 +125,19 @@ class TestLocalPath(common.CommonFSTests):
assert path1.chdir() is None
assert os.getcwd() == str(path1)
with pytest.raises(py.error.ENOENT):
with p.as_cwd():
raise NotImplementedError
@skiponwin32
def test_chdir_gone_in_as_cwd(self, path1):
p = path1.ensure("dir_to_be_removed", dir=1)
p.chdir()
p.remove()
with path1.as_cwd() as old:
assert old is None
def test_as_cwd(self, path1):
dir = path1.ensure("subdir", dir=1)
old = py.path.local()
......@@ -581,6 +594,39 @@ class TestImport:
assert str(root1) not in sys.path[:-1]
class TestImportlibImport:
pytestmark = py.test.mark.skipif("sys.version_info < (3, 5)")
OPTS = {'ensuresyspath': 'importlib'}
def test_pyimport(self, path1):
obj = path1.join('execfile.py').pyimport(**self.OPTS)
assert obj.x == 42
assert obj.__name__ == 'execfile'
def test_pyimport_dir_fails(self, tmpdir):
p = tmpdir.join("hello_123")
p.ensure("__init__.py")
with pytest.raises(ImportError):
p.pyimport(**self.OPTS)
def test_pyimport_execfile_different_name(self, path1):
obj = path1.join('execfile.py').pyimport(modname="0x.y.z", **self.OPTS)
assert obj.x == 42
assert obj.__name__ == '0x.y.z'
def test_pyimport_relative_import_fails(self, path1):
otherdir = path1.join('otherdir')
with pytest.raises(ImportError):
otherdir.join('a.py').pyimport(**self.OPTS)
def test_pyimport_doesnt_use_sys_modules(self, tmpdir):
p = tmpdir.ensure('file738jsk.py')
mod = p.pyimport(**self.OPTS)
assert mod.__name__ == 'file738jsk'
assert 'file738jsk' not in sys.modules
def test_pypkgdir(tmpdir):
pkg = tmpdir.ensure('pkg1', dir=1)
pkg.ensure("__init__.py")
......
import sys
import types
import py
from py.builtin import set, frozenset, reversed, sorted
from py.builtin import set, frozenset
def test_enumerate():
l = [0,1,2]
......@@ -53,29 +53,6 @@ def test_frozenset():
s = set([frozenset([0, 1]), frozenset([1, 0])])
assert len(s) == 1
def test_sorted():
if sorted == py.builtin.sorted:
return # don't test a real builtin
for s in [py.builtin.sorted]:
def test():
assert s([3, 2, 1]) == [1, 2, 3]
assert s([1, 2, 3], reverse=True) == [3, 2, 1]
l = s([1, 2, 3, 4, 5, 6], key=lambda x: x % 2)
assert l == [2, 4, 6, 1, 3, 5]
l = s([1, 2, 3, 4], cmp=lambda x, y: -cmp(x, y))
assert l == [4, 3, 2, 1]
l = s([1, 2, 3, 4], cmp=lambda x, y: -cmp(x, y),
key=lambda x: x % 2)
assert l == [1, 3, 2, 4]
def compare(x, y):
assert type(x) == str
assert type(y) == str
return cmp(x, y)
data = 'The quick Brown fox Jumped over The lazy Dog'.split()
s(data, cmp=compare, key=str.lower)
yield test
def test_print_simple():
from py.builtin import print_
......@@ -116,7 +93,7 @@ def test_execfile(tmpdir):
def test_getfuncdict():
def f():
pass
raise NotImplementedError
f.x = 4
assert py.builtin._getfuncdict(f)["x"] == 4
assert py.builtin._getfuncdict(2) is None
......
......@@ -3,10 +3,9 @@
envlist=py{27,34,35,36}-pytest{29,30,31},py37-pytest{30,31}
[testenv]
changedir=testing
commands=
pip install -U .. # hande the install order fallout since pytest depends on pip
py.test --confcutdir=.. -rfsxX --junitxml={envlogdir}/junit-{envname}.xml []
pip install -U . # hande the install order fallout since pytest depends on pip
py.test --confcutdir=. --junitxml={envlogdir}/junit-{envname}.xml []
deps=
attrs
pytest29: pytest~=2.9.0
......@@ -20,15 +19,26 @@ deps=
pytest-xdist<=1.16.0
commands=
pip install -U .. # hande the install order fallout since pytest depends on pip
py.test -n3 -rfsxX --confcutdir=.. --runslowtests \
py.test -n3 --confcutdir=.. --runslowtests \
--junitxml={envlogdir}/junit-{envname}.xml []
[testenv:jython]
changedir=testing
commands=
{envpython} -m pip install -U .. # hande the install order fallout since pytest depends on pip
{envpython} -m pytest --confcutdir=.. -rfsxX --junitxml={envlogdir}/junit-{envname}0.xml {posargs:io_ code}
{envpython} -m pytest --confcutdir=.. --junitxml={envlogdir}/junit-{envname}0.xml {posargs:io_ code}
[pytest]
rsyncdirs = conftest.py py doc testing
addopts = -ra
testpaths = testing
[coverage:run]
branch = 1
source = .
parallel = 1
[coverage:report]
include = py/*,testing/*
exclude_lines =
#\s*(pragma|PRAGMA)[:\s]?\s*(no|NO)\s*(cover|COVER)
^\s*raise NotImplementedError\b
Markdown is supported
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