2626import importlib
2727import inspect
2828import os
29- from pathlib import Path
3029import platform
3130import re
3231import socket
3332import string
3433import tempfile
3534from threading import Thread
36- from typing import Union
35+ from typing import Callable , Dict , Iterable , List , Tuple , Union
3736from warnings import warn
3837
3938import numpy as np
4039
41- from ansys .mapdl import core as pymapdl
4240from ansys .mapdl .core import _HAS_PYVISTA , LOG
4341
4442# path of this module
@@ -59,7 +57,7 @@ class ROUTINES(Enum):
5957 AUX15 = 65
6058
6159
62- def check_valid_routine (routine ) :
60+ def check_valid_routine (routine : ROUTINES ) -> bool :
6361 """Check if a routine is valid.
6462
6563 Acceptable aliases for "Begin level" include "begin".
@@ -98,7 +96,7 @@ def check_valid_routine(routine):
9896 return True
9997
10098
101- def is_float (input_string ) :
99+ def is_float (input_string : str ) -> bool :
102100 """Returns true when a string can be converted to a float"""
103101 try :
104102 float (input_string )
@@ -107,14 +105,14 @@ def is_float(input_string):
107105 return False
108106
109107
110- def random_string (stringLength = 10 , letters = string .ascii_lowercase ):
108+ def random_string (stringLength : int = 10 , letters : str = string .ascii_lowercase ) -> str :
111109 """Generate a random string of fixed length"""
112110 import secrets
113111
114112 return "" .join (secrets .choice (letters ) for _ in range (stringLength ))
115113
116114
117- def _check_has_ansys ():
115+ def _check_has_ansys () -> bool :
118116 """Safely wraps check_valid_ansys
119117
120118 Returns
@@ -131,7 +129,7 @@ def _check_has_ansys():
131129 return False
132130
133131
134- def supress_logging (func ) :
132+ def supress_logging (func : Callable ) -> Callable :
135133 """Decorator to suppress logging for a MAPDL instance"""
136134
137135 @wraps (func )
@@ -182,7 +180,7 @@ def wrapper(self, *args, **kwargs):
182180 return decorator
183181
184182
185- def threaded (func ) :
183+ def threaded (func : Callable ) -> Callable :
186184 """Decorator to call a function using a thread"""
187185
188186 @wraps (func )
@@ -196,7 +194,7 @@ def wrapper(*args, **kwargs):
196194 return wrapper
197195
198196
199- def threaded_daemon (func ) :
197+ def threaded_daemon (func : Callable ) -> Callable :
200198 """Decorator to call a function using a daemon thread."""
201199
202200 @wraps (func )
@@ -214,18 +212,18 @@ def wrapper(*args, **kwargs):
214212 return wrapper
215213
216214
217- def unique_rows (a ) :
218- """Returns unique rows of a and indices of those rows"""
219- if not a .flags .c_contiguous :
220- a = np .ascontiguousarray (a )
215+ def unique_rows (arr : np . ndarray ) -> Tuple [ Union [ np . ndarray , np . ndarray , np . ndarray ]] :
216+ """Returns unique rows of `arr` and indices of those rows"""
217+ if not arr .flags .c_contiguous :
218+ arr = np .ascontiguousarray (arr )
221219
222- b = a .view (np .dtype ((np .void , a .dtype .itemsize * a .shape [1 ])))
220+ b = arr .view (np .dtype ((np .void , arr .dtype .itemsize * arr .shape [1 ])))
223221 _ , idx , idx2 = np .unique (b , True , True )
224222
225- return a [idx ], idx , idx2
223+ return arr [idx ], idx , idx2
226224
227225
228- def creation_time (path_to_file ) :
226+ def creation_time (path_to_file : str ) -> float :
229227 """The file creation time.
230228
231229 Try to get the date that a file was created, falling back to when
@@ -237,7 +235,7 @@ def creation_time(path_to_file):
237235 else :
238236 stat = os .stat (path_to_file )
239237 try :
240- return stat .st_birthtime
238+ return float ( stat .st_birthtime )
241239 except AttributeError :
242240 LOG .debug (
243241 "We're probably on Linux. No easy way to get creation dates here, "
@@ -246,7 +244,7 @@ def creation_time(path_to_file):
246244 return stat .st_mtime
247245
248246
249- def last_created (filenames ) :
247+ def last_created (filenames : List [ str ]) -> str :
250248 """Return the last created file given a list of filenames
251249
252250 If all filenames have the same creation time, then return the last
@@ -260,7 +258,7 @@ def last_created(filenames):
260258 return filenames [idx ]
261259
262260
263- def create_temp_dir (tmpdir = None , name = None ):
261+ def create_temp_dir (tmpdir : str = None , name : str = None ) -> str :
264262 """Create a new unique directory at a given temporary directory"""
265263 if tmpdir is None :
266264 tmpdir = tempfile .gettempdir ()
@@ -285,7 +283,7 @@ def get_name():
285283 return path
286284
287285
288- def no_return (func ) :
286+ def no_return (func : Callable ) -> Callable :
289287 """Decorator to return nothing from the wrapped function"""
290288
291289 @wraps (func )
@@ -296,14 +294,14 @@ def wrapper(*args, **kwargs):
296294 return wrapper
297295
298296
299- def get_bounding_box (nodes_xyz ) :
297+ def get_bounding_box (nodes_xyz : np . ndarray ) -> np . ndarray :
300298 min_ = np .min (nodes_xyz , axis = 0 )
301299 max_ = np .max (nodes_xyz , axis = 0 )
302300
303301 return max_ - min_
304302
305303
306- def load_file (mapdl , fname , priority_mapdl_file = None ):
304+ def load_file (mapdl : "Mapdl" , fname : str , priority_mapdl_file : bool = None ) -> str :
307305 """
308306 Provide a file to the MAPDL instance.
309307
@@ -376,26 +374,26 @@ def load_file(mapdl, fname, priority_mapdl_file=None):
376374 return os .path .basename (fname )
377375
378376
379- def check_valid_ip (ip ) :
377+ def check_valid_ip (ip : str ) -> None :
380378 """Check for valid IP address"""
381379 if ip .lower () != "localhost" :
382380 ip = ip .replace ('"' , "" ).replace ("'" , "" )
383381 socket .inet_aton (ip )
384382
385383
386- def check_valid_port (port , lower_bound = 1000 , high_bound = 60000 ):
384+ def check_valid_port (
385+ port : int , lower_bound : int = 1000 , high_bound : int = 60000
386+ ) -> None :
387387 if not isinstance (port , int ):
388388 raise ValueError ("The 'port' parameter should be an integer." )
389389
390- if lower_bound < port < high_bound :
391- return
392- else :
390+ if not (lower_bound < port < high_bound ):
393391 raise ValueError (
394392 f"'port' values should be between { lower_bound } and { high_bound } ."
395393 )
396394
397395
398- def write_array (filename : Union [str , bytes ], array : np .ndarray ):
396+ def write_array (filename : Union [str , bytes ], array : np .ndarray ) -> None :
399397 """
400398 Write an array to a file.
401399
@@ -414,7 +412,7 @@ def write_array(filename: Union[str, bytes], array: np.ndarray):
414412 np .savetxt (filename , array , fmt = "%20.12f" )
415413
416414
417- def requires_package (package_name , softerror = False ):
415+ def requires_package (package_name : str , softerror : bool = False ) -> Callable :
418416 """
419417 Decorator check whether a package is installed or not.
420418
@@ -452,7 +450,7 @@ def wrapper(self, *args, **kwargs):
452450 return decorator
453451
454452
455- def _get_args_xsel (* args , ** kwargs ) :
453+ def _get_args_xsel (* args : Tuple [ str ] , ** kwargs : Dict [ str , str ]) -> Tuple [ str ] :
456454 type_ = kwargs .pop ("type_" , str (args [0 ]) if len (args ) else "" ).upper ()
457455 item = kwargs .pop ("item" , str (args [1 ]) if len (args ) > 1 else "" ).upper ()
458456 comp = kwargs .pop ("comp" , str (args [2 ]) if len (args ) > 2 else "" ).upper ()
@@ -463,7 +461,9 @@ def _get_args_xsel(*args, **kwargs):
463461 return type_ , item , comp , vmin , vmax , vinc , kabs , kwargs
464462
465463
466- def allow_pickable_entities (entity = "node" , plot_function = "nplot" ):
464+ def allow_pickable_entities (
465+ entity : str = "node" , plot_function : str = "nplot"
466+ ) -> Callable :
467467 """
468468 This wrapper opens a window with the NPLOT or KPLOT, and get the selected points (Nodes or kp),
469469 and feed them as a list to the NSEL.
@@ -528,8 +528,8 @@ def wrapper(self, *args, **kwargs):
528528 return decorator
529529
530530
531- def allow_iterables_vmin (entity = "node" ):
532- def decorator (original_sel_func ) :
531+ def allow_iterables_vmin (entity : str = "node" ) -> Callable :
532+ def decorator (original_sel_func : Callable ) -> Callable :
533533 """
534534 This function wraps a NSEL or KSEL function to allow using a list/tuple/array for vmin argument.
535535
@@ -595,31 +595,12 @@ def wrapper(self, *args, **kwargs):
595595 return decorator
596596
597597
598- def get_active_branch_name ():
599- head_dir = Path ("." ) / ".git" / "HEAD"
600-
601- if os .path .exists (head_dir ):
602- with head_dir .open ("r" ) as f :
603- content = f .read ().splitlines ()
604-
605- for line in content :
606- if line [0 :4 ] == "ref:" :
607- return line .partition ("refs/heads/" )[2 ]
608-
609- # In case the previous statements return None
610- if "dev" in pymapdl .__version__ :
611- kind = "main"
612- else : # pragma: no cover
613- kind = f"release/{ '.' .join (pymapdl .__version__ .split ('.' )[:2 ])} "
614-
615- return kind
616-
617-
618- def only_numbers_and_dots (s ):
619- return bool (re .fullmatch (r"[0-9.]+" , s ))
598+ def only_numbers_and_dots (st : str ) -> bool :
599+ """Return if a string contains only numbers and dots"""
600+ return bool (re .fullmatch (r"[0-9.]+" , st ))
620601
621602
622- def stack (* decorators ) :
603+ def stack (* decorators : Iterable [ Callable ]) -> Callable :
623604 """Stack multiple decorators on top of each other"""
624605
625606 def deco (f ):
0 commit comments