Skip to content

Commit 316dfc3

Browse files
speedup by lazy import
1 parent 9d3b6c8 commit 316dfc3

File tree

19 files changed

+245
-261
lines changed

19 files changed

+245
-261
lines changed

tests/test_tt_getdt.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,18 @@ def test_tt_getdt(fcsv='timetrials_datatime.csv'):
2323

2424

2525
def _run(nto):
26+
# pylint: disable=too-many-locals
2627
timedata = []
2728
#cmp_time = re_compile(r'((\d{1,2}):){0,2}(\d{1,2})\s*(?P<AM_PM>[aApP][mM])')
2829
# pylint: disable=line-too-long
29-
cmp_time = re_compile(r'((?P<hour>\d{1,2})[^-/_](:(?P<minute>\d{1,2}))?[^-/_](:(?P<second>\d{1,2}))?\s*(?P<AM_PM>[aApP][mM])?)')
30+
cmp_time = re_compile(r'((?P<hour>\d{1,2})(:(?P<minute>\d{1,2}))?(:(?P<second>\d{1,2}))?\s*(?P<AM_PM>[aApP][mM])?)')
3031
cmp_date = re_compile(r'((?P<year>\d{4})[-/_]?)?(?P<month>\d{1,2})[-/_](?P<day>\d{1,2})')
3132
print(f'NOW: {NOW}')
3233
for timestr, expdct in TIMESTRS.items():
34+
# pylint: disable=too-many-locals
3335
print(f'\nTIMESTR({timestr})')
3436
tic = default_timer()
35-
print("SEARCH FOR TIME:", cmp_time.search(timestr))
37+
print("SEARCH FOR TIME:", (m := cmp_time.search(timestr)), m.groupdict() if m else '')
3638
print("SEARCH FOR DATE:", cmp_date.search(timestr))
3739
tt0 = timedelta(seconds=default_timer()-tic)
3840
print(f'{tt0} re ({timestr})') # {dta}')
@@ -46,7 +48,7 @@ def _run(nto):
4648
tic = default_timer()
4749
dtb = _conv_datetime(timestr, NOW)
4850
ttb = timedelta(seconds=default_timer()-tic)
49-
#print(f'{ttb} _conv_datetime({timestr}) {dtb}')
51+
print(f'{ttb} _conv_datetime({timestr}) {dtb}')
5052

5153
tic = default_timer()
5254
dtc = _conv_timedelta(timestr)

timetracker/cfg/cfg_global.py

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,12 @@
33
__copyright__ = 'Copyright (C) 2025-present, DV Klopfenstein, PhD. All rights reserved.'
44
__author__ = "DV Klopfenstein, PhD"
55

6-
from os.path import isabs
7-
from os.path import isdir
6+
import os.path as op
87
from os.path import exists
9-
from os.path import dirname
10-
from os.path import join
11-
from os.path import abspath
12-
from os.path import relpath
138
from logging import debug
149
from collections import namedtuple
1510

16-
from tomlkit import comment
17-
from tomlkit import document
18-
from tomlkit import nl
19-
from tomlkit import array
11+
import tomlkit
2012
from tomlkit.toml_file import TOMLFile
2113

2214
from timetracker.cfg.tomutils import read_config
@@ -101,8 +93,8 @@ def _err_reinit(self, ntcfg):
10193

10294
# -------------------------------------------------------------
10395
def _chk_global_dir(self):
104-
dir_global = dirname(self.filename)
105-
if exists(dir_global) and isdir(dir_global) or dir_global == '':
96+
dir_global = op.dirname(self.filename)
97+
if exists(dir_global) and op.isdir(dir_global) or dir_global == '':
10698
return
10799
raise NotADirectoryError(f'{dir_global}\n'
108100
f'Directory for global config does not exist({dir_global})\n'
@@ -112,7 +104,7 @@ def _chk_global_dir(self):
112104
def _add_project(self, doc, project, fcfgproj):
113105
"""Add a project to the global config file, if it is not already present"""
114106
debug('CfgGlobal _add_project(%s, %s)', project, fcfgproj)
115-
assert isabs(fcfgproj), f'CfgGlobal._add_project(...) cfg NOT abspath: {fcfgproj}'
107+
assert op.isabs(fcfgproj), f'CfgGlobal._add_project(...) cfg NOT abs path: {fcfgproj}'
116108
debug('CfgGlobal %s', doc)
117109
# If project is not already in global config
118110
if self._noproj(doc, project, fcfgproj):
@@ -150,23 +142,23 @@ def _wr_project_init(self, project, fcfgproj):
150142
def _get_docprt(self, doc):
151143
doc_cur = doc.copy()
152144
##truehome = expanduser('~')
153-
dirhome = dirname(self.filename)
145+
dirhome = op.dirname(self.filename)
154146
for idx, (projname, projdir) in enumerate(doc['projects'].unwrap()):
155-
##pdir = relpath(abspath(projdir), truehome)
156-
##pdir = relpath(abspath(projdir), dirhome)
147+
##pdir = op.relpath(op.abspath(projdir), truehome)
148+
##pdir = op.relpath(op.abspath(projdir), dirhome)
157149
##if pdir[:2] != '..':
158-
if has_homedir(dirhome, abspath(projdir)):
159-
##pdir = join('~', pdir)
160-
pdir = join('~', relpath(abspath(projdir), dirhome))
150+
if has_homedir(dirhome, op.abspath(projdir)):
151+
##pdir = op.join('~', pdir)
152+
pdir = op.join('~', op.relpath(op.abspath(projdir), dirhome))
161153
doc_cur['projects'][idx] = [projname, pdir]
162154
debug('CFGGLOBAL XXXXXXXXXXX %20s %s', projname, pdir)
163155
return doc_cur
164156

165157
def _get_new_doc(self):
166-
doc = document()
167-
doc.add(comment("TimeTracker global configuration file"))
168-
doc.add(nl())
169-
arr = array()
158+
doc = tomlkit.document()
159+
doc.add(tomlkit.comment("TimeTracker global configuration file"))
160+
doc.add(tomlkit.nl())
161+
arr = tomlkit.array()
170162
arr.multiline(True)
171163
doc["projects"] = arr
172164
return doc

timetracker/cfg/cfg_local.py

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,13 @@
99
__copyright__ = 'Copyright (C) 2025-present, DV Klopfenstein, PhD. All rights reserved.'
1010
__author__ = "DV Klopfenstein, PhD"
1111

12-
from os import makedirs
12+
import os
13+
import os.path as op
1314
from os.path import exists
14-
from os.path import basename
15-
from os.path import join
16-
from os.path import abspath
17-
from os.path import dirname
18-
from os.path import normpath
1915
from logging import debug
2016
from collections import namedtuple
2117

22-
from tomlkit import comment
23-
from tomlkit import document
24-
from tomlkit import nl
25-
from tomlkit import table
18+
import tomlkit
2619
from tomlkit.toml_file import TOMLFile
2720

2821
from timetracker.consts import DIRTRK
@@ -46,19 +39,19 @@ class CfgProj:
4639
def __init__(self, filename):
4740
assert filename is not None
4841
self.filename = filename
49-
####self.exists = exists(self.filename)
5042
debug('CfgProj args %d filename %s', exists(filename), filename)
51-
self.trksubdir = DIRTRK if filename is None else basename(dirname(filename))
52-
self.dircfg = abspath(DIRTRK) if filename is None else normpath(dirname(filename))
53-
self.dirproj = dirname(self.dircfg)
43+
dnam = op.dirname
44+
self.trksubdir = DIRTRK if filename is None else op.basename(dnam(filename))
45+
self.dircfg = op.abspath(DIRTRK) if filename is None else op.normpath(dnam(filename))
46+
self.dirproj = dnam(self.dircfg)
5447

5548
def file_exists(self):
5649
"""Return True if config file exists and False otherwise"""
5750
return exists(self.filename)
5851

5952
def get_filename_cfg(self):
6053
"""Get the full filename of the local config file"""
61-
return join(self.dircfg, 'config')
54+
return op.join(self.dircfg, 'config')
6255

6356
def get_filename_csv(self, username=None, dirhome=None):
6457
"""Get the csv filename by reading the cfg csv pattern and filling in"""
@@ -98,7 +91,7 @@ def wr_ini_file(self, project=None, dircsv=None, fcfg_global=None):
9891
fname = self.get_filename_cfg()
9992
assert not exists(fname)
10093
if not exists(self.dircfg):
101-
makedirs(self.dircfg, exist_ok=True)
94+
os.makedirs(self.dircfg, exist_ok=True)
10295
if dircsv is None:
10396
dircsv = '.'
10497
doc = self._get_new_doc(project, dircsv)
@@ -109,7 +102,7 @@ def wr_ini_file(self, project=None, dircsv=None, fcfg_global=None):
109102
def wr_gitignore(self):
110103
"""Add .gitignore file in .timetracker/ directory"""
111104
error = None
112-
fname = join(self.dircfg, '.gitignore')
105+
fname = op.join(self.dircfg, '.gitignore')
113106
try:
114107
fptr = open(fname, 'w', encoding='utf-8')
115108
except (PermissionError, OSError) as err:
@@ -136,10 +129,11 @@ def reinit(self, project, dircsv, fcfg_global=None, ntdoc=None):
136129
doc['project'] = project
137130
chgd = True
138131
if docproj.csv_filename != (csv_new := self._assemble_csv_filepat(dircsv, doc['project'])):
132+
dnam = op.dirname
139133
print('In local project configuration file, changed csv directory:\n'
140134
f' local cfg: {fname}\n'
141-
f' csvdir WAS: {dirname(docproj.csv_filename)}\n'
142-
f' csvdir NOW: {dirname(csv_new)}')
135+
f' csvdir WAS: {dnam(docproj.csv_filename)}\n'
136+
f' csvdir NOW: {dnam(csv_new)}')
143137
doc['csv']['filename'] = csv_new
144138
chgd = True
145139
if fcfg_global is not None and docproj.global_config_filename != fcfg_global:
@@ -156,13 +150,13 @@ def reinit(self, project, dircsv, fcfg_global=None, ntdoc=None):
156150

157151
def get_project_from_filename(self):
158152
"""Get the default project name from the project directory filename"""
159-
return basename(self.dirproj)
153+
return op.basename(self.dirproj)
160154

161155
#-------------------------------------------------------------
162156
def _assemble_csv_filepat(self, dircsv, project):
163157
if dircsv is None or dircsv == '':
164158
dircsv = '.'
165-
return join(dircsv, self.CSVPAT.replace('PROJECT', project))
159+
return op.join(dircsv, self.CSVPAT.replace('PROJECT', project))
166160

167161
@staticmethod
168162
def _wr_cfg(fname, doc):
@@ -177,7 +171,7 @@ def _wr_cfg(fname, doc):
177171
return ret
178172

179173
def _rd_doc(self):
180-
"""Read a config file and load it into a TOML document"""
174+
"""Read a config file and load it into a TOML doc"""
181175
fin_cfglocal = self.get_filename_cfg()
182176
return TOMLFile(fin_cfglocal).read() if exists(fin_cfglocal) else None
183177

@@ -189,7 +183,7 @@ def _get_dircsv(self, dirhome):
189183
"""Read the project cfg to get the csv dir name for storing time data"""
190184
##fcsv = self._read_csvdir_from_cfgfile(dirhome)
191185
##if fcsv is not None:
192-
## return dirname(fcsv)
186+
## return op.dirname(fcsv)
193187
dircsv = get_abspath(DIRCSV, self.dirproj, dirhome)
194188
return dircsv
195189

@@ -206,17 +200,17 @@ def _get_new_doc(self, project, dircsv):
206200
assert project is not None and isinstance(project, str)
207201
#assert dircsv
208202
debug('TODO: dircsv=%s', dircsv)
209-
doc = document()
210-
doc.add(comment("TimeTracker project configuration file"))
211-
doc.add(nl())
203+
doc = tomlkit.document()
204+
doc.add(tomlkit.comment("TimeTracker project configuration file"))
205+
doc.add(tomlkit.nl())
212206
doc["project"] = project
213207

214208
# [csv]
215209
# format = "timetracker_architecting_bez.csv"
216-
csv_section = table()
210+
csv_section = tomlkit.table()
217211
#csvdir.comment("Directory where the csv file is stored")
218212
##csvpat = self.CSVPAT.replace('PROJECT', project)
219-
##csv_section.add("filename", join(self._get_dircsv_relname(dirhome), csvpat))
213+
##csv_section.add("filename", op.join(self._get_dircsv_relname(dirhome), csvpat))
220214
csv_section.add("filename", self._assemble_csv_filepat(dircsv, project))
221215
doc.add("csv", csv_section)
222216
return doc
@@ -237,7 +231,7 @@ def _update_doc_globalcfgname(self, doc, fcfg_global):
237231
def _add_doc_globalcfgfname(doc, fcfg_global):
238232
# [global_config]
239233
# filename = "/home/uname/myglobal.cfg"
240-
section = table()
234+
section = tomlkit.table()
241235
#csvdir.comment("Directory where the csv file is stored")
242236
section.add("filename", fcfg_global)
243237
doc.add("global_config", section)

timetracker/cfg/doc_local.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,11 @@
99
__copyright__ = 'Copyright (C) 2025-present, DV Klopfenstein, PhD. All rights reserved.'
1010
__author__ = "DV Klopfenstein, PhD"
1111

12+
import os.path as op
1213
from os.path import dirname
13-
from os.path import normpath
14-
from os.path import basename
1514
from collections import namedtuple
1615
from glob import glob
17-
from timetracker.cfg.utils import get_username
18-
from timetracker.cfg.utils import get_abspath
19-
from timetracker.cfg.utils import replace_envvar
16+
from timetracker.cfg import utils
2017
from timetracker.cfg.tomutils import read_config
2118
from timetracker.cfg.docutils import get_ntvalue
2219
from timetracker.starttime import Starttime
@@ -47,7 +44,7 @@ def __init__(self, doc, filename):
4744
assert type(doc).__name__ != 'RdCfg'
4845
assert filename is not None
4946
self.filename = filename
50-
self.dircfg = normpath(dirname(filename))
47+
self.dircfg = op.normpath(dirname(filename))
5148
self.project, self.csv_filename, self.global_config_filename, self.errors = \
5249
self._init_cfg_values(doc)
5350
self.dircsv = dirname(self.csv_filename) if self.csv_filename else None
@@ -56,24 +53,24 @@ def get_abspath_dircsv(self):
5653
"""Get the absolute pathname for doc['csv']['filename']"""
5754
dirproj = dirname(self.dircfg)
5855
if self.dircsv is not None and dirproj is not None:
59-
return get_abspath(self.dircsv, dirproj)
56+
return utils.get_abspath(self.dircsv, dirproj)
6057
return None
6158

6259
def get_filename_csv(self, username=None, dirhome=None):
6360
"""Get the csv filename by reading the cfg csv pattern and filling in"""
6461
assert username is None or '/' not in username
65-
username = get_username(username)
62+
username = utils.get_username(username)
6663
return self._get_csvfilename_proj_user(username, dirhome)
6764

6865
def get_filenames_csv(self, dirhome):
6966
"""Get the csv filename by reading the cfg csv pattern and filling in"""
7067
if (fcsvpat := self._get_csvfilename_proj(dirhome)) is not None:
71-
return glob(replace_envvar(fcsvpat, '*'))
68+
return glob(utils.replace_envvar(fcsvpat, '*'))
7269
return None
7370

7471
def get_csv_username(self, fcsv):
7572
"""Using the csv pattern in the project config, determine the username"""
76-
bname = basename(self.csv_filename)
73+
bname = op.basename(self.csv_filename)
7774
pc0 = bname.find('$')
7875
if pc0 == -1:
7976
return None
@@ -105,21 +102,21 @@ def timer_started(self, username):
105102
def get_startobj(self, username):
106103
"""Get a Starttime object"""
107104
if self.project:
108-
return Starttime(self.dircfg, self.project, get_username(username))
105+
return Starttime(self.dircfg, self.project, utils.get_username(username))
109106
return None
110107

111108
##-------------------------------------------------------------
112109
def _get_csvfilename_proj_user(self, username, dirhome):
113110
"""Read a config file and load it into a TOML document"""
114111
fcsvpat = self._get_csvfilename_proj(dirhome)
115112
if fcsvpat:
116-
return replace_envvar(fcsvpat, username) if '$' in fcsvpat else fcsvpat
113+
return utils.replace_envvar(fcsvpat, username) if '$' in fcsvpat else fcsvpat
117114
return None
118115

119116
def _get_csvfilename_proj(self, dirhome):
120117
"""Read a config file and load it into a TOML document"""
121118
if self.csv_filename and self.project:
122-
fpat = get_abspath(self.csv_filename, dirname(self.dircfg), dirhome)
119+
fpat = utils.get_abspath(self.csv_filename, dirname(self.dircfg), dirhome)
123120
return fpat.replace('PROJECT', self.project)
124121
return None
125122

0 commit comments

Comments
 (0)