From 78969b7d137703737f7b0fdd3c20fa8b208219c5 Mon Sep 17 00:00:00 2001 From: jgd10 Date: Wed, 19 Jan 2022 14:51:21 +0000 Subject: [PATCH 1/3] Incorporated pathlib.Path compatibility In this commit I have added input (and explicit output) compatibility between pymapdl-reader and the pathlib.Path class. All file path-input arguments should now be accepted as either strings or pathlib.Path objects. Additionally there is no breaing change regarding the filename properties. These will continue to return strings. Wherever possible I have made it so that internally we store paths as pathlib.Path objects and they are returned as strings through properties. Setters additionally will accept strings or pathlib.Path objects. Unfortunately i have not been able to get the test suite working on my local machine and so have not been able to write tests to go with these changes. I would appreciate input from others regarding how to get the tests running and if my changes do break any existing tests. I do not believe so but I am very limited in how I can check. --- ansys/mapdl/reader/archive.py | 24 +++++++++++++++---- ansys/mapdl/reader/common.py | 16 ++++++------- ansys/mapdl/reader/cyclic_reader.py | 1 + ansys/mapdl/reader/dis_result.py | 4 +++- ansys/mapdl/reader/emat.py | 32 ++++++++++++++++++------- ansys/mapdl/reader/full.py | 29 ++++++++++++++++------- ansys/mapdl/reader/mesh.py | 4 ++-- ansys/mapdl/reader/rst.py | 36 +++++++++++++++++++++-------- 8 files changed, 106 insertions(+), 40 deletions(-) diff --git a/ansys/mapdl/reader/archive.py b/ansys/mapdl/reader/archive.py index 2553e07f..7e5f2785 100644 --- a/ansys/mapdl/reader/archive.py +++ b/ansys/mapdl/reader/archive.py @@ -3,6 +3,8 @@ import os import logging from functools import wraps +import pathlib +from typing import Union import numpy as np from pyvista._vtk import (VTK_TETRA, VTK_QUADRATIC_TETRA, VTK_PYRAMID, @@ -37,7 +39,7 @@ class Archive(Mesh): Parameters ---------- - filename : string + filename : string, pathlib.Path Filename of block formatted cdb file read_parameters : bool, optional @@ -113,9 +115,9 @@ def __init__(self, filename, read_parameters=False, verbose=False, name=''): """Initializes an instance of the archive class.""" self._read_parameters = read_parameters - self._filename = filename + self._filename = pathlib.Path(filename) self._name = name - self._raw = _reader.read(filename, read_parameters=read_parameters, + self._raw = _reader.read(self.filename, read_parameters=read_parameters, debug=verbose) super().__init__(self._raw['nnum'], self._raw['nodes'], @@ -136,6 +138,20 @@ def __init__(self, filename, read_parameters=False, self._grid = self._parse_vtk(allowable_types, force_linear, null_unallowed) + @property + def filename(self) -> str: + """String form of the filename. Accepts ``pathlib.Path`` and string objects when set.""" + return str(self._filename) + + @property + def pathlib_filename(self) -> pathlib.Path: + """Return the ``pathlib.Path`` version of the filename. This property can not be set.""" + return self._filename + + @filename.setter + def filename(self, value: Union[str, pathlib.Path]): + self._filename = pathlib.Path(value) + @property def raw(self): # pragma: no cover raise AttributeError('The `raw` attribute has been depreciated. Access' @@ -262,7 +278,7 @@ def save_as_archive(filename, grid, mtype_start=1, etype_start=1, Parameters ---------- - filename : str + filename : str, pathlib.Path Filename to write archive file. grid : vtk.UnstructuredGrid diff --git a/ansys/mapdl/reader/common.py b/ansys/mapdl/reader/common.py index b1afffb7..30cfff19 100644 --- a/ansys/mapdl/reader/common.py +++ b/ansys/mapdl/reader/common.py @@ -1,6 +1,7 @@ """Methods common to binary files""" import struct -import os +import pathlib +from typing import Union from collections import Counter import numpy as np @@ -24,7 +25,6 @@ 45: 'Component Mode Synthesis Matrices (CMS) File'} - # c *** standard usage of the block number (buffers) and file unit number(FUN) # c for the ansys files # c @@ -61,9 +61,9 @@ # c ASI -> ASIRSTNM FUN66 9 asi results -class AnsysBinary(): +class AnsysBinary: """ANSYS binary file class""" - filename = None + filename: Union[str, pathlib.Path] = None # read only file handle _cfile = None @@ -120,7 +120,7 @@ def read_binary(filename, **kwargs): Parameters ---------- - filename : str + filename : str, pathlib.Path Filename to read. **kwargs : keyword arguments @@ -148,9 +148,9 @@ def read_binary(filename, **kwargs): - Jobname.RMG A magnetic analysis - Jobname.RFL A FLOTRAN analysis (a legacy results file) """ - if not os.path.isfile(filename): - raise FileNotFoundError('%s is not a file or cannot be found' % - str(filename)) + filename = pathlib.Path(filename) + if not filename.is_file(): + raise FileNotFoundError(f'{filename} is not a file or cannot be found') file_format = read_standard_header(filename)['file format'] diff --git a/ansys/mapdl/reader/cyclic_reader.py b/ansys/mapdl/reader/cyclic_reader.py index fbbcb440..33d77fd9 100644 --- a/ansys/mapdl/reader/cyclic_reader.py +++ b/ansys/mapdl/reader/cyclic_reader.py @@ -1645,6 +1645,7 @@ def animate_nodal_solution(self, rnum, comp='norm', plotter.camera_position = cpos if movie_filename: + movie_filename = str(movie_filename) if movie_filename.strip()[-3:] == 'gif': plotter.open_gif(movie_filename) else: diff --git a/ansys/mapdl/reader/dis_result.py b/ansys/mapdl/reader/dis_result.py index 98f78a5a..cf905246 100644 --- a/ansys/mapdl/reader/dis_result.py +++ b/ansys/mapdl/reader/dis_result.py @@ -3,6 +3,8 @@ import glob import os from functools import wraps +from typing import Union +import pathlib import pyvista as pv import numpy as np @@ -17,7 +19,7 @@ from ansys.mapdl.reader._rst_keys import element_index_table_info -def find_dis_files(main_file): +def find_dis_files(main_file: Union[str, pathlib.Path]): """Find the individual distributed result files given a main result file""" basename = os.path.basename(main_file) jobname = basename[:basename.rfind('0')] diff --git a/ansys/mapdl/reader/emat.py b/ansys/mapdl/reader/emat.py index 7fb3c2ab..963fee44 100644 --- a/ansys/mapdl/reader/emat.py +++ b/ansys/mapdl/reader/emat.py @@ -311,6 +311,8 @@ c kygrf global restoring force matrix calculate key """ +import pathlib + import numpy as np from ansys.mapdl.reader.common import read_table, parse_header @@ -334,7 +336,7 @@ class EmatFile(object): Parameters ---------- - filename : str + filename : str, pathlib.Path File to open. Generally ends in ``*.emat``. Examples @@ -350,12 +352,26 @@ def __init__(self, filename): self._nnum = None self._eeqv = None self._enum = None - self.filename = filename + self._filename = pathlib.Path(filename) self.read_header() + @property + def filename(self): + """String form of the filename. Accepts ``pathlib.Path`` and string objects when set.""" + return str(self._filename) + + @property + def pathlib_filename(self): + """Return the ``pathlib.Path`` version of the filename. This property can not be set.""" + return self._filename + + @filename.setter + def filename(self, value): + self._filename = pathlib.Path(value) + def read_header(self): """Read standard emat file header""" - with open(self.filename, 'rb') as f: + with open(self.pathlib_filename, 'rb') as f: f.seek(103*4) self.header = parse_header(read_table(f), EMAT_HEADER_KEYS) @@ -402,7 +418,7 @@ def read_element_matrix_header(self, f_index): lower triangular form. """ - with open(self.filename, 'rb') as f: + with open(self.pathlib_filename, 'rb') as f: f.seek(4*f_index) return parse_header(read_table(f), ELEMENT_HEADER_KEYS) @@ -410,7 +426,7 @@ def read_element_matrix_header(self, f_index): def element_matrices_index_table(self): """Return element matrices index table""" if self._element_matrices_index_table is None: - with open(self.filename, 'rb') as f: + with open(self.pathlib_filename, 'rb') as f: f.seek(self.header['ptrIDX']*4) self._element_matrices_index_table = read_table(f) return self._element_matrices_index_table @@ -435,7 +451,7 @@ def neqv(self): for storage to the actual node number. """ if self._neqv is None: - with open(self.filename, 'rb') as f: + with open(self.pathlib_filename, 'rb') as f: f.seek(self.header['ptrBAC']*4) self._neqv = read_table(f) return self._neqv @@ -459,7 +475,7 @@ def eeqv(self): table equates the order number used to the actual element. """ if self._eeqv is None: - with open(self.filename, 'rb') as f: + with open(self.pathlib_filename, 'rb') as f: f.seek(self.header['ptrElm']*4) self._eeqv = read_table(f) return self._eeqv @@ -540,7 +556,7 @@ def read_element(self, index, stress=True, mass=True, reference number given by ``dof_idx``. """ element_data = {} - with open(self.filename, 'rb') as fobj: + with open(self.pathlib_filename, 'rb') as fobj: # seek to the position of the element table in the file fobj.seek(self.element_matrices_index_table[index]*4) diff --git a/ansys/mapdl/reader/full.py b/ansys/mapdl/reader/full.py index ed93f334..967b3203 100644 --- a/ansys/mapdl/reader/full.py +++ b/ansys/mapdl/reader/full.py @@ -4,7 +4,9 @@ """ import os +import pathlib import warnings +from typing import Union import numpy as np @@ -68,7 +70,7 @@ class FullFile(AnsysBinary): """ - def __init__(self, filename): + def __init__(self, filename: Union[str, pathlib.Path]): """Loads full header on initialization. See ANSYS programmer's reference manual full header section @@ -86,13 +88,10 @@ def __init__(self, filename): self._m = None self._dof_ref = None - self.filename = filename + self._filename = pathlib.Path(filename) self._standard_header = read_standard_header(self.filename) self._header = parse_header(self.read_record(103), SYMBOLIC_FULL_HEADER_KEYS) - # if not self._header['fun04'] < 0: - # raise NotImplementedError("Unable to read a frontal assembly full file") - # Check if lumped (item 11) if self._header['lumpm']: raise NotImplementedError("Unable to read a lumped mass matrix") @@ -101,6 +100,20 @@ def __init__(self, filename): if self._header['keyuns']: raise NotImplementedError("Unable to read an unsymmetric mass/stiffness matrix") + @property + def filename(self): + """String form of the filename. Accepts ``pathlib.Path`` and string objects when set.""" + return str(self._filename) + + @property + def pathlib_filename(self): + """Return the ``pathlib.Path`` version of the filename. This property can not be set.""" + return self._filename + + @filename.setter + def filename(self, value): + self._filename = pathlib.Path(value) + @property def k(self): """Stiffness Matrix corresponding to sorted DOF. @@ -221,8 +234,8 @@ def load_km(self, as_sparse=True, sort=False): Constrained DOF can be accessed from ``const``, which returns the node number and DOF constrained in ANSYS. """ - if not os.path.isfile(self.filename): - raise Exception('%s not found' % self.filename) + if not self.pathlib_filename.is_file(): + raise Exception('%s not found' % self.pathlib_filename) if as_sparse: try: @@ -242,7 +255,7 @@ def load_km(self, as_sparse=True, sort=False): ptrDOF = self._header['ptrDOF'] # pointer to DOF info # DOF information - with open(self.filename, 'rb') as f: + with open(self.pathlib_filename, 'rb') as f: read_table(f, skip=True) # standard header read_table(f, skip=True) # full header read_table(f, skip=True) # number of degrees of freedom diff --git a/ansys/mapdl/reader/mesh.py b/ansys/mapdl/reader/mesh.py index a42cdf2a..ecd1bade 100644 --- a/ansys/mapdl/reader/mesh.py +++ b/ansys/mapdl/reader/mesh.py @@ -558,7 +558,7 @@ def save(self, filename, binary=True, force_linear=False, allowable_types=[], Parameters ---------- - filename : str + filename : str, pathlib.Path Filename of output file. Writer type is inferred from the extension of the filename. @@ -593,7 +593,7 @@ def save(self, filename, binary=True, force_linear=False, allowable_types=[], grid = self._parse_vtk(allowable_types=allowable_types, force_linear=force_linear, null_unallowed=null_unallowed) - return grid.save(filename, binary=binary) + return grid.save(str(filename), binary=binary) @property def n_node(self): diff --git a/ansys/mapdl/reader/rst.py b/ansys/mapdl/reader/rst.py index f94d58e8..11bc8f1d 100644 --- a/ansys/mapdl/reader/rst.py +++ b/ansys/mapdl/reader/rst.py @@ -8,6 +8,8 @@ import warnings from threading import Thread from functools import wraps +from typing import Union +import pathlib import numpy as np import pyvista as pv @@ -75,7 +77,7 @@ class Result(AnsysBinary): Parameters ---------- - filename : str, optional + filename : str, pathlib.Path, optional Filename of the ANSYS binary result file. ignore_cyclic : bool, optional Ignores any cyclic properties. @@ -97,7 +99,7 @@ class Result(AnsysBinary): def __init__(self, filename, read_mesh=True, parse_vtk=True, **kwargs): """Load basic result information from result file and init the rst object.""" - self.filename = filename + self._filename = pathlib.Path(filename) self._cfile = AnsysFile(filename) self._resultheader = self._read_result_header() self._animating = False @@ -131,6 +133,20 @@ def __init__(self, filename, read_mesh=True, parse_vtk=True, **kwargs): if read_mesh: self._store_mesh(parse_vtk) + @property + def filename(self) -> str: + """String form of the filename. Accepts ``pathlib.Path`` and string objects when set.""" + return str(self._filename) + + @property + def pathlib_filename(self) -> pathlib.Path: + """Return the ``pathlib.Path`` version of the filename. This property can not be set.""" + return self._filename + + @filename.setter + def filename(self, value: Union[str, pathlib.Path]): + self._filename = pathlib.Path(value) + @property def mesh(self): """Mesh from result file. @@ -868,7 +884,7 @@ def animate_nodal_solution(self, rnum, comp='norm', animate once and close. Automatically disabled when ``off_screen=True`` and ``movie_filename`` is set. - movie_filename : str, optional + movie_filename : str, pathlib.Path, optional Filename of the movie to open. Filename should end in ``'mp4'``, but other filetypes may be supported like ``"gif"``. See ``imagio.get_writer``. A single loop of @@ -2794,6 +2810,7 @@ def _plot_point_scalars(self, scalars, rnum=None, grid=None, plotter.camera_position = cpos if movie_filename: + movie_filename = str(movie_filename) if movie_filename.strip()[-3:] == 'gif': plotter.open_gif(movie_filename) else: @@ -3014,6 +3031,7 @@ def _animate_point_scalars(self, scalars, grid=None, plotter.camera_position = cpos if movie_filename: + movie_filename = str(movie_filename) if movie_filename.strip()[-3:] == 'gif': plotter.open_gif(movie_filename) else: @@ -3167,7 +3185,7 @@ def save_as_vtk(self, filename, rsets=None, result_types=['ENS'], Parameters ---------- - filename : str + filename : str, pathlib.Path Filename of grid to be written. The file extension will select the type of writer to use. ``'.vtk'`` will use the legacy writer, while ``'.vtu'`` will select the VTK XML @@ -3273,23 +3291,23 @@ def save_as_vtk(self, filename, rsets=None, result_types=['ENS'], if pbar is not None: pbar.update(1) - grid.save(filename) + grid.save(str(filename)) if pbar is not None: pbar.close() - def write_tables(self, filename): + def write_tables(self, filename: Union[str, pathlib.Path]): """Write binary tables to ASCII. Assumes int32 Parameters ---------- - filename : str + filename : str, pathlib.Path Filename to write the tables to. Examples -------- >>> rst.write_tables('tables.txt') """ - rawresult = open(self.filename, 'rb') + rawresult = open(self.pathlib_filename, 'rb') with open(filename, 'w') as f: while True: try: @@ -4714,7 +4732,7 @@ def _is_main(self): @property def _is_thermal(self): """True when result file is a rth file""" - return self.filename[-3:] == 'rth' + return self.pathlib_filename.suffix == 'rth' @property def _is_cyclic(self): From 0ad8342a355b216530407024f94c7005c622f02b Mon Sep 17 00:00:00 2001 From: jgd10 Date: Wed, 26 Jan 2022 10:08:42 +0000 Subject: [PATCH 2/3] changed suffix comparison to include the . Changed the suffix comparison to include the leading '.' because pathlib.Path.suffix does include it. Made sure that AnsysFile converts any potential paths to string before they are passed as arguments. Additionally split thermal test up until multiple tests within a class to make it easier to read. All existing tests pass with pathlib changes. --- ansys/mapdl/reader/rst.py | 4 ++-- tests/test_binary_reader.py | 47 +++++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/ansys/mapdl/reader/rst.py b/ansys/mapdl/reader/rst.py index 11bc8f1d..1725a42a 100644 --- a/ansys/mapdl/reader/rst.py +++ b/ansys/mapdl/reader/rst.py @@ -100,7 +100,7 @@ class Result(AnsysBinary): def __init__(self, filename, read_mesh=True, parse_vtk=True, **kwargs): """Load basic result information from result file and init the rst object.""" self._filename = pathlib.Path(filename) - self._cfile = AnsysFile(filename) + self._cfile = AnsysFile(str(filename)) self._resultheader = self._read_result_header() self._animating = False self.__element_map = None @@ -4732,7 +4732,7 @@ def _is_main(self): @property def _is_thermal(self): """True when result file is a rth file""" - return self.pathlib_filename.suffix == 'rth' + return self.pathlib_filename.suffix == '.rth' @property def _is_cyclic(self): diff --git a/tests/test_binary_reader.py b/tests/test_binary_reader.py index ca82a91c..035be547 100644 --- a/tests/test_binary_reader.py +++ b/tests/test_binary_reader.py @@ -435,23 +435,36 @@ def test_reaction_forces(): assert np.allclose(forces[:, 1], [-600, 250, 500, -900]) -def test_thermal_result(thermal_rst): - assert thermal_rst._is_thermal - assert thermal_rst.result_dof(0) == ['TEMP'] - with pytest.raises(AttributeError): - thermal_rst.nodal_displacement() - - with pytest.raises(AttributeError): - thermal_rst.nodal_velocity(0) - - with pytest.raises(AttributeError): - thermal_rst.nodal_acceleration(0) - - with pytest.raises(AttributeError): - thermal_rst.plot_nodal_solution(0, 'NORM') - - with pytest.raises(ValueError): - thermal_rst.plot_nodal_solution(0, 'ROTX') +class TestThermalResult: + def test_nodal_displacement(self, thermal_rst): + assert thermal_rst._is_thermal + assert thermal_rst.result_dof(0) == ['TEMP'] + with pytest.raises(AttributeError): + thermal_rst.nodal_displacement() + + def test_nodal_velocity(self, thermal_rst): + assert thermal_rst._is_thermal + assert thermal_rst.result_dof(0) == ['TEMP'] + with pytest.raises(AttributeError): + thermal_rst.nodal_velocity(0) + + def test_nodal_acceleration(self, thermal_rst): + assert thermal_rst._is_thermal + assert thermal_rst.result_dof(0) == ['TEMP'] + with pytest.raises(AttributeError): + thermal_rst.nodal_acceleration(0) + + def test_nodal_solution(self, thermal_rst): + assert thermal_rst._is_thermal + assert thermal_rst.result_dof(0) == ['TEMP'] + with pytest.raises(AttributeError): + thermal_rst.plot_nodal_solution(0, 'NORM') + + def test_plot_nodal_solution(self, thermal_rst): + assert thermal_rst._is_thermal + assert thermal_rst.result_dof(0) == ['TEMP'] + with pytest.raises(ValueError): + thermal_rst.plot_nodal_solution(0, 'ROTX') def test_plot_temperature(thermal_rst): From 02f73c783eed2d9a5ae4001772d1121bcbb7b107 Mon Sep 17 00:00:00 2001 From: jgd10 Date: Wed, 26 Jan 2022 11:21:38 +0000 Subject: [PATCH 3/3] Added tests for each altered class Added additional tests to check the input and output is correct for the 4 classes that use pathlib.Path now. --- tests/archive/test_archive.py | 28 ++++++++++++++++++++++++++ tests/test_emat.py | 25 +++++++++++++++++++++++ tests/test_full.py | 26 ++++++++++++++++++++++++ tests/test_rst.py | 38 +++++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+) diff --git a/tests/archive/test_archive.py b/tests/archive/test_archive.py index 59bf3163..21475458 100644 --- a/tests/archive/test_archive.py +++ b/tests/archive/test_archive.py @@ -1,4 +1,5 @@ import os +import pathlib import pytest import numpy as np @@ -19,6 +20,7 @@ TEST_PATH = os.path.dirname(os.path.abspath(__file__)) TESTFILES_PATH = os.path.join(TEST_PATH, 'test_data') +TESTFILES_PATH_PATHLIB = pathlib.Path(TESTFILES_PATH) DAT_FILE = os.path.join(TESTFILES_PATH, 'Panel_Transient.dat') @@ -49,6 +51,12 @@ def proto_cmblock(array): return items[:c] +@pytest.fixture() +def pathlib_archive(): + filename = TESTFILES_PATH_PATHLIB / 'ErnoRadiation.cdb' + return pymapdl_reader.Archive(filename) + + @pytest.fixture() def hex_archive(): return pymapdl_reader.Archive(examples.hexarchivefile) @@ -440,3 +448,23 @@ def test_rlblock_prior_to_nblock(): archive = pymapdl_reader.Archive(filename) assert archive.n_node == 65 assert archive.n_elem == 36 + + +class TestPathlibFilename: + def test_pathlib_filename_property(self, pathlib_archive): + assert isinstance(pathlib_archive.pathlib_filename, pathlib.Path) + + def test_filename_property_is_string(self, pathlib_archive): + filename = TESTFILES_PATH_PATHLIB / 'ErnoRadiation.cdb' + a = pymapdl_reader.Archive(filename) + assert isinstance(a.filename, str) + + def test_filename_setter_pathlib(self, pathlib_archive): + pathlib_archive.filename = pathlib.Path('dummy2') + assert isinstance(pathlib_archive.filename, str) + assert isinstance(pathlib_archive.pathlib_filename, pathlib.Path) + + def test_filename_setter_string(self, pathlib_archive): + pathlib_archive.filename = 'dummy2' + assert isinstance(pathlib_archive.filename, str) + assert isinstance(pathlib_archive.pathlib_filename, pathlib.Path) diff --git a/tests/test_emat.py b/tests/test_emat.py index 5654395b..abbec3c1 100644 --- a/tests/test_emat.py +++ b/tests/test_emat.py @@ -1,4 +1,5 @@ import os +import pathlib import pytest import numpy as np @@ -19,6 +20,12 @@ def emat(): return emat_bin +@pytest.fixture(scope='module') +def emat_pathlib(): + emat_bin = EmatFile(pathlib.Path(emat_filename)) + return emat_bin + + def test_load_element(emat): dof_idx, element_data = emat.read_element(0) assert 'stress' in element_data @@ -36,3 +43,21 @@ def test_eeqv(emat): def test_neqv(emat): assert np.allclose(np.sort(emat.neqv), emat.nnum) + + +class TestPathlibFilename: + def test_pathlib_filename_property(self, emat_pathlib): + assert isinstance(emat_pathlib.pathlib_filename, pathlib.Path) + + def test_filename_property_is_string(self, emat_pathlib): + assert isinstance(emat_pathlib.filename, str) + + def test_filename_setter_pathlib(self, emat_pathlib): + emat_pathlib.filename = pathlib.Path('dummy2') + assert isinstance(emat_pathlib.filename, str) + assert isinstance(emat_pathlib.pathlib_filename, pathlib.Path) + + def test_filename_setter_string(self, emat_pathlib): + emat_pathlib.filename = 'dummy2' + assert isinstance(emat_pathlib.filename, str) + assert isinstance(emat_pathlib.pathlib_filename, pathlib.Path) diff --git a/tests/test_full.py b/tests/test_full.py index 268a84b5..6f3d833d 100644 --- a/tests/test_full.py +++ b/tests/test_full.py @@ -2,15 +2,23 @@ import scipy import pytest +import pathlib import numpy as np from ansys.mapdl import reader as pymapdl_reader from ansys.mapdl.reader import examples +from ansys.mapdl.reader.full import FullFile test_path = os.path.dirname(os.path.abspath(__file__)) testfiles_path = os.path.join(test_path, 'testfiles') +@pytest.fixture() +def sparse_full_pathlib_full_file(): + filename = os.path.join(testfiles_path, 'sparse.full') + return FullFile(pathlib.Path(filename)) + + @pytest.fixture() def sparse_full(): filename = os.path.join(testfiles_path, 'sparse.full') @@ -67,3 +75,21 @@ def test_full_load_km(sparse_full): def test_load_vector(sparse_full): assert not sparse_full.load_vector.any() + + +class TestPathlibFilename: + def test_pathlib_filename_property(self, sparse_full_pathlib_full_file): + assert isinstance(sparse_full_pathlib_full_file.pathlib_filename, pathlib.Path) + + def test_filename_property_is_string(self, sparse_full_pathlib_full_file): + assert isinstance(sparse_full_pathlib_full_file.filename, str) + + def test_filename_setter_pathlib(self, sparse_full_pathlib_full_file): + sparse_full_pathlib_full_file.filename = pathlib.Path('dummy2') + assert isinstance(sparse_full_pathlib_full_file.filename, str) + assert isinstance(sparse_full_pathlib_full_file.pathlib_filename, pathlib.Path) + + def test_filename_setter_string(self, sparse_full_pathlib_full_file): + sparse_full_pathlib_full_file.filename = 'dummy2' + assert isinstance(sparse_full_pathlib_full_file.filename, str) + assert isinstance(sparse_full_pathlib_full_file.pathlib_filename, pathlib.Path) diff --git a/tests/test_rst.py b/tests/test_rst.py index 3a266ec8..63569543 100644 --- a/tests/test_rst.py +++ b/tests/test_rst.py @@ -32,6 +32,7 @@ mapdl.modal_analysis(nmode=1) """ +import pathlib import platform import os from shutil import copy @@ -43,6 +44,7 @@ from ansys.mapdl import reader as pymapdl_reader from ansys.mapdl.reader import examples +from ansys.mapdl.reader.rst import Result from ansys.mapdl.reader.examples.downloads import _download_and_read try: @@ -84,6 +86,12 @@ temperature_known_result = os.path.join(testfiles_path, 'temp_v13.npz') +@pytest.fixture(scope='module') +def pathlib_result(): + temperature_rst_pathlib = pathlib.Path(temperature_rst) + return Result(temperature_rst_pathlib) + + @pytest.fixture(scope='module') def hex_pipe_corner(): filename = os.path.join(testfiles_path, 'rst', 'cyc_stress.rst') @@ -310,6 +318,36 @@ def test_plot_nodal_temperature(): temp_rst.plot_nodal_temperature(0, off_screen=True) +class TestPathlibFilename: + @skip_plotting + @pytest.mark.skipif(not os.path.isfile(temperature_rst), + reason="Requires example files") + def test_pathlib_filename_property(self, pathlib_result): + assert isinstance(pathlib_result.pathlib_filename, pathlib.Path) + + @skip_plotting + @pytest.mark.skipif(not os.path.isfile(temperature_rst), + reason="Requires example files") + def test_filename_property_is_string(self, pathlib_result): + assert isinstance(pathlib_result.filename, str) + + @skip_plotting + @pytest.mark.skipif(not os.path.isfile(temperature_rst), + reason="Requires example files") + def test_filename_setter_pathlib(self, pathlib_result): + pathlib_result.filename = pathlib.Path('dummy2') + assert isinstance(pathlib_result.filename, str) + assert isinstance(pathlib_result.pathlib_filename, pathlib.Path) + + @skip_plotting + @pytest.mark.skipif(not os.path.isfile(temperature_rst), + reason="Requires example files") + def test_filename_setter_string(self, pathlib_result): + pathlib_result.filename = 'dummy2' + assert isinstance(pathlib_result.filename, str) + assert isinstance(pathlib_result.pathlib_filename, pathlib.Path) + + def test_rst_node_components(hex_rst): assert 'ELEM_COMP' not in hex_rst.node_components np.allclose(hex_rst.node_components['NODE_COMP'].nonzero()[0],