commit 4164c7a6203fae6671075dfba69461340dd05bc5 Author: Damian Johnson atagar@torproject.org Date: Tue Sep 1 13:57:23 2020 -0700
Replace all IOErrors with OSErrors
PEP 3151 deprecated IOError...
https://www.python.org/dev/peps/pep-3151/#confusing-set-of-os-related-except...
Python 3.3 turned IOError into an OSError alias, so this commit shouldn't impact our users...
>>> raise OSError('boom') Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: boom
>>> raise IOError('boom') Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: boom --- cache_fallback_directories.py | 2 +- cache_manual.py | 4 +- docs/_static/example/check_digests.py | 2 +- docs/_static/example/manual_config_options.py | 2 +- docs/_static/example/reading_twitter.py | 4 +- docs/change_log.rst | 1 + stem/__init__.py | 2 +- stem/connection.py | 2 +- stem/descriptor/__init__.py | 10 ++--- stem/descriptor/bandwidth_file.py | 2 +- stem/descriptor/collector.py | 8 ++-- stem/descriptor/extrainfo_descriptor.py | 2 +- stem/descriptor/hidden_service.py | 2 +- stem/descriptor/microdescriptor.py | 2 +- stem/descriptor/networkstatus.py | 6 +-- stem/descriptor/router_status_entry.py | 2 +- stem/descriptor/server_descriptor.py | 2 +- stem/descriptor/tordnsel.py | 2 +- stem/directory.py | 18 ++++---- stem/interpreter/__init__.py | 2 +- stem/manual.py | 26 +++++------ stem/util/conf.py | 8 ++-- stem/util/connection.py | 12 +++--- stem/util/proc.py | 62 +++++++++++++-------------- stem/util/system.py | 16 +++---- stem/version.py | 12 +++--- test/integ/util/connection.py | 2 +- test/integ/version.py | 4 +- test/unit/descriptor/collector.py | 8 ++-- test/unit/directory/fallback.py | 6 +-- test/unit/manual.py | 12 +++--- test/unit/util/connection.py | 48 ++++++++++----------- test/unit/util/proc.py | 4 +- test/unit/util/system.py | 4 +- test/unit/version.py | 4 +- 35 files changed, 153 insertions(+), 152 deletions(-)
diff --git a/cache_fallback_directories.py b/cache_fallback_directories.py index 7f712683..8fe425d1 100755 --- a/cache_fallback_directories.py +++ b/cache_fallback_directories.py @@ -26,7 +26,7 @@ if __name__ == '__main__':
try: stem_commit = stem.util.system.call('git rev-parse HEAD')[0] - except IOError as exc: + except OSError as exc: print("Unable to determine stem's current commit: %s" % exc) sys.exit(1)
diff --git a/cache_manual.py b/cache_manual.py index 803197f1..4ddb843f 100755 --- a/cache_manual.py +++ b/cache_manual.py @@ -26,7 +26,7 @@ if __name__ == '__main__':
try: stem_commit = stem.util.system.call('git rev-parse HEAD')[0] - except IOError as exc: + except OSError as exc: print("Unable to determine stem's current commit: %s" % exc) sys.exit(1)
@@ -39,7 +39,7 @@ if __name__ == '__main__': db_schema = cached_manual.schema except stem.manual.SchemaMismatch as exc: cached_manual, db_schema = None, exc.database_schema - except IOError: + except OSError: cached_manual, db_schema = None, None # local copy has been deleted
if db_schema != stem.manual.SCHEMA_VERSION: diff --git a/docs/_static/example/check_digests.py b/docs/_static/example/check_digests.py index 2be3c368..69f509cf 100644 --- a/docs/_static/example/check_digests.py +++ b/docs/_static/example/check_digests.py @@ -19,7 +19,7 @@ def download_descriptors(fingerprint): router_status_entries = filter(lambda desc: desc.fingerprint == fingerprint, conensus_query.run())
if len(router_status_entries) != 1: - raise IOError("Unable to find relay '%s' in the consensus" % fingerprint) + raise OSError("Unable to find relay '%s' in the consensus" % fingerprint)
return ( router_status_entries[0], diff --git a/docs/_static/example/manual_config_options.py b/docs/_static/example/manual_config_options.py index 964ff523..4a503579 100644 --- a/docs/_static/example/manual_config_options.py +++ b/docs/_static/example/manual_config_options.py @@ -5,7 +5,7 @@ try: print("Downloading tor's manual information, please wait...") manual = Manual.from_remote() print(" done\n") -except IOError as exc: +except OSError as exc: print(" unsuccessful (%s), using information provided with stem\n" % exc) manual = Manual.from_cache() # fall back to our bundled manual information
diff --git a/docs/_static/example/reading_twitter.py b/docs/_static/example/reading_twitter.py index 7f9094b3..5709e1f4 100644 --- a/docs/_static/example/reading_twitter.py +++ b/docs/_static/example/reading_twitter.py @@ -65,7 +65,7 @@ def poll_twitter_feed(user_id, tweet_count): try: api_response = urllib2.urlopen(api_request).read() except: - raise IOError("Unable to reach %s" % TWITTER_API_URL) + raise OSError("Unable to reach %s" % TWITTER_API_URL)
return json.loads(api_response)
@@ -81,7 +81,7 @@ try: print("%i. %s" % (index + 1, tweet["created_at"])) print(tweet["text"]) print("") -except IOError as exc: +except OSError as exc: print(exc) finally: tor_process.kill() # stops tor diff --git a/docs/change_log.rst b/docs/change_log.rst index f5a96d7b..bbd13ef5 100644 --- a/docs/change_log.rst +++ b/docs/change_log.rst @@ -54,6 +54,7 @@ The following are only available within Stem's `git repository * Migrated to `asyncio https://docs.python.org/3/library/asyncio.html`_. Stem can now be used by `both synchronous and asynchronous applications https://blog.atagar.com/july2020/`_. * Installation has migrated from distutils to setuptools. * Added the 'reset_timeouts' argument to :func:`~stem.control.Controller.drop_guards` (:ticket:`73`) + * Replace all IOErrors with OSErrors. Python 3.3 changed IOError into an `OSError alias https://docs.python.org/3/library/exceptions.html#OSError`_ to `deprecate it https://www.python.org/dev/peps/pep-3151/#confusing-set-of-os-related-exceptions`_.
* **Controller**
diff --git a/stem/__init__.py b/stem/__init__.py index 228ec7be..e8782115 100644 --- a/stem/__init__.py +++ b/stem/__init__.py @@ -731,7 +731,7 @@ class SocketClosed(SocketError): 'Control socket was closed before completing the message.'
-class DownloadFailed(IOError): +class DownloadFailed(OSError): """ Inability to download a resource. Python's urllib module raises a wide variety of undocumented exceptions (urllib.request.URLError, diff --git a/stem/connection.py b/stem/connection.py index 0dbbcfbf..f5f92464 100644 --- a/stem/connection.py +++ b/stem/connection.py @@ -1157,7 +1157,7 @@ def _read_cookie(cookie_path: str, is_safecookie: bool) -> bytes: try: with open(cookie_path, 'rb', 0) as f: return f.read() - except IOError as exc: + except OSError as exc: exc_msg = "Authentication failed: unable to read '%s' (%s)" % (cookie_path, exc) raise UnreadableCookieFile(exc_msg, cookie_path, is_safecookie)
diff --git a/stem/descriptor/__init__.py b/stem/descriptor/__init__.py index df947cf7..58a88d55 100644 --- a/stem/descriptor/__init__.py +++ b/stem/descriptor/__init__.py @@ -238,7 +238,7 @@ class _Compression(object): :raises: If unable to decompress this provide...
- * **IOError** if content isn't compressed with this + * **OSError** if content isn't compressed with this * **ImportError** if this method if decompression is unavalable """
@@ -253,7 +253,7 @@ class _Compression(object): try: return self._decompression_func(self._module, content) except Exception as exc: - raise IOError('Failed to decompress as %s: %s' % (self, exc)) + raise OSError('Failed to decompress as %s: %s' % (self, exc))
def __str__(self) -> str: return self._name @@ -370,7 +370,7 @@ def parse_file(descriptor_file: Union[str, BinaryIO, tarfile.TarFile, IO[bytes]] :raises: * **ValueError** if the contents is malformed and validate is True * **TypeError** if we can't match the contents of the file to a descriptor type - * **IOError** if unable to read from the descriptor_file + * **OSError** if unable to read from the descriptor_file """
# Delegate to a helper if this is a path or tarfile. @@ -392,7 +392,7 @@ def parse_file(descriptor_file: Union[str, BinaryIO, tarfile.TarFile, IO[bytes]] return
if not descriptor_file.seekable(): # type: ignore - raise IOError(UNSEEKABLE_MSG) + raise OSError(UNSEEKABLE_MSG)
# The tor descriptor specifications do not provide a reliable method for # identifying a descriptor file's type and version so we need to guess @@ -860,7 +860,7 @@ class Descriptor(object): :raises: * **ValueError** if the contents is malformed and validate is True * **TypeError** if we can't match the contents of the file to a descriptor type - * **IOError** if unable to read from the descriptor_file + * **OSError** if unable to read from the descriptor_file """
if 'descriptor_type' not in kwargs and cls.TYPE_ANNOTATION_NAME is not None: diff --git a/stem/descriptor/bandwidth_file.py b/stem/descriptor/bandwidth_file.py index 2b1ed5d3..f449665d 100644 --- a/stem/descriptor/bandwidth_file.py +++ b/stem/descriptor/bandwidth_file.py @@ -175,7 +175,7 @@ def _parse_file(descriptor_file: BinaryIO, validate: bool = False, **kwargs: Any
:raises: * **ValueError** if the contents is malformed and validate is **True** - * **IOError** if the file can't be read + * **OSError** if the file can't be read """
if kwargs: diff --git a/stem/descriptor/collector.py b/stem/descriptor/collector.py index 8c05a832..892ccc30 100644 --- a/stem/descriptor/collector.py +++ b/stem/descriptor/collector.py @@ -307,7 +307,7 @@ class File(object):
:raises: * :class:`~stem.DownloadFailed` if the download fails - * **IOError** if a mismatching file exists and **overwrite** is **False** + * **OSError** if a mismatching file exists and **overwrite** is **False** """
filename = self.path.split('/')[-1] @@ -332,7 +332,7 @@ class File(object): if expected_hash == actual_hash: return path # nothing to do, we already have the file elif not overwrite: - raise IOError("%s already exists but mismatches CollecTor's checksum (expected: %s, actual: %s)" % (path, expected_hash, actual_hash)) + raise OSError("%s already exists but mismatches CollecTor's checksum (expected: %s, actual: %s)" % (path, expected_hash, actual_hash))
response = stem.util.connection.download(COLLECTOR_URL + self.path, timeout, retries)
@@ -624,7 +624,7 @@ class CollecTor(object): If unable to retrieve the index this provide...
* **ValueError** if json is malformed - * **IOError** if unable to decompress + * **OSError** if unable to decompress * :class:`~stem.DownloadFailed` if the download fails """
@@ -664,7 +664,7 @@ class CollecTor(object): If unable to retrieve the index this provide...
* **ValueError** if json is malformed - * **IOError** if unable to decompress + * **OSError** if unable to decompress * :class:`~stem.DownloadFailed` if the download fails """
diff --git a/stem/descriptor/extrainfo_descriptor.py b/stem/descriptor/extrainfo_descriptor.py index 86458cdf..8d9cbf30 100644 --- a/stem/descriptor/extrainfo_descriptor.py +++ b/stem/descriptor/extrainfo_descriptor.py @@ -182,7 +182,7 @@ def _parse_file(descriptor_file: BinaryIO, is_bridge = False, validate = False,
:raises: * **ValueError** if the contents is malformed and validate is **True** - * **IOError** if the file can't be read + * **OSError** if the file can't be read """
if kwargs: diff --git a/stem/descriptor/hidden_service.py b/stem/descriptor/hidden_service.py index 49737f9d..dc86b382 100644 --- a/stem/descriptor/hidden_service.py +++ b/stem/descriptor/hidden_service.py @@ -451,7 +451,7 @@ def _parse_file(descriptor_file: BinaryIO, desc_type: Optional[Type['stem.descri
:raises: * **ValueError** if the contents is malformed and validate is **True** - * **IOError** if the file can't be read + * **OSError** if the file can't be read """
if desc_type is None: diff --git a/stem/descriptor/microdescriptor.py b/stem/descriptor/microdescriptor.py index 0b015ebb..ea48fce8 100644 --- a/stem/descriptor/microdescriptor.py +++ b/stem/descriptor/microdescriptor.py @@ -108,7 +108,7 @@ def _parse_file(descriptor_file: BinaryIO, validate: bool = False, **kwargs: Any
:raises: * **ValueError** if the contents is malformed and validate is True - * **IOError** if the file can't be read + * **OSError** if the file can't be read """
if kwargs: diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py index f216e427..e8cf90eb 100644 --- a/stem/descriptor/networkstatus.py +++ b/stem/descriptor/networkstatus.py @@ -317,7 +317,7 @@ def _parse_file(document_file: BinaryIO, document_type: Optional[Type] = None, v :raises: * **ValueError** if the document_version is unrecognized or the contents is malformed and validate is **True** - * **IOError** if the file can't be read + * **OSError** if the file can't be read """
# we can't properly default this since NetworkStatusDocumentV3 isn't defined yet @@ -390,7 +390,7 @@ def _parse_file_key_certs(certificate_file: BinaryIO, validate: bool = False) ->
:raises: * **ValueError** if the key certificates are invalid and validate is **True** - * **IOError** if the file can't be read + * **OSError** if the file can't be read """
while True: @@ -419,7 +419,7 @@ def _parse_file_detached_sigs(detached_signature_file: BinaryIO, validate: bool
:raises: * **ValueError** if the detached signatures are invalid and validate is **True** - * **IOError** if the file can't be read + * **OSError** if the file can't be read """
while True: diff --git a/stem/descriptor/router_status_entry.py b/stem/descriptor/router_status_entry.py index ecfcb7fd..aa94a703 100644 --- a/stem/descriptor/router_status_entry.py +++ b/stem/descriptor/router_status_entry.py @@ -72,7 +72,7 @@ def _parse_file(document_file: BinaryIO, validate: bool, entry_class: Type['stem
:raises: * **ValueError** if the contents is malformed and validate is **True** - * **IOError** if the file can't be read + * **OSError** if the file can't be read """
if start_position: diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py index 6e6a5369..e49688e1 100644 --- a/stem/descriptor/server_descriptor.py +++ b/stem/descriptor/server_descriptor.py @@ -159,7 +159,7 @@ def _parse_file(descriptor_file: BinaryIO, is_bridge: bool = False, validate: bo
:raises: * **ValueError** if the contents is malformed and validate is True - * **IOError** if the file can't be read + * **OSError** if the file can't be read """
# Handler for relay descriptors diff --git a/stem/descriptor/tordnsel.py b/stem/descriptor/tordnsel.py index 6b9d4ceb..32cf1863 100644 --- a/stem/descriptor/tordnsel.py +++ b/stem/descriptor/tordnsel.py @@ -35,7 +35,7 @@ def _parse_file(tordnsel_file: BinaryIO, validate: bool = False, **kwargs: Any)
:raises: * **ValueError** if the contents is malformed and validate is **True** - * **IOError** if the file can't be read + * **OSError** if the file can't be read """
if kwargs: diff --git a/stem/directory.py b/stem/directory.py index 20982ccc..39abfb90 100644 --- a/stem/directory.py +++ b/stem/directory.py @@ -192,7 +192,7 @@ class Directory(object):
try: authorities = stem.directory.Authority.from_remote() - except IOError: + except OSError: authorities = stem.directory.Authority.from_cache()
.. versionadded:: 1.5.0 @@ -205,7 +205,7 @@ class Directory(object): :returns: **dict** of **str** identifiers to their :class:`~stem.directory.Directory`
- :raises: **IOError** if unable to retrieve the fallback directories + :raises: **OSError** if unable to retrieve the fallback directories """
raise NotImplementedError('Unsupported Operation: this should be implemented by the Directory subclass') @@ -251,7 +251,7 @@ class Authority(Directory): lines = str_tools._to_unicode(urllib.request.urlopen(GITWEB_AUTHORITY_URL, timeout = timeout).read()).splitlines()
if not lines: - raise IOError('no content') + raise OSError('no content') except: exc, stacktrace = sys.exc_info()[1:3] message = "Unable to download tor's directory authorities from %s: %s" % (GITWEB_AUTHORITY_URL, exc) @@ -280,7 +280,7 @@ class Authority(Directory): v3ident = matches.get(AUTHORITY_V3IDENT), # type: ignore ) except ValueError as exc: - raise IOError(str(exc)) + raise OSError(str(exc))
return results
@@ -373,7 +373,7 @@ class Fallback(Directory): attr[attr_name] = conf.get(key)
if not attr[attr_name] and attr_name not in ('nickname', 'has_extrainfo', 'orport6_address', 'orport6_port'): - raise IOError("'%s' is missing from %s" % (key, FALLBACK_CACHE_PATH)) + raise OSError("'%s' is missing from %s" % (key, FALLBACK_CACHE_PATH))
if attr['orport6_address'] and attr['orport6_port']: orport_v6 = (attr['orport6_address'], int(attr['orport6_port'])) @@ -399,7 +399,7 @@ class Fallback(Directory): lines = str_tools._to_unicode(urllib.request.urlopen(GITWEB_FALLBACK_URL, timeout = timeout).read()).splitlines()
if not lines: - raise IOError('no content') + raise OSError('no content') except: exc, stacktrace = sys.exc_info()[1:3] message = "Unable to download tor's fallback directories from %s: %s" % (GITWEB_FALLBACK_URL, exc) @@ -408,7 +408,7 @@ class Fallback(Directory): # header metadata
if lines[0] != '/* type=fallback */': - raise IOError('%s does not have a type field indicating it is fallback directory metadata' % GITWEB_FALLBACK_URL) + raise OSError('%s does not have a type field indicating it is fallback directory metadata' % GITWEB_FALLBACK_URL)
header = {}
@@ -418,7 +418,7 @@ class Fallback(Directory): if mapping: header[mapping.group(1)] = mapping.group(2) else: - raise IOError('Malformed fallback directory header line: %s' % line) + raise OSError('Malformed fallback directory header line: %s' % line)
Fallback._pop_section(lines) # skip human readable comments
@@ -446,7 +446,7 @@ class Fallback(Directory): header = header, ) except ValueError as exc: - raise IOError(str(exc)) + raise OSError(str(exc))
return results
diff --git a/stem/interpreter/__init__.py b/stem/interpreter/__init__.py index 1445d9bb..53589bf8 100644 --- a/stem/interpreter/__init__.py +++ b/stem/interpreter/__init__.py @@ -137,7 +137,7 @@ def main() -> None: try: for line in open(args.run_path).readlines(): interpreter.run_command(line.strip(), print_response = True) - except IOError as exc: + except OSError as exc: print(format(msg('msg.unable_to_read_file', path = args.run_path, error = exc), *ERROR_OUTPUT)) sys.exit(1) else: diff --git a/stem/manual.py b/stem/manual.py index 26249abc..dbde9827 100644 --- a/stem/manual.py +++ b/stem/manual.py @@ -100,7 +100,7 @@ CATEGORY_SECTIONS = collections.OrderedDict(( ))
-class SchemaMismatch(IOError): +class SchemaMismatch(OSError): """ Database schema doesn't match what Stem supports.
@@ -281,13 +281,13 @@ def download_man_page(path: Optional[str] = None, file_handle: Optional[BinaryIO :param url: url to download tor's asciidoc manual from :param timeout: seconds to wait before timing out the request
- :raises: **IOError** if unable to retrieve the manual + :raises: **OSError** if unable to retrieve the manual """
if not path and not file_handle: raise ValueError("Either the path or file_handle we're saving to must be provided") elif not stem.util.system.is_available('a2x'): - raise IOError('We require a2x from asciidoc to provide a man page') + raise OSError('We require a2x from asciidoc to provide a man page')
with tempfile.TemporaryDirectory() as dirpath: asciidoc_path = os.path.join(dirpath, 'tor.1.txt') @@ -308,7 +308,7 @@ def download_man_page(path: Optional[str] = None, file_handle: Optional[BinaryIO if not os.path.exists(manual_path): raise OSError('no man page was generated') except stem.util.system.CallError as exc: - raise IOError("Unable to run '%s': %s" % (exc.command, stem.util.str_tools._to_unicode(exc.stderr))) + raise OSError("Unable to run '%s': %s" % (exc.command, stem.util.str_tools._to_unicode(exc.stderr)))
if path: try: @@ -319,7 +319,7 @@ def download_man_page(path: Optional[str] = None, file_handle: Optional[BinaryIO
shutil.copyfile(manual_path, path) except OSError as exc: - raise IOError(exc) + raise OSError(exc)
if file_handle: with open(manual_path, 'rb') as manual_file: @@ -385,7 +385,7 @@ class Manual(object): :raises: * **ImportError** if cache is sqlite and the sqlite3 module is unavailable - * **IOError** if a **path** was provided and we were unable to read + * **OSError** if a **path** was provided and we were unable to read it or the schema is out of date """
@@ -398,7 +398,7 @@ class Manual(object): path = CACHE_PATH
if not os.path.exists(path): - raise IOError("%s doesn't exist" % path) + raise OSError("%s doesn't exist" % path)
with sqlite3.connect(path) as conn: try: @@ -409,7 +409,7 @@ class Manual(object):
name, synopsis, description, man_commit, stem_commit = conn.execute('SELECT name, synopsis, description, man_commit, stem_commit FROM metadata').fetchone() except sqlite3.OperationalError as exc: - raise IOError('Failed to read database metadata from %s: %s' % (path, exc)) + raise OSError('Failed to read database metadata from %s: %s' % (path, exc))
commandline = dict(conn.execute('SELECT name, description FROM commandline').fetchall()) signals = dict(conn.execute('SELECT name, description FROM signals').fetchall()) @@ -442,7 +442,7 @@ class Manual(object):
:returns: :class:`~stem.manual.Manual` for the system's man page
- :raises: **IOError** if unable to retrieve the manual + :raises: **OSError** if unable to retrieve the manual """
man_cmd = 'man %s -P cat %s' % ('--encoding=ascii' if HAS_ENCODING_ARG else '', man_path) @@ -450,7 +450,7 @@ class Manual(object): try: man_output = stem.util.system.call(man_cmd, env = {'MANWIDTH': '10000000'}) except OSError as exc: - raise IOError("Unable to run '%s': %s" % (man_cmd, exc)) + raise OSError("Unable to run '%s': %s" % (man_cmd, exc))
categories = _get_categories(man_output) config_options = collections.OrderedDict() # type: collections.OrderedDict[str, stem.manual.ConfigOption] @@ -484,7 +484,7 @@ class Manual(object):
try: manual = stem.manual.from_remote() - except IOError: + except OSError: manual = stem.manual.from_cache()
In addition to our GitWeb dependency this requires 'a2x' which is part of @@ -499,7 +499,7 @@ class Manual(object):
:returns: latest :class:`~stem.manual.Manual` available for tor
- :raises: **IOError** if unable to retrieve the manual + :raises: **OSError** if unable to retrieve the manual """
with tempfile.NamedTemporaryFile() as tmp: @@ -519,7 +519,7 @@ class Manual(object): :raises: * **ImportError** if saving as sqlite and the sqlite3 module is unavailable - * **IOError** if unsuccessful + * **OSError** if unsuccessful """
try: diff --git a/stem/util/conf.py b/stem/util/conf.py index 1ac0d107..4760d7b4 100644 --- a/stem/util/conf.py +++ b/stem/util/conf.py @@ -267,7 +267,7 @@ def uses_settings(handle: str, path: str, lazy_load: bool = True) -> Callable: :returns: **function** that can be used as a decorator to provide the configuration
- :raises: **IOError** if we fail to read the configuration file, if + :raises: **OSError** if we fail to read the configuration file, if **lazy_load** is true then this arises when we use the decorator """
@@ -416,7 +416,7 @@ class Config(object):
try: user_config.load("/home/atagar/myConfig") - except IOError as exc: + except OSError as exc: print "Unable to load the user's config: %s" % exc
# This replace the contents of ssh_config with the values from the user's @@ -485,7 +485,7 @@ class Config(object): otherwise
:raises: - * **IOError** if we fail to read the file (it doesn't exist, insufficient + * **OSError** if we fail to read the file (it doesn't exist, insufficient permissions, etc) * **ValueError** if no path was provided and we've never been provided one """ @@ -547,7 +547,7 @@ class Config(object): :param path: location to be saved to
:raises: - * **IOError** if we fail to save the file (insufficient permissions, etc) + * **OSError** if we fail to save the file (insufficient permissions, etc) * **ValueError** if no path was provided and we've never been provided one """
diff --git a/stem/util/connection.py b/stem/util/connection.py index f8a21f50..a83922f7 100644 --- a/stem/util/connection.py +++ b/stem/util/connection.py @@ -224,7 +224,7 @@ def get_connections(resolver: Optional['stem.util.connection.Resolver'] = None, :raises: * **ValueError** if neither a process_pid nor process_name is provided
- * **IOError** if no connections are available or resolution fails + * **OSError** if no connections are available or resolution fails (generally they're indistinguishable). The common causes are the command being unavailable or permissions. """ @@ -235,7 +235,7 @@ def get_connections(resolver: Optional['stem.util.connection.Resolver'] = None, if available_resolvers: resolver = available_resolvers[0] else: - raise IOError('Unable to determine a connection resolver') + raise OSError('Unable to determine a connection resolver')
if not process_pid and not process_name: raise ValueError('You must provide a pid or process name to provide connections for') @@ -258,12 +258,12 @@ def get_connections(resolver: Optional['stem.util.connection.Resolver'] = None,
if len(all_pids) == 0: if resolver in (Resolver.NETSTAT_WINDOWS, Resolver.PROC, Resolver.BSD_PROCSTAT): - raise IOError("Unable to determine the pid of '%s'. %s requires the pid to provide the connections." % (process_name, resolver)) + raise OSError("Unable to determine the pid of '%s'. %s requires the pid to provide the connections." % (process_name, resolver)) elif len(all_pids) == 1: process_pid = all_pids[0] else: if resolver in (Resolver.NETSTAT_WINDOWS, Resolver.PROC, Resolver.BSD_PROCSTAT): - raise IOError("There's multiple processes named '%s'. %s requires a single pid to provide the connections." % (process_name, resolver)) + raise OSError("There's multiple processes named '%s'. %s requires a single pid to provide the connections." % (process_name, resolver))
if resolver == Resolver.PROC: return stem.util.proc.connections(pid = process_pid) @@ -273,7 +273,7 @@ def get_connections(resolver: Optional['stem.util.connection.Resolver'] = None, try: results = stem.util.system.call(resolver_command) except OSError as exc: - raise IOError("Unable to query '%s': %s" % (resolver_command, exc)) + raise OSError("Unable to query '%s': %s" % (resolver_command, exc))
resolver_regex_str = RESOLVER_FILTER[resolver].format( protocol = '(?P<protocol>\S+)', @@ -330,7 +330,7 @@ def get_connections(resolver: Optional['stem.util.connection.Resolver'] = None, _log('%i connections found' % len(connections))
if not connections: - raise IOError('No results found using: %s' % resolver_command) + raise OSError('No results found using: %s' % resolver_command)
return connections
diff --git a/stem/util/proc.py b/stem/util/proc.py index 802937b5..106c666b 100644 --- a/stem/util/proc.py +++ b/stem/util/proc.py @@ -108,7 +108,7 @@ def system_start_time() -> float:
:returns: **float** for the unix time of when the system started
- :raises: **IOError** if it can't be determined + :raises: **OSError** if it can't be determined """
start_time, parameter = time.time(), 'system start time' @@ -119,7 +119,7 @@ def system_start_time() -> float: _log_runtime(parameter, '/proc/stat[btime]', start_time) return result except: - exc = IOError('unable to parse the /proc/stat btime entry: %s' % btime_line) + exc = OSError('unable to parse the /proc/stat btime entry: %s' % btime_line) _log_failure(parameter, exc) raise exc
@@ -131,7 +131,7 @@ def physical_memory() -> int:
:returns: **int** for the bytes of physical memory this system has
- :raises: **IOError** if it can't be determined + :raises: **OSError** if it can't be determined """
start_time, parameter = time.time(), 'system physical memory' @@ -142,7 +142,7 @@ def physical_memory() -> int: _log_runtime(parameter, '/proc/meminfo[MemTotal]', start_time) return result except: - exc = IOError('unable to parse the /proc/meminfo MemTotal entry: %s' % mem_total_line) + exc = OSError('unable to parse the /proc/meminfo MemTotal entry: %s' % mem_total_line) _log_failure(parameter, exc) raise exc
@@ -155,7 +155,7 @@ def cwd(pid: int) -> str:
:returns: **str** with the path of the working directory for the process
- :raises: **IOError** if it can't be determined + :raises: **OSError** if it can't be determined """
start_time, parameter = time.time(), 'cwd' @@ -167,7 +167,7 @@ def cwd(pid: int) -> str: try: cwd = os.readlink(proc_cwd_link) except OSError: - exc = IOError('unable to read %s' % proc_cwd_link) + exc = OSError('unable to read %s' % proc_cwd_link) _log_failure(parameter, exc) raise exc
@@ -183,7 +183,7 @@ def uid(pid: int) -> int:
:returns: **int** with the user id for the owner of the process
- :raises: **IOError** if it can't be determined + :raises: **OSError** if it can't be determined """
start_time, parameter = time.time(), 'uid' @@ -195,7 +195,7 @@ def uid(pid: int) -> int: _log_runtime(parameter, '%s[Uid]' % status_path, start_time) return result except: - exc = IOError('unable to parse the %s Uid entry: %s' % (status_path, uid_line)) + exc = OSError('unable to parse the %s Uid entry: %s' % (status_path, uid_line)) _log_failure(parameter, exc) raise exc
@@ -209,7 +209,7 @@ def memory_usage(pid: int) -> Tuple[int, int]: :returns: **tuple** of two ints with the memory usage of the process, of the form **(resident_size, virtual_size)**
- :raises: **IOError** if it can't be determined + :raises: **OSError** if it can't be determined """
# checks if this is the kernel process @@ -228,7 +228,7 @@ def memory_usage(pid: int) -> Tuple[int, int]: _log_runtime(parameter, '%s[VmRSS|VmSize]' % status_path, start_time) return (residentSize, virtualSize) except: - exc = IOError('unable to parse the %s VmRSS and VmSize entries: %s' % (status_path, ', '.join(mem_lines))) + exc = OSError('unable to parse the %s VmRSS and VmSize entries: %s' % (status_path, ', '.join(mem_lines))) _log_failure(parameter, exc) raise exc
@@ -243,11 +243,11 @@ def stats(pid: int, *stat_types: 'stem.util.proc.Stat') -> Sequence[str]:
:returns: **tuple** with all of the requested statistics as strings
- :raises: **IOError** if it can't be determined + :raises: **OSError** if it can't be determined """
if CLOCK_TICKS is None: - raise IOError('Unable to look up SC_CLK_TCK') + raise OSError('Unable to look up SC_CLK_TCK')
start_time, parameter = time.time(), 'process %s' % ', '.join(stat_types)
@@ -266,7 +266,7 @@ def stats(pid: int, *stat_types: 'stem.util.proc.Stat') -> Sequence[str]: stat_comp += stat_line[cmd_end + 1:].split()
if len(stat_comp) < 44 and _is_float(stat_comp[13], stat_comp[14], stat_comp[21]): - exc = IOError('stat file had an unexpected format: %s' % stat_path) + exc = OSError('stat file had an unexpected format: %s' % stat_path) _log_failure(parameter, exc) raise exc
@@ -312,21 +312,21 @@ def file_descriptors_used(pid: int) -> int:
:returns: **int** of the number of file descriptors used
- :raises: **IOError** if it can't be determined + :raises: **OSError** if it can't be determined """
try: pid = int(pid)
if pid < 0: - raise IOError("Process pids can't be negative: %s" % pid) + raise OSError("Process pids can't be negative: %s" % pid) except (ValueError, TypeError): - raise IOError('Process pid was non-numeric: %s' % pid) + raise OSError('Process pid was non-numeric: %s' % pid)
try: return len(os.listdir('/proc/%i/fd' % pid)) except Exception as exc: - raise IOError('Unable to check number of file descriptors used: %s' % exc) + raise OSError('Unable to check number of file descriptors used: %s' % exc)
def connections(pid: Optional[int] = None, user: Optional[str] = None) -> Sequence['stem.util.connection.Connection']: @@ -340,7 +340,7 @@ def connections(pid: Optional[int] = None, user: Optional[str] = None) -> Sequen
:returns: **list** of :class:`~stem.util.connection.Connection` instances
- :raises: **IOError** if it can't be determined + :raises: **OSError** if it can't be determined """
start_time, conn = time.time(), [] @@ -352,9 +352,9 @@ def connections(pid: Optional[int] = None, user: Optional[str] = None) -> Sequen pid = int(pid)
if pid < 0: - raise IOError("Process pids can't be negative: %s" % pid) + raise OSError("Process pids can't be negative: %s" % pid) except (ValueError, TypeError): - raise IOError('Process pid was non-numeric: %s' % pid) + raise OSError('Process pid was non-numeric: %s' % pid) elif user: parameter = 'connections for user %s' % user else: @@ -362,7 +362,7 @@ def connections(pid: Optional[int] = None, user: Optional[str] = None) -> Sequen
try: if not IS_PWD_AVAILABLE: - raise IOError("This requires python's pwd module, which is unavailable on Windows.") + raise OSError("This requires python's pwd module, which is unavailable on Windows.")
inodes = _inodes_for_sockets(pid) if pid else set() process_uid = stem.util.str_tools._to_bytes(str(pwd.getpwnam(user).pw_uid)) if user else None @@ -402,14 +402,14 @@ def connections(pid: Optional[int] = None, user: Optional[str] = None) -> Sequen continue # no port
conn.append(stem.util.connection.Connection(l_addr, l_port, r_addr, r_port, protocol, is_ipv6)) - except IOError as exc: - raise IOError("unable to read '%s': %s" % (proc_file_path, exc)) + except OSError as exc: + raise OSError("unable to read '%s': %s" % (proc_file_path, exc)) except Exception as exc: - raise IOError("unable to parse '%s': %s" % (proc_file_path, exc)) + raise OSError("unable to parse '%s': %s" % (proc_file_path, exc))
_log_runtime(parameter, '/proc/net/[tcp|udp]', start_time) return conn - except IOError as exc: + except OSError as exc: _log_failure(parameter, exc) raise
@@ -422,7 +422,7 @@ def _inodes_for_sockets(pid: int) -> Set[bytes]:
:returns: **set** with inodes for its sockets
- :raises: **IOError** if it can't be determined + :raises: **OSError** if it can't be determined """
inodes = set() @@ -430,7 +430,7 @@ def _inodes_for_sockets(pid: int) -> Set[bytes]: try: fd_contents = os.listdir('/proc/%s/fd' % pid) except OSError as exc: - raise IOError('Unable to read our file descriptors: %s' % exc) + raise OSError('Unable to read our file descriptors: %s' % exc)
for fd in fd_contents: fd_path = '/proc/%s/fd/%s' % (pid, fd) @@ -447,7 +447,7 @@ def _inodes_for_sockets(pid: int) -> Set[bytes]: continue # descriptors may shift while we're in the middle of iterating over them
# most likely couldn't be read due to permissions - raise IOError('unable to determine file descriptor destination (%s): %s' % (exc, fd_path)) + raise OSError('unable to determine file descriptor destination (%s): %s' % (exc, fd_path))
return inodes
@@ -519,7 +519,7 @@ def _get_lines(file_path: str, line_prefixes: Sequence[str], parameter: str) ->
:returns: mapping of prefixes to the matching line
- :raises: **IOError** if unable to read the file or can't find all of the prefixes + :raises: **OSError** if unable to read the file or can't find all of the prefixes """
try: @@ -544,10 +544,10 @@ def _get_lines(file_path: str, line_prefixes: Sequence[str], parameter: str) -> else: msg = '%s did not contain %s entries' % (file_path, ', '.join(remaining_prefixes))
- raise IOError(msg) + raise OSError(msg) else: return results - except IOError as exc: + except OSError as exc: _log_failure(parameter, exc) raise
diff --git a/stem/util/system.py b/stem/util/system.py index b0130fb1..5d3e3e2b 100644 --- a/stem/util/system.py +++ b/stem/util/system.py @@ -525,7 +525,7 @@ def name_by_pid(pid: int) -> Optional[str]: if stem.util.proc.is_available(): try: process_name = stem.util.proc.stats(pid, stem.util.proc.Stat.COMMAND)[0] - except IOError: + except OSError: pass
# attempts to resolve using ps, failing if: @@ -923,7 +923,7 @@ def cwd(pid: int) -> Optional[str]: if stem.util.proc.is_available(): try: return stem.util.proc.cwd(pid) - except IOError: + except OSError: pass
# Fall back to a pwdx query. This isn't available on BSD. @@ -1024,7 +1024,7 @@ def start_time(pid: str) -> Optional[float]: if stem.util.proc.is_available(): try: return float(stem.util.proc.stats(pid, stem.util.proc.Stat.START_TIME)[0]) - except IOError: + except OSError: pass
try: @@ -1053,7 +1053,7 @@ def tail(target: Union[str, BinaryIO], lines: Optional[int] = None) -> Iterator[
:returns: **generator** that reads lines, starting with the end
- :raises: **IOError** if unable to read the file + :raises: **OSError** if unable to read the file """
if isinstance(target, str): @@ -1163,7 +1163,7 @@ def is_tarfile(path: str) -> bool: # Checking if it's a tar file may fail due to permissions so failing back # to the mime type... # - # IOError: [Errno 13] Permission denied: '/vmlinuz.old' + # OSError: [Errno 13] Permission denied: '/vmlinuz.old' # # With python 3 insuffient permissions raises an AttributeError instead... # @@ -1171,7 +1171,7 @@ def is_tarfile(path: str) -> bool:
try: return tarfile.is_tarfile(path) - except (IOError, AttributeError): + except (OSError, AttributeError): return mimetypes.guess_type(path)[0] == 'application/x-tar'
@@ -1402,7 +1402,7 @@ def set_process_name(process_name: str) -> None:
:param process_name: new name for our process
- :raises: **IOError** if the process cannot be renamed + :raises: **OSError** if the process cannot be renamed """
# This is mostly based on... @@ -1448,7 +1448,7 @@ def _set_argv(process_name: str) -> None: Py_GetArgcArgv(argv, ctypes.pointer(argc))
if len(process_name) > _MAX_NAME_LENGTH: - raise IOError("Can't rename process to something longer than our initial name (this would overwrite memory used for the env)") + raise OSError("Can't rename process to something longer than our initial name (this would overwrite memory used for the env)")
# space we need to clear zero_size = max(len(current_name), len(process_name)) diff --git a/stem/version.py b/stem/version.py index 9ed5fa37..cd2c3c39 100644 --- a/stem/version.py +++ b/stem/version.py @@ -60,7 +60,7 @@ def get_system_tor_version(tor_cmd: str = 'tor') -> 'stem.version.Version':
:returns: :class:`~stem.version.Version` provided by the tor command
- :raises: **IOError** if unable to query or parse the version + :raises: **OSError** if unable to query or parse the version """
if tor_cmd not in VERSION_CACHE: @@ -73,11 +73,11 @@ def get_system_tor_version(tor_cmd: str = 'tor') -> 'stem.version.Version':
if 'No such file or directory' in str(exc): if os.path.isabs(tor_cmd): - raise IOError("Unable to check tor's version. '%s' doesn't exist." % tor_cmd) + raise OSError("Unable to check tor's version. '%s' doesn't exist." % tor_cmd) else: - raise IOError("Unable to run '%s'. Maybe tor isn't in your PATH?" % version_cmd) + raise OSError("Unable to run '%s'. Maybe tor isn't in your PATH?" % version_cmd)
- raise IOError(exc) + raise OSError(exc)
for line in version_output: # output example: @@ -90,10 +90,10 @@ def get_system_tor_version(tor_cmd: str = 'tor') -> 'stem.version.Version': VERSION_CACHE[tor_cmd] = Version(version_str) break except ValueError as exc: - raise IOError(exc) + raise OSError(exc)
if tor_cmd not in VERSION_CACHE: - raise IOError("'%s' didn't provide a parseable version:\n\n%s" % (version_cmd, '\n'.join(version_output))) + raise OSError("'%s' didn't provide a parseable version:\n\n%s" % (version_cmd, '\n'.join(version_output)))
return VERSION_CACHE[tor_cmd]
diff --git a/test/integ/util/connection.py b/test/integ/util/connection.py index 3e22667e..d2401aab 100644 --- a/test/integ/util/connection.py +++ b/test/integ/util/connection.py @@ -69,7 +69,7 @@ class TestConnection(unittest.TestCase): def test_connections_by_ss(self): try: self.check_resolver(Resolver.SS) - except (IOError, OSError): + except OSError: self.skipTest('(ticket 27479)')
def test_connections_by_lsof(self): diff --git a/test/integ/version.py b/test/integ/version.py index 0df48646..1241fcfd 100644 --- a/test/integ/version.py +++ b/test/integ/version.py @@ -25,10 +25,10 @@ class TestVersion(unittest.TestCase): stem.version.get_system_tor_version()
# try running against a command that exists, but isn't tor - self.assertRaises(IOError, stem.version.get_system_tor_version, 'ls') + self.assertRaises(OSError, stem.version.get_system_tor_version, 'ls')
# try running against a command that doesn't exist - self.assertRaises(IOError, stem.version.get_system_tor_version, 'blarg') + self.assertRaises(OSError, stem.version.get_system_tor_version, 'blarg')
@test.require.controller @async_test diff --git a/test/unit/descriptor/collector.py b/test/unit/descriptor/collector.py index 2960cf53..3f053a02 100644 --- a/test/unit/descriptor/collector.py +++ b/test/unit/descriptor/collector.py @@ -99,16 +99,16 @@ class TestCollector(unittest.TestCase):
@patch('urllib.request.urlopen') def test_index_retries(self, urlopen_mock): - urlopen_mock.side_effect = IOError('boom') + urlopen_mock.side_effect = OSError('boom')
collector = CollecTor(retries = 0) - self.assertRaisesRegexp(IOError, 'boom', collector.index) + self.assertRaisesRegexp(OSError, 'boom', collector.index) self.assertEqual(1, urlopen_mock.call_count)
urlopen_mock.reset_mock()
collector = CollecTor(retries = 4) - self.assertRaisesRegexp(IOError, 'boom', collector.index) + self.assertRaisesRegexp(OSError, 'boom', collector.index) self.assertEqual(5, urlopen_mock.call_count)
@patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(b'not json'))) @@ -123,7 +123,7 @@ class TestCollector(unittest.TestCase):
with patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(b'not compressed'))): collector = CollecTor() - self.assertRaisesRegexp(IOError, 'Failed to decompress as %s' % compression, collector.index, compression) + self.assertRaisesRegexp(OSError, 'Failed to decompress as %s' % compression, collector.index, compression)
@patch('stem.descriptor.collector.CollecTor.index', Mock(return_value = EXAMPLE_INDEX)) def test_files(self): diff --git a/test/unit/directory/fallback.py b/test/unit/directory/fallback.py index 7b8f6da8..878218b8 100644 --- a/test/unit/directory/fallback.py +++ b/test/unit/directory/fallback.py @@ -117,11 +117,11 @@ class TestFallback(unittest.TestCase):
@patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(b'\n'.join(FALLBACK_GITWEB_CONTENT.splitlines()[1:])))) def test_from_remote_no_header(self): - self.assertRaisesRegexp(IOError, 'does not have a type field indicating it is fallback directory metadata', stem.directory.Fallback.from_remote) + self.assertRaisesRegexp(OSError, 'does not have a type field indicating it is fallback directory metadata', stem.directory.Fallback.from_remote)
@patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(FALLBACK_GITWEB_CONTENT.replace(b'version=2.0.0', b'version')))) def test_from_remote_malformed_header(self): - self.assertRaisesRegexp(IOError, 'Malformed fallback directory header line: /\* version \*/', stem.directory.Fallback.from_remote) + self.assertRaisesRegexp(OSError, 'Malformed fallback directory header line: /\* version \*/', stem.directory.Fallback.from_remote)
def test_from_remote_malformed(self): test_values = { @@ -135,7 +135,7 @@ class TestFallback(unittest.TestCase):
for entry, expected in test_values.items(): with patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(entry))): - self.assertRaisesRegexp(IOError, re.escape(expected), stem.directory.Fallback.from_remote) + self.assertRaisesRegexp(OSError, re.escape(expected), stem.directory.Fallback.from_remote)
def test_persistence(self): expected = { diff --git a/test/unit/manual.py b/test/unit/manual.py index 9d842972..d290f332 100644 --- a/test/unit/manual.py +++ b/test/unit/manual.py @@ -238,14 +238,14 @@ class TestManual(unittest.TestCase): @patch('stem.util.system.is_available', Mock(return_value = False)) def test_download_man_page_requires_a2x(self): exc_msg = 'We require a2x from asciidoc to provide a man page' - self.assertRaisesWith(IOError, exc_msg, stem.manual.download_man_page, '/tmp/no_such_file') + self.assertRaisesWith(OSError, exc_msg, stem.manual.download_man_page, '/tmp/no_such_file')
@patch('tempfile.TemporaryDirectory', Mock(return_value = TEMP_DIR_MOCK)) - @patch('stem.manual.open', Mock(side_effect = IOError('unable to write to file')), create = True) + @patch('stem.manual.open', Mock(side_effect = OSError('unable to write to file')), create = True) @patch('stem.util.system.is_available', Mock(return_value = True)) def test_download_man_page_when_unable_to_write(self): exc_msg = "Unable to download tor's manual from https://gitweb.torproject.org/tor.git/plain/doc/man/tor.1.txt to /no/such/path/tor.1.txt: unable to write to file" - self.assertRaisesWith(IOError, exc_msg, stem.manual.download_man_page, '/tmp/no_such_file') + self.assertRaisesWith(OSError, exc_msg, stem.manual.download_man_page, '/tmp/no_such_file')
@patch('tempfile.TemporaryDirectory', Mock(return_value = TEMP_DIR_MOCK)) @patch('stem.manual.open', Mock(return_value = io.BytesIO()), create = True) @@ -253,7 +253,7 @@ class TestManual(unittest.TestCase): @patch('urllib.request.urlopen', Mock(side_effect = urllib.request.URLError('<urlopen error [Errno -2] Name or service not known>'))) def test_download_man_page_when_download_fails(self): exc_msg = "Unable to download tor's manual from https://www.atagar.com/foo/bar to /no/such/path/tor.1.txt: <urlopen error <urlopen error [Errno -2] Name or service not known>>" - self.assertRaisesWith(IOError, exc_msg, stem.manual.download_man_page, '/tmp/no_such_file', url = 'https://www.atagar.com/foo/bar') + self.assertRaisesWith(OSError, exc_msg, stem.manual.download_man_page, '/tmp/no_such_file', url = 'https://www.atagar.com/foo/bar')
@patch('tempfile.TemporaryDirectory', Mock(return_value = TEMP_DIR_MOCK)) @patch('stem.manual.open', Mock(return_value = io.BytesIO()), create = True) @@ -262,7 +262,7 @@ class TestManual(unittest.TestCase): @patch('urllib.request.urlopen', Mock(return_value = io.BytesIO(b'test content'))) def test_download_man_page_when_a2x_fails(self): exc_msg = "Unable to run 'a2x -f manpage /no/such/path/tor.1.txt': call failed" - self.assertRaisesWith(IOError, exc_msg, stem.manual.download_man_page, '/tmp/no_such_file', url = 'https://www.atagar.com/foo/bar') + self.assertRaisesWith(OSError, exc_msg, stem.manual.download_man_page, '/tmp/no_such_file', url = 'https://www.atagar.com/foo/bar')
@patch('tempfile.TemporaryDirectory', Mock(return_value = TEMP_DIR_MOCK)) @patch('stem.manual.open', create = True) @@ -290,7 +290,7 @@ class TestManual(unittest.TestCase): @patch('stem.util.system.call', Mock(side_effect = OSError('man --encoding=ascii -P cat tor returned exit status 16'))) def test_from_man_when_manual_is_unavailable(self): exc_msg = "Unable to run 'man --encoding=ascii -P cat tor': man --encoding=ascii -P cat tor returned exit status 16" - self.assertRaisesWith(IOError, exc_msg, stem.manual.Manual.from_man) + self.assertRaisesWith(OSError, exc_msg, stem.manual.Manual.from_man)
@patch('stem.util.system.call', Mock(return_value = [])) def test_when_man_is_empty(self): diff --git a/test/unit/util/connection.py b/test/unit/util/connection.py index 848ce989..575667b4 100644 --- a/test/unit/util/connection.py +++ b/test/unit/util/connection.py @@ -181,12 +181,12 @@ class TestConnection(unittest.TestCase): def test_download_retries(self, urlopen_mock): urlopen_mock.side_effect = urllib.request.URLError('boom')
- self.assertRaisesRegexp(IOError, 'boom', stem.util.connection.download, URL) + self.assertRaisesRegexp(OSError, 'boom', stem.util.connection.download, URL) self.assertEqual(1, urlopen_mock.call_count)
urlopen_mock.reset_mock()
- self.assertRaisesRegexp(IOError, 'boom', stem.util.connection.download, URL, retries = 4) + self.assertRaisesRegexp(OSError, 'boom', stem.util.connection.download, URL, retries = 4) self.assertEqual(5, urlopen_mock.call_count)
@patch('os.access') @@ -249,8 +249,8 @@ class TestConnection(unittest.TestCase):
self.assertEqual(expected, stem.util.connection.get_connections(Resolver.PROC, process_pid = 1111))
- proc_mock.side_effect = IOError('No connections for you!') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.PROC, process_pid = 1111) + proc_mock.side_effect = OSError('No connections for you!') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.PROC, process_pid = 1111)
@patch('stem.util.system.call') def test_get_connections_by_netstat(self, call_mock): @@ -262,11 +262,11 @@ class TestConnection(unittest.TestCase): expected = [Connection('192.168.0.1', 44284, '38.229.79.2', 443, 'tcp', False)] self.assertEqual(expected, stem.util.connection.get_connections(Resolver.NETSTAT, process_pid = 15843, process_name = 'tor'))
- self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.NETSTAT, process_pid = 15843, process_name = 'stuff') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.NETSTAT, process_pid = 1111, process_name = 'tor') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.NETSTAT, process_pid = 15843, process_name = 'stuff') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.NETSTAT, process_pid = 1111, process_name = 'tor')
call_mock.side_effect = OSError('Unable to call netstat') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.NETSTAT, process_pid = 1111) + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.NETSTAT, process_pid = 1111)
@patch('stem.util.system.call', Mock(return_value = NETSTAT_IPV6_OUTPUT.split('\n'))) def test_get_connections_by_netstat_ipv6(self): @@ -291,10 +291,10 @@ class TestConnection(unittest.TestCase): expected = [Connection('192.168.0.1', 44284, '38.229.79.2', 443, 'tcp', False)] self.assertEqual(expected, stem.util.connection.get_connections(Resolver.NETSTAT_WINDOWS, process_pid = 15843, process_name = 'tor'))
- self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.NETSTAT_WINDOWS, process_pid = 1111, process_name = 'tor') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.NETSTAT_WINDOWS, process_pid = 1111, process_name = 'tor') call_mock.side_effect = OSError('Unable to call netstat')
- self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.NETSTAT_WINDOWS, process_pid = 1111) + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.NETSTAT_WINDOWS, process_pid = 1111)
@patch('stem.util.system.call') def test_get_connections_by_ss(self, call_mock): @@ -309,11 +309,11 @@ class TestConnection(unittest.TestCase): ] self.assertEqual(expected, stem.util.connection.get_connections(Resolver.SS, process_pid = 15843, process_name = 'tor'))
- self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.SS, process_pid = 15843, process_name = 'stuff') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.SS, process_pid = 1111, process_name = 'tor') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.SS, process_pid = 15843, process_name = 'stuff') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.SS, process_pid = 1111, process_name = 'tor')
call_mock.side_effect = OSError('Unable to call ss') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.SS, process_pid = 1111) + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.SS, process_pid = 1111)
@patch('stem.util.system.call', Mock(return_value = SS_IPV6_OUTPUT.split('\n'))) def test_get_connections_by_ss_ipv6(self): @@ -345,11 +345,11 @@ class TestConnection(unittest.TestCase): ] self.assertEqual(expected, stem.util.connection.get_connections(Resolver.LSOF, process_pid = 15843, process_name = 'tor'))
- self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.LSOF, process_pid = 15843, process_name = 'stuff') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.LSOF, process_pid = 1111, process_name = 'tor') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.LSOF, process_pid = 15843, process_name = 'stuff') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.LSOF, process_pid = 1111, process_name = 'tor')
call_mock.side_effect = OSError('Unable to call lsof') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.LSOF, process_pid = 1111) + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.LSOF, process_pid = 1111)
@patch('stem.util.system.call', Mock(return_value = LSOF_IPV6_OUTPUT.split('\n'))) def test_get_connections_by_lsof_ipv6(self): @@ -392,11 +392,11 @@ class TestConnection(unittest.TestCase): ] self.assertEqual(expected, stem.util.connection.get_connections(Resolver.BSD_SOCKSTAT, process_pid = 4397, process_name = 'tor'))
- self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.BSD_SOCKSTAT, process_pid = 4397, process_name = 'stuff') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.BSD_SOCKSTAT, process_pid = 1111, process_name = 'tor') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.BSD_SOCKSTAT, process_pid = 4397, process_name = 'stuff') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.BSD_SOCKSTAT, process_pid = 1111, process_name = 'tor')
call_mock.side_effect = OSError('Unable to call sockstat') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.BSD_SOCKSTAT, process_pid = 1111) + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.BSD_SOCKSTAT, process_pid = 1111)
@patch('stem.util.system.call') def test_get_connections_by_procstat(self, call_mock): @@ -413,11 +413,11 @@ class TestConnection(unittest.TestCase): ] self.assertEqual(expected, stem.util.connection.get_connections(Resolver.BSD_PROCSTAT, process_pid = 3561, process_name = 'tor'))
- self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.BSD_PROCSTAT, process_pid = 3561, process_name = 'stuff') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.BSD_PROCSTAT, process_pid = 1111, process_name = 'tor') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.BSD_PROCSTAT, process_pid = 3561, process_name = 'stuff') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.BSD_PROCSTAT, process_pid = 1111, process_name = 'tor')
call_mock.side_effect = OSError('Unable to call procstat') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.BSD_PROCSTAT, process_pid = 1111) + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.BSD_PROCSTAT, process_pid = 1111)
@patch('stem.util.system.call') def test_get_connections_by_fstat(self, call_mock): @@ -432,11 +432,11 @@ class TestConnection(unittest.TestCase): ] self.assertEqual(expected, stem.util.connection.get_connections(Resolver.BSD_FSTAT, process_pid = 15843, process_name = 'tor'))
- self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.BSD_FSTAT, process_pid = 15843, process_name = 'stuff') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.BSD_FSTAT, process_pid = 1111, process_name = 'tor') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.BSD_FSTAT, process_pid = 15843, process_name = 'stuff') + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.BSD_FSTAT, process_pid = 1111, process_name = 'tor')
call_mock.side_effect = OSError('Unable to call fstat') - self.assertRaises(IOError, stem.util.connection.get_connections, Resolver.BSD_FSTAT, process_pid = 1111) + self.assertRaises(OSError, stem.util.connection.get_connections, Resolver.BSD_FSTAT, process_pid = 1111)
def test_is_valid_ipv4_address(self): """ diff --git a/test/unit/util/proc.py b/test/unit/util/proc.py index b5667c62..31fd742c 100644 --- a/test/unit/util/proc.py +++ b/test/unit/util/proc.py @@ -174,7 +174,7 @@ class TestProc(unittest.TestCase): # check that we reject bad pids
for arg in (None, -100, 'hello',): - self.assertRaises(IOError, proc.file_descriptors_used, arg) + self.assertRaises(OSError, proc.file_descriptors_used, arg)
# when proc directory doesn't exist
@@ -182,7 +182,7 @@ class TestProc(unittest.TestCase): listdir_mock.side_effect = OSError(error_msg)
exc_msg = 'Unable to check number of file descriptors used: %s' % error_msg - self.assertRaisesWith(IOError, exc_msg, proc.file_descriptors_used, 2118) + self.assertRaisesWith(OSError, exc_msg, proc.file_descriptors_used, 2118)
# successful calls
diff --git a/test/unit/util/system.py b/test/unit/util/system.py index 042c1bd1..fe501389 100644 --- a/test/unit/util/system.py +++ b/test/unit/util/system.py @@ -402,11 +402,11 @@ class TestSystem(unittest.TestCase): self.assertEqual(14, len(list(system.tail(path)))) self.assertEqual(14, len(list(system.tail(path, 200))))
- self.assertRaises(IOError, list, system.tail('/path/doesnt/exist')) + self.assertRaises(OSError, list, system.tail('/path/doesnt/exist'))
fd, temp_path = tempfile.mkstemp() os.chmod(temp_path, 0o077) # remove read permissions - self.assertRaises(IOError, list, system.tail(temp_path)) + self.assertRaises(OSError, list, system.tail(temp_path)) os.close(fd) os.remove(temp_path)
diff --git a/test/unit/version.py b/test/unit/version.py index 33439cf8..70109aca 100644 --- a/test/unit/version.py +++ b/test/unit/version.py @@ -58,7 +58,7 @@ class TestVersion(unittest.TestCase): Tor version output that doesn't include a version within it. """
- self.assertRaisesRegexp(IOError, "'tor_unit --version' didn't provide a parseable version", stem.version.get_system_tor_version, 'tor_unit') + self.assertRaisesRegexp(OSError, "'tor_unit --version' didn't provide a parseable version", stem.version.get_system_tor_version, 'tor_unit')
@patch('stem.util.system.call', Mock(return_value = MALFORMED_TOR_VERSION.splitlines())) @patch.dict(stem.version.VERSION_CACHE) @@ -68,7 +68,7 @@ class TestVersion(unittest.TestCase): version. """
- self.assertRaisesWith(IOError, "'0.2.blah (git-73ff13ab3cc9570d)' isn't a properly formatted tor version", stem.version.get_system_tor_version, 'tor_unit') + self.assertRaisesWith(OSError, "'0.2.blah (git-73ff13ab3cc9570d)' isn't a properly formatted tor version", stem.version.get_system_tor_version, 'tor_unit')
def test_parsing(self): """
tor-commits@lists.torproject.org