Skip to content

@activity.defn support and other minor things - #16

Merged
cretz merged 3 commits into
temporalio:mainfrom
cretz:activity-defn
Mar 28, 2022
Merged

@activity.defn support and other minor things#16
cretz merged 3 commits into
temporalio:mainfrom
cretz:activity-defn

Conversation

@cretz

@cretz cretz commented Mar 25, 2022

Copy link
Copy Markdown
Contributor

What was changed

  • Moved from dict-based worker activities to @activity.defn decorator
  • Moved activity tests to proper package and updated them for the aforementioned decorator
  • Changed a bunch of imports for test code for reading clarity
  • Support autosummary-based docs and other doc changes to start looking like real API docs
  • Other minor things

@cretz
cretz requested a review from a team March 25, 2022 21:19
Comment thread tests/test_client.py
await handle.result()
await handle.cancel()
# Ignore this error
with pytest.raises(temporalio.client.RPCError):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hehe I am noticing someone is coming around to more frequent relative imports

@cretz cretz Mar 28, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha, I am actually deviating from the suggestions of the community. In fact, I had to update the README to basically say "We know the Google Style Guide says not to use relatively imported classes/functions, but we are anyways in tests but not library code!"

The main reason is I want the test to be more readable w/ less characters

async def test_activity_custom_name(client: Client, worker: ExternalWorker):
@activity.defn(name="my custom activity name!")
async def get_name(name: str) -> str:
return f"Name: {activity.info().activity_type}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that we call it name in the decorator but type in the info/protos is maybe sliiiightly confusing.

We're inconsistent with this in a bunch of places in all the SDKs and such currently, but perhaps it'd be best to call everything type while we have the chance? Thoughts? Not the biggest deal in the world.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as we don't use the keyword type, I agree.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I struggle with these two terms. I also call it activity_type in temporalio.activity.Info. But when it's in a decorator, I need a short non-keyword term, so both type and activity_type fail that test. Java does this as well with their annotation and really, despite the ambiguity, name= just looks better.

Comment thread temporalio/activity.py
return fn

# If name option is available, return decorator function
if name is not None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should return partial if fn is None, otherwise defn() doesn't work.

@cretz cretz Mar 28, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I did that then defn sans parens wouldn't work. There is no overload that supports defn() from the type perspective, so if they are calling it, they are violating the docs/spec here.

I could hack it to have name have some kind of tertiary value to support defn() but I would rather not support that form of decorator at all. I suppose I can have a runtime check that if both fn and name are None that it's an error.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYM no overload that supports defn()? Both params are optional.
I see no harm in supporting defn(), what are you concerned about?

@cretz cretz Mar 28, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both params are optional in the non-overloaded function. Calling the non-@overload will fail a type checker with:

All overload variants of "defn" require at least one argument

I see no harm in supporting defn(), what are you concerned about?

There is no harm, there's just no benefit. I will add a runtime failure too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Runtime failure added

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am merging this to get started on the rest of the workflow impl, but we can revisit this if needed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I missed the overloads there.

Not critical but really don't see a good reason not to support that..

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I don't see a good reason to support it.

Comment thread temporalio/worker/activity.py Outdated

@bergundy bergundy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one slight issue

@cretz
cretz merged commit 23aa7ae into temporalio:main Mar 28, 2022
@cretz
cretz deleted the activity-defn branch March 28, 2022 19:37
# Confirm name is present
name: Optional[str] = getattr(activity, "__temporal_activity_name", None)
if not name:
fn_name = getattr(activity, "__name__", "<unknown>")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: I'd not take the name here and instead print the object directly, it might not even be a function.

@cretz cretz Mar 28, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mentioned in the other now-resolved thread, this gives something like <function test_activity_without_decorator.<locals>.say_hello at 0x0000020D5FC33D90> which is rough. That ugly string is why I didn't put the activity in the string in the first place. I settled on name here now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants