diff --git a/neo/io/baseio.py b/neo/io/baseio.py index e3ef71922..3d4fa7fdb 100644 --- a/neo/io/baseio.py +++ b/neo/io/baseio.py @@ -97,7 +97,7 @@ class BaseIO: mode = 'file' # or 'fake' or 'dir' or 'database' def __init__(self, filename=None, **kargs): - self.filename = filename + self.filename = str(filename) # create a logger for the IO class fullname = self.__class__.__module__ + '.' + self.__class__.__name__ self.logger = logging.getLogger(fullname) diff --git a/neo/io/igorproio.py b/neo/io/igorproio.py index 79f8a4109..a18a776af 100644 --- a/neo/io/igorproio.py +++ b/neo/io/igorproio.py @@ -12,7 +12,7 @@ """ from warnings import warn -import numpy as np +import pathlib import quantities as pq from neo.io.baseio import BaseIO from neo.core import Block, Segment, AnalogSignal @@ -66,28 +66,29 @@ def __init__(self, filename=None, parse_notes=None): """ BaseIO.__init__(self) - assert any([filename.endswith('.%s' % x) for x in self.extensions]), \ + filename = pathlib.Path(filename) + assert filename.suffix[1:] in self.extensions, \ "Only the following extensions are supported: %s" % self.extensions self.filename = filename - self.extension = filename.split('.')[-1] + self.extension = filename.suffix[1:] self.parse_notes = parse_notes self._filesystem = None def read_block(self, lazy=False): assert not lazy, 'This IO does not support lazy mode' - block = Block(file_origin=self.filename) + block = Block(file_origin=str(self.filename)) block.segments.append(self.read_segment(lazy=lazy)) block.segments[-1].block = block return block def read_segment(self, lazy=False): assert not lazy, 'This IO does not support lazy mode' - segment = Segment(file_origin=self.filename) + segment = Segment(file_origin=str(self.filename)) if self.extension == 'pxp': if not self._filesystem: - _, self.filesystem = pxp.load(self.filename) + _, self.filesystem = pxp.load(str(self.filename)) def callback(dirpath, key, value): if isinstance(value, WaveRecord): @@ -109,7 +110,7 @@ def read_analogsignal(self, path=None, lazy=False): raise Exception("`igor` package not installed. " "Try `pip install igor`") if self.extension == 'ibw': - data = bw.load(self.filename) + data = bw.load(str(self.filename)) version = data['version'] if version > 5: raise IOError("Igor binary wave file format version {} " @@ -118,7 +119,7 @@ def read_analogsignal(self, path=None, lazy=False): assert type(path) is str, \ "A colon-separated Igor-style path must be provided." if not self._filesystem: - _, self.filesystem = pxp.load(self.filename) + _, self.filesystem = pxp.load(str(self.filename)) path = path.split(':') location = self.filesystem['root'] for element in path: @@ -162,7 +163,7 @@ def _wave_to_analogsignal(self, content, dirpath): signal = AnalogSignal(signal, units=units, copy=False, t_start=t_start, sampling_period=sampling_period, name=name, - file_origin=self.filename, **annotations) + file_origin=str(self.filename), **annotations) return signal diff --git a/neo/io/nixio.py b/neo/io/nixio.py index 320c21ff1..57c017140 100644 --- a/neo/io/nixio.py +++ b/neo/io/nixio.py @@ -175,7 +175,7 @@ def __init__(self, filename, mode="rw"): """ check_nix_version() BaseIO.__init__(self, filename) - self.filename = filename + self.filename = str(filename) if mode == "ro": filemode = nix.FileMode.ReadOnly elif mode == "rw": diff --git a/neo/rawio/axonarawio.py b/neo/rawio/axonarawio.py index 70c347bec..31d824c32 100644 --- a/neo/rawio/axonarawio.py +++ b/neo/rawio/axonarawio.py @@ -22,7 +22,7 @@ import numpy as np import os import re -import contextlib +import pathlib import datetime @@ -66,10 +66,11 @@ class AxonaRawIO(BaseRawIO): def __init__(self, filename): BaseRawIO.__init__(self) + filename = pathlib.Path(filename) # We accept base filenames, .bin and .set extensions - self.filename = filename.replace('.bin', '').replace('.set', '') - self.bin_file = os.path.join(self.filename + '.bin') - self.set_file = os.path.join(self.filename + '.set') + self.filename = filename.with_suffix('') + self.bin_file = self.filename.with_suffix('.bin') + self.set_file = self.filename.with_suffix('.set') self.set_file_encoding = 'cp1252' def _source_name(self): diff --git a/neo/rawio/blackrockrawio.py b/neo/rawio/blackrockrawio.py index 5629f7456..1f3c51d73 100644 --- a/neo/rawio/blackrockrawio.py +++ b/neo/rawio/blackrockrawio.py @@ -132,7 +132,7 @@ def __init__(self, filename=None, nsx_override=None, nev_override=None, """ BaseRawIO.__init__(self) - self.filename = filename + self.filename = str(filename) # remove extension from base _filenames for ext in self.extensions: diff --git a/neo/rawio/elanrawio.py b/neo/rawio/elanrawio.py index 447032168..22759099b 100644 --- a/neo/rawio/elanrawio.py +++ b/neo/rawio/elanrawio.py @@ -22,9 +22,8 @@ import numpy as np import datetime -import os import re -import io +import pathlib class ElanRawIO(BaseRawIO): @@ -33,13 +32,15 @@ class ElanRawIO(BaseRawIO): def __init__(self, filename=None, entfile=None, posfile=None): BaseRawIO.__init__(self) - self.filename = filename + self.filename = pathlib.Path(filename) # check whether ent and pos files are defined + # keep existing suffixes in the process of ent and pos filename + # generation if entfile is None: - entfile = self.filename + '.ent' + entfile = self.filename.with_suffix(self.filename.suffix + '.ent') if posfile is None: - posfile = self.filename + '.pos' + posfile = self.filename.with_suffix(self.filename.suffix + '.pos') self.entfile = entfile self.posfile = posfile diff --git a/neo/rawio/nixrawio.py b/neo/rawio/nixrawio.py index 722144876..d492c7a45 100644 --- a/neo/rawio/nixrawio.py +++ b/neo/rawio/nixrawio.py @@ -42,7 +42,7 @@ class NIXRawIO(BaseRawIO): def __init__(self, filename=''): check_nix_version() BaseRawIO.__init__(self) - self.filename = filename + self.filename = str(filename) def _source_name(self): return self.filename diff --git a/neo/rawio/tdtrawio.py b/neo/rawio/tdtrawio.py index 473bba0d7..3f2a09030 100644 --- a/neo/rawio/tdtrawio.py +++ b/neo/rawio/tdtrawio.py @@ -42,6 +42,7 @@ def __init__(self, dirname='', sortname=''): which uses the original online sort. """ BaseRawIO.__init__(self) + dirname = str(dirname) if dirname.endswith('/'): dirname = dirname[:-1] self.dirname = dirname diff --git a/neo/test/iotest/common_io_test.py b/neo/test/iotest/common_io_test.py index 6610391ca..59466036f 100644 --- a/neo/test/iotest/common_io_test.py +++ b/neo/test/iotest/common_io_test.py @@ -21,6 +21,7 @@ import inspect from copy import copy import unittest +import pathlib from neo.core import Block, Segment from neo.io.basefromrawio import BaseFromRaw @@ -39,6 +40,7 @@ close_object_safe, create_generic_io_object, create_generic_reader, create_generic_writer, + get_test_file_full_path, iter_generic_io_objects, iter_generic_readers, iter_read_objects, read_generic, @@ -205,65 +207,6 @@ def generic_io_object(self, filename=None, return_path=False, clean=False): return_path=return_path, clean=clean) - def create_file_reader(self, filename=None, return_path=False, - clean=False, target=None, readall=False): - ''' - Create a function that can read from the specified filename. - - If filename is None, create a filename (default). - - If return_path is True, return the full path of the file along with - the reader function. return reader, path. Default is False. - - If clean is True, try to delete existing versions of the file - before creating the io object. Default is False. - - If target is None, use the first supported_objects from ioobj - If target is False, use the 'read' method. - If target is the Block or Segment class, use read_block or - read_segment, respectively. - If target is a string, use 'read_'+target. - - If readall is True, use the read_all_ method instead of the read_ - method. Default is False. - ''' - ioobj, path = self.generic_io_object(filename=filename, - return_path=True, clean=clean) - - res = create_generic_reader(ioobj, target=target, readall=readall) - - if return_path: - return res, path - return res - - def create_file_writer(self, filename=None, return_path=False, - clean=False, target=None): - ''' - Create a function that can write from the specified filename. - - If filename is None, create a filename (default). - - If return_path is True, return the full path of the file along with - the writer function. return writer, path. Default is False. - - If clean is True, try to delete existing versions of the file - before creating the io object. Default is False. - - If target is None, use the first supported_objects from ioobj - If target is False, use the 'write' method. - If target is the Block or Segment class, use write_block or - write_segment, respectively. - If target is a string, use 'write_'+target. - ''' - ioobj, path = self.generic_io_object(filename=filename, - return_path=True, clean=clean) - - res = create_generic_writer(ioobj, target=target) - - if return_path: - return res, path - return res - def read_file(self, filename=None, return_path=False, clean=False, target=None, readall=False, lazy=False): ''' @@ -569,3 +512,14 @@ def test_create_group_across_segment(self): reader(lazy=self.ioclass.support_lazy, create_group_across_segment=case) else: reader(lazy=self.ioclass.support_lazy, create_group_across_segment=case) + + def test__handle_pathlib_filename(self): + if self.files_to_test: + filename = get_test_file_full_path(self.ioclass, filename=self.files_to_test[0], + directory=self.local_test_dir) + pathlib_filename = pathlib.Path(filename) + + if self.ioclass.mode == 'file': + self.ioclass(filename=pathlib_filename) + elif self.ioclass.mode == 'dir': + self.ioclass(dirname=pathlib_filename) diff --git a/neo/test/iotest/tools.py b/neo/test/iotest/tools.py index bc49d7e12..8eb8c7d06 100644 --- a/neo/test/iotest/tools.py +++ b/neo/test/iotest/tools.py @@ -45,23 +45,16 @@ def cleanup_test_file(mode, path, directory=None): shutil.rmtree(path) -def get_test_file_full_path(ioclass, filename=None, - directory=None, clean=False): +def get_test_file_full_path(ioclass, filename=None, directory=None, clean=False): """ Get the full path for a file of the given filename. If filename is None, create a filename. - If filename is a list, get the full path for each item in the list. - If return_path is True, also return the full path to the file. - If directory is not None and path is not an absolute path already, use the file from the given directory. - If return_path is True, return the full path of the file along with - the io object. return reader, path. Default is False. - If clean is True, try to delete existing versions of the file before creating the io object. Default is False. """