Permalink
Browse files

More PEP-8 fixes and improvements

- added initial contributing guide
  • Loading branch information...
mrbean-bremen committed Dec 27, 2017
1 parent 6154330 commit 964239c468c66e32e492b40cabdb6bd346a557a1
View
@@ -0,0 +1,50 @@
# Contributing to pyfakefs
We welcome any contributions that help to improve pyfakefs for the community.
This may include bug reports, bug fixes, new features, infrastructure enhancements, or
documentation updates.
## How to contribute
### Reporting Bugs
If you think you found a bug in pyfakefs, you can [create an issue](https://help.github.com/articles/creating-an-issue/).
Before filing the bug, please check, if it still exists in the [master branch](https://github.com/jmcgeheeiv/pyfakefs).
If you can reproduce the problem, please provide enough information to reproduce the problem.
This includes:
* The Operating System
* The Python version
* A minimal example to reproduce the problem (preferably in the form of a failing test, if possible)
* The stack trace in case of an unexpected excpetion
For better readabilty, you may use [markdown code formatting](https://help.github.com/articles/creating-and-highlighting-code-blocks/) for any included code.
### Proposing Enhancements
If you need a specific feature that is not implemented, or have an idea for the next
exciting enhancement in pyfakefs, you can also create a respective issue. The best chances
to get it are of course if you implement it yourself, as described in the next item.
### Contributing Code
The preferred workflow for contributing code is to [fork](https://help.github.com/articles/fork-a-repo/) the
[repository](https://github.com/jmcgeheeiv/pyfakefs) on GitHub, clone,
develop on a feature branch, and [create a pull requests](https://help.github.com/articles/creating-a-pull-request-from-a-fork).
There are a few things to consider for contributing code:
* Please use the standard [PEP-8 coding style](https://www.python.org/dev/peps/pep-0008/)
(your IDE or tools like [pep8](https://pypi.python.org/pypi/pep8) or [pylint](https://pypi.python.org/pypi/pylint) will help you)
* Use the [Google documentation style](https://google.github.io/styleguide/pyguide.html) to document new public classes or methods
* Provide unit tests for bug fixes or new functionality - check the existing tests for examples
* Provide meaningful commit messages
### Contributing Documentation
If you want to improve the existing documentation, you can just create a pull request with the changes.
You can contribute to:
* the source code documentation using [Google documentation style](https://google.github.io/styleguide/pyguide.html)
* the [README](https://github.com/jmcgeheeiv/pyfakefs/blob/master/README.md)
* the documentation published on [GitHub Pages](http://jmcgeheeiv.github.io/pyfakefs/), located in the 'docs' directory.
For building the documentation, you will need [sphinx](http://sphinx.pocoo.org/).
* [this file](https://github.com/jmcgeheeiv/pyfakefs/blob/master/CONTRIBUTING.md) if you want to enhance the contributing guide itself
Thanks for taking the time to contribute to pyfakefs!
View
@@ -143,7 +143,7 @@ pyfakefs is currently automatically tested:
* On Linux, with Python 2.7, 3.3 and above using [Travis](https://travis-ci.org/jmcgeheeiv/pyfakefs)
* On MacOS, with Python 2.7 and 3.6, also using [Travis](https://travis-ci.org/jmcgeheeiv/pyfakefs).
The Linux/MacOS build is currently [![Build Status](https://travis-ci.org/jmcgeheeiv/pyfakefs.svg)](https://travis-ci.org/jmcgeheeiv/pyfakefs).
* On Windows, with Python 2.7, 3.3 and 3.6 using [Appveyor](https://ci.appveyor.com/project/jmcgeheeiv/pyfakefs).
* On Windows, with Python 2.7, 3.4 and above using [Appveyor](https://ci.appveyor.com/project/jmcgeheeiv/pyfakefs).
The Windows build is currently [![Build status](https://ci.appveyor.com/api/projects/status/4o8j21ufuo056873/branch/master?svg=true)](https://ci.appveyor.com/project/jmcgeheeiv/pyfakefs/branch/master).
### Running pyfakefs unit tests
View
@@ -57,7 +57,7 @@ def add(clss, func, deprecated_name):
Gives a deprecation warning on usage.
Args:
cls: the class where the deprecated function is to be added
clss: the class where the deprecated function is to be added
func: the actual function that is called by the deprecated version
deprecated_name: the deprecated name of the function
"""
View
@@ -80,7 +80,8 @@ class _FakeAccessor(pathlib._Accessor): # pylint: disable=protected-access
stat = _wrap_strfunc(FakeFilesystem.stat)
lstat = _wrap_strfunc(lambda fs, path: FakeFilesystem.stat(fs, path, follow_symlinks=False))
lstat = _wrap_strfunc(lambda fs, path: FakeFilesystem.stat(fs, path,
follow_symlinks=False))
listdir = _wrap_strfunc(FakeFilesystem.listdir)
@@ -431,7 +432,8 @@ class FakePath(pathlib.Path):
def __new__(cls, *args, **kwargs):
"""Creates the correct subclass based on OS."""
if cls is FakePathlibModule.Path:
cls = FakePathlibModule.WindowsPath if os.name == 'nt' else FakePathlibModule.PosixPath
cls = (FakePathlibModule.WindowsPath if os.name == 'nt'
else FakePathlibModule.PosixPath)
self = cls._from_parts(args, init=True)
return self
@@ -553,10 +555,11 @@ def samefile(self, other_path):
(as returned by os.path.samefile()).
Args:
other_path: a path object or string of the file object to be compared with
other_path: A path object or string of the file object
to be compared with
Raises:
OSError: if the filesystem object doesn't exist.
OSError: if the filesystem object doesn't exist.
"""
st = self.stat()
try:
@@ -573,7 +576,8 @@ def expanduser(self):
.replace(os.path.sep, self.filesystem.path_separator))
def touch(self, mode=0o666, exist_ok=True):
"""Create a fake file for the path with the given access mode, if it doesn't exist.
"""Create a fake file for the path with the given access mode,
if it doesn't exist.
Args:
mode: the file mode for the file if it does not exist
@@ -73,6 +73,18 @@ def testPathlibPatch(self):
file_object = self.fs.get_object(file_path)
self.assertEqual('test', file_object.contents)
def testPathlibPathPatch(self):
from pathlib import Path
file_path = 'test.txt'
path = Path(file_path)
with path.open('w') as f:
f.write('test')
self.assertTrue(self.fs.exists(file_path))
file_object = self.fs.get_object(file_path)
self.assertEqual('test', file_object.contents)
if __name__ == "__main__":
unittest.main()
View
@@ -66,11 +66,11 @@ def create_file(path):
True
>>> with open('/test/file.txt') as f:
... f.readlines()
["This is test file '/test/file.txt'.\\n", 'It was created using the open() function.\\n']
["This is test file '/test/file.txt'.\\n", 'It was created using open().\\n']
"""
with open(path, 'w') as f:
f.write("This is test file '{0}'.\n".format(path))
f.write("It was created using the open() function.\n")
f.write("It was created using open().\n")
def delete_file(path):
@@ -134,7 +134,7 @@ def test_rmtree_non_existing_dir_with_handler(self):
class NonLocal:
pass
def error_handler(_, path, error_info):
def error_handler(_, path, _error_info):
NonLocal.errorHandled = True
NonLocal.errorPath = path
@@ -263,11 +263,13 @@ def test_add_real_file(self):
self.assertEqual(self.real_byte_contents, fake_file.byte_contents)
def test_add_real_directory(self):
'''Add a real directory and the contained files to the fake file system to be read on demand'''
'''Add a real directory and the contained files to the fake file system
to be read on demand'''
# this tests only the basic functionality inside a unit test, more thorough tests
# are done in fake_filesystem_test.RealFileSystemAccessTest
# Note: this test fails (add_real_directory raises) if 'genericpath' is not added to SKIPNAMES
# Note: this test fails (add_real_directory raises) if 'genericpath'
# is not added to SKIPNAMES
root_path = os.path.split(os.path.dirname(self.filepath))[0]
real_dir_path = os.path.join(root_path, 'pyfakefs')
self.fs.add_real_directory(real_dir_path)
@@ -27,29 +27,37 @@
from pyfakefs import fake_filesystem
def Sep(path):
def sep(path):
"""Converts slashes in the path to the architecture's path seperator."""
if isinstance(path, str):
return path.replace('/', os.sep)
return path
def _get_errno(raised_error):
if raised_error is not None:
try:
return raised_error.errno
except AttributeError:
pass
class TestCase(unittest.TestCase):
is_windows = sys.platform.startswith('win')
_FAKE_FS_BASE = Sep('/fakefs')
_FAKE_FS_BASE = sep('/fakefs')
class FakeFilesystemVsRealTest(TestCase):
def _Paths(self, path):
"""For a given path, return paths in the real and fake filesystems."""
if not path:
return (None, None)
return None, None
return (os.path.join(self.real_base, path),
os.path.join(self.fake_base, path))
def _CreateTestFile(self, file_type, path, contents=None):
"""Create a dir, file, or link in both the real fs and the fake."""
path = Sep(path)
path = sep(path)
self._created_files.append([file_type, path, contents])
real_path, fake_path = self._Paths(path)
if file_type == 'd':
@@ -137,14 +145,8 @@ def tearDown(self):
shutil.rmtree(self.real_base)
os.chdir(self.cwd)
def _GetErrno(self, raised_error):
try:
return (raised_error and raised_error.errno) or None
except AttributeError:
return None
def _CompareBehaviors(self, method_name, path, real, fake,
method_returns_path=False):
def _compare_behaviors(self, method_name, path, real, fake,
method_returns_path=False):
"""Invoke an os method in both real and fake contexts and compare results.
Invoke a real filesystem method with a path to a real file and invoke a fake
@@ -167,8 +169,8 @@ def _CompareBehaviors(self, method_name, path, real, fake,
"""
# pylint: disable=C6403
def _ErrorClass(e):
return (e and e.__class__.__name__) or 'None'
def _error_class(exc):
return (exc and exc.__class__.__name__) or 'None'
real_value = None
fake_value = None
@@ -195,26 +197,26 @@ def _ErrorClass(e):
fake_err = e
# We only compare on the error class because the acutal error contents
# is almost always different because of the file paths.
if _ErrorClass(real_err) != _ErrorClass(fake_err):
if _error_class(real_err) != _error_class(fake_err):
if real_err is None:
return '%s: real version returned %s, fake raised %s' % (
method_call, real_value, _ErrorClass(fake_err))
method_call, real_value, _error_class(fake_err))
if fake_err is None:
return '%s: real version raised %s, fake returned %s' % (
method_call, _ErrorClass(real_err), fake_value)
method_call, _error_class(real_err), fake_value)
return '%s: real version raised %s, fake raised %s' % (
method_call, _ErrorClass(real_err), _ErrorClass(fake_err))
real_errno = self._GetErrno(real_err)
fake_errno = self._GetErrno(fake_err)
method_call, _error_class(real_err), _error_class(fake_err))
real_errno = _get_errno(real_err)
fake_errno = _get_errno(fake_err)
if real_errno != fake_errno:
return '%s(%s): both raised %s, real errno %s, fake errno %s' % (
method_name, path, _ErrorClass(real_err), real_errno, fake_errno)
method_name, path, _error_class(real_err), real_errno, fake_errno)
# If the method is supposed to return a full path AND both values
# begin with the expected full path, then trim it off.
if method_returns_path:
if (real_value and fake_value
and real_value.startswith(self.real_base)
and fake_value.startswith(self.fake_base)):
and real_value.startswith(self.real_base)
and fake_value.startswith(self.fake_base)):
real_value = real_value[len(self.real_base):]
fake_value = fake_value[len(self.fake_base):]
if real_value != fake_value:
@@ -239,9 +241,9 @@ def assertOsMethodBehaviorMatches(self, method_name, path,
Returns:
A description of the difference in behavior, or None.
"""
path = Sep(path)
return self._CompareBehaviors(method_name, path, os, self.fake_os,
method_returns_path)
path = sep(path)
return self._compare_behaviors(method_name, path, os, self.fake_os,
method_returns_path)
def DiffOpenMethodBehavior(self, method_name, path, mode, data,
method_returns_data=True):
@@ -263,8 +265,8 @@ def DiffOpenMethodBehavior(self, method_name, path, mode, data,
"""
with open(path, mode) as real_fh:
with self.fake_open(path, mode) as fake_fh:
return self._CompareBehaviors(method_name, data, real_fh, fake_fh,
method_returns_data)
return self._compare_behaviors(method_name, data, real_fh, fake_fh,
method_returns_data)
def DiffOsPathMethodBehavior(self, method_name, path,
method_returns_path=False):
@@ -283,8 +285,8 @@ def DiffOsPathMethodBehavior(self, method_name, path,
Returns:
A description of the difference in behavior, or None.
"""
return self._CompareBehaviors(method_name, path, os.path, self.fake_os.path,
method_returns_path)
return self._compare_behaviors(method_name, path, os.path, self.fake_os.path,
method_returns_path)
def assertOsPathMethodBehaviorMatches(self, method_name, path,
method_returns_path=False):
@@ -302,13 +304,13 @@ def assertOsPathMethodBehaviorMatches(self, method_name, path,
Raises:
AssertionError if there is any difference in behavior.
"""
path = Sep(path)
path = sep(path)
diff = self.DiffOsPathMethodBehavior(method_name, path, method_returns_path)
if diff:
self.fail(diff)
def assertAllOsBehaviorsMatch(self, path):
path = Sep(path)
path = sep(path)
os_method_names = [] if self.is_windows else ['readlink']
os_method_names_no_args = ['getcwd']
if sys.version_info < (3, 0):
@@ -321,7 +323,7 @@ def assertAllOsBehaviorsMatch(self, path):
if not self.is_windows:
os_path_method_names.append('islink')
os_path_method_names.append('lexists')
wrapped_methods = [['access', self._AccessReal, self._AccessFake],
wrapped_methods = [['access', self._access_real, self._access_fake],
['stat.size', self._StatSizeReal, self._StatSizeFake],
['lstat.size', self._LstatSizeReal, self._LstatSizeFake]
]
@@ -341,15 +343,15 @@ def assertAllOsBehaviorsMatch(self, path):
if diff:
differences.append(diff)
for m in wrapped_methods:
diff = self._CompareBehaviors(m[0], path, m[1], m[2])
diff = self._compare_behaviors(m[0], path, m[1], m[2])
if diff:
differences.append(diff)
if differences:
self.fail('Behaviors do not match for %s:\n %s' %
(path, '\n '.join(differences)))
def assertFileHandleBehaviorsMatch(self, path, mode, data):
path = Sep(path)
path = sep(path)
write_method_names = ['write', 'writelines']
read_method_names = ['read', 'readlines']
other_method_names = ['truncate', 'flush', 'close']
@@ -365,12 +367,13 @@ def assertFileHandleBehaviorsMatch(self, path, mode, data):
if differences:
self.fail('Behaviors do not match for %s:\n %s' %
(path, '\n '.join(differences)))
# Helpers for checks which are not straight method calls.
def _AccessReal(self, path):
# Helpers for checks which are not straight method calls.
@staticmethod
def _access_real(path):
return os.access(path, os.R_OK)
def _AccessFake(self, path):
def _access_fake(self, path):
return self.fake_os.access(path, os.R_OK)
def _StatSizeReal(self, path):
@@ -597,7 +600,7 @@ def test_builtin_open_modes(self):
self.assertFileHandleBehaviorsMatch('append', 'ab', 'other contents')
def main(unused_argv):
def main(_):
unittest.main()
View
@@ -1442,4 +1442,4 @@ def test_that_drive_letters_are_preserved(self):
def test_that_unc_paths_are_preserved(self):
self.filesystem.is_windows_fs = True
self.assertEqual('!!foo!bar!baz',
self.filesystem.resolve_path('!!foo!bar!baz!!'))
self.filesystem.resolve_path('!!foo!bar!baz!!'))
@@ -56,7 +56,8 @@ def test_mkstemp(self):
next_fd = len(self.fs.open_files)
temporary = tempfile.mkstemp()
self.assertEqual(2, len(temporary))
self.assertTrue(temporary[1].startswith(os.path.join(tempfile.gettempdir(), 'tmp')))
self.assertTrue(
temporary[1].startswith(os.path.join(tempfile.gettempdir(), 'tmp')))
self.assertEqual(next_fd, temporary[0])
self.assertTrue(self.fs.exists(temporary[1]))
mode = 0o666 if self.fs.is_windows_fs else 0o600
Oops, something went wrong.

0 comments on commit 964239c

Please sign in to comment.