Skip to content

Commit 931ad33

Browse files
authored
Fix compatibility with latest ovos-utils release (#562)
* Update ovos-utils dependency and replace deprecated import * Remove `packages-exclude` override in license_tests * Pin setuptools to resolve import errors * Update `web_tuil_tests` to account for website redisign * Update `signal_utils` and tests to account for ovos_utils update * Remove deprecated `ovos_utils.signal` patching * Patch backwards-compat. to troubleshoot skill test failures * Relax test case for equavalent locations
1 parent cadff3d commit 931ad33

7 files changed

Lines changed: 106 additions & 46 deletions

File tree

.github/workflows/license_tests.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,3 @@ jobs:
1111
uses: neongeckocom/.github/.github/workflows/license_tests.yml@master
1212
with:
1313
package-extras: audio,configuration,networking
14-
packages-exclude: '^(precise-runner|fann2|tqdm|bs4|ovos-phal-plugin|ovos-skill|neon-core|nvidia|neon-phal-plugin|bitstruct|audioread|RapidFuzz|click|setuptools|typing_extensions|urllib|marisa-trie).*'

neon_utils/file_utils.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@
3434
from tempfile import mkstemp
3535

3636
from typing import Optional, List
37-
from ovos_utils.signal import ensure_directory_exists
38-
37+
from ovos_utils.file_utils import ensure_directory_exists
3938
from neon_utils.logger import LOG
4039

4140

neon_utils/signal_utils.py

Lines changed: 95 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,11 @@ def init_signal_handlers():
124124
log_deprecation("Import patching will be deprecated. Disable in "
125125
"configuration by setting `signal`.`patch_imports` "
126126
"to `False`", "2.0.0")
127-
import ovos_utils.signal
128-
ovos_utils.signal.check_for_signal = _check_for_signal
129-
ovos_utils.signal.create_signal = _create_signal
130127
try:
131128
import mycroft.util.signal
132129
mycroft.util.signal.create_signal = _create_signal
133130
mycroft.util.signal.check_for_signal = _check_for_signal
134-
LOG.info(f"Overrode mycroft.util.signal methods")
131+
LOG.info("Overrode mycroft.util.signal methods")
135132
except (ImportError, AttributeError) as e:
136133
LOG.debug(e)
137134
except TypeError as e:
@@ -141,12 +138,100 @@ def init_signal_handlers():
141138
else:
142139
LOG.warning("FS signals are deprecated. Signal methods will have no effect.")
143140
if patch_imports:
144-
log_deprecation("Import patching will be deprecated. Disable in "
145-
"configuration by setting `signal`.`patch_imports` "
146-
"to `False`", "2.0.0")
147-
import ovos_utils.signal
148-
_create_signal = ovos_utils.signal.create_signal
149-
_check_for_signal = ovos_utils.signal.check_for_signal
141+
import os
142+
import tempfile
143+
from ovos_utils.file_utils import ensure_directory_exists
144+
145+
def get_ipc_directory(domain=None, config=None):
146+
"""Get the directory used for Inter Process Communication
147+
148+
Files in this folder can be accessed by different processes on the
149+
machine. Useful for communication. This is often a small RAM disk.
150+
151+
Args:
152+
domain (str): The IPC domain. Basically a subdirectory to prevent
153+
overlapping signal filenames.
154+
config (dict): mycroft.conf, to read ipc directory from
155+
156+
Returns:
157+
str: a path to the IPC directory
158+
"""
159+
if config is None:
160+
try:
161+
from ovos_config.config import Configuration
162+
config = Configuration()
163+
except ImportError:
164+
LOG.warning("Config not provided and ovos_config not available")
165+
config = dict()
166+
path = config.get("ipc_path")
167+
if not path:
168+
# If not defined, use /tmp/mycroft/ipc
169+
path = os.path.join(tempfile.gettempdir(), "mycroft", "ipc")
170+
return ensure_directory_exists(path, domain)
171+
172+
def create_file(filename):
173+
""" Create the file filename and create any directories needed
174+
175+
Args:
176+
filename: Path to the file to be created
177+
"""
178+
try:
179+
os.makedirs(os.path.dirname(filename))
180+
except OSError:
181+
pass
182+
with open(filename, 'w') as f:
183+
f.write('')
184+
185+
def create_signal(signal_name, config=None):
186+
"""Create a named signal
187+
188+
Args:
189+
signal_name (str): The signal's name. Must only contain characters
190+
valid in filenames.
191+
config (dict): mycroft.conf, to read ipc directory from
192+
"""
193+
try:
194+
path = os.path.join(get_ipc_directory(config=config),
195+
"signal", signal_name)
196+
create_file(path)
197+
return os.path.isfile(path)
198+
except IOError:
199+
return False
200+
201+
202+
def check_for_signal(signal_name, sec_lifetime=0, config=None):
203+
"""See if a named signal exists
204+
205+
Args:
206+
signal_name (str): The signal's name. Must only contain characters
207+
valid in filenames.
208+
sec_lifetime (int, optional): How many seconds the signal should
209+
remain valid. If 0 or not specified, it is a single-use signal.
210+
If -1, it never expires.
211+
config (dict): mycroft.conf, to read ipc directory from
212+
213+
Returns:
214+
bool: True if the signal is defined, False otherwise
215+
"""
216+
path = os.path.join(get_ipc_directory(config=config),
217+
"signal", signal_name)
218+
if os.path.isfile(path):
219+
if sec_lifetime == 0:
220+
# consume this single-use signal
221+
os.remove(path)
222+
elif sec_lifetime == -1:
223+
return True
224+
elif int(os.path.getctime(path) + sec_lifetime) < int(time.time()):
225+
# remove once expired
226+
os.remove(path)
227+
return False
228+
return True
229+
230+
# No such signal exists
231+
return False
232+
233+
_create_signal = create_signal
234+
_check_for_signal = check_for_signal
150235
_wait_for_signal_clear = _fs_wait_for_signal_clear
151236
_wait_for_signal_create = _fs_wait_for_signal_create
152237
else:

requirements/requirements.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,7 @@ pyyaml>=5.4,<7.0
77
ovos-lingua-franca~=0.4
88
ovos-utils~=0.0,>=0.0.35
99
geopy~=2.1
10-
ovos-config~=0.0,>=0.0.9
11-
ovos-workshop~=0.0,>=0.0.15
10+
ovos-config~=0.1
11+
ovos-workshop~=0.0,>=0.0.15
12+
# TODO: Refactor to remove `pkg_resources` imports
13+
setuptools<82.0.0

tests/location_util_tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,9 @@ def test_get_full_location(self):
126126

127127
location_es = get_full_location("Seattle, Washington", "es")
128128
self.assertAlmostEqual(float(location_es['lat']),
129-
float(location_en['lat']), places=6)
129+
float(location_en['lat']), places=3)
130130
self.assertAlmostEqual(float(location_es['lon']),
131-
float(location_en['lon']), places=6)
131+
float(location_en['lon']), places=3)
132132
self.assertEqual(location_es['address']['country'],
133133
"Estados Unidos de América")
134134
self.assertEqual(location_en['address']['country_code'], "us")

tests/signal_util_tests.py

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
from threading import Event
3434
from os.path import join, dirname
3535

36-
import ovos_utils.signal
3736
from ovos_bus_client import Message
3837
from ovos_utils.messagebus import FakeBus
3938

@@ -132,7 +131,7 @@ def on_create(message):
132131
self.assertEqual(msg.data, {'signal_name': 'test_signal'})
133132
self.assertEqual(msg.context['origin_module'],
134133
'tests.signal_util_tests')
135-
self.assertEqual(msg.context['origin_line'], 130)
134+
self.assertEqual(msg.context['origin_line'], 129)
136135

137136
def test_signal_utils_manager_available(self):
138137
TestSignalManager(self.test_bus)
@@ -151,40 +150,21 @@ def test_signal_utils_manager_available(self):
151150
self.assertEqual(neon_utils.signal_utils._wait_for_signal_create,
152151
neon_utils.signal_utils._manager_wait_for_signal_create)
153152

154-
# Check ovos_utils references
155-
self.assertEqual(ovos_utils.signal.check_for_signal,
156-
neon_utils.signal_utils._manager_check_for_signal)
157-
self.assertEqual(ovos_utils.signal.create_signal,
158-
neon_utils.signal_utils._manager_create_signal)
159-
160153
def test_signal_utils_manager_unavailable(self):
161-
import ovos_utils.signal
162154
neon_utils.signal_utils.init_signal_handlers()
163155
self.assertFalse(neon_utils.signal_utils.check_signal_manager_available())
164156
self.assertIsInstance(neon_utils.signal_utils._MAX_TIMEOUT, int)
165-
self.assertEqual(neon_utils.signal_utils._check_for_signal,
166-
ovos_utils.signal.check_for_signal)
167-
self.assertEqual(neon_utils.signal_utils._create_signal,
168-
ovos_utils.signal.create_signal)
169157
self.assertEqual(neon_utils.signal_utils._wait_for_signal_clear,
170158
neon_utils.signal_utils._fs_wait_for_signal_clear)
171159
self.assertEqual(neon_utils.signal_utils._wait_for_signal_create,
172160
neon_utils.signal_utils._fs_wait_for_signal_create)
173161

174162
def test_signal_utils_reload(self):
175-
import ovos_utils.signal
176-
from neon_utils.signal_utils import _check_for_signal
177163
self.assertFalse(neon_utils.signal_utils.check_signal_manager_available())
178-
self.assertEqual(neon_utils.signal_utils._check_for_signal,
179-
ovos_utils.signal.check_for_signal)
180-
self.assertEqual(neon_utils.signal_utils._create_signal,
181-
ovos_utils.signal.create_signal)
182164
self.assertEqual(neon_utils.signal_utils._wait_for_signal_clear,
183165
neon_utils.signal_utils._fs_wait_for_signal_clear)
184166
self.assertEqual(neon_utils.signal_utils._wait_for_signal_create,
185167
neon_utils.signal_utils._fs_wait_for_signal_create)
186-
self.assertEqual(_check_for_signal,
187-
ovos_utils.signal.check_for_signal)
188168

189169
TestSignalManager(self.test_bus)
190170
neon_utils.signal_utils.init_signal_handlers()
@@ -197,13 +177,8 @@ def test_signal_utils_reload(self):
197177
self.assertEqual(neon_utils.signal_utils._wait_for_signal_create,
198178
neon_utils.signal_utils._manager_wait_for_signal_create)
199179

200-
# Previously imported method is not updated
201-
self.assertEqual(_check_for_signal,
202-
ovos_utils.signal.check_for_signal)
203-
204180
def test_check_signal_manager_available_lazy_load_bus(self):
205181
from ovos_bus_client import MessageBusClient
206-
from neon_utils.signal_utils import check_signal_manager_available
207182
neon_utils.signal_utils._BUS = None
208183
neon_utils.signal_utils.check_signal_manager_available()
209184
self.assertIsInstance(neon_utils.signal_utils._BUS, MessageBusClient)

tests/web_util_tests.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
class WebUtilTests(unittest.TestCase):
3838
def test_scrape_page_for_links(self):
3939
try:
40-
links = scrape_page_for_links("neon.ai")
40+
links = scrape_page_for_links("2025.neon.ai")
4141
self.assertIsInstance(links, dict)
4242
self.assertIn("company", links.keys())
4343
# TODO: Update test to validate absolute and relative URL paths
4444
# Relative href
4545
self.assertIn(links["company"],
46-
("https://neon.ai/company",
47-
"https://neon.ai/company/"))
46+
("https://2025.neon.ai/company",
47+
"https://2025.neon.ai/company/"))
4848
except ConnectTimeout:
4949
LOG.error("Github testing breaks here")
5050

0 commit comments

Comments
 (0)