Skip to content
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