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

type hints #1

Merged
merged 3 commits into from
Oct 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions secretsanta/main/core.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from smtplib import SMTP # Note: Required for the type hint to work
from typing import Dict, Tuple
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

Expand All @@ -13,11 +15,15 @@ class SecretSanta:
# getter-only decorator @property, exposing the helper attribute.
# It is afterwards accessed like any attribute, i.e. without ().
@property
def helper(self):
def helper(self: "SecretSanta") -> str:
return self._helper

# "SecretSanta" string type hint follows Python 3.6 convention, see
# https://stackoverflow.com/questions/33533148/how-do-i-specify-that-the-return-type-of-a-method-is-the-same-as-the-class-itsel
# for more modern ways to use a class within its own definition as a type hint

# constructor
def __init__(self, email, person):
def __init__(self: "SecretSanta", email: str, person: str) -> None:
# https://stackoverflow.com/questions/5599254/how-to-use-sphinxs-autodoc-to-document-a-classs-init-self-method
"""
init method
Expand All @@ -35,7 +41,9 @@ def __init__(self, email, person):
self.email = email
self.person = person

def send(self, subject, from_address, message, mailserver, test=False):
# Note: Instead of returning a dictionary, it may also raise an error (see SMTP.sendmail documentation)
def send(self: "SecretSanta", subject: str, from_address: str,
message: str, mailserver: SMTP, test: bool = False) -> Dict[str, Tuple[int, bytes]]:
"""
send method

Expand Down
18 changes: 13 additions & 5 deletions secretsanta/main/funs.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import smtplib
from typing import Optional, Dict, Tuple, Union
import numpy as np
import datetime
from contextlib import suppress
from secretsanta.main.core import SecretSanta

# PyCharm: ctrl-p inside parentheses shows function args!
sendmailDictOrInt = Union[Dict[str, Tuple[int, bytes]], int]


def make_santa_dict(dictionary, seed=None, verbose=False):
# Todo: figure out how to deal with missing library stub file for module 'numpy'
# workaround: append --ignore-missing-imports to the mypy call (see https://github.com/python/mypy/issues/3905)
def make_santa_dict(dictionary: Dict[str, str], seed: Optional[int] = None, verbose: bool = False) -> Dict[str, str]:
spoltier marked this conversation as resolved.
Show resolved Hide resolved
# type triple-quotes and press enter to generate empty docstring stub
"""
creates a randomized 'santa' dictionary from an initial dictionary of names with associated email addresses
Expand All @@ -33,6 +37,7 @@ def make_santa_dict(dictionary, seed=None, verbose=False):
# print(dictionary.get(name))
if verbose:
print(name)
# PyCharm: Alt+Enter (on variable definition) -> Add type hint - automatically generates type given assignment
pick = names.copy()
if len(pick) == 2:
swapname1 = name
Expand All @@ -51,7 +56,7 @@ def make_santa_dict(dictionary, seed=None, verbose=False):
picked = np.random.choice(pick, 1)[0]
if verbose:
print(picked)
senddict[name] = dictionary.get(picked)
senddict[name] = dictionary[picked]
names.remove(picked)

# if swap is necessary ...
Expand All @@ -63,7 +68,8 @@ def make_santa_dict(dictionary, seed=None, verbose=False):
return senddict


def send_santa_dict(smtpserverwithport, sender, pwd, senddict, test=False):
def send_santa_dict(smtpserverwithport: str, sender: str, pwd: str,
senddict: Dict[str, str], test: bool = False) -> sendmailDictOrInt:
"""
loops over a 'santa' dictionary and sends respective emails

Expand All @@ -83,10 +89,12 @@ def send_santa_dict(smtpserverwithport, sender, pwd, senddict, test=False):
server.login(sender, pwd)

subj = 'Secret Santa %d' % datetime.datetime.now().year
check = 0
# Note: Need to explicitly state type to avoid 'incompatible types in assignment' error,
# see https://stackoverflow.com/questions/43910979/mypy-error-incompatible-types-in-assignment
check: sendmailDictOrInt = 0

for name in senddict:
obj = SecretSanta(senddict.get(name), name)
obj = SecretSanta(senddict[name], name)
check = obj.send(subj, sender, 'Lucky you! You got the lovely', server, test)

server.quit()
Expand Down