#internals-and-peps
1 messages · Page 136 of 1
And they can contend with the lack of safety precautions just fine. But I don't want anyone swimming into too deep of waters in search of treasure, and drowning
It seems, though, that there is a consensus. Don't even bother with the babyproofing. Just try to keep it as clean and logical as possible, and then document it to death
you achieve that by good and proper doc strings for whatevery you intent as user-facing API
I'm intending this library for people with zero experience, who just want to pick it up and start playing with graphics right away. I can't trust them to read the docs or even know how to
actually, you can
help(stuff), IDEs etc. all rely on proper docstrings
and are presented to the user whenever they run into trouble
external web sources as documentation on the other hand probably are only looked at if there's a link in the docstring
Hmmmm
Well, nothing for it but to push forward I guess
Though, I'm still keeping the Cython idea in the back of my mind. Its a means of completely cutting off access to stuff if need be, without having to jump through any convoluted hoops
ate you distributing binary-only releases?
And again, its not about preventing anyone from messing around, just separating the safe from the unsafe
No, pip
I mean, I'd never considered a binary-only research.
*release
thats nice
then why even consider being a jerk 😉
if people run into problems, having the source can help a great deal
Always a pleasure my friends. I'm off to go learn about 'cin' and 'cout' in C++. Riviting stuff
Why are some standard library modules written in C and others are written in python? Even if it’s a module where speed doesn’t matter, wouldn’t writing it in C reduce python’s overall size?
because python is easier to maintain
More maintainable to write in, and wouldn't distributed python source be smaller than including the binary?
Plus- messing with the innards of a module is one thing, but you want the language itself to be static
doesn't really matter if they're not distributed, and locally their size is irrelevant
Oh
my whole testing python install is only 300MB with a lot of huge frameworks which is fairly small compared to other things you'd find on a modern PC
So it’s a non-issue
Yes, the few saved kb if we're generous are vastly outweighed by the ease of maintaining python instead of C
On disk or in-memory?
On disk
Would memory be much different?
It’s still dealing with python objects underneath, right?
Yes, but depending on what this module does you don't need to always deal with Python's object.
Hmm, I don't have a good way to compare sadly. I was thinking of using some Cython-generated files I have but Cython uses macros very strongly to tweak code so the files become huge.
same reason why people write python even though C runs faster, can be applied to writing python when C could produce smaller sized files. (which, i dont even know if that's true or not. but even if it was true, theres always tradeoffs to consider)
the idea is it's portable and can be used by other pythons too
any new module written in C has to have a writeup justifying it, I think
I think there's also something to be said for Python intermediates who don't know C being able to investigate how a module does what it does
It is able to grasp pretty complex functions, as with this example: #internals-and-peps message
I gave it very specific instructions, and while the end result isn't necessarily pretty, it followed my instructions completely...
i could get behind running mypyc on all the pure python stdlib modules
"pure python stdlib" .. ehh.. yeah :p
Many of them are slight hacks though right
I don't think they would get behind strongly typing it
"slight" 😉
lol
What's the correct way to report a malware package (such as a typo-squatting token grabber) to PyPI?
there's a reason they said "don't imitate stdlib" i guess
there's an email address for that purpose
security@python.org?
it would probably produce volumes of output
For those who use VScode, there is an important feature that needs votes here (TOC for .py files): https://github.com/microsoft/vscode-python/issues/17218
Thank you
aha, that's how you get support for features in python, i see 😉 good to know
upvote
@verbal escarp , thanks man
hmm, here https://pypi.org/security/ it says that I should report there
trying to remember how i reported a package once
I reported two packages, didn't get an ACK, one of the packages is still up 😦
well, there's https://github.com/pypa/warehouse/issues/4131
and from there, there are several other issues
specifically
which was opened 2018 and is still open :p
Should I reemail pypi? Maybe they just lost my message?
then there's https://github.com/pypa/warehouse/issues/2982
but how does a security team miss an email?
aha - https://github.com/pypa/warehouse/pull/2991 curious
doesn't that mean there should be a button on pypi to report spam?
maybe you need to be logged in?
doesn't look like that was merged
sigh.
i guess the question is "what security team?" :p
support isn't a big topic for pypi
"how to get support" says: For support related to a specific project, see the links on the Projects page. For something more general, or when you’re just not sure, please open an issue on the packaging-problems repository on GitHub.
maybe reporting it via github is the way to go?
no, it explicitly says on the page to not report security issues publically
that would be a disaster
You don't expose any vulnerability by reporting a malicious package, it's even better as other people can clearly see that it's malicious without looking at it themselves before it's removed
some people will inadvertently download it
whether it would be the proper place, I have no idea but there seem to have been a few issues like that
I already defused the package, so no worries
public and non-anonymous doesn't feel right, though.. i wished there was a sanctioned method for this 😐
What's TOC?
Oooooh, that would be interesting to see how that's implemented
it's surprising that they've been hit quite a few times and there's still no interest in an efficient reporting mechanism
don't jupyter notebook store python in json though?
Yes
.ipnyb files are just JSON
i see its a floating widget with the TOC on the notebook itself
seems like vscode should have just implemented a notebook extension, then TOC would automatically work
What on earth is a TOC
It is
Im asking with regards to the vscode gh issue above, is it actually table of contents?
We're discussing IPython features I guess?
I really do think it is
The typical workflow is then to open an Interactive Window and execute a few of the cells of interest. So for finding these cells in the large file the described TOC is useful.
Pretty sure vscode already has a table of contents of some sorts, doesnt breadcrumbs count as a navigation tool
hello guys, anyone with can help me with generating a small ms access report of the database?
Do you guys get the thing with Exception groups?
Gonna read the proposal now but interested what others think
Which proposal?
See newest message in #mailing-lists
Hmm, it seems interesting but also confusing
Maybe the PEP is just too verbose but is this trying to do something with Exceptions having sub-exceptions for example so you can catch them too??
Hmm, I don’t really like this proposal
I think it will be good
Yeah I just don’t think I’m understanding it
I guess it can result in more descriptive errors
If I kind of understand it correctly, instead of discord.py's CommandInvokeError wrapping an error you can have this I think?
So less of a need of inheritance, I suppose?
Alright, so lets say I have a decorator, which decorates a function. Inside this decorator, I want to access all of the variables inside the decorated function, without having any variables that I declared in the decorator show up or overlap
is there a way for me to access the decorated functions state here
can you post your code?
for the decorator?
Did I spell it wrong, hm
def macro(func: typing.Callable):
source_str = inspect.getsource(func)
source_str = source_str.replace("@macro", "")
source_str = source_str.replace(f"def {func.__name__}():", "")
source_str = textwrap.dedent(source_str)
tokens = tokenize.tokenize(BytesIO(source_str.encode("utf-8")).readline)
for toktype, tokval, _, _, _ in tokens:
if toktype == tokenize.COMMENT:
lexer = MacroLexer(tokval.replace("#", ""))
lexer.tokenize()
parser = MacroParser(lexer.tokens)
code = parser.parse()
source_str = source_str.replace(tokval, code)
@functools.wraps(func)
def wrapper():
exec(source_str)
return wrapper
I'm finding and replacing certain parts of code with python code
I'm not sure its quite practical, but its fun :P
Could you get the frame of the function and do f_locals, would that work?
the function only has some state while it's running, how do you want to access is outside of the function's runtime? (without concurrency)
wdym?
that sounds like a job for the AST
hm, I could read up on it
I mean I found and replaced parts of python code without the AST, but maybe it wasn’t the best way
It probably wasn’t
No, less of a need of fake "wrapped exceptions"
Ahh
I'm taking code as a string, finding comments, taking the text inside the comments, sticking it to a parser, which then gives me valid python code in return, which I then insert into a string which contains the original functions source code, and then I exec it
if you have def f(): a=5; b=6 the locals with the values only exist during the function's execution, but it doesn't sound like you need to access that state. This sounds more suited to something like an import hook
oh yeah
hm, what's an import hook?
If I can't access the functions locals while running, what if I modify the function a bit so that it returns the locals stored inside that function, run it, get the locals from that, and then work from there
wait no, that doesn't work
hm, what if I tokenize the functions code, extract the locals, and evaluate them
hm, maybe not
wait nvm it might work
An import hook is something that intercepts an import (I think)
At least from what I've gathered while readin gstuff
I need help in generating a ms access database report, anyone to assist me?
@tulip condor your question isn't on-topic for this channel. See #❓|how-to-get-help.
Pretty sure I've discovered a bug in the CPython implementation of context managers. No idea how I triggered it, but at the end of my program, if I use a context manager to clean up, it dumps random binary in the first print called from the exit function of the context manager. Switch from a context manager to a try/finally block and voila, it disappears...
Wait no, nevermind. Switching to a try/finally only fixes it sometimes...
can you post your code?
the snippet that you think is giving you trouble, not your whole project please
cd to the directory, run python Logical.py examples\led.lgc
minimal example 😉
Frankly I have no idea what's causing it.
here's the context manager: https://pastebin.com/xPiD6F51
and here's the code that calls it:
if __name__ == '__main__':
with ansiManager():
sim = simulation()
sim.main()
Have not yet been able to reproduce outside of this project
and the last stable release did not do it. I didn't really touch the ANSI part between then, but I have no idea what's happening here.
Ok, I figured it was dumping memory...
looks like a help string
anyone who knows how to use libcst can i get some help in #help-potato
link?
Is programming in danger in the future? because of possible AI programmers and these days anyone can create websites and projects easily.
Simple answer no
Who is making those services that allow anyone to create websites?
The AIs are trained on human programming yeah?
!ot
Off-topic channels
There are three off-topic channels:
• #ot0-psvm’s-eternal-disapproval
• #ot1-perplexing-regexing
• #ot2-never-nester’s-nightmare
Their names change randomly every 24 hours, but you can always find them under the OFF-TOPIC/GENERAL category in the channel list.
Please read our off-topic etiquette before participating in conversations.
humans writing code directly is bad enough
humans writing code writing code will be better, im sure
Wait isn't ParamSpec implemented yet?!
hu?
not sure what ParamSpec is supposed to be
I have a usage that looks roughly like this: ```python
P = ParamSpec('P')
class Command:
def init(self, callback: Callable[P, Coroutine]) -> None:
...
def __call__(self, *args: P, **kwargs: P) -> Coroutine:
...
Wait it was merged: https://github.com/python/cpython/pull/23702
Why can't I find documentation about it
never encountered it in the wild
Aaaaahhhh
Python 3.10
Decorators that mutate the signature of the decorated function present challenges for type annotations. The
ParamSpecandConcatenatemechanisms described in PEP 612 provide some help here, but these are available only in Python 3.10 and newer. More complex signature mutations may require type annotations that erase the original signature, thus blinding type checkers and other tools that provide signature assistance. As such, library authors are discouraged from creating decorators that mutate function signatures in this manner.
Aiiight AD people
I'd like to steal some brain power if it's okay
This framework I'm working on. The graphics library.
The shape its taking, frankensteined together as it is, is essentially a python powered web browser
As with Chromium (google chrome minus the bells and whistles), my program is a multiprocessed one. I have a strong suspicion that other browsers also run each window in their own processes as Chromium does
So here's the basic setup. I've got a main Application Process (AP), and each window does its work in its own Window Process (or Render Process)
This setup is something I just gravitated towards as I worked the problem, but I know its not the only option. If its alright, I was hoping someone could help me spitball the pros and cons of this approach
shoot
def add_logging(f: Callable[..., R]) -> Callable[..., Awaitable[R]]:
that just makes me cry
Callable[..., R] gives zero information except that it returns something called R, no?
I have... no idea what you're talking about
different topic :p
it's code from the Parameter Spec PEP
what's the approach? having 2 processes is required by the way Chromium is designed right
Forget it XD I'm in too deep. I can't get any good feedback from anyone without explaining so fuckin much, and even then people are missing big chunks and can't really see the whole project
I appreciate it, and I'll just keep my mouth shut from now on
i'm reading what you wrote and still a bit confused what it has to do with python
or why you wouldn't use something like pyglet or pygame/opengl instead of subprocessing browsers
Pygame is fairly primitive, and opengl is way too low level
If either of those were good answers to making applications with Python, there would be plenty of applications with Python already made in them
Can't say I've ever given pyglet much thought though
quite a few applications use pygame https://libraries.io/pypi/pygame
Don't get me wrong, Pygame is lovely ❤️ It has a special place in hearts of many python devs because its a great place to start with both graphics, and python in general.
But its surface based approach, as opposed to element based, prohibits 'serious' usage. Any time you make a change to some 'thing' you need to completely wipe the screen, and redraw. This is very slow and complicated.
I went through the motions of implanting an object based architecture on top of Pygame that took care of clearing and redrawing elements every frame (assuming some change to some object had occured since the last one). Aside from being hellishly slow, it began to resemble an element based system
right, pygame with software rendering is very slow, wouldn't recommend it
To my understanding, every other graphics frame is (and rightly should be) widget based in that you the user never actually make any draw calls, you just specify the graphical attributes of a thing and the system takes care of the rest.
From what I've seen, and it has been a while since I toured all the different libraries, they are all either too complicated or just look like crap—or both
I don't ever expect anyone to use my library, but the theory is sound. Remote control over web graphics using a pythonic implementation of Javascript's element API
remote control over web graphics is pretty common in industry prototypes, putting python in the browser not so much
also almost nobody gets data streaming into or out of browsers right
had to explain to two different roomfuls of engineers that browsers can't open raw UDP sockets just last week 😄
how do you have to redraw everything?
it's double buffered
you just draw the changed stuff, right
then it blits the area to your screen
just wondering why build a library you don't expect anyone to use? and why concerned about locking down stuff ? 😅
Not called R, I would assume that is a TypeVar. So basically add_logging takes a callable which takes unknown arguments (...) and returns what we assign to R. Then add_logging returns a callable that also takes some unknown arguments (...) and returns an Awaitable which when awaited returns the same R that the original callable did
The problem is that type checkers don't know if the first ... and the second ... is the same ...
This is what ParamSpec solves
ohh, i ser
why is it ... ? doesn't the function have to know what the arguments are?
... is a sentinel (special flag value) that means "variable unknown arguments"
No it doesn't. add_logging doesn't have to know what arguments it takes.
Otherwise you would have the arguments in a list like: [int, str, str] (a: int, b: str, c: str)
It's not a bug in python it seems, just time.sleep playing with output buffering...
And generally conhost's output buffering breaking. I suspect Windows Update had something to do with that...
gotcha, its like printf
wow random binary?
as far as I can tell
printing reprs of things has crashed my terminal before
I saw stuff like help strings, pyc binaries, etc. The weird part was that a specific print statement always triggered it.
Sounds like memory corruption
use-after-free?
I think something one of my libraries was doing or how rapidly I was calling print without scrolling the console caused buffer overflows, either in CPython's print source or in conhost.
honestly dont know how that stuff could end up in a python string unless it was overwrittrn
I honestly think conhost was reading outside the string
maybe some atexit() function
that is where it happened but not what caused it
Anyway, this is what fixed it:
sys.stdout = io.TextIOWrapper(open(sys.stdout.fileno(), 'wb', 0), write_through=True)
I put that after the imports in the main file, then fixed a thread contention and voila!
I reinitialized it with buffering disabled
sure seems like a bug..
How exactly does an import hook work?
wdym
The ones that can edit source code
I’ve seen something that imports from a “MetaPathFinder” and uses importlib
How do they work exactly
wait nope
you implement a Finder protocol
and stick it in sys.meta_path
!e
import importlib.abc
print(dir(importlib.abc))
@lusty scroll :white_check_mark: Your eval job has completed with return code 0.
['ExecutionLoader', 'FileLoader', 'Finder', 'InspectLoader', 'Loader', 'MetaPathFinder', 'PathEntryFinder', 'Protocol', 'ResourceLoader', 'ResourceReader', 'SourceLoader', 'Traversable', 'TraversableResources', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_bootstrap', '_bootstrap_external', '_frozen_importlib', '_frozen_importlib_external', '_register', 'abc', 'machinery', 'runtime_checkable', 'warnings']
... basically
then you'll get called to find modules and you can respond, delegate loading the source code from the successive finder, then do whatever replacement you want, and return that basically
MetaPathFinder is the easiest to subclass
!warn 890860286007971861 Don't post random dodgy links here
:incoming_envelope: :ok_hand: applied warning to @idle garnet.
!e
from importlib.abc import Finder
from _sitebuiltins import _Helper as help
help(Finder.__init__)
can you help me with this
looks like theres a weird character on line 31. try deletimg the entire line and retyping it
There's just a missing parenthesis on the line above (27)
What is the reasoning behind set methods such as set.intersection and set.union accepting any iterable as the second argument but the corresponding operators (|, &) accepting only sets?
Possibly to ensure a & b is the same as b & a, for example
It's more explicit and shows that it's the set that's controlling the operation, not the other type
doesn't it have to be an iterable of sets?
!e no
print({1, 2, 3}.intersection([2, 3, 4, 5]))
print({1, 2, 3} & [2, 3, 4, 5])
@native flame :x: Your eval job has completed with return code 1.
001 | {2, 3}
002 | Traceback (most recent call last):
003 | File "<string>", line 3, in <module>
004 | TypeError: unsupported operand type(s) for &: 'set' and 'list'
oh duh, you can still loop
hm i wonder if there's any operators which work with a X b but not b X a
can't think of anything builtin
yeah can't think of anything
**
list += str
🤔
2 ** 3 != 3 ** 2
oh depends on your definition of work
no i meant whether or not it errors
a and b are just placeholders, how could it logically work with a X b but error with b X a?
list can use += with any iterable but not necessarily the other way around
Although, I guess the assignment operator works like that
a = 1 is fine but 1 = a will error
if a class A implemented __mul__ and not __rmul__ then 1 + A() would error but A() + 1 wouldn't
oh right, = does count as an operator
Is = an operator? I guess it's mainly just semantics, but i'm not sure i'd call it one. I'd say := would be more of on operator, still not sure i'd call it one though
nvm I guess it is
"assigment operator" is a fairly common term
oh i found one, str % int and int % str
In [25]: "h %d" % 1
Out[25]: 'h 1'
In [26]: 1 % "h %d"
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-26-0be8d1c43bc1> in <module>
----> 1 1 % "h %d"
TypeError: unsupported operand type(s) for %: 'int' and 'str'
Whether or not = would count as an operator in Python is an interesting question since it doesn't return anything, unlike in most other languages
Really just depends on how you define "operator", I'd call = itself an operator but as a whole it's the assignment statement
I mean if the __i*__ set is considered as operators, = is probably an operator too
actually, = is an operator, you can modify the behaviour
i've done so once, but i wouldn't recommend it in general
What do you mean by "modify the behaviour"?
you can have side-effects on assignment
on assignment of a name - no
with descriptors?
no, python
then what do you mean?
let me show you the one and only example where i used it to make things nicer for the user
for example in [4], there's T.down = S(20, 20)
S is a function which is turned into a Set on assignment as a sideeffect to add logical operators
which makes it much nicer for the user
def __setattr__(self, name, value):
"""Define a set within a domain or assign a value to a domain attribute."""
# It's a domain attr
if name in self.__slots__:
object.__setattr__(self, name, value)
# We've got a fuzzyset
else:
assert str.isidentifier(name), f"{name} must be an identifier."
if not isinstance(value, Set):
# Often useful to just assign a function for simple sets..
value = Set(value)
# However, we need the abstraction if we want to use Superfuzzysets (derived sets).
self._sets[name] = value
value.domain = self
value.name = name
that's how it works behind the scene
i'm pretty sure you could also do that with module-level variables, but i've never tried to change the Module implementation, so feel free to experiment
yeah, you can customize attribute setting
but you can't do that with module-level vars
well, you can if you return a proxy instead of your module
Is there any way in python to fork a new process from a function when calling another function which is totally independent from the calling fn?
Example:
def fn1():
stmt1
call_independent_fn2() #achieve ||elization here
stmt3
return
then you'll have to use something weird if you want to set variables in your module
because they're two separate attributes that get called potentially
Is multiprocessing what you want? https://docs.python.org/3/library/multiprocessing.html
you should probably ask in #async-and-concurrency
@verbal escarp Wait so what's your definition of an operator?
something like that. But my Q is
def fn1():
stmt1
call_independent_fn2()
stmt3
return
there's not really a nice and clean definition.. but coming from the literal meaning of the word, i'd say an operator is something that does something
I'm afraid everything is an operator then
yeah, pretty much
or set __class__ of the module right?
hm???
that comes down to the same thing, basically
lol, fair
- to a subtype of
ModuleTypeso__getattr__and__setattr__can be customised, that is
well, let's try it and see
__getattr__ already works
idk what exactly was meant by proxy but figured subtype of ModuleType isnt necessarily one
proxy would be kind of a delegating module, I would think
tricky
i guess you start with a regular ModuleType object, then set __class__ on it?
but i think you can only do that on a module you imported
not on the module you're coming from, no?
oh, I don't think it specifies. I'll dig it up
ohh
you could get it via sys.modules["__main__"]
hehe
😈
<method-wrapper '__setattr__' of module object at 0x00000264BB8872C0>```
ohh yeah
now we only need to rebind a free function as a method of that module
This goal that motivated this patch was getting
__class__assignment to work on modules, which are mutable and uncacheable and totally safe. With this patch it becomes possible to e.g. issue deprecation warnings on module attribute access,
https://bugs.python.org/issue24912
some strong opinions on that bug 👀
at this point the whole distinction of "free variable" and "bound" becomes a blur
almost as blurred as the boundary between cpython bug and feature, apparently
if you write a function in a module, it's kind of bound to that module.. philosophically, there's never a "free function"
lmao
a long stroll into monkey-patching land
heheh
let's try it with a MethodType
not sure why this isn't working
import sys
from types import MethodType, ModuleType
def foo(mod, name, value):
object.__setattr__(mod, name, value * 2)
sys.modules["__main__"].__setattr__ = MethodType(foo, sys.modules["__main__"])
x = 2
print(x)
but i guess that's one way to approach it
In your case, __setattr__ becomes an instance attribute
Most dunders aren't directly looked up on the instance, they're looked up on its type instance
which is correct, since __main__ is an instance of ModuleType
!e ```py
class Example: pass
e = Example()
e.setattr = print
e.xample = 42
type(e).setattr = print
e.xample = 42
@spice pecan :white_check_mark: Your eval job has completed with return code 0.
xample 42
So that's one of the reasons it didn't work
The other is I'm not sure if global assignments use __setattr__ at all
that's what i was wondering about, yeah
!e ```py
import main as main
from types import ModuleType
class Doubler(ModuleType):
def setattr(self, attr, value):
if isinstance(value, int):
value *= 2
super().setattr(attr, value)
main.class = Doubler
x = 21
print(x)
@spice pecan :white_check_mark: Your eval job has completed with return code 0.
21
Seems like it isn't
Module-level __getattr__ is special-cased, right?
As in, it works if it's defined on an instance and not its type
ye, that one is an entirely different protocol
so does it need to be a class attribute?
Generally, yes, but global assignments don't trigger __setattr__ anyway
As demonstrated here, most (if not all) dunders are looked up on the type, not the instance
then how does it happen with __main__ for example
something must be calling __setattr__ (or Py_GenericSetAttr or some C function I guess)
Not necessarily, it could directly affect the dict, for example
i wonder if a ModuleType could have __slots__
!e ```py
class Example:
setattr = lambda *a: print('No')
e = Example()
e.denied = 10
e.dict['sneaky'] = 10
print(e.sneaky)
@spice pecan :white_check_mark: Your eval job has completed with return code 0.
001 | No
002 | 10
then changing the dunders of ModuleType could work?
Technically yes, but, as I've shown a bit later, assignments don't trigger __setattr__
Traceback (most recent call last):
File "F:\Dropbox (Privat)\code\justuse\tests.tests.A", line 7, in <module>
sys.modules["main"].class.setattr = MethodType(foo, sys.modules["main"])
TypeError: can't set attributes of built-in/extension type 'module'
You can either replace the class or use something like forbiddenfruit to patch the original
python doesn't like that at all
Here's an example with class replacement
replace the class, yeah
If you do the same but explicitly use attribute assignment, the value should be doubled
!e ```py
import main as main
from types import ModuleType
class Doubler(ModuleType):
def setattr(self, attr, value):
if isinstance(value, int):
value *= 2
super().setattr(attr, value)
main.class = Doubler
x = 21
main.y = 21
print(x, y)
@spice pecan :white_check_mark: Your eval job has completed with return code 0.
21 42
Maybe you could fiddle with the underlying dict, actually
well, that's what i feared about the current module being special
you can do the whole weird stuff with modules you imported, but the one you're currently in is somehow holy
I wouldn't say so
If you try the same with a different module, assignments within that module are treated the same way
but it only works with main.y, not x
if __main__ really was the module you're currently executing, it should also hit x, no?
and i'm replicating the same behaviour here
either way i'm trying to execute it, doesn't work
No, because the implementation of assignments uses a different mechanism. Regular assignment and attribute assignment aren't the same thing, even though their semantics are similar (especially in terms of modules)
If you try to do that in a different module and then perform a global assignment within that module, it still won't trigger __setattr__
Regardless of whether it's imported
okay
!e ```py
class DoubleDict(dict):
def setitem(self, key, value):
if isinstance(value, int):
value *= 2
super().setitem(key, value)
from types import ModuleType
class Doubler(ModuleType):
pass
import main as main
main.class = Doubler
main.dict = DoubleDict(main.dict)
x = 10
print(x)
so pure x is never an attribute of the current module, truely free?
@spice pecan :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 13, in <module>
003 | AttributeError: readonly attribute
Ah, that's unfortunate
It can be accessed as an attribute and it does reside in the __dict__, but assigning to it can be done in different ways, only one of which is attribute access
but assignment is restricted
bleh
so, how does python assign a free variable?
it's a weird question.. 😄
Most likely by directly changing the module dictionary
that's something a noob would ask in the first 5 minutes of learning the language
We'll have to take a look at the source for STORE_NAME/STORE_GLOBAL
15 years later.. same question
Python/ceval.c line 3020
TARGET(STORE_GLOBAL): {```
how do you get it to show multiple lines again?
Python/ceval.c lines 3020 to 3029
TARGET(STORE_GLOBAL): {
PyObject *name = GETITEM(names, oparg);
PyObject *v = POP();
int err;
err = PyDict_SetItem(GLOBALS(), name, v);
Py_DECREF(v);
if (err != 0)
goto error;
DISPATCH();
}```
so there's no way to delegate this behaviour at this point, ok
Reassigning __dict__ was the closest one, but still not enough
at least it's possible for vars in "imported" modules
is your goal to control what happens when globals().__setitem__ is called?
as long as it involves an attribute access
the initial question was whether = should be considered as an operator, something whose behaviour you could modify
now it's getting funky ^^
Spoiler, didn't work
aw
!e ```py
from ctypes import *
obase = py_object.from_address(id(globals()) + 8)
class fglobals(dict):
slots = ()
def setitem(self, key, value, dict=dict):
try:
obase.value = dict
print('setting', key, 'to', value)
self[key] = value
finally:
obase.value = class
obase.value = fglobals
a = 1```
@pliant tusk :white_check_mark: Your eval job has completed with return code 0.
setting a to 1
oh god xD
ctypes wins again
forbidden fruit wouldn't help because that changes behavior for all dictionarys
Let's see if I can remember how to make a recursive tuple
so we cheat and change the type the dictionary that globals returns to a subclass that we control
that's so crazy
@spice pecan challenge, make a recursive tuple without ctypes
!e ```py
tup = [],
tup[0].append(tup)
print(tup)
@spice pecan :white_check_mark: Your eval job has completed with return code 0.
([(...)],)
!e ```py
def gadget(n):
def f(*v):
nonlocal n
if v:
n = v[0]
else:
return n
return f
C = gadget.code
gadget.code = C.replace(
co_code=b'\x88' + C.co_code[1:]
)
x = (0,)
gadget(list.setitem)(tuple)
list.setitem((x, 1, 2, 3), 3, x)
gadget(list.setitem)(list)
print(x)```
@pliant tusk :white_check_mark: Your eval job has completed with return code 0.
((...),)
Ok, that's smart
Defining a function to alter it's bytecode is a genuinely interesting move
yea i got it down to one byte of alteration too
damn
but i wouldn't rely on this trick for obvious reasons :p
i wouldn't have guessed it's possible though, at all to manipulate the code on this level
boon and bane of leaky internals, i guess?
the above code actually abuses a bug to write an address to id(object) + 3 * 8
what's that?
hello
im new
and im 13 years old and intrested in coding
!e
i cant send my code
too bug
big
!paste
Pasting large amounts of code
If your code is too long to fit in a codeblock in discord, you can paste your code here:
https://paste.pythondiscord.com/
After pasting your code, save it by clicking the floppy disk icon in the top right, or by typing ctrl + S. After doing that, the URL should change. Copy the URL and post it here so others can see it.
hi, if you're looking for help with your code, you could try to post it in one of the available help channels 🙂
this channel is for discussing weird quirks and uses of the language itself
just a name of different channels
yeah, those are open
just click on one of them and start asking there
whichever suits your taste best 😉
since you already asked and i feel that it should be said - please stop commenting everything 😉
comments are directed at people unfamiliar with your code - or you, in a year or so - that is, people who know how to code but don't know why you did what you did
your comments indicate that you grew bored of repeating your code - a good sign to start using loops and functions
and then.. finite state machines 🙂
A finite-state machine (FSM) or finite-state automaton (FSA, plural: automata), finite automaton, or simply a state machine, is a mathematical model of computation. It is an abstract machine that can be in exactly one of a finite number of states at any given time. The FSM can change from one state to another in response to some inputs; the chan...
it's the go-to concept of anything that relates to states - from flowcharts (conversation scripts) to buttons being clicked
FSMs are used extensively in GUIs, game scripts
im on mac rn and it shows idle is open but i cant close it and i cant open it what do i do
Question — what exactly is mappingproxy?
it's essentially a mapping not backed by a hash table, e.g. for classes with slots
Ah
Crypto.Cipher is from pycrypto which is deprecated, yet pycryptodome seems to be using it, am I the only one to light up here a big WTF bulb?
Same module names in 2 different libraries
There is no enforcement that module names be unique across packages distributed on pypi
I think the "cryptography" library also uses those names
!pypi pycryptodome
!pypi cryptography
Ah no, cryptography has a different API
https://github.com/Legrandin/pycryptodome/blob/master/lib/Crypto/Cipher/AES.py Its using Crypto.Cipher it says
And if you do Crypto.__file__ on your pc you will see that Crypto is from pycrypto, and crypto is from pycryptodome I guess
C vs c difference
would you believe there are teachers out there telling students to "comment every line" .. that's probably where the inspiration is from
could be boredom too, ig 😅
its a thin wrapper over a dict oftentimes
in fact you can get the original (mutable) dict if you use a simple helper function to read 8 bytes into the mappingproxy object (with ctypes)
Hm, what would be an example of this?
import ctypes
mp = type.__dict__
realdict = ctypes.py_object.from_address(id(mp) + 16).value
Hm
If type is a mapping proxy wouldn’t that not work?
Oh wait Nvm
Class dictionaries are mapping proxies
idk if mappingproxy has to contain a regular dict, but whatever it contains should be some kind of mapping-like thing (and the offset to it is fixed)
also taking advantage of the fact that id is the address of the object
lets see if the eval is on a 64-bit python
!e
import ctypes
mp = type.__dict__
print(mp)
realdict = ctypes.py_object.from_address(id(mp) + 16).value
print(realdict)
@lusty scroll :white_check_mark: Your eval job has completed with return code 0.
001 | {'__repr__': <slot wrapper '__repr__' of 'type' objects>, '__call__': <slot wrapper '__call__' of 'type' objects>, '__getattribute__': <slot wrapper '__getattribute__' of 'type' objects>, '__setattr__': <slot wrapper '__setattr__' of 'type' objects>, '__delattr__': <slot wrapper '__delattr__' of 'type' objects>, '__init__': <slot wrapper '__init__' of 'type' objects>, '__new__': <built-in method __new__ of type object at 0x7fa5721aa980>, 'mro': <method 'mro' of 'type' objects>, '__subclasses__': <method '__subclasses__' of 'type' objects>, '__prepare__': <method '__prepare__' of 'type' objects>, '__instancecheck__': <method '__instancecheck__' of 'type' objects>, '__subclasscheck__': <method '__subclasscheck__' of 'type' objects>, '__dir__': <method '__dir__' of 'type' objects>, '__sizeof__': <method '__sizeof__' of 'type' objects>, '__basicsize__': <member '__basicsize__' of 'type' objects>, '__itemsize__': <member '__itemsize__' of 'type' objects>, '__flags__': <member '__flags
... (truncated - too long)
Full output: https://paste.pythondiscord.com/cuyatejuca.txt?noredirect
weird, for me the first prints as
mappingproxy({ ... }) but not here?
It's the difference between str and repr
printing it skips the mappingproxy(...) wrapper
thats what i was looking at, added the prints so we could see somethimg here
!e
import ctypes
mp = type.__dict__
print(repr(mp)[0:128])
realdict = ctypes.py_object.from_address(id(mp) + 16).value
print(repr(realdict)[0:128])
@lusty scroll :white_check_mark: Your eval job has completed with return code 0.
001 | mappingproxy({'__repr__': <slot wrapper '__repr__' of 'type' objects>, '__call__': <slot wrapper '__call__' of 'type' objects>,
002 | {'__repr__': <slot wrapper '__repr__' of 'type' objects>, '__call__': <slot wrapper '__call__' of 'type' objects>, '__getattribu
does https://github.com/python/cpython/blob/f25f2e2e8c8e48490d22b0cdf67f575608701f6f/Objects/setobject.c#L177 mean that when a set resizes, it allocates memory for twice the number of items if over 50k elements are used, and 4x the number of items if under 50k elements are used?
Objects/setobject.c line 177
return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);```
i know that dicts resize following a 2x rule, but i'm trying to figure out the rule for sets
i'm also trying to figure out what size a newly created set starts at. i found https://github.com/python/cpython/blob/f25f2e2e8c8e48490d22b0cdf67f575608701f6f/Objects/setobject.c#L577, but that's under set_merge so i don't think it's called when simply creating a set
Objects/setobject.c line 577
if ((so->fill + other->used)*5 >= so->mask*3) {```
ok, did some getsizeof testing, and it seems that a set expands from 216 bytes to 728 bytes as soon as the 5th element is added (though 728 bytes may be including the size of the ints i added, i'm not sure about that), so i think it starts with allocating space for 4 objects
216 bytes?
yes
isn't that a big for a set?
nah
nah empty dicts are like 340
it used to be 232 bytes for an empty set a while back
Would one of you fine gentle-people mind giving this a look: https://hastebin.com/apapobered.py
I'm still working on my best practices, hence my asking you guys to take a look
Can you elaborate?
as for line length, it looks like it follows a consistent max character count, which is good
"horrific" was a bit startling. I didn't think it could be that bad
100 characters
I've taken a poll in the past, and there doesn't seem to be a consensus on the matter. Some people even use more than 100
however if using 88 adds a significant amount of lines, 100 isn't a bad choice
honestly, some of the projects i contribute to use 120, and it looks fine to me, but i also do very little coding on my phone
i only do it when my bot breaks and i dont have my computer on me
i see that you have some comments on the line they're describing, and some right before the line, and some right after
i believe best practice is to put all comments right before the line they describe
taking notes
you use a lot of getattr without specifying a fallback value. for example in approveTransit (i'll get to using snake_case later). you can just use ``self.family, target.document`, etc
function names use camelCase, when they should be snake_case (at least in python). variable names shuld be snake_case too, only class names should be camelCase
other than that, just look into isort and try it out, and you should be set. your imports aren't horribly sorted/formatted, but it doesn't hurt to familiarize yourself with isort
Ahhhhhehe, yeah, theres a good reason for the camel case
yeah, dom stuff
Yeah, DOM stuff
in that case, i'd just use the style that the people most likely to be reading your code would use
if you're targeting it to be used by python users though, i'd use snake_case
I'm targeting complete beginners to all languages primarily, and then JS users looking to build apps offline with a better language secondarily
And, and I might be totally off the mark here, but between a python programmer and a JS programmer its the JS programmer who needs the handicap
Nontheless, thanks so much for giving it a look! I'm happy to hear no major issues, apart from the obvious offensive disregard of some standards
And I do hear you with regard to the stylistic stuff. I'm walking a bit of a tightrope
Cause it's pretty :3
@white nexus ping me if you like
Huh, I personally define them above except if it's part of a section and I'm only explaining a part of the line
Most things default to 79, Black's 88 default is nice tho.
@static bluff sorry, I shouldn't have called it horrific, that's disrespectful regardless of who wrote it 👀 I also heavily lint and style my code which makes me biased
Well—for technical reasons—I have to go about things a bit differently and it can be blinding to a lot of python devs, especially experts
I don't take it personally
But please, I'm all ears if you have comments
Ye, I actually understand a lot more from what you've explained now :P
I've come to find a style I really enjoy.
79 for docstrings and comments
With a goal and upper limit of 95, then error on 105 giving me the flexibility if there are long lines that would look worse over multiple lines
I rather have a higher length for linter error, than set it at 95 and have a bunch of noqa comments
assuming that by above, you mean a single line above, then i think we both agree on that, right before and above a single lne are the same thing to me
fair, i only use black though so noqa doesn't really work
flake8-bugbear has one for this
B950
if you can help me dm me pls
ok am I crazy? I have a hand compiled python 3.9.5 install with a virtual environment, it's been working like a chaaarm for months now, but today I try to install numpy on a new system and it's freaking out about the wrong version of libc (wants 2.29, but 2,28 is installed) I tested this across several systems and experienced the same problem; however, it was working fine last weekend O_o
try installing an older version of numpy
or maybe you did a system update and forgot to reboot?
That's just it I did, same problem, I have several systems running on cloned images
to verify I did a pip freeze on the environment I setup last week (that is still working in place mind you)
so I created a new virtual environment, sources into it and installed the same version of numpy that is working in the origional
hard crashes on import stating a versioning problem with libc
black and sourcery all the way for me 🙂 there are very few places where #fmt:off is necessary to keep extra long lines that would be harder to read if wrapped
and sourcery really helps simplifying the code down to well known idioms
like turning "if foo == False" into "if not foo" etc
which also helps a lot when it comes to mental load and readability
i believe i just found a potential bug in your code @static bluff
clone = getattr(self, 'document').createElement(getattr(self, 'tagname'))
if self.document is None, it will throw an attribute error because None has no attribute createElement
L376
Doesnt List[...] imply Iterable[...]
i'd say so
Ok im missing something then, thanks
nobody would be crazy enough to remove the ability to iterate from a list, i don't think
maybe it needs to be a mutable iterable?
Ok so the problem is im going from a union of a couple things to a union of fewer things i believe
the whole typing should be boiled down to protocols methinks
Im going from List[one | two | three] down to List[one | two], i think thats why i get an error
that could be an issue, yeah
maybe you can reformulate one | two to include three implicitely
Im not sure i can, theyre both different structures of tuples
do you have to throw out three?
Tuple[str,str,str], Tuple[str,str] and Tuple[str,int]
Its a config dict and i possibly need all of them or a combination
ahh
I guess i can generalise my target list
heh
||psst we have #type-hinting now||
("foo", "1") 😉
Not exactly, if all you do is iterate through it then yes
Im extending another list so i guess so? Not sure
Oh lmao, when did this happen
meh :p
today for me, yesterday for you probably
if you construct the other list, you don't pass it in as an argument
how does that spoiler thing work?
||text||
||uhh.. offtopic as spoiler, neat 😉 ||
why do you need a (str, str, str) for a config?
Im parsing excel sheets, its
(heading, direction, alias)
and why do you need (str, int), you could just handle (str, str) and convert the value to what you need.. ohh, god excel, no.. ahhh
The entire function is in #type-hinting
I can figure it out some other time anyway, this isnt even on the list of problems with the codebase
i can only imagine :p
if that is your config
you have my sympathy
@astral gazelle maybe you can use pandas for that job
it handles excel okay
although, you'd need to query numpy arrays instead of dicts..
shrug
Already using openpyxl which is what pandas uses
Its okay i guess, but im trying to move to either json or literal python files with dict configs would be so much better
The problem is the users dont know python, but everyone knows excel
At least it's not word
just to settle this:
!e
from collections.abc import Iterable
print(f"{issubclass(list, Iterable)=}")
@lusty scroll :white_check_mark: Your eval job has completed with return code 0.
issubclass(list, Iterable)=True
ofc ABCs are all dirty, lying cheaters anyway
if i had to design this, i'd have proposed a way to combine protocols
a list would be <iterable + mutable> or somesuch
what would be in a mutable protocol then?
the approach I normally see goes something like Iterable -> Collection -> Ordered -> MutableOrdered -> List
i.e. the immutable-mutable split is last
I mean, isn't that literally the inheritance hierarchy?
Except for the fact that list isn't a subclass
Lists conform to the MutableSequence ABC, which inherits from Sequence, which inherits from Reversible and Collection, which inherits from Sized, Iterable and Container
ish
like "mutable" by itself
wouldn't fit as an interface/protocol/whatever IMO?
except as a marker
because the nature of mutation differs for each type of container
Yeah, containers just get another MutableX variant
well, probably depends on the default
if we say immutable is the default
then mutable might be more meaningful
maybe mutable is a bad example
but my point is still valid
if we had a way to combine protocols, we wouldn't need to codify every single possible combination as an ABC
imagine ABCs as tokens that represent specific protocols and then have sets of those tokens to represent possible combinations
say, you need an ordered collection that's usable as a key (-> hashable)
but also mutable like a list
you could just combine ABC-"tokens" that represent those traits
{hashable, ordered, mutable}[int]
something like that
it's basically a promise that whatever thing is used, it has those traits
as a container for ints
doesn't look too shabby, does it?
Again, that's mostly the way it already is
The mutable thing is the only issue, because you can't really have that as a protocol, you never know if a method does or doesn't mutate the container
that's nowhere near how it currently is
There are ABCs for hashable and ordered containers
yeah, but how do you combine those promises?
yeah, that's nowhere near what i'm proposing
I mean, so far the only difference is the ability to combine them without defining a named protocol
As well as difficult-to-define traits such as mutable
not really difficult, no
the problem is that there is no defined unified protocol for mutability
Exactly, that's what makes it difficult
but it's not difficult to define
Any method can potentially mutate the container, and there can be containers that are mutable, but don't implement __setitem__, for example
How would you define Mutable?
i wouldn't, i'd regard it as a promise, delegatable to icontract and friends for testing
It's an interesting topic, I'd love to hear your ideas on it, since I don't really know how we could define a Mutable protocol either without it not being applicable to a valid mutable (albeit unconventional) container or directly inheriting from it
maybe hypothesis can help
(this may be on topic for here) is there a way to see how much memory a specific object is taking? in my case ```py
big_honking_dict = {...}
big_honking_dict.sizeof() # Always returns 216, irrespective of the size
how do i know how much memory `big_honking_dict` is taking (in bytes btw)?
go through all methods, pass in stand-in items as params and check if the items in the container were mutated
i can very well imagine that it could work as a automatic test
__sizeof__ and sys.getsizeof actually do give you the correct answer in bytes
The reason it doesn't change is because it's not filled up enough to trigger a resize, try larger numbers
ah that makes sense
let me try and get back
!e ```py
from sys import getsizeof
print(getsizeof(dict.fromkeys(range(10_000))))
@spice pecan :white_check_mark: Your eval job has completed with return code 0.
295000
Yeah
thanks @spice pecan 👍
While that would technically be possible, there still needs to be some convention regarding checking the internal state of the container, as well as I imagine it would be computationally challenging
Though that would be a curious solution to the problem
I feel like having an empty Mutable ABC that is an explicit base class for all mutable containers would be the most reliable solution, although that would require certain changes to built-ins and stdlib
for some reason this doesn't work on my computer ```py
from sys import getsizeof
N = 10000000
data = {"verybigwordhehe": 1.474848393847393 for _ in range(N)}
print( getsizeof(data) )
That's because you're using the same key over and over again
The resulting dictionary only contains one key-value pair
heh
fromkeys is a good way to quickly create a dict with a certain amount of keys
why not just take the _ as key?
i basically want to know how much a dict with 10000 string-float key value pairs will take, which is what i was aiming for
im not sure i understand, _ as key?
the code you posted
The keys and values themselves aren't counted
oh....
you're throwing away the _ in the range
__sizeof__ only gives you the size of the container itself, because every object can have a different amount of references to it, and counting them as part of the container would be a bit incorrect
perhaps for my use case i should just pickle.dump it and look at its file size
you can just use that as key, you could convert it to str if you really want str-keys
(since that was im going to be doing in the end)
sorry for the inconvenience, carry on 👍
That would sort-of work, but do keep in mind that in a real environment it depends a lot on how your strings and floats are conceived
Actually, nevermind, that would be more important for lists than dictionaries, since you can't have equivalent strings in a dict and floats are vastly more likely to be separate objects than to reference the same float
I've got 2 decorators, one of them being new_thread() which launches the function in a new thread, other being error_handler() which handles exceptions. In error_handler() I've got line_number = currentframe().f_back.f_lineno which gets the line number where the function was called.
If I run the below code with @new_thread() commented out, the error handler decorator prints Error handler ... line 14 ... which is correct. But if I run it in a new thread, it prints Error handler ... line 892 .... How could I get the accurate line number if a new thread is involved?
@new_thread()
@error_handler()
def test_func():
x = 1/0
return x
test_func() # <- Looking for the line number of this, `currentframe().f_back.f_lineno` works if `@new_thread()` is not used
def new_thread():
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
t = threading.Thread(target=func, args=args, kwargs=kwargs)
t.start()
return t
return wrapper
return decorator
def error_handler(count=0, wait=0, log_exc=True, exc_info=True, capture_exc=True, print_exc=True, print_traceback=True, slack_exc=True, message=None):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
retries = 0
while True:
try:
return func(*args, **kwargs)
except Exception as e:
retries += 1
func_name = func.__qualname__
line_number = currentframe().f_back.f_lineno
if message is None:
exc_message = f"{type(e).__name__}: {e}"
else:
exc_message = message
msg = f"Error handler ({func_name}, line {line_number}): {exc_message} ({retries}/{count if count != 0 else 'INFINITE'})"
print(msg)
...
whats th meaning of protocol here
we sort of have that with "virtual fake" multiple inheritance
i'd argue Sequence, Iterable et al should appear in the bases and mro for 'list'
we need to decide, is 'list' an implementation of these ABCs or isnt it
the whole thing is a big pile of leaky abstractions 😫
well, as i said earlier about "mutable", i'm not sure if there is any point in trying to codify those abstractions, they only become meaningful if you regard them as promise or contract and be able to test against them
is there a language that has the preferred semantics? one that doesnt rely on implementation inheritance ideally
so, they can be as abstract as you like, really, as long as you can think of ways to test them
and discovery
yeah, and that
good question, no idea
well its cut off, but the point is that UserList is the only subclass of MutableSequence that's in any way close to list, and it has no subclasses
perhaps the abc registration thing (I think a register method is used to make issubclass/isinstance work with abcs) should somehow add to the list of subclasses?
!e
from collections.abc import *; from collections import *; [print(f"{cls.__name__} subclasses:\n\t{list(map(type.__dict__['__qualname__'].__get__, cls.__subclasses__()))}") for cls in (Collection, Sequence, MutableSequence, UserList, list)]
@lusty scroll :white_check_mark: Your eval job has completed with return code 0.
001 | Collection subclasses:
002 | ['Set', 'Mapping', 'ValuesView', 'Sequence']
003 | Sequence subclasses:
004 | ['ByteString', 'MutableSequence', 'UserString']
005 | MutableSequence subclasses:
006 | ['UserList']
007 | UserList subclasses:
008 | []
009 | list subclasses:
010 | []
how should that be explained to a beginning python user who is just learning their ABCs...
there's room for improvement, we just need a couple more APIs
to reflect this hierarchy
this sounds like a child on the first day of school ;D
but, don't look too closely at them..
tbh why did we ever start doing the capitalized types thing
because type annotations were supposed to be executable but the regular types would be incompatible to eval() in this context
i'm not going to say again that i find the idea stupid, but there i go
they broke that then, because if I try to run, say, List[str] its an error, right?
at least unsatusfying :\
and we have the various ABCs clashing with the typing ones
the solution: metaclasses!
reminds me of what is said about regex
"you think 'i have this problem, right - let's use regex!', now you have two problems"
exactly
class BowEstimator(BaseBowEstimator):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@classmethod
def from_config(cls, *args, **kwargs):
return super().from_config(*args, **kwargs)
@classmethod
def from_saved(cls, *args, **kwargs):
return super().from_saved(*args, **kwargs)
Is there any way in which this is different from just not implementing these methods?
i don't see any
I guess there's a chance that they're not class methods in the superclass?
they are class methods in the superclass, apparently. Thanks!
Hello everyone i am new here
please i wanted to ask if anyone knows how to convert perl code to python? Thannk you
perl code to python?
urgs
you could also execute perl in python
Embed a Perl interpreter in Python
Thank you
i wouldn't expect to find these methods in a class
i would look in the module probably
i dont know if factory functions in python are very common?
in a class i mean
by factory function, do you mean a method that returns a new instance of its class?
yeah, a "static method"
yeah, dict.fromkeys for example
exactly
actually, one of my favorite python "design patterns" are class method constructors.
wdym
a class method, often with a different signature than the __init__ method, that returns a new instance.
an advantage of this approach is that since it's a class method, any subclasses will return an instance of that subclass rather than the class in which the method is defined.
often seen when homebrewing deserialization, e.g. from_json(...)
can you give a minimal example how you use that?
class A:
def __init__(self, one: str, two: int):
# ???
@classmethod
def alternative_init(cls, one: float):
return cls(str(one), int(one))
class B(A):
pass
b = B.alternative_init(3.14)
isinstance(b, B)
# True
!e
import json
class Thing:
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
@classmethod
def from_json(cls, data):
parsed = json.loads(data)
return cls(parsed["foo"], parsed["bar"])
t = Thing.from_json('{"foo": 1, "bar": 2}')
print(t.__dict__)
@main lynx :white_check_mark: Your eval job has completed with return code 0.
{'foo': 1, 'bar': 2}
the thing I like about it is that it lets you reserve __init__ for little more than assigning some attributes
and it's nice and explicit
it looks like a kind of dispatch pattern for init
I dunno
I should go back to work but perhaps we can continue this lovely OOP discussion some time.
sure
Anyone knows any python script that generates the Arp table information using snmp?
will this do what you want?
https://gist.github.com/glallen01/7593320
Hm, I'm still confused about import hooks
what is an example of one that simply just takes the file and changes i + 1 to i
not really
but thank you
you could write some simple script with scapy, it has very simple function to make ARP requests and send them
or do you just want to read the arp cache
Heya advanced ppl
Go one for ya
custom_array : MyIterableClass['SomeSpecificType'] = MyIterableClass()
Is this possible? I'm wanting to write an iterable class which can be hinted in this manner, but which does not inherit from list
inherit from typing.Generic[T]?
I'm just reading about that now. I have noooooooo idea how any of that works
So I'll read up on that, happy to take any tidbits of wisdom though
think it's like
T = TypeVar("T")
class MyIterableClass(Generic[T]):
def __iter__(self) -> Iterator[T]:
...
What if I want to specify a specific class, instead of 'T' (just curious)
Generic[MyClass]?
i think so
Weird that Iterable[MyClass] isn't the way. Seems logical
Another question — if I want to hold onto element's 'internally' to an object, as opposed to my attaching a list to it as an internal attribute and referencing that lists contents as if it were inside the outer object
That's not possible I'm guessing. The 'storage' of the stuff for a list happens in C, I'm guessing, and to get that I would have to inherit list?
driver.find_element_by_xpath('//*[@id="UserName"]').send_keys("ExampleUsername") # username
driver.find_element_by_xpath('//*[@id="Password"]').send_keys("ExamplePass") # password
#So this is part of my selenium code where the chromedriver will input the username and password, but I dont want to just
put the info on my bare script. So I need a way to encrypt this.
The problem I'm having is that I need to at the end of all this, turn my script into a .exe file and deploy it into another machine.
How will my local encryption hold over other machines?
What is the best approach here?
My goal is that I will have one .exe file at the end and if somehow people go into looking at the source code, the username and password will look encrypted.
we also have #type-hinting now
yesterday
yes i do using snmp
are you talking about the generic argument?
ah i forgot snmp. ig i dont know anything abt snmp 😂
Hmm i tought str(obj) checks directly if obj has a method called __str__ if it has that, it calls that otherwise, it calls the default one
but does it check differently?
because it is not checked via __getattribute__.
oh
oh i see
so str(obj) does something like
internal -> check if obj has __str__
yes?
python -> call it
no?
internal -> call default
?
i see
i tot maybe using metaclass i can do it, but since it checks internally that also wont work right?
i see
For efficiency yes, magic methods have to actually be set on the type.
Why's it more efficient for magic methods to be set on the type?
Because the type object at the C level has a huge pile of function pointers corresponding to each magic method. To call the method, it just has to lookup the right pointer.
Ah, cool
the direct pointer check will probably be ob_type.tp_str im thinking
not something dynamic
oh
the tp_str being one such pointer that is
Ooh
The r version is "reflected add"
Nope, "reflected", per the docs. https://docs.python.org/3/reference/datamodel.html#object.__radd__
As in, the expression is mirrored and evaluated in reverse
Though I suppose "right" works as a mnemonic for all the binary ones (all but __rpow__)
too slow I guess__radd__
Just found out you can typehint self
Just, I mean, duhhhhh you can typehint self
Still, got me out of a tricky little issue 😄 😄 😄
What exactly is wheels in python?
precompiled libraries more or less
Can you explain more? Why it is required n all?
because say you have numpy. In order to install from source, you would need to compile all the C, C++, and fortran code it involves. This is a painfully slow process, so instead python has a system where it gets compiled once for your OS and CPU architecture and then the compiled version gets uploaded to pypi and when installing it, it uses that. The compiled package you can install is a wheel
Why, in Gods name, is Github so complicated?
lmao its fine
Why don't they have a simple, visual, drag and drop interface?
because thats not how most of their customer base works
though if you use the visual editor you can do that iirc
(press . on any repo)
I'm all for advanced usage by the command line
But there's no reason they can't make no code version
because it exists to host git repositories, and their website is not the correct way to modify the uploaded code (maybe with workflows I could understand it). They do have a web editor, but it is not great and you shouldn't use it.
they do make a no code version: see github desktop
(no idea what state codespaces are in, but those would also work)
there is a new web-editor which is basically vscode without the terminal (which you can get if you have access to codespaces)
that's codespaces afaik
In case you guys want to take a look
There's no comments, sadly. I'm trying to get better at commenting but I find it quite hard. Also, please note, I am aware that Python is supposed to use snake_case. My choice to use camelCase is intentional and I stand by it
Still a bit rough around the edges, but it'll do for the time being
404
Sorry, its private still aprrently
Lemme figure out how to make it public...
Try that
LOOOOVE it
Like it's so easy to check out PRs or if you need to only commit some lines of your changes
low demand?
god, i'm asking that question at least twice a week
their merge conflict editor is horror
is there any documentation for why in subscripted types (ie list[int]) if a one item tuple is passed in it gets flattened?
!e py print(list[int].__args__) print(list[(int,)].__args__)
@pliant tusk :white_check_mark: Your eval job has completed with return code 0.
001 | (<class 'int'>,)
002 | (<class 'int'>,)
this means that list[int, str] and list[(int, str)] are equivalent but they feel like they shouldn't be
isn't that just implicit tupling
if i implement a class with __class_getitem__, the args are not implicitly tupled
!e
d = {(1, 2, 3): 'a'}
print(d[1, 2, 3])
@gleaming rover :white_check_mark: Your eval job has completed with return code 0.
a
yea it implicitly destructures passed in tuples
it would be like if d[1,] implicitly did d[1]
Objects/genericaliasobject.c lines 583 to 586
static inline int
setup_ga(gaobject *alias, PyObject *origin, PyObject *args) {
if (!PyTuple_Check(args)) {
args = PyTuple_Pack(1, args);```
i think this is the culprit, it only packs the tuple if the args aren't already a tuple
so it is more the other way round
which means after that line list[int,] and list[int] both have args set to (int,)
yea it only builds the tuple if one isn't passed in
its barely more than a big, laggy textarea. seems like one gigantic textarea the size of the entire conflicted file
this is not a help channel. perhaps you can ask your question in one of the off topic rooms. see ot.
!ot
Off-topic channels
There are three off-topic channels:
• #ot0-psvm’s-eternal-disapproval
• #ot1-perplexing-regexing
• #ot2-never-nester’s-nightmare
Their names change randomly every 24 hours, but you can always find them under the OFF-TOPIC/GENERAL category in the channel list.
Please read our off-topic etiquette before participating in conversations.
Why do I need to implement distutils.util.strtobool myself? 😦
deprecation?
Yea, but point the reason why it wasn't moved to an another module or sth
lazyness?
isnt that basically a 5 line function
dont really see the need for it anywhere in the stdlib
what lib would it live in?
Why do people still use CPython if the PyPy implementation is so much faster? What's the actual benefit of CPython over PyPy, since I pretty much can't see any
maybe string
It's not always much faster
from what I've tested so far, it usually was a lot faster, especially with lists, and I mean a lot faster, from a program that made ~20M calls for list.append and list.pop in pure python, vs in pypy, it was a huge performance difference
but even if it's not faster in every little aspect, for most things, it seems to be a lot faster so what are the actual reasons we're still using CPython by default?
The jit has to warm up so it's not suited for most small scripts, the c API is also much slower
is the JIT a requirement for pypy though? Can't it be turned off?
try it again with deque, which is specific for this purpose
That's what the implementation depends on for all the speedups
