#internals-and-peps
1 messages ยท Page 139 of 1
yeah, it's tricky
gone :0
i wonder if you could throw away the stack and just return an "empty" exception at this point
with/finally also gets in the way of that i guess
and honestly, I will take consistency over some minor performance improvements any day
my tco cant optimize py try: return tail_optimised_call() except: ... because python inserts a POP_BLOCK op before the RETURN_VALUE op
lovely
can the block pop be "anticipated"?
i was thinking of implicit function arguments, but that would be even worse :p
yes but it needs to run to avoid the block stack getting smashed
oh
on the other hand.. if we actually have an implicit function argument pointing to the qual_name of the caller it would make inspect unnecessary in many cases..
all very tricky ๐
There's no more low hanging fruit left? like removing metaclaesses? ๐
low hanging fruit.. pff :p all eaten
simplifying stuff, removing unnecessary optimizations for the greater good might be "low hanging"
in combination with a JIT, exactly
like... adaptive interpreter
yeah
thinking of numba
i was really baffled to see how a simple for-loop optimized by numba was faster than the same thing in numpy
we just need numba on the entire stdlib
probably allocations.
numpy uses flat C arrays right?
afaik yes
what about the stdlib array module.. replace some of the most highly accessed lists with static arrays
oh god
array.. that's just crap if you ask me
not even sure why it's in the stdlib
for C interop
it has some uses, but replacing lists is not one of them
then the implementation just needs to be replaced maybe, it should be faster?
it'll be slower than lists for most operations you'd use them for as you'll be converting back and forth from native types to objects
or is the problem still that everything's allocated in the heap
you can't use stack allocated things in python since they would go out of scope when you give python access to them
maybe you could make it work for internal functions, but I would assume that is already done where possible just by implementing the function in C
not really, it's afaik mostly indirect calls and pointer chasing
ah
dynamic allocations are quite well optimised, as you will quickly find out when you compile python with malloc instead of the custom allocator
why default to it then, pymalloc is default right?
What is malloc? All Iโve heard of is tracemalloc which is for the GC
pymalloc is the default, and it is the well optimised one
I do wonder how python would do with jermalloc
what's the custom one
pymalloc is the custom one
my point was that compared to conventional malloc, the python allocator is faster for python
oh, i just thought you were saying the opposite. makes sense
Ohh is pymalloc the allocator that puts the memory into the pools, arenas, etc.?
afaik yes
glibc malloc does use arenas too.. dunno about pools
I just realized -
memoryallocator
oops
jemalloc is supposed to also be well optimized, iirc
i suppose one might be able to LD_PRELOAD it to test? if it's not too deeply linkrd in
What do you guys think is going to be next language people shift to after python? Julia, Rust, Python4?
that question doesn't make much sense
I don't think there is going to be an after python
Julia will probably end up quite major in data science
and Python4 isn't a thing
Rust is playing in a totally different niche
There isn't going to be a python 4?
no plans whatsoever
they're very close
100 loops, best of 5: 2.88 msec per loop
python3.11 -s -S -m timeit -c "list(x for x in range(0, 5000))"
100 loops, best of 5: 2.86 msec per loop
Oh yeah I haven't heard of any plans but why wouldn't they do it eventually?
probably a bad benchmark, but oh well :p
"eventually" can be in 50 years
50 years is far too long in this field lol. I think in 10 years you will need to consider it.
agreed
We also have new types of computers like quantum
they all work nicely with python 3
if quantum computing ends up useful enough to actually replace current computers, then there will probably be entirely new languages
I'm not sure if you will replace computers but it's like GPU right
no, there are extensions for python in quantum computing
Wait it's not better for anything?
array is for some byte twiddling and C interop
You might want some ability to tap into quantum but maybe that's better off as a cloud API
Is this really something that they optimized?
you are mixing things up
"Optimizing Python " doesn't mean that everything magically runs faster
Mixing what up lol
๐คทโโ๏ธ
we already have python modules for quantum computers
we don't need a new language for that
i was comparing them in the least scientific, easiest way possible
Sure I know this lol. But may be better to make new languages better suited for future landscape.
I would argue that quantum computing is too different idiomatically from python to be considered the same language, even if the syntax looks would look kinda similar
who said "optimizing python"?
Ah, so when you need to pass it to some C extension?
yeah
I thought that was what you were trying to compare?
i've seen quantum computing code for python, it's quite funky
I guess a quantum programming DSL would technically qualify as python, but it is still very different code
but apparently (according to the scientist who wrote it) it works quite well
just the relative overhead of pymalloc vs jemalloc
python as a glue-language does a good job at wrapping at a high level
I would also be surprised if that actually worked
we may get some pytorch tensor-like higher level API as python, that is true
yeah, that's what i'm expecting for the future
i'm thinking quantum computing could make a difference in db lookups like JOINS
So python might be interface but a lot of code might be written in other languages?
which could be an optional optimization like with GPUs in tensorflow
that's the way it always has been, yes
I am asking in terms of this distribution like if 90% of your written code is in python (not all the codebase). When we will shit to 50%+ of that time in other languages.
depends on the level of abstraction you're working at
there's no such thing as "the average current python programmer" - python devs are across many different fields
I do expect python to be used less these days as it is now competing with pretty cool languages, whereas in the past, you had... ecmascript 5, java and were trying to phase out perl
Yes I know this lol
just look at all the topical channels
I know this lol
so now that you have languages like go, julia, rust, typescript, python is a lot less attractive
what languages make the pretty cool curt
oh
I think if Python doesn't knock off the "Python is slow" people are gonna start using NodeJS / TypeScript much much more over Python.
It's very fast with no pain or afterthought
looking at https://insights.stackoverflow.com/survey/2021 i'm not seeing that
yeah, modern demands on performance are quite a shift
I'm pretty average imo
it can do stuff js can't though, seems like
good for you ๐
but I'll take average ๐
but well, there are efforts to fix that, and there are still a ton of places which are IO bound enough that python is more than fast enough
I mean, is python really in some race to be The Programming Language
i agree
if people want to use other languages, that is fine. All languages should have their pros and cons
Do you guys think GIL will be an increasing problem
and it doesn't require compiling some monstrocity like V8, LLVM, or chromium to get a working interpreter
The GIL is a solution, not a problem
speed just isn't python's strong suit at the moment, but it is definitely quick when it comes to scripting up something quickly
the GIL only matters for CPU bound workloads, which is things python will never be good at
at least not without removing a lot of runtime introspection
I wouldn't want to build an executable in Windows for it though for someone who doesn't use Python
it can be considered a problem in certain applications, just not as big as most people make it out to be as you can work around it if you want
CPU bound matters don't matter nowadays really anyway
how's that gilectomy coming along... ๐
it's either GPU-bound or bus-bound
Python isn't a program for GUI applications no
I quite like it with Qt
Yeah I am not sure lmao, you're free to give a try at it ๐
and well, the GIL is great from a usability standpoint. No weird crashes from using thread unsafe data structures like in C++ or java, while keeping performance in single threaded workloads. Java tried having the approach where each data structure had a lock on it, and it was just too slow to be useful.
he was gonna do lock-per-object iirc
that's what the old Vector class does
With his complicated buffered-reference-count approach he was able to get his โgilectomizedโ interpreter to reach performance parity with CPythonโexcept that his interpreter was running on around seven cores to keep up with CPython on one.
I don't even have 7 cores.
lol ne neither
heh
Yeah if I've seen the 2 or 3 talks on it. The plan became like lock-per-object and maybe somehow statically figure out if an object is only ever used inside one thread which means that you don't need a lock on it
slower python !
and well, threads do introduce a whole host of issues in that you now have to think about context switches.
wow, that sounds tricky
like full-blown escape analysis
you could just do a simple if refcount == 1: don't lock I think to start with
Yeah this was the transaction thing?
Where reference counts get sent to a thread with a queue which then works itself through this and frees objects as their count end up at 0.
oh wait, weakrefs
I want to say "But what if another thread increments it while you're executing it" but that means the count has to be more than haha
talk about scope creep
I might be wrong, not sure. I just know that it is something that Larry talked about, perhaps only something that was considered
don't try to remove python's GIL because it might be the last thing you do in your career
Sounds like removing GIL would require a pseudo new language/framework.
@lusty scroll suppose we can tackle that after we reinvented the import system ๐
Ah yes I was wrong. This was only something that was considered.
CPU-provided atomic INC/DECRs are used:
or python implemented in Rust
This is what I was thinking about I guess?
Aaaahh, read for yourself if you're interested haha I am confused https://speakerdeck.com/pycon2017/larry-hastings-the-gilectomy-hows-it-going?slide=16
actually that might be the next best answer to that initial question
What does that mean?
Like Cpython interpreter to a Rustpython?
i mean that CPython might not be the future but an interpreter written in a different language like Rust
yes
PyPy is another good contester
PyPy is an incredibly good contester but it is very complex compared to CPython
Yeah you would need to adapt the python language to take advantage of Rust memory management I would assume though.
moving to another default interpreter would be a major shift, definitely involving lots of PEPs
i'm imagining that people would even might ask for a formal specification before that happens
which is a big change from the status quo
I don't think that will ever happen
i'm really not sure, i couldn't bet on either side
there are many good reasons why it might happen
What I would like to see though, would be that someone can become a core-developer even though they're not directly a core-developer of CPython
it could happen instead of a push for Python 4
Anyone have any good ideas for bash scripting projects?
Im not sure how well the general project repos would translate to bash, I have little experience with it
@wary harborthis is more a question for off topic channels, such as #ot2-never-nesterโs-nightmare
oh gotcha
There is a python implementation in Rust
lol
I don't think I understand what you mean. When we say "core developer", it's shorthand for "CPython core developer". What would we gain by calling someone who never contributes to CPython a core developer?
that didn't take long
lmao
full backwards compatibility with C extensions is a major showstopper though
CI: Failing
:(
not sure what to think tbh
I still don't understand it fully lol
i see it's still a draft PEP, so it must predate the PEP i guess
my understanding was they replace parts of the bytecode (in existing code object) once some counters tick dowm to some "hotness" threshold
it's an Informational PEP - which AFAIK means that it's not a proposal, but a form of documentation. It's something that will be happening, not something that they're soliciting community feedback on.
are the replacement opcodes type-specific versions of existing ones?
Python/ceval.c line 2086
TARGET(BINARY_ADD_INT) {```
it seems like a half-step towards a profiling JIT compiler for bytecode? or perhaps an optimizer
yeah I'm sure some people would not like the term JIT here because it's not emitting new machine code
but it's like a profiling optimizer
just-in-time optimizer :)
Extensive experimentation suggests speedups of up to 50%.
๐๐
that would be huge obviously
I'm wanting to write a decorator class whose instances perfectly resemble the functioon it wraps, from the outside
class Decorator(object):
def __init__(self, function: FunctionType) -> None:
self.function = function
self.name = ''
def __set_name__(self, owner: Type['Node'], name: str) -> None:
self.name = name
def __repr__(self) -> str:
return str(self.function)
def __str__(self) -> str:
return str(self.function)
@property
def __class__(self) -> Type:
return type(self.function)
@property
def __signature__(self) -> str:
return self.function.__signature__
@property
def __text_signature__(self) -> str:
return self.function.__text_signature__
def __call__(*arguments: Any, **keywords : Any) -> Any:
return self.function(*arguments, **keywords)
Am I missing anything? I know I need to make the decorator's __call__ method's return type the same as the decoratee, but other than that, am I missing anything?
you can delegate almost everything to __getattr__, no?
!e ```python
class A:
def repr(self): return "A()"
def str(self): return "A"
def add(self, other): return 1 + 1
def radd(self, other): return 1 + 1
class B:
def init(self, wrapped):
self.wrapped = wrapped
def getattr(self, attr):
return getattr(self.wrapped, attr)
a = A()
b = B(a)
print(repr(b))
print(str(b))
print(b + b)
@paper echo :x: Your eval job has completed with return code 1.
001 | <__main__.B object at 0x7f3a1744bfa0>
002 | <__main__.B object at 0x7f3a1744bfa0>
003 | Traceback (most recent call last):
004 | File "<string>", line 18, in <module>
005 | TypeError: unsupported operand type(s) for +: 'B' and 'B'
hooo interesting dunder interactions
@static bluff you forgot __annotations__
and yes you'll have to override __getattr__ of course even if it doesn't work with the dunders
Good catch
not sure if you can hook into dir()
I'd rather do it all explicitly (property by property) at least until I understand it
oh you need __doc__ of course, and __qualname__ and __name__ and __module__ - not sure if you can override any of those last 3 without breaking something
basically go through the python reference
i don't even want to know why ๐
Emulating dir() might be more than I need โ I just don't like how decorating a function returns something that complete disresembles the original
Especially the name. You've got a function with a name go in, and you get something like 'wrapped' or 'decorated' come out, its a bit primitive. I'd rather use an object and get at least a little more grace out of it
!e ```python
from functools import wraps
def nicen(cls):
@wraps(cls)
class Wrapper(cls):
def getattr(self, attr):
print('nice')
return super.getattr(attr)
return Wrapper
@nicen
class Thing:
def one():
return 1
print(Thing.name)
thing = Thing()
print(thing.one())
@paper echo :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 12, in <module>
003 | File "<string>", line 5, in nicen
004 | File "/usr/local/lib/python3.9/functools.py", line 58, in update_wrapper
005 | getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
006 | AttributeError: 'mappingproxy' object has no attribute 'update'
heh
__set_name__ actually work outside of descriptors?
Sure, anything that gets embedded within a class's namespace
You're trying to decorate methods?
class Foo:
@Decorator
def bar(self, *args, **kwargs):
...
``` ?
Honestly man
I would customize __init__ and then rework your __call__ to take in the method you're decorating and return self
Then implement __get__ to return the decorated method
What you have right now is that upon decoration you are initializing the Decorator instance and the method is passed to that
If you instead do @Decorator() then the wrapping happens in __call__ and to actually get the method back out you would have to implement __get__
Descriptor decorator as it's described in Fluent python
Plus in your current state, how are you going to bind the instance
I'm trying to build an object that decorates a function and resembles that function as closely as possible, particularly its name its type hints
Like if you do it how you have it now then when __call__ happens you don't have access to the instance of the owner class to pass down
Return = TypeVar('Return')
def decorate(function: Callable[..., Return]):
class Decorator:
def __call__(self, *args) -> Return:
return function(*args)
return Decorator()
PyCharm's linter catches the return type with this, but
Not the arguments
Ellipsis notation can't catch the complexities of the signature. I can have the class return the signature programatically, but I don't think there is anything I can do for it linter wise
3.10 has ParamSpec, not 100% sure what that does but I think it might be more or less what I'm after โ but I can't use 3.10 sadly, since I'm relying on another library and I'm lucky it even has a 3.9 release
Are you trying to decorate methods or functions?
Both, really
This is important
Capturing the instance wouldn't be too much trouble, I know how to work that
Well the thing you got going above, the one I originally responded to, won't work for methods
I know how to convert a decorating object to to bound method form
How are you gonna bind the method without __get__
I've navigated worse. I say this because I don't know exactly how, but, I know the ins and outs of the process, I'm sure I can figure it out
The typing is what I'm not sure about
I don't know much about typing either
Its an artform unto itself ๐
shouldn't functools.wraps and ParamSpec be enough for that?
In theory yeah, but paramspec doesn't seem to work in 3.9
And I can't upgrade due to an important dependancy
hm
Hello guys, how i can include an inequality on my sistem?? ```python
import numpy as np
from scipy.optimize import nnls
A = np.array([
[-190,-30,-30,10,10],
[-27,-197,-27,3,3],
[-36,-26,-196,4,4],
])
b= np.array([-45,0,0])
x= nnls(A, b)[0]
Can always backport it yourself https://github.com/python/cpython/blob/784905dbeff68cf788bbeefe0a675af1af04affc/Lib/typing.py#L859
Lib/typing.py line 859
class ParamSpec(_Final, _Immutable, _TypeVarLike, _root=True):```
ParamSpec lives in typing_extensions as a backport
then there's @classmethod ......
That people who work on other implementations of Python can get into the steering council
Oh yeah, that is very true
There's no requirement that steering council members be CPython core devs, is there?
Granted only CPython core devs vote in the election, but it's not unreasonable to think that many of them would vote for a PyPy core dev if one were nominated
Even if it was only core devs, there are core devs brought on who's motivation isn't working on CPython itself.
I want to learn OOP in python any Good resources ?
This channel is for discussion of advanced Python concepts. If you need help, you can ask in #python-discussion or open a help channel, see #โ๏ฝhow-to-get-help.
yeah, i knew about that ๐
oop
yep
@lusty scroll where was that multi-page series/blog on github on how to make the "perfect" decorator?
it was pretty extensive
How do I become better at reading Python code? any suggestions?
practice!
try to read code that's in big applications/libraries
and in general try to read other people's code
How is that going to help with method binding?
I will do that. Thank you!
i found it
it won't ; it will make things more difficult for getting the decorator/descriptor to be transparent @verbal escarp
Picture sent so you can see how its all be highlighted
It seems that in my sleep deprived state last night, I couldn't really see the forest for the trees
PyCharm's linter has no trouble tracing the typing, and warning appropriately. The only issue is that it sees the ParamSpec argument as an error and highlights it in red. This doesn't actually throw an errors, but there is no way to turn it off
That's the kind of problem I'd simply solve with a comment
I'm dependant on wxPython and cefPython, which I don't think are supported on 3.10 yet, and its 3.10 that this support is native. Hopefully in a year or two they will be updated or maybe I'll just update them myself
With the typing issue 'solved' though, I think between this and functools.update_wrapper I can hit all of the important points of introspection. I don't want my decorators to be identical, I just wanted a bit more control than the traditional decorator pattern offered
i posted the link because the "blog" is quite informative
Gonna give that a read when I'm on the bus. Only just waking up now
there's more to it than what he published on github too, he goes deeper into potential concerns
similarly if I call inspect.getsource() on decoratee, I'm gonna be pretty disappointed I get the source of decorator -- and doubly sad if the decorator source, locals, etc. gets printed outt as "my" source during a unit test failure (has actually happened to me!) ๐
What I posted was just to test the linter. I'm not sure what I'd do about source and other such introspection. I'm also not sure to what level I want my decorator to resemble the decoratee. They are, after all, different objects. I just wanted a little more horsepower than the standard pattern
all good
Is there anything like typeshed's sqlite3/dbapi2.pyi for generic use in libraries? I can go write up a module full of Protocols but I'd rather not if there's a lazy option.
Kinda surprised we don't have something in stdlib, actually
why does the help channels keep changing names
to keep it interesting, also wrong channel this is for advanced python discussion
i need help
how do you pass an variable from a .py file to a .kv file
please help ๐
I do miss the elements
TypeError: Argument 'real' has incorrect type (expected numpy.ndarray, got NoneType)
this sounds like it belongs in #data-science-and-ml or a help channel, #โ๏ฝhow-to-get-help . when you post your question in one of those places, please post your code and the full error output.
@unkempt rock #โ๏ฝhow-to-get-help
You are right, thanks
I didn't know you could override the main module to be a new module type
I just created a constants module that actually enforces constants
from types import ModuleType
from sys import modules
class ConstantsModule(ModuleType):
constant = property(lambda self: 11)
modules[__name__].__class__ = ConstantsModule
this is some pretty cool stuff that i have somehow just discovered
are you sure about the main module?
we had exactly that question a while ago in here
I meant that you can override the module class to act differently, I think godlygeek posted something earlier about it
With the __setattr__ thing
the conclusion was that python handles global variables differently than those that require an attribute lookup
and since module-level variables in __main__ don't require attribute-lookup, you can't replace it with a property
Ah yeah, the global state discussion right/
but when you import it into another file, it's not the main file anymore, so wouldn't it would work?
exactly
because it's using attribute access since the module is basically a class
then you need an attribute lookup, which you can manipulate
well, that's how justuse works ๐
I've heard about that in here, but I'm curious, how does it work?
in https://github.com/amogorkon/justuse we use a ProxyModule to wrap additional functionality around imported modules
currently we add auto-reloading that way but it's also possible to add operators to modules
we considered the idea of using the @ operator for decorating stuff
reloading is when a file is imported again, or just that the module class in the sys.modules is reloaded
ooh, module decorators?
or [..] on the module for filtering stuff
yes, kinda
we implemented our own reloading, which will reload the module when you modified the file
Ah
you could think of all kinds of manipulations on that level, but it's hard to think of something that makes sense for multiplication or addition ^^
numpy + math = ? ๐
numpy * 3 = ?
I would wonder how you would implement module addition and module decorators, I've tried but it fails
class ProxyModule(ModuleType):
def __init__(self, mod):
self.__implementation = mod
self.__condition = threading.RLock()
def __getattribute__(self, name):
if name in (
"_ProxyModule__implementation",
"_ProxyModule__condition",
"",
"__class__",
"__metaclass__",
"__instancecheck__",
):
return object.__getattribute__(self, name)
with self.__condition:
return getattr(self.__implementation, name)
def __setattr__(self, name, value):
if name in (
"_ProxyModule__implementation",
"_ProxyModule__condition",
):
object.__setattr__(self, name, value)
return
with self.__condition:
setattr(self.__implementation, name, value)
that's the ProxyModule we wrap all loaded modules with, which allows adding any kind of dunders like __add__ or __mulmat__ (@)
to apply decorators on the module, we use the aspectize function i came up with
for (check, pattern), decorator in aspectize.items():
_apply_aspect(
mod, check, pattern, decorator, aspectize_dunders=aspectize_dunders
)
with
def _apply_aspect(
thing,
check,
pattern,
decorator: Callable[[Callable[..., Any]], Any],
aspectize_dunders=False,
) -> Any:
"""Apply the aspect as a side-effect, no copy is created."""
for name, obj in thing.__dict__.items():
if not aspectize_dunders and name.startswith("__") and name.endswith("__"):
continue
if check(obj) and re.match(pattern, name):
log.debug(f"Applying aspect to {thing}.{name}")
thing.__dict__[name] = decorator(obj)
return thing
which lets you apply decorators to anything that matches a regex pattern (against the name) and a check (against inspect.isfunction or any custom check)
like mod = use(Path("some_module.py"), aspectize={(use.isfunction, ""): timeit})
we considered putting the aspectize argument in matmul, to have it like mod = use(Path("some_module.py")) @ {use.isfunction, ""): timeit}
but never got around to do it ^^
also i kinda forgot to make it work for recursive objects, but yeah..
we're now working on mass-testing, making sure that all conda packages etc. work with justuse so those crazy-ass ideas had to take a little step back ๐
@regal tide is nuts enough to join our little team and make the effort ๐
You will need to create a game where the user trys to break a code before the time runs out. The user must enter a 4 digit code that is compared to the randomly generated four-digit code (1000 - 9999). Your program should provide output containing the number of correct digits in correct locations, as well as the number of correct digits in incorrect locations. Have an * indicate that the number entered in that position is incorrect. Have $ indicate the number at the position is incorrect but still belongs somewhere in the code. If the number is in the correct position, then just print the number in its position.
Example 1:
Difusal code: 1234
User guess: 1365
Output: 1$**
Example 2:
Difusal code: 1234
User guess: 9867
Output: ****
Can anyone help me how to isolate each digit
#โ๏ฝhow-to-get-help @dusk quartz
man, reminds me of the first TMNT game on game boy.. and then i got into CS and it all boiled down to divide&conquer and O(log n) sigh - recursion in python ๐ฆ
Ruby, unlike Python, makes lots of things implicit, and there's a special kind of if expression that demonstrates this well. It's often referred to as an "inline-if" or "conditional modifier", and this special syntax is able to return one value when a condition is true, but another value (nil, specifically) when a condition is false. Here's an e...
@sly raft nice work!
https://softwareengineering.stackexchange.com/questions/432512/matching-records-into-groups-and-buckets-architecture-problem
Hey, who can help me
You know, it would have been lovely if they put somewhere in PyInstaller's documentation that it won't copy a directory over if its empty
Just spent three hours figuring that out
you can make a PR ๐
PR?
Oh a pull request
I've never done that
You know guys
This graphics engine of mine is really coming along
Its taken a lot of work, but I think I can see the light at the end
It would also be nice if they put somewhere how much of a pain it is to legally distribute pyinstaller apps without breaching licensing rules / for pyinstaller to actually help you do that side of things
And there was an issue on this, but it went stale because no one finds licensing fun to work on
What sort of licensing issues are there?
O.O This sounds like something I should know
Dependencies + python licensing you have to disclose are annoying
Iโll see if I can find the GitHub issue
Guh, this looks like an ugly thing to have to worry about it
You'll have to, what, track down the licensing of everything you use, recursively, and manually include them?
Pretty much. Thereโs a tool called piplicenses on PyPI that can help though
!pypi pip-licenses
And that list has to be easily available from inside the app you bundled too, since no one is going to poke around inside an executable trying to find license files
Like a button or link
Would a big document containing the licenses, and a function injected into the global scope of all modules license(), do??
Also, you seem to have used PyInstaller in the past
My project uses cefpython and wxpython. I was testing to make sure both of those would bundle without issue. They did, but the resulting application took about 20s to launch. I know this has to do with pyinstaller rewriting all the scripts
Depends on what app your making i guess. The thing that matters is that the end users can easily find the licenses while using your app
Any thoughts on speeding it up?
Hello, good morning
Thatโs more of a pyinstaller thing. But some time is definitely contributed by CEF. I havenโt used wxpython before. AFAIK pyinstaller is meant to only be slow on the first launch. After that itโs slightly less slow
how to use this help exactly? Don't understand how to call this directly
DeprecationWarning: `set_matplotlib_formats` is deprecated since IPython 7.23, directly use `matplotlib_inline.backend_inline.set_matplotlib_formats()`
set_matplotlib_formats('svg')
PyInstaller seems to be rewriting everything every time it launches
Unbundled cef takes no time to launch
Or like, half a second maybe
What do you mean by โrewritingโ? Pyinstaller doesnโt embed your scripts in the app directlyโit compiles them to .pyc files first
Don't distribute as onefile if you want speed perhaps. Just zip the bundle
Since onefile mode essentially needs to be unpacked again before running
Why, youre using the wrong channel
Try #python-discussion or one of the offtopics
i got one for you ๐
for our AST-jugglers, mostly
let's say i have a mod = use(...) call, i only get the module that was returned
if i'm only interested in a function or variable that lives in that module, i'd need to write a = use(...).a
but that's not very DRY, and it gets worse with multiples:
mod = use(...)
a, b = mod.a, mod.b
so, i'm wondering
what if it was possible to write a, b = ~use(...) where ~ would mean "take the names of the variables that are to be assigned and turn it into an iterator of .get(name) calls
i'm not set on the ~, it could be any operation if that'd make things easier
just to clarify
I don't think it is possible to know what you are unpacking into otherwise
an __unpack__ dunder could be interesting, hmmm
could you write me a little prototype example from where i could go on? i have no idea how to tackle this otherwise ๐
how in the heck is mutilating licenses any concern of pyinstaller's
a simple, contained example, 10 lines of code or somesuch that demonstrates how to go about the "take the names of the to-be-assigned-variables and turn them into a function call on the right-hand-side"
or maybe even better <= as "reverse assignment operator"
could that work?
a, b <= use(..)
usually that would raise a NameError, maybe that could be caught and handled somehow?
hm.. sad
yeah, it's not ideal, i know
if it wasn't hard-coded, i'd go for "a, b from use(..)"
Ok
hehe
for a, b in use(...): pass could work :p
but it got the same reverse-naming issue as the assignment
Why not just use next()?
how would that help?
a, b = next(use(...))
that's not really the issue, i'm afraid. the problem is that the variable names "a" and "b" are unknown before calling the right-hand side
so next(use(..)) is meaningless because the order is arbitrary
Oh so use() may return something else than an unpack-able iterable?
yes
use() usually returns the whole module
the "proper" way would be mod = use(..); a, b = mod.a, mod.b
Oh you want the attributes of that. Like JavaScript?
i'd like to get as close to from mod import a, b as possible
something like that, yes
well, impossible is what we do in here, isn't it ๐
The issue becomes that Python has no sense of variable names right?
i was thinking an AST-transform of sorts could solve the conundrum
You have no idea when being called what the name of the variables are.. even if you inspect the locals of the caller (because they haven't been defined yet ;-;).
Right?
yeah i was thinking if it was possible at the AST
actually, that's not totally true
you could observe the globals dict
i'm wondering at which level that NameError is raised, actually
does that happen at the AST level?
that should be an actual PEP, imo
{a, b} = use(..) would be perfect
it is raised during runtime
So this is a thing, right? Do you want alternate assignment syntax for this? Is that what the question/wishlist* boils down to?
Could that be confusing? I mean in Python that's a set. Pretty sure that's already valid syntax and would be a major breaking change
!e ```python
{a, b} = 1, 2
@elder blade :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | {a, b} = 1, 2
003 | ^
004 | SyntaxError: cannot assign to set display
Don't think it is valid syntax
Ah cool
oh interesting
i don't think it could be confusing because {} on the left side doesn't mean anything
- yet
I don't understand the motivation when the from syntax already exists, could you elaborate?
!e ```python
{'a': a, 'b': b} = {'a': 1, 'b': 2}
@elder blade :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | {'a': a, 'b': b} = {'a': 1, 'b': 2}
003 | ^
004 | SyntaxError: cannot assign to dict display
That feels patma-ey
I wonder if that would be more Pythonic. Being able to assign to a dictionary
Why not use the from syntax for this
From module import a, b already does it no?
Then you'd just have to add __getitem__ to make it supported?
because i'm not using "import" ๐
use(..) is a complete alternative to import
But you said it's a module?
Oh. Well in that case pep20 says there should be one and preferably only one way to do it
that ship has long sailed
And in this instance, I strongly agree with the Zen. ๐
and that "one way" doesn't do a lot of the things use() can do ๐
Use is something you're making?
yup
Maybe you could consider some kind of patch on globals, though I'm surprised why you opted to use use instead of patching the import system
because the import system sucks big time
So something like expose(use(...), a, b, c) I suppose?
that could work, but it would be confusing to IDEs that look for assignments
I mean, use is confusing to python Devs who look for imports
Aka every python dev.
Doesn't just-use already mess up module pretty greatly?
not really
ooh, you made justuse
it' pretty transparent and doesn't interfere with the rest of the import system
But for editors?
Nothing, just makes sense now
ah ๐
I wish to use justuse in some of my script to auto download libs, but it turns into a chicken egg problem, as you'd still need to manually install justuse
not really an issue, vscode has no problem figuring out the modules that are use()d from my experience
bbl
So I guess I can visualise the issue clearer. You essentially want to hijack assignments a,b = blah such that blah actually sees the names
This however is fairly different from how python does assignments though , meaning I don't think the outlook is good without some probably python level hacks
Since python completely evaluates what's on the RHS first
Oh really? So you get the typings?
Ironically enough I guess your best bet is to use from use(...) import a, b probably
But that won't unpack by name
exactly
that's a very interesting proposal
hijacking the import system to override its behaviour when encountering a ProxyModule returned from use(..)
i'd still prefer the JS-ique {a, b} = mod as a more general solution
but the import .. from syntax might be a viable workaround
In [79]: f("""
...: from types import SimpleNamespace
...: a, b = ~SimpleNamespace(a=1, b=2)
...: print(a, b)
...: """)
1 2
success, i guess
Is that legal?
!e ```python
def func():
return 'collections'
from func() import Counter
@elder blade :x: Your eval job has completed with return code 1.
001 | File "<string>", line 4
002 | from func() import Counter
003 | ^
004 | SyntaxError: invalid syntax
@unkempt rock :white_check_mark: Your eval job has completed with return code 0.
hi
What is a legitimate use case for __foo method names? I see them in e.g. motor and all they do is make it hard/impossible to extend
Preventing name clashes with subclasses
I think that's the intended purpose of mangling
Could someone help with my logging setup at #help-pancakes please?
i think the use in ProxyModule in justuse is quite legitimate - you could write a proxy for any class with a simple getattr and avoid clashes that way
i agree that it's annoying as hell though
but i don't see any other solution for the name clashing really
how did you do that?
does it also work for b, a = ~SimpleNamespace(a=1, b=2); print(a,b) -> 1,2?
Oh, looks like it's not, eh? Hmm, I hadn't considered that. If the grammar itself stops it then we are back to square one, would require hacking through python itself I presume
the original idea was to avoid any third-party extensions and have the module self-contained so that people could just copy&paste the whole thing and be done with it, but by now it's pretty much grown out of that..
oh, I see
it would've been doable up to the point where it only handled importing single modules
but since we got into the whole package installation business, it's far too complex to do it all by ourselves
just yesterday i added pydantic as requirement to help deal with pypi json etc.. meh
works by changing the ast https://paste.pythondiscord.com/regegoriya.py
yeah
In [86]: f("""
...: from types import SimpleNamespace
...: b, a = ~SimpleNamespace(a=1, b=2)
...: print(a, b)
...: """)
1 2
don't think its entirely foolproof though
it'll fail for a = ~SimpleNamespace(a=1) because it expects the LHS to be a tuple; but that could be special-cased
also probably fails for x = a, b = ~SimpleNamespace(a=1, b=2) though idk what the expected behaviour for that would be in the first place
nobody would do that with imports either :p
it just modifies the ast from a, b = ~x to a, b = [(_ := x), [getattr(x, 'a'), getattr(x, 'b')]][-1]
in general or just for that one class?
wdym?
if the user had another class that implemented ~ with a different meaning, would that be affected?
should work as expected unless there's a __inv__ implemented for that class
oh wait i misread
yeah it won't work if ~ is supposed to carry a different meaning
could we do isinstance(a, ProxyModule) and modify the behaviour only in that case?
hmm im not sure
dont think the ast is aware of types
I wonder if you you could use inspect to read the line use() got called in
and then parse that
you can just return a tuple from inside use then
or well, you would do this for __inv__
pretty crazy, i like it
basically pre-parse the code and replace it in place
would also avoid the type-checking issue on the AST-route
and, depending on how the introspection in the IDE is done, it might "just work"
i don't think that's legitimate python ๐
IIRC, the non-ascii digits don't work in literals
also, seems like you don't always get code_context, so the idea may not work sadly
it works when running a file
from types import SimpleNamespace
import inspect
import ast
data = SimpleNamespace(a=4, b=6, e=7)
def use():
frame = inspect.currentframe()
finfo = inspect.getframeinfo(frame.f_back, context=1)
line, = finfo.code_context
target, = ast.parse(line.strip()).body[0].targets
if isinstance(target, ast.Tuple):
return [getattr(data, el.id) for el in target.elts]
else:
return data
That makes sense, if you need to delegate to arbitrary attributes at runtime
at least it's one viable approach.. better than nothing ๐
thanks!
might as well put to use some of the cycles consumed checking for such odd dynamic uses ๐
like setting __class__ or having the builtin getattr overridden comes to mind
but i don't think it'd be worth trading features for performance... if you want that you can just use Lua ๐
what's your usecase actually? would it help if we bundled all dependencies of justuse into a single zip?
Hmm, that's an interesting question
I basically have a utility script inside a Rust project that changes the value of an ELF symbol. Not that relevant, but it requires a library to be installed for that, and it would be nice if could just use that library and have the library installed if that's required.
As to whenever a zip file would be a good idea, maybe it is, I am not 100% sure how I want to manage my build system so far
I might just ensure we have a venv with the dep included before running the script
let me write up an issue on our tracker for that suggestion, maybe we can come up with a solution after we mass-tested all conda packages ๐
That'd be quite cool
By the way, would you perhaps have some good first issues you need contributions to?
Plug project again please? If mods are ok with it
np
Does anyone know how to create a code that helps you write backwards?
@round hull Per Rule 6, your invite link has been removed. If you believe this was a mistake, please let staff know!
Our server rules can be found here: https://pythondiscord.com/pages/rules
What do you mean?
https://discuss.python.org/t/how-do-we-want-to-manage-additions-removals-to-the-stdlib/10681 <- that might also be interesting to us here
What sort of requirements do we want to place on ourselves for adding modules to the stdlib as well as removing them (this is not about what to do with the stdlib in terms of what kinds of modules should be there, etc.)? Clarifying our views on this affects multiple PEPs such as 4, 411, and 594 (and the latter is the reason Iโm asking now so th...
I have some problems with a program thats a number guessing game where u have 3 attempts. If the player guesses the number correctly on the first attempt he wins *10 the money he bet, if he guesses the number on the second attempt he wins *5 the money he bet, on the third attempt he wins *3 the money he bet. After 3 attempts he loses the money he bet. The game should carry on as long as the player wants to play if he has money
Rules:
Number between 1 and 50
The program keeps looping after you get it right. I expect the game to stop btw a tired to use break but didnt work at all
maybe you should ask in one of the help-channels ๐
Im in cooldown for some reason im new to this discord so idk what i did wrong
did you try writing in #help-donut for example?
Yes nothing comes up i just get cooldown
you might already have an open help channel?
huh, i just went through all of them
ask in #community-meta why you're on help channel cooldown
you must have nested loops then
either that or your break isn't bring hit
put a print right before it and make sure you see the print
if it's nested loops you have to separately break out of each loop
afaik :\
Wowww lol
ekil siht
It sounds like you want to split a string and reverse each word. Questions like this are great for our help channel system #โ๏ฝhow-to-get-help
No offense but ew
Does anybody understand how Hata's (https://github.com/HuyaneMatsu/hata/) extension loader works?
It looks like pure magic
To show this is not blackmagic, here is an example: **main.py** ```py from hata.ext.extension_loader import EXTENSION_LOADER from datetime import datetime cake = 'cake' now = datetime.now() EXTENSION_LOADER.add_default_variables(cake=cake, now=now) EXTENSION_LOADER.load_extension('extension') ``` **extension.py** ```py print(cake, now) ```
After you ran `main.py` you should see the following (the date should be different tho): ``` cake 2020-03-14 09:40:41.587673 ``` Because now we have the interpreter, you can change the variables. ```py >>> EXTENSION_LOADER.add_default_variables(cake='cakes taste good, and now is:') >>> EXTENSION_LOADER.reload_all() ``` And a different text is printed out: ``` cakes taste good, and now is: 2020-03-14 09:40:41.587673 ```
Ah, found where the magic is done! https://github.com/HuyaneMatsu/hata/blob/master/hata/ext/extension_loader/extension.py#L342
hata/ext/extension_loader/extension.py line 342
def _load(self):```
This is pretty interesting stuff ngl
How much math is needed for data science ?
this isn't on-topic for this channel, try #data-science-and-ml or #career-advice
Thanks
How to get the source of str.endswith for example? inspect.getsource(<what>)?
inspect.getsource wouldn't work with that as str.endswith is implemented in C iirc
some things in python are written in C proper, so you wont be able to inspect them like that
You will wanna check out CPython source code if you want to find it
Let me try and find where it is
Okey, fine
How can I find out if method I'm interested in is implemented in bare C?
<=> so not possible to get the source in mentioned way?
Objects/unicodeobject.c line 13660
PyDoc_STRVAR(endswith__doc__,```
(If I'm wrong, correct me) I believe inspect.getsource will raise an error about a method-wrapper/method-descriptor/builtin-method-or-function which implies that it's implemented in C
In this case I really didn't even know that to type as argument ๐
Nevertheless - fine, thanks
0 issues? that doesn't sound right..
Oh yeah there isn't an issue tab
cpython* doesnt do issues on github iirc.
i see typeguard will become unmaintained soon, would you say pytypes is a good replacement?
What do you mean?
Is typeguard a static type checker?
no, runtime
this would be a better fit for #type-hinting. It's not on topic for this channel.
there's a hook that decorates all functions and methods in a project to check against the annotation
A friend made a tool for this, it lets you call cinspect to get the c source of a Python function: https://github.com/punchagan/cinspect
looks like the indexes have not updated since 3.4 and the indexer only run on python 2 because at the time libclang wasn't available for py3
I used to monkeypatch inspect with it since it passes through, and you just get to be surprised sometimes when C code comes up from getsource
Is there any performance plus from compiling your own python over using the precompiled one?
Not a meaningful one probably.
It depends where you get the pre-compiled ones. Some OS packagers might not enable certain build time optimizations (e.g pgo or lto) for the Python packages. You can actually test whether they are enabled or disabled by running the following commands: https://pythondev.readthedocs.io/builds.html
the best case, if you build yourself with PGO and LTO and target your machine's particular architecture, might be a 20% performance improvement over your distribution's build of the interpreter, if your distribution didn't use PGO and LTO and targeted an older instruction set.
which isn't a tiny amount, but in the grand scheme of things, it's not going to make your program run twice as fast, or anything like that.
I'm new to GitHub and I've started my first real project. If I want only me and my affiliates to be able to use the project commercially, what license might I use? (Open source)
Ping me with your response please, also if this is the wrong place to ask this please direct me if possible
20% is potentially really big though. Where would those gains come from? Startup time? More efficient calls to other libraries (eg less syscall overhead)? Actual VM performance on loops, math, etc?
I legitimately don't know these things, but if I can get 20% speedup by recompiling Python then I would be tempted to do so
I'm not sure what channel this belongs in, possibly off-topic. But i will say that restricting use means that none of the "free software" licenses will work for you, and you might need to make your own. What you can do instead is use a copyleft license like AGPL, which does not prohibit commercial use, but forces commercial users (including you) to publish the source code and forces derivative works to be published under the same terms, and thereby generally acts as a deterrent towards other companies using the code.
Creative Commons has "non-commercial" licenses but CC recommends against using their licenses for source code
Why does AGPL force you as well to publish the source?
You have all rights reserved under copyright untill you give something a license. A license doesn't restrict usage, it allows it.
Oh that's a good point and very true
wow there's hope for no gil python somebody posted this one the python dev list https://mail.python.org/archives/list/python-dev@python.org/thread/ABR2L6BENNA6UPSPKV474HCS4LWT26GY/
Fun fact, I started the tests when sending this message, I am only at test 313/425
the nogil fork is pretty impressive
I don't know why it takes so much time
I do wonder if it is just frozen
I guess I could strace it and see what is causing so much trouble
I just read all of that, that's so awesome.
wow!
best part not breaking changes to the c extensions which is really great, it's too good to be true but I wishing the devs best of luck.
Yeah after hearing about the pains of the GILectomy it really does seem too good to be true
I am guessing the secret sauce to success is using a thread safe memory allocator mimalloc
Pythonโs built-in โpymallocโ memory allocator is not thread-safe. This project replaces pymalloc with mimalloc [link], a memory allocator developed by Daan Leijen at Microsoft. Mimalloc generally has better performance than pymalloc and is thread-safe. Additionally, mimallocโs layout of objects in the heap allows for finding all GC-tracked objects without maintaining an explicit list, which isnโt possible to do efficiently with pymalloc or other allocators built on top of malloc. Finally, the design of mimalloc enables a thread-safe implementation of dictionaries and other collections that avoids locking during most non-mutating access.
Hi. I have made an anonymous, end-to-end encrypted, decentralized chat application (for PC) with python, Anyone wants to try it out? https://github.com/SamratDuttaOfficial/onymochat
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.
Oh okkk
i think the only thing he should do in return is learn python 
Yes, i dont even want him to learn python, he want to be a Skidder
interesting proof-of-concept ๐
if im having a hard time deciding whether i should learn django or typescript for my backend framework given ik MERN and python
i have a group of friends that just wanna built stuff (hopefully one will be succesful) and idk which framework i should use
every idea is somewhat diff and i will eventually learn both but idk what to start with if that makes sense
what do u think the pros and cons are for each
what's a self-promoting bot?
depends on what you actually want to achieve and what other dependencies you might need - a good argument is that everyone should use the same language to help maintain things in the long run
do you have any experience with gzip on heroku?
More optimized performance on the eval loop of the virtual machine, mostly. Each of those things individually might buy you ~5% speedup if your distribution doesn't do them. PGO runs a big chunk of the test suite under an instrumented version of the interpreter to figure out which branches are taken most often, and then uses that information to rebuild the interpreter so that the branch predictor prefers the branches that tend to be taken most often. LTO allows functions to be inlined across translation units. And your distribution has some minimum version of the x64 ISA that it will target - it may ship binaries that work with every x64 processor from the AMD Opteron on, for instance. If you compile yourself, you can ask the compiler to produce code that will only work for Core i7 processors and newer, for instance, which means that it can take advantage of newer instructions that weren't available for the earlier chips in places where multiple instructions would have previously needed to be used.
of the 3, two of them can be done without costing you anything but build time. If your distro doesn't do PGO and LTO, you should file an issue about it and ask the maintainers to do it. They make the package faster for everyone, at the cost of making it take longer for the maintainer to build it, which is a huge win for distribution packages.
so, we're testing to auto-install all the packages in the conda distribution via justuse (up to 80% passing now!), but we're stumbling over a few roadblocks, namely packages that need extra stuff like dll's that you would have to download manually and on-site compiled packages that might require adding cython (and/or some other build-environment) as an extra dependency to justuse
are there any elegant solutions to any of those problems that might come to mind?
for the second issue i could think of some trusted third party service that could compile packages to certain configurations, is there anything like that?
Interesting, thanks for the explanation
Seems worth it for a production environment
Ask the devs to package the dlls in package resources ๐
That's part of what auditwheel does.
interesting
I saw some answers on qoura that computer science can also be used in healthcare. So do you think we can also use CS to help with mental health? And in what ways can we use CS in healthcare?
excellent questions, but wrong channel ๐
Ohh really? Which channel can i ask this question?
#career-advice is likely the best fit, since that channel is broadly about Python and jobs
Got it, thx!
hi
why doesn't numpy include Cython in its setup_requires or somewhere
it just bails out and says "Oh, you needed Cython"
setup_requires isn't the recommended way to declare build dependencies anymore. The "build-system.requires" key in pyproject.toml is, and Cython is declared there. https://github.com/numpy/numpy/blob/main/pyproject.toml#L7
pyproject.toml line 7
"Cython>=0.29.24,<3.0", # Note: keep in sync with tools/cythonize.py```
so why wouldn't that automatically be installed by pip? is it supposed to be?
it might be because I used setup.py ?
It is
ahh
Did you run python setup.py install or something like that?
i did pip install, but I don't know if wheel was installed at the time. It warned that it was "using legacy setup.py"
Yeah, sounds like pip was unable to use the modern PEP 517 builds, then, and fell back to directly running setup.py without installing the build dependencies in an isolated build environment.
ok, so if I have an up-to-date pip, and wheel, I suppose it should work?
Yep
Hello. I start new project and search for guy that can work with me. If anybody interest just send me message. Thank you
thanks

https://discuss.python.org/t/announcement-pip-21-3-has-now-been-released/11078
Editable installs for build systems other than setuptools! โจ
๐ฎ
Hello Pythonistas! On behalf of the PyPA, I am pleased to announce that we have just released pip 21.3, a new version of pip. You can install it by running python -m pip install --upgrade pip . This is the last scheduled release for 2021, following our regular quarterly release schedule . Highlights This release has a lot of good stuff in it...
Can someone please help: https://discordapp.com/channels/267624335836053506/696353510488539206/897314725480787989
Does this mean that you could,in theory, install packages built with poetry?
Two questions:
-
Not sure if I missed it here but is there a planned replacement for XMLRPC for using pip? I know it's been down for some time due to what basically amounts to DDOS attacks but the status page for it doesn't mention of any replacement
-
I know on installation that Python can be set to have the standard library compiled into
.pyc, but are their talks of speeding up the standard library further by compiling them into something like Cython'spydfor Windows andsofiles for Unix systems? Essentially move as much of the functionality that 99% of projects derive from to give an overall performance increase?
The more manual method would be to rewrite the standard library in C but that could introduce so many more issues
Yes that's the point. Pip now supports the pyproject.toml file thing
anyone who is good at apache nifi do let me know, I need help in intergration of Apache NIFI, will pay you if needed. DM
any reasons why we couldn't have USE flags like gentoo?
if there was a unified way to globally manage flags we could do optimized on-site build/compilation
Of Python?
yeah
-> cython for example
or consider tensorflow
or other packages with specific hardware configurations
Ooh, I see now yeah
and if pypi was managing things, we could condense all flags into a single number ๐
like.. numpy-2.21.0-298 would correspond to a bitmask of 100101010
you could look up the flags set
if flags were never removed, only appended, that system would be backwards compatible forever
Er - pip has supported pyproject.toml and PEP 517 for years now, @grave jolt . The new feature is that pip install -e . would work with things that use poetry as their build backend
Previously only pip install . would work.
Idk, maybe the backends don't support it yet. And note that this is only for editable installs, poetry has always been a valid build backend for wheel
Basically what godlygeek said ๐
What's the difference?
I thought that is what PEP 517 did
the PEP 517 build-backend tells pip how to build a wheel, that's it
"editable" installs are like pip install -e - they leave the files in place and create a "link" that tells python where to import the modules from. entirely different system, and was a setuptools-specific feature until now
Hello everyone! How do I display the image from Google Earth by giving the valid co-ordinates in ".png" help will be appreciated!!
- that's the wrong channel for this question 2) that question doesn't make much sense in any case
I mean I have to write all of this in Python code.
If you need help, please read #โ๏ฝhow-to-get-help to claim a help channel ๐
Why is hash same?
>>> a=[1,2,3]
>>> object.__hash__(a)
116525477204
>>> a.append(2)
>>> object.__hash__(a)
116525477204
because it's the same object and object's eq goes by identity
theres a reason dicts dont accept lists as keys. relying on hashes of mutable containers is a recipe for disaster
how does object.__hash__ work? list is unhashable right
does it work on any object?
object.__hash__ works by id
I think it just divides the id by pointer alignment and uses that directly as the hash
Python/pyhash.c lines 137 to 145
Py_hash_t
_Py_HashPointerRaw(const void *p)
{
size_t y = (size_t)p;
/* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
excessive hash collisions for dicts and sets */
y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4));
return (Py_hash_t)y;
}```
In class methods, we can use super() to call methods in base class (MRO). Is there any way to reference static properties of base clases in the same way?
Something like this (which is NON functional python):
class CommonStuff():
INTERESTING_ITEMS = ["Banana", "Potatos", "Carrot"]
class MoreStuff(CommonStuff):
INTERESTING_ITEMS = super().INTERESTING_ITEMS + ["Spinach", "Stew", "Caraway"]
Is the implementation of super() heavily reliant on there actually being a self? (Since the earlier invocation of super had to look like super(CommonStuff, self))
IIRC it gets transformed at compile stage
So the change is purely syntactic, it fills the call with the same arguments as before, except automatically
yeah that seems like what I would have guessed.
Alas, it would have been useful in the above example
That wouldn't be enough since MoreStuff is not defined yet.
>>> class MoreStuff(CommonStuff):
... INTERESTING_ITEMS = super(MoreStuff, None).INTERESTING_ITEMS + ["Spinach", "Stew", "Caraway"]
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in MoreStuff
NameError: name 'MoreStuff' is not defined
i think you'd have to walk through cls.__bases__
Is cls defined at that point?
oh i was thinking inside a classmethod, sorry
no, it's not defined
you have to refer to the class by name
unfortunately you have to write INTERESTING_ITEMS = CommonStuff.INTERESTING_ITEMS + ["Spinach", "Stew", "Caraway"]
Yeah I know that works, just trying to find if there was aonther way ๐
you can actually quite easily make a hashable list
but it can get tricky if you want to use a list as key in dicts either way
it'd be really nice if super() did that, but it's probably too niche of a feature to be supported
but it'd be fairly useless, no?
it'd be nice if class definition scoping wasn't so fucking weird anyway
coming from you!
if it's immutable 1) use a tuple, 2) if not, why are you hashing it
frozenlist when
tuples are semantically different from lists!
!e ```python
class frozenlist(tuple):
def repr(self):
return 'โ๏ธ'+repr(list(self))
def __str__(self):
return 'โ๏ธ'+str(list(self))
lst = frozenlist([1,2,3])
print(str(lst))
print(repr(lst))
than an immutable list?
@paper echo :white_check_mark: Your eval job has completed with return code 0.
001 | โ๏ธ[1, 2, 3]
002 | โ๏ธ[1, 2, 3]
yeah i'd say so. a tuple is a "record" (a generalization of a "pair") with unnamed fields, a list is still an arbitrary-length sequence, it's just immutable
a long time ago i actually had a case where i (iirc) used hash(tuple(self)) to use a list as key in a dict
what? tuples are record, says who? :p
but don't ask me about the context
salt did just now! (in all seriousness though, yes tuples can carry extra meaning in context)
eg coordinate systems anyone? (x, y, z)
yep, that, or a row from a database, or the result of ziping things together, etc.
this does give them an inherent semantic meaning above and beyond just being an immutable list
a tuple is a heterogeneous fixed-size record, a list is a homogeneous (modulo Union) sequence of arbitrary/unknown-until-runtime size
yeah, tuples basically scream "record!" and a list screams "homogenous output of a generator!"
but who listens..
๐ค
I've heard it. They don't have to scream when talking to me any longer.
it's just naming imo
yes
but don't confuse convention with semantics
essentially semantics can make the same code easier or harder to understand and maintain, simply because we tend to rely on meanings a lot more often than we realise.
semantics are codified convention
until they aren't and it's all anarchy \o/
sounds like an oxymoron. "codified convention"?
it's python, what do you expect?
the way you can hack anything..
who knows
it's not an oxymoron, the point is that generally-accepted convention is no different from semantic meaning
and the difference between "what the compiler/parser accepts" and "what people just like to use" is kind of arbitrary
that's your opinion
that is indeed my opinion
and i will continue to reject tuples-that-should-be-lists in code review!
ok, it's settled then
:p
who thinks tuples should be lists
they deserve to be smacked
ahhh!
i've seen it before, people wishing we had const like in javascript
(not that const means what that means anyway)
i.e. people wishing we had frozen lists
using tuples instead
oh lmao
What is PR?
yeah I know ^^ thx
yw ^^
I have only done 1 of those, so the abbreviation doesnt auto expand ๐
you'll get used to it ๐
pytjon lists are linked lists, right
is that what a tuple has too?
"arrays of references" is the mental model
it's just an array I assume, no need to resize
it's literally an array of PyObject* in cpython, right?
afaik
is there any linked-anything in python? deque comes to mind.. heapq maybe?
heapq works on any mutable seq I think
deque is a linked list (of constant size arrays (to save memory))
so the pointer chasing that's bandied about is just one pointer dereference?
two, I guess, for a list
i've never heard people complain about "pointer chasing" in python fwiw
i think it's just one of the ways people complain about python being slow
yeah
something like lisp that has "real linked lists" would seem to demand much more traversing
I plan to rewrite a memoize decorator using weakrefs. Are there any special considerations I need to take? Just read the docs first?
oh god.. that's how it all starts
haha
we have a not so good decorator now, that keeps references to all instantiatons of a class, eating a lot of memory during the run of the script. (It's memoizing class methods)
What are weakrefs exactly? Are they just a reference that doesnโt get counted in the ref counting?
Yep. So you can call them to retrieve the object if it still exists, but they don't keep it alive.
If the object dies they change to return None.
well.. you should try to keep the linked object and context as simple as possible and you'll need a refcounter handy and you'll probably need to look into memory leaks
for breaking cycles, is a big use case right
It's one yes.
lisp has vectors with array-like semantics too fwiw, although they don't necessarily have a strict O(1) lookup guarantee for AREF
The other is stuff like caching, so when the object is otherwise unreferenced your cache doesn't keep it alive.
you'll need a refcounter handy what does this mean? A manual refcounter?
yeah, for debugging
One thing to note is that an alive weakref implements equality and hashing based on the object value (so you can simply create another weakref to do dict lookups), but when it's dead you must use the same weakref object to do so.
they click when they're near a reference leak
since anything anywhere can be a property and thus a potential cache of the linked object, you might miss a ref or two and you'll wonder why your program suddenly runs out of memory although everything should be a weakref
i'm fortunate that most of the code i write is "stupid" and i have never had to use a weakref
You can probably just use the WeakKeyDict / WeakValueDict and not worry about directly using the ref, but if you do you should probably look at that code for some subtleties.
gremlins, gremlins everywhere! crazymumble
zombie qremlins?
damn moonlight makes them all go haywire and sneak into your beautiful code, messing everything up while you're not looking
btw, python is #1 now - wonder how long that'll last :p and i'm curious what features people will come up with to keep the throne ๐
is there any big new change in the pipeline i haven't heard of yet? py311 seems boring compared to 310
Do you mean the swedish car registered with PEP310? (Volvo 850 Sedan 2.5 Automatisk, 170hk, 1995)
i mean python3.11 :p
oh
oh, there's a poll
In Python today, for loops run in the same scope as their enclosing block. Some languages have for loops create their own scope, as functions and classes do. Pythonโs current behaviour is discussed here. Some people would like Python for each iteration of a loop to run in its own scope. That would probably solve the issue described in the top...
muaha
wait, how did that escalate from lambdas to loops
Well it's because the i in [lambda: i for i in range(10)] is "locked" and inaccessible after the comprehension is completed, right?
that.. i'm surprised that is even working syntax
but nobody would write that
what's wrong with the syntax?
the lambda: i inside the comprehension is ambiguous
ambiguous?
yes, it could mean [lambda: [0,1,2,3,4,5,6,7,8,9]]
oh, right
but actually it means
[<function <listcomp>.<lambda> at 0x000001868E2C7430>, <function <listcomp>.<lambda> at 0x000001868E2C74C0>, <function <listcomp>.<lambda> at 0x000001868E2C7550>, <function <listcomp>.<lambda> at 0x000001868E2C75E0>, <function <listcomp>.<lambda> at 0x000001868E2C7670>, <function <listcomp>.<lambda> at 0x000001868E2C7700>, <function <listcomp>.<lambda> at 0x000001868E2C7790>, <function <listcomp>.<lambda> at 0x000001868E2C7820>, <function <listcomp>.<lambda> at 0x000001868E2C78B0>, <function <listcomp>.<lambda> at 0x000001868E2C7940>]
for the computer it's not ambiguous similar to how 2 + 42/2 is not ambiguous.
actually, i'm tempted to post that as bug - it's absolutely not clear which should take precedence here
ie. it has a priority of parsing and it sticks to it. that we don't come across this priority much is on us, not on the computer
!e ```python
funcs = []
for i in range(10):
funcs.append(lambda: i)
print([f() for f in funcs])
@paper echo :white_check_mark: Your eval job has completed with return code 0.
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
i don't see why you'd expect that to be any different in a list comprehension
loops don't have local scopes
get over it people, go home
its the same in both
i am big -1 on local scopes in loops anyway
oh, thats what you mean
but a local keyword that introduces a local scope, yes please
agreed
for local i in range(10):
funcs.append(lambda: i)
?
x = 10
local x = 1, y = 2:
print(x) # prints "1"
print(x) # prints "10"
basically i want LET* from lisp
you can even call it let x = 1, y = 2:
there's no logical reason why lambda shouldn't have precedence over the comprehension, just from reading the expression
I would like where from haskell.
banana = x + diff * times where:
diff = start - end
times = total // step
or something
logic is a human construct.
I guess it's similar to let
is there a point somewhere? ๐
if you accept 2 + 42 / 2 as unambiguous, it's essentially the same deal. we "chose" to resolve it some way.
i don't accept it
fair. and all i know is, i'd rather type 2 + 42/2 because i prefer making life easier, not more difficult.
the problem with the lambda and the comprehension is that it's too rarely used in conjunction so that people couldn't tell which one gets precedence - codified convention and all
Hmm, I saw a suggestion from someone in r/ProgrammingLanguages on a language that gave syntax errors if operators with different priority were used in the same expression without parenthesis. It's a nice idea I think.
It would help with the lambda vs comprehension-for, for example. Forcing you to provide parentheses to not get syntax error
i think practically it adds complexity to the language for very little benefit. clearly as established this scenario doesnt come up much at all, why should we have to add and maintain a special case for it. additionally, if you're not sure, use brackets to make things unambiguous. that's an advice that has always been good
yeah, i see what you're getting at, but it might lead to a mess of () in normal circumstances..
essentially, this is a "nice to have" thing if you completely ignore the big picture and look at only this one instance
but there's always tradeoffs when taking decisions like this, they are worth considering.
It would be nice when mixing with shifters >> or % which I'm never 100% sure about precedence with
i'd say use brackets for those anyways
yes, but why not enforce it in the syntax?
Only way to control other programmers ๐
Of course you don't have to enforce it when just using /*-+
perhaps. without offering my personal opinion, i know python's stance on it is generally more towards open-ness and simplicity in the language, and conventions in cases where ambuigity needs to be resolved or intent needs to be clarified.
right
>>> lambda: i for i in range(10)
File "<pyshell>", line 1
lambda: i for i in range(10)
^
SyntaxError: invalid syntax
So at least in python it wont come up. basically, there is complexity and cost to these decisions that are worth thinking about
in that case, Im a bit surprised that pycodestyle doesn't complain about it, because I don't think it does?
without saying whether one is better or worse, just saying it's important to note that the goal of language itself needs to be simple too
yep, python's grammar resolves it in a consistent way
Yes, it's just an interesting idea. I'm not really advocating for it in Python.
But what I have missed a few times is comprehension-like filtering in regular for-loops:
for f in fruits if f.size < 5:
pass
oh, that's a cute idea
all that saves is one line and one level of indent...