Comments (1)
This isn't a bug. Let's discuss why.
I have a set of rules that I follow while designing and developing Jishaku.
While some of these are documented or enforced by circumstance (e.g., 'all code must comply by the pylint/flake8 rules or have commented exceptions in the code, else the CI will fail and the publish process for a new version will fail'), most of the rules I set either by word of mouth or just personally retain as part of my development or design principles.
One of these unspoken design principles is the reason why this behavior isn't a bug. I'll write it out in plain English for reference later, but for now, I'm going to try and see if you can derive what the rule is from a set of examples regarding the design of the REPL components that back AsyncCodeExecutor
, and by extension, jsk py
and jsk pyi
.
A REPL with a little more
Jishaku's design motive is to be a Discord-based frontend for evaluating and executing code.
It takes a lot of inspiration from how the standard Python REPL works - the one you get when you just run python
, but simple Python evaluation isn't all Jishaku offers within its environment.
Let's go over some features Jishaku adds, starting from "least obviously magic" to "most obviously magic" (a sort of increasing nonstandardness). I'll also include how it differs from what you'd expect with standard Python, for reference.
Returned values are sent back to Discord
When you execute a block of code that contains a return
, the value returned is sent to Discord as a message.
The value is interpreted and sent in whatever format is deemed most appropriate. For instance, discord.Embed
instances get sent as actual embeds, discord.File
instances get uploaded, etc.
This is the "most standard" behavior, because typically all eval or REPL command implementations have some variant of this kind of behavior. Some even have automatic await
, but Jishaku doesn't.
What Would Python Do (WWPD)?
Either:
- nothing (return value ignored)
SyntaxError: 'return' outside function
Bare expressions at the end of the top-level scope are sent back to Discord
When you execute a block of code that includes a bare expression at the end that isn't in control flow (such as for
, while
, if
, etc), the value of the expression is sent back to Discord as a message.
This follows the same display procedures as returning. It is sometimes referred to as an "implicit return" in old documentation, but this isn't always how it's implemented, as we will soon find out.
What Would Python Do (WWPD)?
- nothing (expression would be evaluated but nothing else would happen, for basic operations the bytecode may optimize it out - see "Statement seems to have no effect"
pointless-statement (W0104)
from the pylint documentation)
Yielded values are sent back to Discord
When you execute a block of code that includes yield
statements, the yielded values are sent back to Discord as messages.
This is similar to the "implicit return", except it doesn't halt execution. This allows data to be sent back easily during longer evals, or in situations where states may have to be read at different times (such as wanting to check the attribute of an object before and after a given function call).
The message is even sent back to the evaluation context from the yield, allowing it to be inspected or edited.
What Would Python Do (WWPD)?
Depends on the exact context, but typically:
SyntaxError: 'yield' outside function
TypeError: object async_generator can't be used in 'await' expression
Yielding and returning values can be mixed.
When you execute a block of code that includes both 'yield' and 'return', they both work and function as expected.
While you may not see this as weird, this is actually nonstandard because it is usually not allowed for yield
and return
(with a value) to both be in an async generator (although it is OK for normal generators to have them).
To deal with this, Jishaku automatically packs out return x
into the two separate statements when yields are present:
yield x
return
This allows returning of values to not require the cognitive overhead of checking whether it already contains a yield, as Jishaku makes the transformation for you.
What Would Python Do (WWPD)?
SyntaxError: 'return' with value in async generator
Import expressions
When a name is suffixed with an exclamation mark (!
), the name is treated as a module and is implicitly imported for direct usage.
The module name to be imported can even be a submodule:
This is the most 'nonstandard' feature because it's effectively an in-Python extension of standard syntax. It allows what is usually a tedious procedure to write longform to be done quickly and effectively in-line, with nothing more than the acknowledgement of what needs to be imported.
What Would Python Do (WWPD)?
SyntaxError: invalid syntax
So what's the rule?
If you haven't yet figured out what the rule is, now's your chance to stop and reflect on the features I've highlighted above. I've formatted them very specifically, so try to pick out the pattern.
Here's an image to act as a scroll buffer while you think.
The answer, as you might expect, lies in the What Would Python Do (WWPD)? section.
Do you notice how for each of these changes, the way Python traditionally reacts is either by doing nothing or raising an exception? Or, in terms more fitting to this context, no feature modifies existing behavior as to subvert the developer's expectations?
This is the fiber that makes up one of the primary design philosophies that underpins Jishaku as an REPL. In plain English, it goes something like this:
When evaluating code, the intention of the developer is to be maintained; no amount of magic or extensibility should cause the effect of a given block of code to become unpredictable, or to have its behavior be in direct conflict with what is written.
Jishaku is a toolset designed to be used for legitimate, serious development and debugging. There may be legitimate times where a developer does, truly, wish to send their token to chat for whatever reason.
The reason the [token omitted]
clause exists in the first place is to protect situations where developers unfamiliar with the logistics of the "implicit return" may, for instance, return the contents of their config file or the attributes of a class without realizing it. I consider this substitution acceptable because the implicit return is already augmented behavior - it doesn't happen in most other debug cogs.
However, outside of such cases, the intention is clear. In accordance with the above philosophy, when you write await _ctx.send(_bot.http.token)
, I assume you mean it. Jishaku isn't doing anything wrong - it is merely doing exactly what you are asking it to do.
The solution for this problem is thus clear: if you don't want your token to be sent to chat, don't run code that sends your token to chat.
The power of the interpreter is unwieldy. One who wields Jishaku holds the same power as whatever user it is running under (which in some cases, can even mean root access - depending on how the host is set up).
Perhaps in the future I should have Jishaku warn you more aggressively about this during usage, but for now, I think referring to the sudo lecture is most appropriate:
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
from jishaku.
Related Issues (20)
- ability to add user who can run jishaku on the fly HOT 2
- Button disable
- Add Whois command HOT 2
- Unsupport discord.py v1.7.x HOT 1
- Python 3.9.13 not supported HOT 1
- Proper user configurable jsk py dict vars HOT 1
- change jishaku commands names HOT 1
- Jishaku version occasionally appears as vNone in selftest HOT 4
- Adding asqlite to options for the sql features HOT 3
- Unhandled code branch in `jishaku voice` command.
- Cog already loaded when loading it HOT 1
- I canβt use jishaku shell command HOT 2
- `jishaku timeit` raises an AttributeError upon use. HOT 1
- Tracking: need for a new release
- KeyError on Python version 3.11.0 HOT 3
- AttributeError: 'Context' object has no attribute 'add_reaction' HOT 2
- Question about next possible release to pypi HOT 2
- Convert message links to Message objects in REPLs HOT 1
- [Tracking] import_expression doesn't function correctly in 3.12 HOT 3
- jsk sync command broken on dpy master HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jishaku.