Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: small memory leak #223

Merged
merged 9 commits into from
Jul 17, 2024
16 changes: 12 additions & 4 deletions azure/functions/decorators/function_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ def app_script_file(self) -> str:
return self._app_script_file

def function_name(self, name: str,
setting_extra_fields: Dict[str, Any] = {},
setting_extra_fields: Optional[Dict[str, Any]] = None,
) -> Callable[..., Any]:
"""Optional: Sets name of the :class:`Function` object. If not set,
it will default to the name of the method name.
Expand All @@ -343,6 +343,8 @@ def function_name(self, name: str,
additional setting fields
:return: Decorator function.
"""
if setting_extra_fields is None:
setting_extra_fields = {}

@self._configure_function_builder
def wrap(fb):
Expand Down Expand Up @@ -437,8 +439,8 @@ def route(self,
methods: Optional[
Union[Iterable[str], Iterable[HttpMethod]]] = None,
auth_level: Optional[Union[AuthLevel, str]] = None,
trigger_extra_fields: Dict[str, Any] = {},
binding_extra_fields: Dict[str, Any] = {}
trigger_extra_fields: Optional[Dict[str, Any]] = None,
binding_extra_fields: Optional[Dict[str, Any]] = None
) -> Callable[..., Any]:
"""The route decorator adds :class:`HttpTrigger` and
:class:`HttpOutput` binding to the :class:`FunctionBuilder` object
Expand Down Expand Up @@ -469,6 +471,10 @@ def route(self,
json. For example,
>>> data_type='STRING' # 'dataType': 'STRING' in binding json
"""
if trigger_extra_fields is None:
trigger_extra_fields = {}
if binding_extra_fields is None:
binding_extra_fields = {}

@self._configure_function_builder
def wrap(fb):
Expand Down Expand Up @@ -3197,7 +3203,7 @@ def retry(self,
delay_interval: Optional[str] = None,
minimum_interval: Optional[str] = None,
maximum_interval: Optional[str] = None,
setting_extra_fields: Dict[str, Any] = {},
setting_extra_fields: Optional[Dict[str, Any]] = None,
) -> Callable[..., Any]:
"""The retry decorator adds :class:`RetryPolicy` to the function
settings object for building :class:`Function` object used in worker
Expand All @@ -3219,6 +3225,8 @@ def retry(self,
additional setting fields.
:return: Decorator function.
"""
if setting_extra_fields is None:
setting_extra_fields = {}

@self._configure_function_builder
def wrap(fb):
Expand Down
28 changes: 15 additions & 13 deletions azure/functions/extension/app_extension_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,13 @@ def post_function_load_app_level(cls,
# DO NOT decorate this with @abc.abstractstatismethod
# since implementation by subclass is not mandatory
@classmethod
def pre_invocation_app_level(cls,
logger: Logger,
context: Context,
func_args: typing.Dict[str, object] = {},
*args,
**kwargs) -> None:
def pre_invocation_app_level(
cls,
logger: Logger,
context: Context,
func_args: typing.Optional[typing.Dict[str, object]] = None,
*args,
**kwargs) -> None:
"""This must be implemented as a @staticmethod. It will be called right
before a customer's function is being executed.

Expand All @@ -90,13 +91,14 @@ def pre_invocation_app_level(cls,
# DO NOT decorate this with @abc.abstractstatismethod
# since implementation by subclass is not mandatory
@classmethod
def post_invocation_app_level(cls,
logger: Logger,
context: Context,
func_args: typing.Dict[str, object] = {},
func_ret: typing.Optional[object] = None,
*args,
**kwargs) -> None:
def post_invocation_app_level(
cls,
logger: Logger,
context: Context,
func_args: typing.Optional[typing.Dict[str, object]] = None,
func_ret: typing.Optional[object] = None,
*args,
**kwargs) -> None:
"""This must be implemented as a @staticmethod. It will be called right
after a customer's function is being executed.

Expand Down
28 changes: 15 additions & 13 deletions azure/functions/extension/func_extension_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,13 @@ def post_function_load(self,

# DO NOT decorate this with @abc.abstractmethod
# since implementation by subclass is not mandatory
def pre_invocation(self,
logger: Logger,
context: Context,
func_args: typing.Dict[str, object] = {},
*args,
**kwargs) -> None:
def pre_invocation(
self,
logger: Logger,
context: Context,
func_args: typing.Optional[typing.Dict[str, object]] = None,
*args,
**kwargs) -> None:
"""This hook will be called right before customer's function
is being executed.

Expand All @@ -113,13 +114,14 @@ def pre_invocation(self,

# DO NOT decorate this with @abc.abstractmethod
# since implementation by subclass is not mandatory
def post_invocation(self,
logger: Logger,
context: Context,
func_args: typing.Dict[str, object] = {},
func_ret: typing.Optional[object] = None,
*args,
**kwargs) -> None:
def post_invocation(
self,
logger: Logger,
context: Context,
func_args: typing.Optional[typing.Dict[str, object]] = None,
func_ret: typing.Optional[object] = None,
*args,
**kwargs) -> None:
"""This hook will be called right after a customer's function
is executed.

Expand Down
9 changes: 5 additions & 4 deletions azure/functions/timer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@

class TimerRequest(azf_abc.TimerRequest):

def __init__(self, *, past_due: bool = False, schedule_status: dict = {},
schedule: dict = {}) -> None:
def __init__(self, *, past_due: bool = False,
schedule_status: typing.Optional[dict] = None,
schedule: typing.Optional[dict] = None) -> None:
self.__past_due = past_due
self.__schedule_status = schedule_status
self.__schedule = schedule
self.__schedule_status = schedule_status if schedule_status else {}
self.__schedule = schedule if schedule else {}

@property
def past_due(self) -> bool:
Expand Down
12 changes: 12 additions & 0 deletions tests/test_timer.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ def test_timer_initialize_without_args(self):
self.assertEqual(schedule_status, test_timer.schedule_status)
self.assertEqual(schedule, test_timer.schedule)

def test_timer_initialize_empty_dicts(self):
# given
past_due = False

# when
test_timer = timer.TimerRequest()

# then
self.assertEqual(past_due, test_timer.past_due)
self.assertEqual({}, test_timer.schedule_status)
self.assertEqual({}, test_timer.schedule)

def test_timer_no_implementation_exception(self):
# given
datum: Datum = Datum(value="test", type='string')
Expand Down