
On Tue, Apr 21, 2020 at 7:01 PM M.-A. Lemburg <mal@egenix.com> wrote:
Instead of keeping values in local variables, you store them in the namespace object and because this knows about its attributes you can do a lot more in terms of introspection than what is possible when just relying on local variables in a function call context.
See e.g. argparse's various namespace uses for an example in the stdlib.
Let me make things even clearer here. This is the entire code for the index page handler. @app.route("/") @app.route("/editor/<channelid>") def mainpage(channelid=None): # NOTE: If we've *reduced* the required scopes, this will still force a re-login. # However, it'll be an easy login, as Twitch will recognize the existing auth. if "twitch_token" not in session or session.get("twitch_auth_scopes") != REQUIRED_SCOPES: return render_template("login.html") user = session["twitch_user"] if channelid is None: channelid = user["_id"] try: channelid = str(int(channelid)) except ValueError: # If you go to /editor/somename, redirect to /editor/equivalent-id # Bookmarking the version with the ID will be slightly faster, but # streamers will usually want to share the version with the name. users = query("helix/users", token=None, params={"login": channelid})["data"] # users is either an empty list (bad login) or a list of one. if not users: return redirect("/") return redirect("/editor/" + users[0]["id"]) if not may_edit_channel(user["_id"], channelid): return redirect(url_for("mainpage")) database.create_user(channelid) # Just in case, make sure the database has the basic structure channel = get_channel_setup(channelid) sched_tz, schedule, sched_tweet = database.get_schedule(channelid) if "twitter_oauth" in session: auth = session["twitter_oauth"] username = auth["screen_name"] twitter = "Twitter connected: " + username tweets = list_scheduled_tweets(auth["oauth_token"], auth["oauth_token_secret"], sched_tz) else: twitter = Markup("""<div id="login-twitter"><a href="/login-twitter"><img src="/static/Twitter_Social_Icon_Square_Color.svg" alt="Twitter logo"><div>Connect with Twitter</div></a></div>""") tweets = [] error = session.get("last_error_message", "") session["last_error_message"] = "" return render_template("index.html", twitter=twitter, username=user["display_name"], channel=channel, channelid=channelid, error=error, setups=database.list_setups(channelid), sched_tz=sched_tz, schedule=schedule, sched_tweet=sched_tweet, checklist=database.get_checklist(channelid), timers=database.list_timers(channelid), tweets=tweets, ) Now, show me which part of this should become a "namespace object". That namespace would be *unique* to this function - it would have no purpose or value outside of this one exact function. Show me how the use of such a namespace object would improve this code. There is no way that you would be able to share it with any other function in the entire program. The original proposal (or at least, one of the early proposals) is an entirely self-contained change that allows a notation like "twitter=" rather than "twitter=twitter", removing the repetition and thus the chance for error (consider if one of these got renamed or had a typo), without mandating any sort of wholesale architectural change. You're insisting that this entire concept is an anti-pattern and that the architectural change would improve it. Prove that. ChrisA