Skip to content

Commit 94996df

Browse files
committed
Started replacing relative imports with absolute imports
1 parent dd674a1 commit 94996df

File tree

10 files changed

+205
-119
lines changed

10 files changed

+205
-119
lines changed

flika/__init__.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
from .logger import logger
1+
"""
2+
Flika: An interactive image processing program for biologists written in Python.
3+
"""
4+
5+
from flika.logger import logger
26
logger.debug("Started 'reading __init__.py'")
3-
from .version import __version__
4-
from .flika import start_flika
5-
from . import global_vars as g
6-
logger.debug("Completed 'reading __init__.py'")
7+
from flika.version import __version__
8+
from flika.flika import start_flika
9+
import flika.global_vars as g
10+
logger.debug("Completed 'reading __init__.py'")
11+
12+
# Define public API
13+
__all__ = ["start_flika", "__version__", "g"]

flika/flika.py

Lines changed: 64 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,38 @@
11
# -*- coding: utf-8 -*-
2-
from .logger import logger
3-
logger.debug("Started 'reading flika.py'")
4-
import sys, os
2+
"""
3+
Main module for the flika application.
4+
"""
5+
6+
# Standard library imports
7+
import os
8+
import sys
59
import platform
610
import optparse
711
import warnings
12+
import pathlib
13+
from typing import Any
814

915
# Set Jupyter to use platformdirs (fixes deprecation warning)
1016
os.environ['JUPYTER_PLATFORM_DIRS'] = '1'
1117

18+
# Third-party imports
19+
import numpy as np
20+
import beartype
21+
22+
# Local application imports
23+
from flika.logger import logger
24+
from flika.version import __version__
25+
from flika.app.application import FlikaApplication
26+
27+
logger.debug("Started 'reading flika.py'")
1228
logger.debug("Started 'reading flika.py, importing numpy'")
13-
import numpy as np # type: ignore
1429
logger.debug("Completed 'reading flika.py, importing numpy'")
15-
from .version import __version__
16-
from .app.application import FlikaApplication
1730

1831
# Filter out known warnings
1932
warnings.filterwarnings("ignore", category=np.exceptions.VisibleDeprecationWarning)
2033

21-
def parse_arguments(argv):
34+
@beartype.beartype
35+
def parse_arguments(argv: list[str]) -> tuple[Any, list[str]]:
2236
''' Parses command line arguments for valid flika args
2337
2438
Arguments:
@@ -59,19 +73,19 @@ def parse_arguments(argv):
5973

6074
err_msg = verify(parser, argv)
6175
if err_msg:
62-
sys.stderr.write('\n%s\n' % err_msg)
76+
sys.stderr.write(f'\n{err_msg}\n')
6377
parser.print_help()
6478
sys.exit(1)
6579

6680
return parser.parse_args(argv)
6781

68-
def verify(parser, argv):
69-
"""verify(parser, argv)
70-
Check for input errors
82+
@beartype.beartype
83+
def verify(parser: optparse.OptionParser, argv: list[str]) -> str|None:
84+
"""Check for input errors
7185
7286
Arguments:
7387
parser: OptionParser instance
74-
argv (list): Argument list
88+
argv: Argument list
7589
7690
Returns:
7791
An error message in the event of an input error, or None
@@ -83,32 +97,37 @@ def verify(parser, argv):
8397

8498
return err_msg
8599

86-
def ipython_qt_event_loop_setup():
100+
@beartype.beartype
101+
def ipython_qt_event_loop_setup() -> None:
102+
"""Set up the IPython Qt event loop if running inside IPython."""
87103
try:
88104
__IPYTHON__
89105
except NameError:
90106
return # If __IPYTHON__ is not defined, we are not in ipython
91107
else:
92108
print("Starting flika inside IPython")
93-
from IPython import get_ipython # type: ignore
109+
from IPython import get_ipython
94110
ipython = get_ipython()
95111
ipython.run_line_magic("gui", "qt")
96112

97-
def load_files(files):
98-
from .process.file_ import open_file
113+
@beartype.beartype
114+
def load_files(files: list[str]) -> None:
115+
from flika.process.file_ import open_file
99116
for f in files:
100117
open_file(f)
101118

102-
def start_flika(files=[]):
119+
@beartype.beartype
120+
def start_flika(files: list[str]|None = None) -> FlikaApplication:
103121
"""Run a flika session and exit, beginning the event loop
104122
105123
Parameters:
106-
files (list): An optional list of data files to load.
124+
files: An optional list of data files to load.
107125
108126
Returns:
109127
A flika application object with optional files loaded
110-
111128
"""
129+
if files is None:
130+
files = []
112131
logger.debug("Started 'flika.start_flika()'")
113132
print('Starting flika')
114133
fa = FlikaApplication()
@@ -118,26 +137,37 @@ def start_flika(files=[]):
118137
logger.debug("Completed 'flika.start_flika()'")
119138
return fa
120139

121-
def exec_():
140+
@beartype.beartype
141+
def exec_() -> int:
142+
"""Execute the flika application."""
122143
fa = start_flika(sys.argv[1:])
123144
return fa.app.exec_()
124145

125-
def post_install():
146+
@beartype.beartype
147+
def post_install() -> None:
126148
if platform.system() == 'Windows':
127149
print("Creating start menu shortcut...")
128-
import winshell # type: ignore
129-
icon_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'images', 'favicon.ico')
130-
flika_exe = os.path.join(sys.exec_prefix, 'Scripts', 'flika.exe')
131-
link_path = os.path.join(winshell.programs(), "flika.lnk")
132-
with winshell.shortcut(link_path) as link:
133-
link.path = flika_exe
134-
link.description = "flika"
135-
link.icon_location = (icon_path, 0)
136-
link_path = os.path.join(winshell.desktop(), "flika.lnk")
137-
with winshell.shortcut(link_path) as link:
138-
link.path = flika_exe
139-
link.description = "flika"
140-
link.icon_location = (icon_path, 0)
150+
try:
151+
import winshell
152+
import importlib.resources as pkg_resources
153+
from flika import images
154+
155+
# Use importlib.resources instead of os.path
156+
with pkg_resources.path(images, 'favicon.ico') as icon_path:
157+
# Use Path for path manipulation
158+
flika_exe = pathlib.Path(sys.exec_prefix) / 'Scripts' / 'flika.exe'
159+
link_path = pathlib.Path(winshell.programs()) / "flika.lnk"
160+
with winshell.shortcut(str(link_path)) as link:
161+
link.path = str(flika_exe)
162+
link.description = "flika"
163+
link.icon_location = (str(icon_path), 0)
164+
link_path = pathlib.Path(winshell.desktop()) / "flika.lnk"
165+
with winshell.shortcut(str(link_path)) as link:
166+
link.path = str(flika_exe)
167+
link.description = "flika"
168+
link.icon_location = (str(icon_path), 0)
169+
except ImportError:
170+
print("winshell package not found. Shortcuts not created.")
141171

142172
if __name__ == '__main__':
143173
start_flika(sys.argv[1:])

flika/global_vars.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,22 @@
99
1010
I = g.win.image
1111
12+
"""
1213

14+
import json
15+
import uuid
16+
import multiprocessing
17+
from collections.abc import MutableMapping
18+
import pathlib
1319

14-
"""
15-
from .logger import logger
16-
logger.debug("Started 'reading global_vars.py'")
17-
import os
18-
from multiprocessing import cpu_count
19-
from os.path import expanduser
20+
# Third-party imports
2021
from qtpy import QtWidgets, QtGui, QtCore
21-
from collections.abc import MutableMapping
22-
import json
23-
from uuid import getnode
24-
from .utils.system_info import get_location
22+
23+
# Local application imports
24+
from flika.logger import logger
25+
import flika.utils.system_info
26+
27+
logger.debug("Started 'reading global_vars.py'")
2528

2629
__all__ = ['m', 'Settings', 'menus', 'alert', 'windows', 'traceWindows', 'currentWindow', 'win', 'currentTrace', 'clipboard']
2730

@@ -42,7 +45,7 @@ class Settings(MutableMapping): #http://stackoverflow.com/questions/3387691/pyth
4245
'show_windows': True,
4346
'recent_scripts': [],
4447
'recent_files': [],
45-
'nCores':cpu_count(),
48+
'nCores':multiprocessing.cpu_count(),
4649
'debug_mode': False,
4750
'point_color': '#ff0000',
4851
'point_size': 5,
@@ -53,8 +56,8 @@ class Settings(MutableMapping): #http://stackoverflow.com/questions/3387691/pyth
5356
'default_roi_on_click': False}
5457

5558
def __init__(self):
56-
self.settings_file = os.path.join(expanduser("~"), '.FLIKA', 'settings.json' )
57-
self.d = Settings.initial_settings
59+
self.settings_file = pathlib.Path(pathlib.Path("~").expanduser() / '.FLIKA' / 'settings.json')
60+
self.d = Settings.initial_settings.copy()
5861
self.load()
5962

6063
def __getitem__(self, item):
@@ -83,15 +86,14 @@ def __contains__(self, item):
8386
def save(self):
8487
"""save(self)
8588
Save settings file. The file is stored in ``~/.FLIKA/settings.json`` """
86-
if not os.path.exists(os.path.dirname(self.settings_file)):
87-
os.makedirs(os.path.dirname(self.settings_file))
89+
self.settings_file.parent.mkdir(parents=True, exist_ok=True)
8890
with open(self.settings_file, 'w') as fp:
8991
json.dump(self.d, fp, indent=4)
9092

9193
def load(self):
9294
"""load(self)
9395
Load settings file. The file is stored in ``~/.FLIKA/settings.json`` """
94-
if not os.path.exists(self.settings_file):
96+
if not self.settings_file.exists():
9597
print('No settings file found. Creating settings file.')
9698
self.save()
9799
try:
@@ -114,9 +116,9 @@ def _load_user_information(self):
114116
if 'user_information' not in self.d:
115117
self.d['user_information'] = {}
116118
if 'UUID' not in self.d['user_information'] or self.d['user_information']['UUID'] is None:
117-
self.d['user_information']['UUID'] = getnode()
119+
self.d['user_information']['UUID'] = uuid.getnode()
118120
if 'location' not in self.d['user_information'] or self.d['user_information']['location'] is None:
119-
self.d['user_information']['location'] = get_location()
121+
self.d['user_information']['location'] = flika.utils.system_info.get_location()
120122

121123

122124
def setmousemode(self, mode):

flika/process/__init__.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
# -*- coding: utf-8 -*-
2-
from ..logger import logger
2+
"""
3+
Process module for flika - provides image processing operations.
4+
"""
5+
6+
# Local application imports
7+
from flika.logger import logger
38
logger.debug("Started 'reading process/__init__.py'")
49

5-
from .stacks import *
6-
from .math_ import *
7-
from .filters import *
8-
from .binary import *
9-
from .roi import *
10-
from .measure import *
11-
from .color import *
12-
from .overlay import *
13-
from .file_ import *
10+
from flika.process.stacks import *
11+
from flika.process.math_ import *
12+
from flika.process.filters import *
13+
from flika.process.binary import *
14+
from flika.process.roi import *
15+
from flika.process.measure import *
16+
from flika.process.color import *
17+
from flika.process.overlay import *
18+
from flika.process.file_ import *
1419

1520
def setup_menus():
21+
"""Set up the flika menu structure for process operations."""
1622
logger.debug("Started 'process.__init__.setup_menus()'")
17-
from .. import global_vars as g
23+
import flika.global_vars as g
1824
if len(g.menus) > 0:
1925
print("flika menubar already initialized.")
2026
return

flika/process/file_.py

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,33 @@
11
# -*- coding: utf-8 -*-
2-
from ..logger import logger
3-
logger.debug("Started 'reading process/file_.py'")
4-
import pyqtgraph as pg
5-
import pyqtgraph.exporters
2+
"""
3+
File-related operations for flika - opening, saving, and closing files.
4+
"""
5+
6+
# Standard library imports
67
import time
78
import os.path
89
import sys
9-
import numpy as np
10-
from qtpy import uic, QtGui, QtCore, QtWidgets
11-
import shutil, subprocess
10+
import shutil
11+
import subprocess
1212
import datetime
1313
import json
1414
import re
1515
import pathlib
1616

17-
from .. import global_vars as g
18-
from ..utils.BaseProcess import BaseDialog
19-
from ..window import Window
20-
from ..utils.misc import open_file_gui, save_file_gui
21-
from ..utils.io import tifffile
17+
# Third-party imports
18+
import numpy as np
19+
import pyqtgraph as pg
20+
from qtpy import QtGui, QtWidgets
21+
22+
# Local application imports
23+
from flika.logger import logger
24+
import flika.global_vars as g
25+
from flika.utils.BaseProcess import BaseDialog
26+
from flika.window import Window
27+
from flika.utils.misc import open_file_gui, save_file_gui
28+
from flika.utils.io import tifffile
29+
30+
logger.debug("Started 'reading process/file_.py'")
2231

2332
__all__ = ['save_file', 'save_points', 'save_rois', 'save_movie_gui', 'open_file', 'open_file_from_gui', 'open_image_sequence_from_gui', 'open_points', 'close']
2433

@@ -247,7 +256,7 @@ def open_image_sequence(filename=None, from_gui=False):
247256
return new_window
248257

249258

250-
def open_file(filename=None, from_gui=False):
259+
def open_file(filename: str|None =None, from_gui: bool =False):
251260
""" open_file(filename=None)
252261
Opens an image or movie file (.tif, .stk, .nd2) into a new_window.
253262
@@ -272,7 +281,7 @@ def open_file(filename=None, from_gui=False):
272281
print(f"Filename: {filename}")
273282
g.m.statusBar().showMessage(f'Loading {os.path.basename(str(filename))}')
274283
t = time.time()
275-
metadata = dict()
284+
metadata: dict = {}
276285
ext = os.path.splitext(str(filename))[1]
277286
if ext in ['.tif', '.stk', '.tiff', '.ome']:
278287
results = open_tiff(str(filename), metadata)

0 commit comments

Comments
 (0)