Your message dated Fri, 31 Dec 2021 07:18:37 +0000
with message-id <e1n3cbr-0006rz...@fasolo.debian.org>
and subject line Bug#1002352: fixed in python-ftputil 3.4-4
has caused the Debian Bug report #1002352,
regarding python-ftputil: FTBFS: dh_auto_test: error: pybuild --test 
--test-pytest -i python{version} -p "3.10 3.9" returned exit code 13
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
1002352: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1002352
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Source: python-ftputil
Version: 3.4-3
Severity: serious
Justification: FTBFS
Tags: bookworm sid ftbfs
User: lu...@debian.org
Usertags: ftbfs-20211220 ftbfs-bookworm

Hi,

During a rebuild of all packages in sid, your package failed to build
on amd64.


Relevant part (hopefully):
>  debian/rules build
> dh build --with python3 --buildsystem=pybuild
> dh: warning: Compatibility levels before 10 are deprecated (level 9 in use)
>    dh_update_autotools_config -O--buildsystem=pybuild
>    dh_auto_configure -O--buildsystem=pybuild
> dh_auto_configure: warning: Compatibility levels before 10 are deprecated 
> (level 9 in use)
> I: pybuild base:237: python3.10 setup.py config 
> /<<PKGBUILDDIR>>/setup.py:14: DeprecationWarning: The distutils package is 
> deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 
> 632 for potential alternatives
>   from distutils import core
> running config
> I: pybuild base:237: python3.9 setup.py config 
> running config
>    dh_auto_build -O--buildsystem=pybuild
> dh_auto_build: warning: Compatibility levels before 10 are deprecated (level 
> 9 in use)
> I: pybuild base:237: /usr/bin/python3.10 setup.py build 
> /<<PKGBUILDDIR>>/setup.py:14: DeprecationWarning: The distutils package is 
> deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 
> 632 for potential alternatives
>   from distutils import core
> running build
> running build_py
> creating /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/__init__.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/file_transfer.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/lrucache.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/session.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/stat.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/sync.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/compat.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/socket_file_adapter.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/path.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/file.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/host.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/stat_cache.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/session_adapter.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/version.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/error.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> copying ftputil/tool.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil
> I: pybuild base:237: /usr/bin/python3 setup.py build 
> running build
> running build_py
> creating /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/__init__.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/file_transfer.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/lrucache.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/session.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/stat.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/sync.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/compat.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/socket_file_adapter.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/path.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/file.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/host.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/stat_cache.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/session_adapter.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/version.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/error.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
> copying ftputil/tool.py -> 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil
>    dh_auto_test -O--buildsystem=pybuild
> dh_auto_test: warning: Compatibility levels before 10 are deprecated (level 9 
> in use)
> I: pybuild base:237: cd 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build; python3.10 -m pytest 
> test
> ============================= test session starts 
> ==============================
> platform linux -- Python 3.10.1, pytest-6.2.5, py-1.10.0, pluggy-0.13.0
> rootdir: /<<PKGBUILDDIR>>
> collected 129 items
> 
> test/test_error.py ......                                                [  
> 4%]
> test/test_file.py ..................                                     [ 
> 18%]
> test/test_file_transfer.py ....                                          [ 
> 21%]
> test/test_host.py .....F.FFF.F.FF.......F....FFFFF..                     [ 
> 48%]
> test/test_path.py FF..FF.F.FFF                                           [ 
> 57%]
> test/test_session.py ......                                              [ 
> 62%]
> test/test_stat.py ........F.FFFFFFFFFFFF                                 [ 
> 79%]
> test/test_stat_cache.py .........F                                       [ 
> 86%]
> test/test_sync.py ...                                                    [ 
> 89%]
> test/test_tool.py ........                                               [ 
> 95%]
> test/test_with_statement.py ......                                       
> [100%]
> 
> =================================== FAILURES 
> ===================================
> ________________________ TestSetParser.test_set_parser 
> _________________________
> 
> self = <test.test_host.TestSetParser object at 0x7ff6ae1fe8f0>
> 
>     def test_set_parser(self):
>         """Test if the selected parser is used."""
>         host = test_base.ftp_host_factory()
>         assert host._stat._allow_parser_switching is True
>         trivial_parser = TestSetParser.TrivialParser()
>         host.set_parser(trivial_parser)
> >       stat_result = host.stat("/home")
> 
> test/test_host.py:241: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae1fd450>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14c280>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> ___________ TestRecursiveListingForDotAsPath.test_recursive_listing 
> ____________
> 
> self = <test.test_host.TestRecursiveListingForDotAsPath object at 
> 0x7ff6ae0a5210>
> 
>     def test_recursive_listing(self):
>         host = test_base.ftp_host_factory(
>                  session_factory=RecursiveListingForDotAsPathSession)
> >       lines = host._dir(host.curdir)
> 
> test/test_host.py:271: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.test_host.RecursiveListingForDotAsPathSession object at 
> 0x7ff6ae0a61d0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14e680>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _____________ TestRecursiveListingForDotAsPath.test_plain_listing 
> ______________
> 
> self = <test.test_host.TestRecursiveListingForDotAsPath object at 
> 0x7ff6ae1d6170>
> 
>     def test_plain_listing(self):
>         host = test_base.ftp_host_factory(
>                  session_factory=RecursiveListingForDotAsPathSession)
> >       lines = host._dir("")
> 
> test/test_host.py:280: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.test_host.RecursiveListingForDotAsPathSession object at 
> 0x7ff6ae1d6ad0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14e050>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _ 
> TestRecursiveListingForDotAsPath.test_empty_string_instead_of_dot_workaround _
> 
> self = <test.test_host.TestRecursiveListingForDotAsPath object at 
> 0x7ff6ae160b80>
> 
>     def test_empty_string_instead_of_dot_workaround(self):
>         host = test_base.ftp_host_factory(
>                  session_factory=RecursiveListingForDotAsPathSession)
> >       files = host.listdir(host.curdir)
> 
> test/test_host.py:289: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/host.py:871: in listdir
>     items = self._stat._listdir(path)
> ftputil/stat.py:725: in _listdir
>     return self.__call_with_parser_retry(self._real_listdir, path)
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:585: in _real_listdir
>     for stat_result in self._stat_results_from_dir(path):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.test_host.RecursiveListingForDotAsPathSession object at 
> 0x7ff6ae161c30>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14e830>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> ________________ TestUploadAndDownload.test_conditional_upload 
> _________________
> 
> self = <test.test_host.TestUploadAndDownload object at 0x7ff6ae1ff9d0>
> 
>     def test_conditional_upload(self):
>         """Test conditional upload."""
>         local_source = "_test_source_"
>         data = binary_data()
>         self.generate_file(data, local_source)
>         # Target is newer, so don't upload.
>         host = test_base.ftp_host_factory(
>                  ftp_host_class=FailingUploadAndDownloadFTPHost)
> >       flag = host.upload_if_newer(local_source, "/home/newer")
> 
> test/test_host.py:325: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/host.py:508: in upload_if_newer
>     return ftputil.file_transfer.copy_file(source_file, target_file,
> ftputil/file_transfer.py:177: in copy_file
>     transfer_condition = not target_file.exists() or \
> ftputil/file_transfer.py:79: in exists
>     return self._path.exists(self.name)
> ftputil/path.py:63: in exists
>     lstat_result = self._host.lstat(
> ftputil/host.py:888: in lstat
>     return self._stat._lstat(path, _exception_for_missing_path)
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae6dce20>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14d900>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> ______ TestUploadAndDownload.test_conditional_download_with_older_target 
> _______
> 
> self = <test.test_host.TestUploadAndDownload object at 0x7ff6ae074850>
> 
>     def test_conditional_download_with_older_target(self):
>         """Test conditional binary mode download with newer source file."""
>         local_target = "_test_target_"
>         # Make target file.
>         open(local_target, "w").close()
>         # Source is newer (date in 2020), so download.
>         host = test_base.ftp_host_factory(
>                  session_factory=BinaryDownloadMockSession)
> >       flag = host.download_if_newer("/home/newer", local_target)
> 
> test/test_host.py:376: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/host.py:557: in download_if_newer
>     return ftputil.file_transfer.copy_file(source_file, target_file,
> ftputil/file_transfer.py:178: in copy_file
>     source_is_newer_than_target(source_file, target_file)
> ftputil/file_transfer.py:124: in source_is_newer_than_target
>     if source_file.mtime_precision() is ftputil.stat.UNKNOWN_PRECISION:
> ftputil/file_transfer.py:90: in mtime_precision
>     return self._host.stat(self.name)._st_mtime_precision
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.test_host.BinaryDownloadMockSession object at 0x7ff6ae0748e0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14c310>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> ______ TestUploadAndDownload.test_conditional_download_with_newer_target 
> _______
> 
> self = <test.test_host.TestUploadAndDownload object at 0x7ff6adfe8910>
> 
>     def test_conditional_download_with_newer_target(self):
>         """Test conditional binary mode download with older source file."""
>         local_target = "_test_target_"
>         # Make target file.
>         open(local_target, "w").close()
>         # Source is older (date in 1970), so don't download.
>         host = test_base.ftp_host_factory(
>                  ftp_host_class=FailingUploadAndDownloadFTPHost,
>                  session_factory=BinaryDownloadMockSession)
> >       flag = host.download_if_newer("/home/older", local_target)
> 
> test/test_host.py:389: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/host.py:557: in download_if_newer
>     return ftputil.file_transfer.copy_file(source_file, target_file,
> ftputil/file_transfer.py:178: in copy_file
>     source_is_newer_than_target(source_file, target_file)
> ftputil/file_transfer.py:124: in source_is_newer_than_target
>     if source_file.mtime_precision() is ftputil.stat.UNKNOWN_PRECISION:
> ftputil/file_transfer.py:90: in mtime_precision
>     return self._host.stat(self.name)._st_mtime_precision
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.test_host.BinaryDownloadMockSession object at 0x7ff6adfeb370>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14eb00>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _________________ TestAcceptEitherUnicodeOrBytes.test_listdir 
> __________________
> 
> self = <test.test_host.TestAcceptEitherUnicodeOrBytes object at 
> 0x7ff6ade864d0>
> 
>     def test_listdir(self):
>         """Test whether `listdir` accepts either unicode or bytes."""
>         host = self.host
>         as_bytes = ftputil.tool.as_bytes
>         host.chdir("/home/file_name_test")
>         # Unicode
> >       items = host.listdir("ä")
> 
> test/test_host.py:529: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/host.py:871: in listdir
>     items = self._stat._listdir(path)
> ftputil/stat.py:725: in _listdir
>     return self.__call_with_parser_retry(self._real_listdir, path)
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:579: in _real_listdir
>     if not self._path.isdir(path):
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ade859c0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14d480>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> __________________ TestAcceptEitherUnicodeOrBytes.test_rmdir 
> ___________________
> 
> self = <test.test_host.TestAcceptEitherUnicodeOrBytes object at 
> 0x7ff6ae0d30d0>
> 
>     def test_rmdir(self):
>         """Test whether `rmdir` accepts either unicode or bytes."""
>         empty_directory_as_required_by_rmdir = "/home/file_name_test/empty_ä"
> >       self._test_method_with_single_path_argument(
>           self.host.rmdir, empty_directory_as_required_by_rmdir)
> 
> test/test_host.py:575: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> test/test_host.py:552: in _test_method_with_single_path_argument
>     method(path)
> ftputil/host.py:707: in rmdir
>     if self.listdir(path):
> ftputil/host.py:871: in listdir
>     items = self._stat._listdir(path)
> ftputil/stat.py:725: in _listdir
>     return self.__call_with_parser_retry(self._real_listdir, path)
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:579: in _real_listdir
>     if not self._path.isdir(path):
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae0d1f30>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14ea70>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> __________________ TestAcceptEitherUnicodeOrBytes.test_remove 
> __________________
> 
> self = <test.test_host.TestAcceptEitherUnicodeOrBytes object at 
> 0x7ff6ae1fe110>
> 
>     def test_remove(self):
>         """Test whether `remove` accepts either unicode or bytes."""
> >       self._test_method_with_single_path_argument(
>           self.host.remove, "/home/file_name_test/ö")
> 
> test/test_host.py:580: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> test/test_host.py:552: in _test_method_with_single_path_argument
>     method(path)
> ftputil/host.py:730: in remove
>     if self.path.isfile(path) or self.path.islink(path) or \
> ftputil/path.py:177: in isfile
>     return self._is_file_system_entity(path, "file")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae1fdfc0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14e710>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> __________________ TestAcceptEitherUnicodeOrBytes.test_rmtree 
> __________________
> 
> self = <test.test_host.TestAcceptEitherUnicodeOrBytes object at 
> 0x7ff6ae113eb0>
> 
>     def test_rmtree(self):
>         """Test whether `rmtree` accepts either unicode or bytes."""
>         empty_directory_as_required_by_rmtree = "/home/file_name_test/empty_ä"
> >       self._test_method_with_single_path_argument(
>           self.host.rmtree, empty_directory_as_required_by_rmtree)
> 
> test/test_host.py:586: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> test/test_host.py:552: in _test_method_with_single_path_argument
>     method(path)
> ftputil/host.py:787: in rmtree
>     names = self.listdir(path)
> ftputil/host.py:871: in listdir
>     items = self._stat._listdir(path)
> ftputil/stat.py:725: in _listdir
>     return self.__call_with_parser_retry(self._real_listdir, path)
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:579: in _real_listdir
>     if not self._path.isdir(path):
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae1110c0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14db40>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> __________________ TestAcceptEitherUnicodeOrBytes.test_lstat 
> ___________________
> 
> self = <test.test_host.TestAcceptEitherUnicodeOrBytes object at 
> 0x7ff6ae0fc700>
> 
>     def test_lstat(self):
>         """Test whether `lstat` accepts either unicode or bytes."""
> >       self._test_method_with_single_path_argument(
>           self.host.lstat, "/home/file_name_test/ä")
> 
> test/test_host.py:591: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> test/test_host.py:552: in _test_method_with_single_path_argument
>     method(path)
> ftputil/host.py:888: in lstat
>     return self._stat._lstat(path, _exception_for_missing_path)
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae0fd690>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14d6c0>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> ___________________ TestAcceptEitherUnicodeOrBytes.test_stat 
> ___________________
> 
> self = <test.test_host.TestAcceptEitherUnicodeOrBytes object at 
> 0x7ff6adfeb340>
> 
>     def test_stat(self):
>         """Test whether `stat` accepts either unicode or bytes."""
> >       self._test_method_with_single_path_argument(
>           self.host.stat, "/home/file_name_test/ä")
> 
> test/test_host.py:596: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> test/test_host.py:552: in _test_method_with_single_path_argument
>     method(path)
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6adfea320>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14c670>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> __________________ TestPath.test_regular_isdir_isfile_islink 
> ___________________
> 
> self = <test.test_path.TestPath object at 0x7ff6ae6d48e0>
> 
>     def test_regular_isdir_isfile_islink(self):
>         """Test regular `FTPHost._Path.isdir/isfile/islink`."""
>         host = test_base.ftp_host_factory()
>         testdir = "/home/sschwarzer"
>         host.chdir(testdir)
>         # Test a path which isn't there.
> >       assert not host.path.isdir("notthere")
> 
> test/test_path.py:47: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae6d5720>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14eb00>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _____________________ TestPath.test_workaround_for_spaces 
> ______________________
> 
> self = <test.test_path.TestPath object at 0x7ff6ae6f6980>
> 
>     def test_workaround_for_spaces(self):
>         """Test whether the workaround for space-containing paths is used."""
>         host = test_base.ftp_host_factory()
>         testdir = "/home/sschwarzer"
>         host.chdir(testdir)
>         # Test a file name containing spaces.
>         testfile = "/home/dir with spaces/file with spaces"
> >       assert not host.path.isdir(testfile)
> 
> test/test_path.py:77: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae6f5a80>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14c310>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _____________ TestPath.test_isdir_isfile_with_infinite_link_chain 
> ______________
> 
> self = <test.test_path.TestPath object at 0x7ff6ade87c70>
> 
>     def test_isdir_isfile_with_infinite_link_chain(self):
>         """
>         Test if `isdir` and `isfile` return `False` if they encounter
>         an infinite link chain.
>         """
>         host = test_base.ftp_host_factory()
> >       assert host.path.isdir("/home/bad_link") is False
> 
> test/test_path.py:111: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ade845e0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14ed40>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _____________________________ TestPath.test_exists 
> _____________________________
> 
> self = <test.test_path.TestPath object at 0x7ff6ae0747c0>
> 
>     def test_exists(self):
>         """Test `FTPHost.path.exists`."""
>         # Regular use of `exists`
>         host = test_base.ftp_host_factory()
>         testdir = "/home/sschwarzer"
>         host.chdir(testdir)
> >       assert host.path.exists("index.html")
> 
> test/test_path.py:120: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/path.py:63: in exists
>     lstat_result = self._host.lstat(
> ftputil/host.py:888: in lstat
>     return self._stat._lstat(path, _exception_for_missing_path)
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae075240>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14eef0>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _ 
> TestAcceptEitherBytesOrUnicode.test_methods_that_take_a_string_and_return_a_bool
>  _
> 
> self = <test.test_path.TestAcceptEitherBytesOrUnicode object at 
> 0x7ff6adf3ebf0>
> 
>     def test_methods_that_take_a_string_and_return_a_bool(self):
>         """Test whether the methods accept byte and unicode strings."""
>         host = self.host
>         as_bytes = ftputil.tool.as_bytes
>         host.chdir("/home/file_name_test")
>         # `isabs`
>         assert not host.path.isabs("ä")
>         assert not host.path.isabs(as_bytes("ä"))
>         # `exists`
> >       assert host.path.exists("ä")
> 
> test/test_path.py:161: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/path.py:63: in exists
>     lstat_result = self._host.lstat(
> ftputil/host.py:888: in lstat
>     return self._stat._lstat(path, _exception_for_missing_path)
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6adf3c760>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14da20>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _________________ TestAcceptEitherBytesOrUnicode.test_getmtime 
> _________________
> 
> self = <test.test_path.TestAcceptEitherBytesOrUnicode object at 
> 0x7ff6ae6d4e20>
> 
>     def test_getmtime(self):
>         """
>         Test whether `FTPHost.path.getmtime` accepts byte and unicode
>         paths.
>         """
>         host = self.host
>         as_bytes = ftputil.tool.as_bytes
>         host.chdir("/home/file_name_test")
>         # We don't care about the _exact_ time, so don't bother with
>         # timezone differences. Instead, do a simple sanity check.
>         day = 24 * 60 * 60  # seconds
>         expected_mtime = time.mktime((2000, 5, 29, 0, 0, 0, 0, 0, 0))
>         mtime_makes_sense = (lambda mtime: expected_mtime - day <= mtime <=
>                                            expected_mtime + day)
> >       assert mtime_makes_sense(host.path.getmtime("ä"))
> 
> test/test_path.py:212: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/path.py:78: in getmtime
>     return self._host.stat(path).st_mtime
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae6d63b0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14e4d0>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _________________ TestAcceptEitherBytesOrUnicode.test_getsize 
> __________________
> 
> self = <test.test_path.TestAcceptEitherBytesOrUnicode object at 
> 0x7ff6ae261540>
> 
>     def test_getsize(self):
>         """
>         Test whether `FTPHost.path.getsize` accepts byte and unicode paths.
>         """
>         host = self.host
>         as_bytes = ftputil.tool.as_bytes
>         host.chdir("/home/file_name_test")
> >       assert host.path.getsize("ä") == 512
> 
> test/test_path.py:222: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/path.py:88: in getsize
>     return self._host.stat(path).st_size
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae263d60>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14ea70>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> ___________________ TestAcceptEitherBytesOrUnicode.test_walk 
> ___________________
> 
> self = <test.test_path.TestAcceptEitherBytesOrUnicode object at 
> 0x7ff6ae075000>
> 
>     def test_walk(self):
>         """Test whether `FTPHost.path.walk` accepts bytes and unicode 
> paths."""
>         host = self.host
>         as_bytes = ftputil.tool.as_bytes
>         def noop(arg, top, names):
>             del names[:]
> >       host.path.walk("ä", noop, None)
> 
> test/test_path.py:231: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/path.py:220: in walk
>     names = self._host.listdir(top)
> ftputil/host.py:871: in listdir
>     items = self._stat._listdir(path)
> ftputil/stat.py:725: in _listdir
>     return self.__call_with_parser_retry(self._real_listdir, path)
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:579: in _real_listdir
>     if not self._path.isdir(path):
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae074e20>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14d870>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _____________________ TestLstatAndStat.test_failing_lstat 
> ______________________
> 
> self = <test.test_stat.TestLstatAndStat object at 0x7ff6adef0670>
> 
>     def test_failing_lstat(self):
>         """Test whether `lstat` fails for a nonexistent path."""
>         with pytest.raises(ftputil.error.PermanentError):
> >           self.stat._lstat("/home/sschw/notthere")
> 
> test/test_stat.py:370: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6adef0fd0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14e560>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> __________________ TestLstatAndStat.test_lstat_one_unix_file 
> ___________________
> 
> self = <test.test_stat.TestLstatAndStat object at 0x7ff6ae163280>
> 
>     def test_lstat_one_unix_file(self):
>         """Test `lstat` for a file described in Unix-style format."""
> >       stat_result = self.stat._lstat("/home/sschwarzer/index.html")
> 
> test/test_stat.py:390: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae162ec0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14e3b0>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> ___________________ TestLstatAndStat.test_lstat_one_ms_file 
> ____________________
> 
> self = <test.test_stat.TestLstatAndStat object at 0x7ff6adf3af20>
> 
>     def test_lstat_one_ms_file(self):
>         """Test `lstat` for a file described in DOS-style format."""
>         self.stat = 
> _test_stat(session_factory=mock_ftplib.MockMSFormatSession)
> >       stat_result = self.stat._lstat("/home/msformat/abcd.exe")
> 
> test/test_stat.py:399: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockMSFormatSession object at 0x7ff6adf3a2f0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14e950>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> ___________________ TestLstatAndStat.test_lstat_one_unix_dir 
> ___________________
> 
> self = <test.test_stat.TestLstatAndStat object at 0x7ff6adfd9720>
> 
>     def test_lstat_one_unix_dir(self):
>         """Test `lstat` for a directory described in Unix-style format."""
> >       stat_result = self.stat._lstat("/home/sschwarzer/scios2")
> 
> test/test_stat.py:404: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6adfdae00>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14e440>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> ____________________ TestLstatAndStat.test_lstat_one_ms_dir 
> ____________________
> 
> self = <test.test_stat.TestLstatAndStat object at 0x7ff6ade83430>
> 
>     def test_lstat_one_ms_dir(self):
>         """Test `lstat` for a directory described in DOS-style format."""
>         self.stat = 
> _test_stat(session_factory=mock_ftplib.MockMSFormatSession)
> >       stat_result = self.stat._lstat("/home/msformat/WindowsXP")
> 
> test/test_stat.py:425: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockMSFormatSession object at 0x7ff6ade83e80>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14ee60>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _________________ TestLstatAndStat.test_lstat_via_stat_module 
> __________________
> 
> self = <test.test_stat.TestLstatAndStat object at 0x7ff6ae039930>
> 
>     def test_lstat_via_stat_module(self):
>         """Test `lstat` indirectly via `stat` module."""
> >       stat_result = self.stat._lstat("/home/sschwarzer/")
> 
> test/test_stat.py:430: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae03b1c0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14c280>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> __________________ TestLstatAndStat.test_stat_following_link 
> ___________________
> 
> self = <test.test_stat.TestLstatAndStat object at 0x7ff6ade82dd0>
> 
>     def test_stat_following_link(self):
>         """Test `stat` when invoked on a link."""
>         # Simple link
> >       stat_result = self.stat._stat("/home/link")
> 
> test/test_stat.py:436: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ade802e0>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14d5a0>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _________ TestLstatAndStat.test_parser_switching_with_permanent_error 
> __________
> 
> self = <test.test_stat.TestLstatAndStat object at 0x7ff6add91150>
> 
>     def test_parser_switching_with_permanent_error(self):
>         """Test non-switching of parser format with `PermanentError`."""
>         self.stat = 
> _test_stat(session_factory=mock_ftplib.MockMSFormatSession)
>         assert self.stat._allow_parser_switching is True
>         # With these directory contents, we get a `ParserError` for
>         # the Unix parser first, so `_allow_parser_switching` can be
>         # switched off no matter whether we got a `PermanentError`
>         # afterward or not.
>         with pytest.raises(ftputil.error.PermanentError):
> >           self.stat._lstat("/home/msformat/nonexistent")
> 
> test/test_stat.py:461: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockMSFormatSession object at 0x7ff6add90310>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14ea70>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> ____________ TestLstatAndStat.test_parser_switching_default_to_unix 
> ____________
> 
> self = <test.test_stat.TestLstatAndStat object at 0x7ff6adef2bf0>
> 
>     def test_parser_switching_default_to_unix(self):
>         """Test non-switching of parser format; stay with Unix."""
>         assert self.stat._allow_parser_switching is True
>         assert isinstance(self.stat._parser, ftputil.stat.UnixParser)
> >       stat_result = self.stat._lstat("/home/sschwarzer/index.html")
> 
> test/test_stat.py:468: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6adef2380>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14eb00>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _________________ TestLstatAndStat.test_parser_switching_to_ms 
> _________________
> 
> self = <test.test_stat.TestLstatAndStat object at 0x7ff6ae0d2410>
> 
>     def test_parser_switching_to_ms(self):
>         """Test switching of parser from Unix to MS format."""
>         self.stat = 
> _test_stat(session_factory=mock_ftplib.MockMSFormatSession)
>         assert self.stat._allow_parser_switching is True
>         assert isinstance(self.stat._parser, ftputil.stat.UnixParser)
>         # Parsing the directory `/home/msformat` with the Unix parser
>         # fails, so switch to the MS parser.
> >       stat_result = self.stat._lstat("/home/msformat/abcd.exe")
> 
> test/test_stat.py:480: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:735: in _lstat
>     return self.__call_with_parser_retry(self._real_lstat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockMSFormatSession object at 0x7ff6ae0d3490>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14e5f0>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> __________ TestLstatAndStat.test_parser_switching_regarding_empty_dir 
> __________
> 
> self = <test.test_stat.TestLstatAndStat object at 0x7ff6ae0a5630>
> 
>     def test_parser_switching_regarding_empty_dir(self):
>         """Test switching of parser if a directory is empty."""
>         self.stat = 
> _test_stat(session_factory=mock_ftplib.MockMSFormatSession)
>         assert self.stat._allow_parser_switching is True
>         # When the directory we're looking into doesn't give us any
>         # lines we can't decide whether the first parser worked,
>         # because it wasn't applied. So keep the parser for now.
> >       result = self.stat._listdir("/home/msformat/XPLaunch/empty")
> 
> test/test_stat.py:493: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:725: in _listdir
>     return self.__call_with_parser_retry(self._real_listdir, path)
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:579: in _real_listdir
>     if not self._path.isdir(path):
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:620: in _real_lstat
>     if not self._path.isdir(dirname) and not _exception_for_missing_path:
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockMSFormatSession object at 0x7ff6ae0a4100>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14d870>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _______________________ TestListdir.test_failing_listdir 
> _______________________
> 
> self = <test.test_stat.TestListdir object at 0x7ff6ae1d6230>
> 
>     def test_failing_listdir(self):
>         """Test failing `FTPHost.listdir`."""
>         with pytest.raises(ftputil.error.PermanentError):
> >           self.stat._listdir("notthere")
> 
> test/test_stat.py:509: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:725: in _listdir
>     return self.__call_with_parser_retry(self._real_listdir, path)
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:579: in _real_listdir
>     if not self._path.isdir(path):
> ftputil/path.py:168: in isdir
>     return self._is_file_system_entity(path, "dir")
> ftputil/path.py:148: in _is_file_system_entity
>     stat_result = self._host.stat(
> ftputil/host.py:904: in stat
>     return self._stat._stat(path, _exception_for_missing_path)
> ftputil/stat.py:746: in _stat
>     return self.__call_with_parser_retry(self._real_stat, path,
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:668: in _real_stat
>     lstat_result = self._real_lstat(path, _exception_for_missing_path)
> ftputil/stat.py:627: in _real_lstat
>     for stat_result in self._stat_results_from_dir(dirname):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae1d4d60>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14d990>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> _____________________ TestListdir.test_succeeding_listdir 
> ______________________
> 
> self = <test.test_stat.TestListdir object at 0x7ff6ae6d5d50>
> 
>     def test_succeeding_listdir(self):
>         """Test succeeding `FTPHost.listdir`."""
>         # Do we have all expected "files"?
> >       assert len(self.stat._listdir(".")) == 9
> 
> test/test_stat.py:514: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/stat.py:725: in _listdir
>     return self.__call_with_parser_retry(self._real_listdir, path)
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:585: in _real_listdir
>     for stat_result in self._stat_results_from_dir(path):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6ae6d6890>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14e0e0>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> ______________________ TestStatCache.test_cache_size_zero 
> ______________________
> 
> self = <test.test_stat_cache.TestStatCache object at 0x7ff6add7c190>
> 
>     def test_cache_size_zero(self):
>         host = test_base.ftp_host_factory()
>         with pytest.raises(ValueError):
>             host.stat_cache.resize(0)
>         # If bug #38 was present, this raised an `IndexError`.
> >       items = host.listdir(host.curdir)
> 
> test/test_stat_cache.py:102: 
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> ftputil/host.py:871: in listdir
>     items = self._stat._listdir(path)
> ftputil/stat.py:725: in _listdir
>     return self.__call_with_parser_retry(self._real_listdir, path)
> ftputil/stat.py:701: in __call_with_parser_retry
>     result = method(*args, **kwargs)
> ftputil/stat.py:585: in _real_listdir
>     for stat_result in self._stat_results_from_dir(path):
> ftputil/stat.py:541: in _stat_results_from_dir
>     lines = self._host_dir(path)
> ftputil/stat.py:533: in _host_dir
>     return self._host._dir(path)
> ftputil/host.py:854: in _dir
>     lines = self._robust_ftp_command(_FTPHost_dir_command, path,
> ftputil/host.py:608: in _robust_ftp_command
>     return command(self, "")
> ftputil/host.py:848: in _FTPHost_dir_command
>     with ftputil.error.ftplib_error_to_ftp_os_error:
> ftputil/host.py:850: in _FTPHost_dir_command
>     self._session.dir("-a", path, callback)
> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> _ 
> 
> self = <test.mock_ftplib.MockUnixFormatSession object at 0x7ff6add7c070>
> args = ('-a', '', <function 
> FTPHost._dir.<locals>._FTPHost_dir_command.<locals>.callback at 
> 0x7ff6ae14ef80>)
> 
>     def dir(self, *args):
>         """
>         Provide a callback function for processing each line of a
>         directory listing. Return nothing.
>         """
>         # The callback comes last in `ftplib.FTP.dir`.
> >       if isinstance(args[-1], collections.Callable):
> E       AttributeError: module 'collections' has no attribute 'Callable'
> 
> test/mock_ftplib.py:157: AttributeError
> =============================== warnings summary 
> ===============================
> .pybuild/cpython3_3.10_ftputil/build/test/test_file.py: 18 warnings
> .pybuild/cpython3_3.10_ftputil/build/test/test_host.py: 32 warnings
> .pybuild/cpython3_3.10_ftputil/build/test/test_path.py: 12 warnings
> .pybuild/cpython3_3.10_ftputil/build/test/test_stat.py: 26 warnings
> .pybuild/cpython3_3.10_ftputil/build/test/test_stat_cache.py: 1 warning
> .pybuild/cpython3_3.10_ftputil/build/test/test_with_statement.py: 5 warnings
>   /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/test/test_base.py:16: 
> DeprecationWarning: `use_list_a_option` will default to `False` in ftputil 
> 4.x.x
>     return ftp_host_class("dummy_host", "dummy_user", "dummy_password",
> 
> .pybuild/cpython3_3.10_ftputil/build/test/test_file.py: 23 warnings
> .pybuild/cpython3_3.10_ftputil/build/test/test_host.py: 5 warnings
> .pybuild/cpython3_3.10_ftputil/build/test/test_with_statement.py: 3 warnings
>   /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/ftputil/host.py:148: 
> DeprecationWarning: `use_list_a_option` will default to `False` in ftputil 
> 4.x.x
>     return self.__class__(*self._args, **self._kwargs)
> 
> .pybuild/cpython3_3.10_ftputil/build/test/test_host.py::TestTimeShift::test_synchronize_times
> .pybuild/cpython3_3.10_ftputil/build/test/test_host.py::TestTimeShift::test_synchronize_times
> .pybuild/cpython3_3.10_ftputil/build/test/test_host.py::TestTimeShift::test_synchronize_times_for_server_in_east
> .pybuild/cpython3_3.10_ftputil/build/test/test_host.py::TestTimeShift::test_synchronize_times_for_server_in_east
>   
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/test/test_host.py:165: 
> DeprecationWarning: `use_list_a_option` will default to `False` in ftputil 
> 4.x.x
>     ftputil.FTPHost.__init__(self, *args, **kwargs)
> 
> .pybuild/cpython3_3.10_ftputil/build/test/test_sync.py::TestUploadFromWindows::test_no_mixed_separators
>   
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build/test/test_sync.py:104: 
> DeprecationWarning: `use_list_a_option` will default to `False` in ftputil 
> 4.x.x
>     super(ArgumentCheckingFTPHost, self).__init__(*args, **kwargs)
> 
> -- Docs: https://docs.pytest.org/en/stable/warnings.html
> =========================== short test summary info 
> ============================
> FAILED test/test_host.py::TestSetParser::test_set_parser - AttributeError: 
> mo...
> FAILED 
> test/test_host.py::TestRecursiveListingForDotAsPath::test_recursive_listing
> FAILED test/test_host.py::TestRecursiveListingForDotAsPath::test_plain_listing
> FAILED 
> test/test_host.py::TestRecursiveListingForDotAsPath::test_empty_string_instead_of_dot_workaround
> FAILED test/test_host.py::TestUploadAndDownload::test_conditional_upload - 
> At...
> FAILED 
> test/test_host.py::TestUploadAndDownload::test_conditional_download_with_older_target
> FAILED 
> test/test_host.py::TestUploadAndDownload::test_conditional_download_with_newer_target
> FAILED test/test_host.py::TestAcceptEitherUnicodeOrBytes::test_listdir - 
> Attr...
> FAILED test/test_host.py::TestAcceptEitherUnicodeOrBytes::test_rmdir - 
> Attrib...
> FAILED test/test_host.py::TestAcceptEitherUnicodeOrBytes::test_remove - 
> Attri...
> FAILED test/test_host.py::TestAcceptEitherUnicodeOrBytes::test_rmtree - 
> Attri...
> FAILED test/test_host.py::TestAcceptEitherUnicodeOrBytes::test_lstat - 
> Attrib...
> FAILED test/test_host.py::TestAcceptEitherUnicodeOrBytes::test_stat - 
> Attribu...
> FAILED test/test_path.py::TestPath::test_regular_isdir_isfile_islink - 
> Attrib...
> FAILED test/test_path.py::TestPath::test_workaround_for_spaces - 
> AttributeErr...
> FAILED test/test_path.py::TestPath::test_isdir_isfile_with_infinite_link_chain
> FAILED test/test_path.py::TestPath::test_exists - AttributeError: module 
> 'col...
> FAILED 
> test/test_path.py::TestAcceptEitherBytesOrUnicode::test_methods_that_take_a_string_and_return_a_bool
> FAILED test/test_path.py::TestAcceptEitherBytesOrUnicode::test_getmtime - 
> Att...
> FAILED test/test_path.py::TestAcceptEitherBytesOrUnicode::test_getsize - 
> Attr...
> FAILED test/test_path.py::TestAcceptEitherBytesOrUnicode::test_walk - 
> Attribu...
> FAILED test/test_stat.py::TestLstatAndStat::test_failing_lstat - 
> AttributeErr...
> FAILED test/test_stat.py::TestLstatAndStat::test_lstat_one_unix_file - 
> Attrib...
> FAILED test/test_stat.py::TestLstatAndStat::test_lstat_one_ms_file - 
> Attribut...
> FAILED test/test_stat.py::TestLstatAndStat::test_lstat_one_unix_dir - 
> Attribu...
> FAILED test/test_stat.py::TestLstatAndStat::test_lstat_one_ms_dir - 
> Attribute...
> FAILED test/test_stat.py::TestLstatAndStat::test_lstat_via_stat_module - 
> Attr...
> FAILED test/test_stat.py::TestLstatAndStat::test_stat_following_link - 
> Attrib...
> FAILED 
> test/test_stat.py::TestLstatAndStat::test_parser_switching_with_permanent_error
> FAILED 
> test/test_stat.py::TestLstatAndStat::test_parser_switching_default_to_unix
> FAILED test/test_stat.py::TestLstatAndStat::test_parser_switching_to_ms - 
> Att...
> FAILED 
> test/test_stat.py::TestLstatAndStat::test_parser_switching_regarding_empty_dir
> FAILED test/test_stat.py::TestListdir::test_failing_listdir - 
> AttributeError:...
> FAILED test/test_stat.py::TestListdir::test_succeeding_listdir - 
> AttributeErr...
> FAILED test/test_stat_cache.py::TestStatCache::test_cache_size_zero - 
> Attribu...
> ================= 35 failed, 94 passed, 130 warnings in 4.27s 
> ==================
> E: pybuild pybuild:355: test: plugin distutils failed with: exit code=1: cd 
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.10_ftputil/build; python3.10 -m pytest 
> test
> I: pybuild base:237: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build; 
> python3.9 -m pytest test
> ============================= test session starts 
> ==============================
> platform linux -- Python 3.9.9, pytest-6.2.5, py-1.10.0, pluggy-0.13.0
> rootdir: /<<PKGBUILDDIR>>
> collected 129 items
> 
> test/test_error.py ......                                                [  
> 4%]
> test/test_file.py ..................                                     [ 
> 18%]
> test/test_file_transfer.py ....                                          [ 
> 21%]
> test/test_host.py ..................................                     [ 
> 48%]
> test/test_path.py ............                                           [ 
> 57%]
> test/test_session.py ......                                              [ 
> 62%]
> test/test_stat.py ......................                                 [ 
> 79%]
> test/test_stat_cache.py ..........                                       [ 
> 86%]
> test/test_sync.py ...                                                    [ 
> 89%]
> test/test_tool.py ........                                               [ 
> 95%]
> test/test_with_statement.py ......                                       
> [100%]
> 
> =============================== warnings summary 
> ===============================
> .pybuild/cpython3_3.9_ftputil/build/test/test_file.py: 18 warnings
> .pybuild/cpython3_3.9_ftputil/build/test/test_host.py: 34 warnings
> .pybuild/cpython3_3.9_ftputil/build/test/test_path.py: 13 warnings
> .pybuild/cpython3_3.9_ftputil/build/test/test_stat.py: 26 warnings
> .pybuild/cpython3_3.9_ftputil/build/test/test_stat_cache.py: 1 warning
> .pybuild/cpython3_3.9_ftputil/build/test/test_with_statement.py: 5 warnings
>   /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/test/test_base.py:16: 
> DeprecationWarning: `use_list_a_option` will default to `False` in ftputil 
> 4.x.x
>     return ftp_host_class("dummy_host", "dummy_user", "dummy_password",
> 
> .pybuild/cpython3_3.9_ftputil/build/test/test_file.py: 23 warnings
> .pybuild/cpython3_3.9_ftputil/build/test/test_host.py: 8 warnings
> .pybuild/cpython3_3.9_ftputil/build/test/test_with_statement.py: 3 warnings
>   /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/ftputil/host.py:148: 
> DeprecationWarning: `use_list_a_option` will default to `False` in ftputil 
> 4.x.x
>     return self.__class__(*self._args, **self._kwargs)
> 
> .pybuild/cpython3_3.9_ftputil/build/test/test_host.py::TestSetParser::test_set_parser
>   
> /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/test/mock_ftplib.py:157: 
> DeprecationWarning: Using or importing the ABCs from 'collections' instead of 
> from 'collections.abc' is deprecated since Python 3.3, and in 3.10 it will 
> stop working
>     if isinstance(args[-1], collections.Callable):
> 
> .pybuild/cpython3_3.9_ftputil/build/test/test_host.py::TestTimeShift::test_synchronize_times
> .pybuild/cpython3_3.9_ftputil/build/test/test_host.py::TestTimeShift::test_synchronize_times
> .pybuild/cpython3_3.9_ftputil/build/test/test_host.py::TestTimeShift::test_synchronize_times_for_server_in_east
> .pybuild/cpython3_3.9_ftputil/build/test/test_host.py::TestTimeShift::test_synchronize_times_for_server_in_east
>   /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/test/test_host.py:165: 
> DeprecationWarning: `use_list_a_option` will default to `False` in ftputil 
> 4.x.x
>     ftputil.FTPHost.__init__(self, *args, **kwargs)
> 
> .pybuild/cpython3_3.9_ftputil/build/test/test_sync.py::TestUploadFromWindows::test_no_mixed_separators
>   /<<PKGBUILDDIR>>/.pybuild/cpython3_3.9_ftputil/build/test/test_sync.py:104: 
> DeprecationWarning: `use_list_a_option` will default to `False` in ftputil 
> 4.x.x
>     super(ArgumentCheckingFTPHost, self).__init__(*args, **kwargs)
> 
> -- Docs: https://docs.pytest.org/en/stable/warnings.html
> ====================== 129 passed, 137 warnings in 2.51s 
> =======================
> dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p "3.10 
> 3.9" returned exit code 13


The full build log is available from:
http://qa-logs.debian.net/2021/12/20/python-ftputil_3.4-3_unstable.log

A list of current common problems and possible solutions is available at
http://wiki.debian.org/qa.debian.org/FTBFS . You're welcome to contribute!

If you reassign this bug to another package, please marking it as 'affects'-ing
this package. See https://www.debian.org/Bugs/server-control#affects

If you fail to reproduce this, please provide a build log and diff it with mine
so that we can identify if something relevant changed in the meantime.

--- End Message ---
--- Begin Message ---
Source: python-ftputil
Source-Version: 3.4-4
Done: Ondřej Nový <on...@debian.org>

We believe that the bug you reported is fixed in the latest version of
python-ftputil, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to 1002...@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Ondřej Nový <on...@debian.org> (supplier of updated python-ftputil package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmas...@ftp-master.debian.org)


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Format: 1.8
Date: Thu, 24 Sep 2020 08:44:03 +0200
Source: python-ftputil
Binary: python3-ftputil
Architecture: source all
Version: 3.4-4
Distribution: unstable
Urgency: medium
Maintainer: Debian Python Team <team+pyt...@tracker.debian.org>
Changed-By: Ondřej Nový <on...@debian.org>
Description:
 python3-ftputil - high-level FTP client library for Python
Closes: 1002352
Changes:
 python-ftputil (3.4-4) unstable; urgency=medium
 .
   [ Olivier Sallou]
   * fix autotests, switching collections.Callable to collections.abc.Callable
    (Closes: #1002352).
 .
   [ Ondřej Nový]
   * d/control: Update Maintainer field with new Debian Python Team
     contact address.
   * d/control: Update Vcs-* fields with new Debian Python Team Salsa
     layout.
 .
   [ Debian Janitor ]
   * Bump debhelper from deprecated 9 to 12.
Checksums-Sha1:
 9408abf6d57eb30bc449ccc525c617bcc7085bb9 2100 python-ftputil_3.4-4.dsc
 50f5bdcbbb7b5f76d819364cf3c95f9e815e63ee 15540 
python-ftputil_3.4-4.debian.tar.xz
 b05b7f228c2244a01ac698747634d281164a03e3 6778 
python-ftputil_3.4-4_amd64.buildinfo
 abb0e5905af83640c949a761ac6ca5767fb61f6f 105104 python3-ftputil_3.4-4_all.deb
Checksums-Sha256:
 e1dc6a5ef6634b76a98e2f603b1988a65f9f14f0b8c31b1a776448d8b2e33a4f 2100 
python-ftputil_3.4-4.dsc
 354f44f77d8fb178018e89c5e4a3cb0ed0f040e7a49eb493bfc4d32c9e57ddd6 15540 
python-ftputil_3.4-4.debian.tar.xz
 d8b0d80a5ae38a210aabde53a5db853c27d01354ae08102ef542d326c08b643b 6778 
python-ftputil_3.4-4_amd64.buildinfo
 99b66d7fd16e9c9665048c3432c6348595c10369f2025c2e3d53bd878934492e 105104 
python3-ftputil_3.4-4_all.deb
Files:
 0376bf008b4c7c393daf783f71fabae0 2100 python optional python-ftputil_3.4-4.dsc
 085e811734718fb5214dc8c3051b882c 15540 python optional 
python-ftputil_3.4-4.debian.tar.xz
 02869688abbecf625ca69d1db2f7553f 6778 python optional 
python-ftputil_3.4-4_amd64.buildinfo
 861bf3b1110002ace8640440649b1a9b 105104 python optional 
python3-ftputil_3.4-4_all.deb

-----BEGIN PGP SIGNATURE-----

iQJHBAEBCAAxFiEEX7Rvg9O5UgRjNdJteNxo2zJthDgFAmHOqFQTHG9zYWxsb3VA
ZGViaWFuLm9yZwAKCRB43GjbMm2EOBRdEACMeytLtrpFhRGj6sgJ3AUVrbCCWPNJ
pGfPZ3lhLhHUkn370URtZPML9TBVEFDZQ4T9d1EfrreipGePOnjxm6OKTiOtC6JT
4iGsgij7Li6UycI7nLPuz8yG+vuumRSbfBw4V5ANpOBwOc+lo0nuzbcC6GXOMIe/
cUXLonud0Pp6EKEO3blol2NmuyeuLMUtVIl2iEH504dTlqqRemNNLQ9nkFRZzBXq
Oxd+E7ZHFfusyfApkOGEBsushswz1p+fjy4ncIhcvHgLz9OGba9MMRADOwMUmc3C
YIGD6KCCvQuLF0k1zadZNZvysEoOUQ4/S1kDuQ7QyaoUGhI2k/XZ/wQsoaU4eM/D
mlk8HD37LmKJuI7nslNgwhO/y7fPlGZY5caSoCylovSq7cd8QqflEUuX5Ya3avd7
ZkKgSN3O2z7Ir0LPTOxsTwI2aGetCc9Ur1mhwUlDBZT47qFULTqPW993lNmkmmJF
y58ksP0sTZLhLSdyb9eyRig56OSAEqSiZMTMuab1oZxZu3eb9UVecNtwqBxqQdDE
X47wU9a1xJLy8vtRJebePOD8FHhwSG2dbY0z4mP4dmFxUHd+/g3Qwmbu76KQcqEg
feW4exGeDUgxUcN3So5IBAU6MHLcxj8hfIgu73SR8TRFhaC+A/R8R9HgmAVEFKDj
wPsrR69lp5Faog==
=01id
-----END PGP SIGNATURE-----

--- End Message ---

Reply via email to