Skip to content

Commit 097a13e

Browse files
committed
respond to code review comments
1 parent 1440822 commit 097a13e

File tree

4 files changed

+111
-58
lines changed

4 files changed

+111
-58
lines changed

arkouda/logger.py

Lines changed: 85 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
Logger,
7272
StreamHandler,
7373
)
74-
from typing import List, Optional, cast
74+
from typing import List, Optional, Union, cast
7575

7676
from typeguard import typechecked
7777

@@ -130,6 +130,11 @@ class LogLevel(Enum):
130130
"""
131131

132132

133+
# sentinel
134+
_UNSET = object()
135+
_UnsetType = object # just for readability in the union
136+
137+
133138
class ArkoudaLogger(Logger):
134139
DEFAULT_LOG_FORMAT = "[%(name)s] Line %(lineno)d %(levelname)s: %(message)s"
135140

@@ -147,7 +152,7 @@ class ArkoudaLogger(Logger):
147152
def __init__(
148153
self,
149154
name: str,
150-
log_level: LogLevel = LogLevel.INFO,
155+
log_level: Union[LogLevel, _UnsetType] = _UNSET, # sentinel means "not provided"
151156
handlers: Optional[List[Handler]] = None,
152157
log_format: Optional[str] = "[%(name)s] Line %(lineno)d %(levelname)s: %(message)s",
153158
**kwargs,
@@ -200,25 +205,37 @@ def __init__(
200205
the individual handlers.
201206
202207
"""
208+
# --- log_level alias handling ---
203209
if "logLevel" in kwargs:
204-
if log_level is not None:
210+
if log_level is not _UNSET:
205211
raise TypeError("Pass only one of 'logLevel' or 'log_level'")
206212
warnings.warn(
207213
"'logLevel' is deprecated; use 'log_level' instead",
208214
DeprecationWarning,
209215
stacklevel=2,
210216
)
211217
log_level = kwargs.pop("logLevel")
218+
elif log_level is _UNSET:
219+
log_level = LogLevel.INFO
212220

221+
# --- log_format alias handling ---
213222
if "logFormat" in kwargs:
214-
if log_format is not None:
223+
if log_format is not _UNSET:
215224
raise TypeError("Pass only one of 'logFormat' or 'log_format'")
216225
warnings.warn(
217226
"'logFormat' is deprecated; use 'log_format' instead",
218227
DeprecationWarning,
219228
stacklevel=2,
220229
)
221230
log_format = kwargs.pop("logFormat")
231+
elif log_format is _UNSET:
232+
log_format = "[%(name)s] Line %(lineno)d %(levelname)s: %(message)s"
233+
234+
if not isinstance(log_level, LogLevel):
235+
raise TypeError("log_level must be a LogLevel")
236+
237+
if not isinstance(log_format, str):
238+
raise TypeError("log_format must be a str")
222239

223240
if kwargs:
224241
raise TypeError(f"Unexpected keyword argument(s): {', '.join(kwargs)}")
@@ -276,7 +293,7 @@ def enableVerbose(self) -> None:
276293
self.changeLogLevel(LogLevel.DEBUG)
277294

278295
@typechecked
279-
def disableVerbose(self, log_level: LogLevel = LogLevel.INFO, **kwargs) -> None:
296+
def disableVerbose(self, log_level: object = _UNSET, **kwargs) -> None:
280297
"""
281298
Disables verbose output.
282299
@@ -293,20 +310,25 @@ def disableVerbose(self, log_level: LogLevel = LogLevel.INFO, **kwargs) -> None:
293310
------
294311
TypeError
295312
Raised if log_level is not a LogLevel enum
296-
297313
"""
298314
if "logLevel" in kwargs:
299-
if log_level is not None:
315+
if log_level is not _UNSET:
300316
raise TypeError("Pass only one of 'logLevel' or 'log_level'")
301317
warnings.warn(
302318
"'logLevel' is deprecated; use 'log_level' instead",
303319
DeprecationWarning,
304320
stacklevel=2,
305321
)
306322
log_level = kwargs.pop("logLevel")
323+
elif log_level is _UNSET:
324+
log_level = LogLevel.INFO
307325

308326
if kwargs:
309327
raise TypeError(f"Unexpected keyword argument(s): {', '.join(kwargs)}")
328+
329+
if not isinstance(log_level, LogLevel):
330+
raise TypeError("log_level must be a LogLevel")
331+
310332
self.changeLogLevel(log_level)
311333

312334
@typechecked
@@ -338,62 +360,64 @@ def getHandler(self, name: str) -> Handler:
338360
raise ValueError(f"The name {name} does not match any handler")
339361

340362

363+
_UNSET = object()
364+
365+
341366
@typechecked
342367
def getArkoudaLogger(
343368
name: str,
344369
handlers: Optional[List[Handler]] = None,
345-
log_format: Optional[str] = ArkoudaLogger.DEFAULT_LOG_FORMAT,
346-
log_level: Optional[LogLevel] = None,
370+
log_format: object = _UNSET,
371+
log_level: object = _UNSET,
347372
**kwargs,
348373
) -> ArkoudaLogger:
349-
"""
350-
Instantiate an ArkoudaLogger that retrieves the logging level from ARKOUDA_LOG_LEVEL env variable.
351-
352-
Parameters
353-
----------
354-
name : str
355-
The name of the ArkoudaLogger
356-
handlers : List[Handler]
357-
A list of logging.Handler objects, if None, a list consisting of
358-
one StreamHandler named 'console-handler' is generated and configured
359-
log_format : str
360-
The format for log messages, defaults to the following format:
361-
'[%(name)s] Line %(lineno)d %(levelname)s: %(message)s'
362-
363-
Returns
364-
-------
365-
ArkoudaLogger
366-
367-
Raises
368-
------
369-
TypeError
370-
Raised if either name or log_format is not a str object or if handlers
371-
is not a list of str objects
372-
373-
Notes
374-
-----
375-
Important note: if a list of 1..n logging.Handler objects is passed in, and
376-
dynamic changes to 1..n handlers is desired, set a name for each Handler
377-
object as follows: handler.name = <desired name>, which will enable retrieval
378-
and updates for the specified handler.
379-
380-
"""
374+
# --- deprecated alias: logFormat -> log_format ---
381375
if "logFormat" in kwargs:
382-
if log_format is not None and kwargs["logFormat"] is not None:
383-
raise TypeError("Pass only one of logFormat or log_format")
384-
warnings.warn("logFormat is deprecated; use log_format", DeprecationWarning, stacklevel=2)
376+
if log_format is not _UNSET:
377+
raise TypeError("Pass only one of 'logFormat' or 'log_format'")
378+
warnings.warn(
379+
"'logFormat' is deprecated; use 'log_format' instead",
380+
DeprecationWarning,
381+
stacklevel=2,
382+
)
385383
log_format = kwargs.pop("logFormat")
386384

385+
# --- deprecated alias: logLevel -> log_level ---
387386
if "logLevel" in kwargs:
388-
if log_level is not None and kwargs["logLevel"] is not None:
389-
raise TypeError("Pass only one of logLevel or log_level")
390-
warnings.warn("logLevel is deprecated; use log_level", DeprecationWarning, stacklevel=2)
387+
if log_level is not _UNSET:
388+
raise TypeError("Pass only one of 'logLevel' or 'log_level'")
389+
warnings.warn(
390+
"'logLevel' is deprecated; use 'log_level' instead",
391+
DeprecationWarning,
392+
stacklevel=2,
393+
)
391394
log_level = kwargs.pop("logLevel")
392395

393-
if not log_level:
394-
log_level = LogLevel(os.getenv("ARKOUDA_LOG_LEVEL", LogLevel("INFO")))
396+
if kwargs:
397+
raise TypeError(f"Unexpected keyword argument(s): {', '.join(kwargs)}")
395398

396-
logger = ArkoudaLogger(name=name, handlers=handlers, log_format=log_format, log_level=log_level)
399+
# defaults
400+
if log_format is _UNSET:
401+
log_format = ArkoudaLogger.DEFAULT_LOG_FORMAT
402+
if log_level is _UNSET:
403+
env_val = os.getenv("ARKOUDA_LOG_LEVEL", "INFO")
404+
try:
405+
log_level = LogLevel(env_val)
406+
except Exception as e:
407+
raise ValueError(f"Invalid ARKOUDA_LOG_LEVEL={env_val!r}") from e
408+
409+
# validate types (since we used object for sentinel)
410+
if not isinstance(log_format, str):
411+
raise TypeError("log_format must be a str")
412+
if not isinstance(log_level, LogLevel):
413+
raise TypeError("log_level must be a LogLevel")
414+
415+
logger = ArkoudaLogger(
416+
name=name,
417+
handlers=handlers,
418+
log_format=log_format,
419+
log_level=log_level,
420+
)
397421
loggers[logger.name] = logger
398422
return logger
399423

@@ -437,8 +461,11 @@ def enableVerbose() -> None:
437461
logger.enableVerbose()
438462

439463

464+
_UNSET = object()
465+
466+
440467
@typechecked
441-
def disableVerbose(log_level: LogLevel = LogLevel.INFO, **kwargs) -> None:
468+
def disableVerbose(log_level: object = _UNSET, **kwargs) -> None:
442469
"""
443470
Disables verbose logging.
444471
@@ -448,27 +475,31 @@ def disableVerbose(log_level: LogLevel = LogLevel.INFO, **kwargs) -> None:
448475
Parameters
449476
----------
450477
log_level : LogLevel
451-
The new log level, defaultts to LogLevel.INFO
478+
The new log level, defaults to LogLevel.INFO
452479
453480
Raises
454481
------
455482
TypeError
456483
Raised if log_level is not a LogLevel enum
457-
458484
"""
459485
if "logLevel" in kwargs:
460-
if log_level is not None:
486+
if log_level is not _UNSET:
461487
raise TypeError("Pass only one of 'logLevel' or 'log_level'")
462488
warnings.warn(
463489
"'logLevel' is deprecated; use 'log_level' instead",
464490
DeprecationWarning,
465491
stacklevel=2,
466492
)
467493
log_level = kwargs.pop("logLevel")
494+
elif log_level is _UNSET:
495+
log_level = LogLevel.INFO
468496

469497
if kwargs:
470498
raise TypeError(f"Unexpected keyword argument(s): {', '.join(kwargs)}")
471499

500+
if not isinstance(log_level, LogLevel):
501+
raise TypeError("log_level must be a LogLevel")
502+
472503
for logger in loggers.values():
473504
logger.disableVerbose(log_level)
474505

arkouda/numpy/pdarraysetops.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ def intersect1d(
722722
ub = bg.unique_keys
723723
else:
724724
ua = ar1
725-
ub = ar1
725+
ub = ar2
726726

727727
# Key for deinterleaving result
728728
isa = concatenate(
@@ -823,9 +823,9 @@ def setdiff1d(ar1: groupable, ar2: groupable, assume_unique: bool = False) -> Un
823823
)
824824
return create_pdarray(cast(str, rep_msg))
825825
if not assume_unique:
826-
a = cast(pdarray, unique(ar1))
827-
b = cast(pdarray, unique(ar2))
828-
x = a[in1d(a, b, invert=True)]
826+
ar1 = cast(pdarray, unique(ar1))
827+
ar2 = cast(pdarray, unique(ar2))
828+
x = ar1[in1d(ar1, ar2, invert=True)]
829829
return x[argsort(x)]
830830
elif (isinstance(ar1, list) or isinstance(ar1, tuple)) and (
831831
isinstance(ar2, list) or isinstance(ar2, tuple)

arkouda/pandas/categorical.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050
import itertools
5151
import json
52+
import warnings
5253

5354
from collections import defaultdict
5455
from typing import (
@@ -241,6 +242,22 @@ def __init__(self, values, **kwargs) -> None:
241242
self.dtype = akdtype(str_)
242243
self.registered_name: Optional[str] = None
243244

245+
@property
246+
def NAvalue(self):
247+
"""
248+
Deprecated alias for `na_value`.
249+
250+
Returns
251+
-------
252+
Same value as `na_value`.
253+
"""
254+
warnings.warn(
255+
"Categorical.NAvalue is deprecated; use Categorical.find_na instead.",
256+
DeprecationWarning,
257+
stacklevel=2,
258+
)
259+
return self.na_value
260+
244261
@property
245262
def nbytes(self):
246263
"""

tests/pandas/categorical_test.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,3 +637,8 @@ def test_copy_empty_categorical(self):
637637
if a is not None:
638638
assert a is not b
639639
assert_equal(a, b)
640+
641+
def test_categorical_NAvalue_deprecated_returns_find_na(self):
642+
cat = Categorical(ak.array(["a", "b"]))
643+
with pytest.deprecated_call():
644+
assert cat.NAvalue == cat.na_value

0 commit comments

Comments
 (0)