#internals-and-peps
1 messages ¡ Page 63 of 1
what is the "context" here
So the way the computations can be evaluated is:
- you perform one
bindand get anotherIOcontainer - you might switch to a different task
- some time in the future you can return to that particular result (
IOcontainer) and compute it further
this way, cooperative multitasking (like async stuff) can be achieved
Callable[[Tuple[int, str], Optional[int], Mapping[FrozenSet[str], int], bool]
I see absolutely nothing wrong here
I'm screaming internally
you haven't seen TypedDict
I use it a fair bit actually
inline typed dict
because I'm working on my startup's REST API that returns almost entirely JSON
:)))))
you know what I miss?
case classes
TypedDict("Hello", {"hey now": Callable[int, float], "lorem ipsum": TypedDict("Hello", {"dolor": str, "sit": int})})
or...normal data, in Haskell
are these - yeah
sorry
perhaps we should have stuck to "if [] should execute"
@paper echo
the bind implementation is written in C in the event loop somehow :)
await is just syntax sugar for calling it
right
case classes are another terminology mystery to me
@paper echo I understand it's because they're great for pattern matching
match case
personally I just think they sound coool
good enough for me
but then you need lenses
which I have foolishly attempted to reimplement in Python because...
...sigh.
https://pypi.org/project/glom @gleaming rover
_[0].attr[42].hello[3:5]
I got so distracted my side project (a game) spawned its own sided project (a sliceable list where the slices update based on the original)
like slice thingy in go?
https://pypi.org/project/glom @gleaming rover
@paper echo that looks COOL
so like a numpy array :p
@grave jolt so in the monad interpretation, await means something like "take an Awaitable thing, and represent the result of future computations on that thing as an Awaitable"
is that close-ish?
>>> l = Sliceable2DList([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
>>> l
[[1, 2, 3]
[4, 5, 6]
[7, 8, 9]]
>>> sub_l = l[1:, 1:]
>>> sub_l
[[5, 6]
[8, 9]]
>>> sub_l.apply(lambda x: x * 2)
>>> l
[[1, 2, 3]
[4, 10, 12]
[7, 16, 18]]
so like a numpy array :p
@teal yacht yes, like anumpyarray, BUT alist
yeah glom is great for hacking apart deeply nested data structures
@paper echo await is an ad-hoc implementation of do-notation from haskell
i.e. not really useful anywhere except in the side project that spawned it but really fun to work on
a few hours just disappeared
I mean, views on arrays can be super useful
Yeah, what you did is a view
yeah, I mean like it's kind of restricted in this case because it has to be 2D and it doesn't support changing dimensions so honestly I should just have used a numpy array
pretend the fact that it's a list has other benefits that you really needed
oh I remember why now
like O(1) append
I didn't want numpy to be a dependency just for this
and I wanted to build something cool
also, constructing a numpy array from a list comes at some cost (for me it's on microsecond level)
honestly I think numpy should just be stdlib
i kinda feel like monads in python might not work because you need to somewhat-strictly enforce the return value of the function being bound
class Option(Monad, Generic[T]):
def __init__(self, value: Optional[T]):
self._value = value
def __bind__(f: Callable[[T], Option[T]]) -> Option[T]:
return Option(None) if self._value is None else f(self._value)
like this
except for the fact that it'd mean slower releases @pseudo cradle
Yeah, that's fair
if anything, start taking stuff out of the stdlib
something something users should know what they're doing something something
numpy only makes sense because it's powered by a C extension, which can't be attached to the spec
(I don't agree with that statement, that's why I'll never prefer dynamic typing)
Maybe it's just me but anything besides a config file is importing numpy
depends on what you're working on
if anything, start taking stuff out of the stdlib
https://docs.python.org/3.9/library/graphlib.html
Doesn't everyone work on algorithms? đ
no, I work on monads đ
I don't know what that is, but it sounds fancy
I'm not sure if it's a joke or sarcasm or something tbh
@pseudo cradle Basically, you flatten the nested monad and that's it
Sounds painful
yeah, sometimes it binds
@grave jolt to be fair, topological sort is a basic necessity for package management, which is a basic necessity for a programming language that isnt stupid. so i'll give that one a pass
i suppose you could say the same about having http and ftp clients for actually fetching packages
don't think it would work as a language feature
but yes IMO there is a ton of nonsense in the standard library
although perhaps I just don't understand some of it
why do we even need stuff like curses?
wdym we don't need turtle ?
(I chose it specifically because I'm actually using it for my side project but it is literally something I have never looked at ever otherwise)
wait
turtle is part of stdlib?
my god
I personally think curses is much higher on the list than some other modules tbh
no wonder I have never seen anyone complain about being unable to install it
WELL
I guess it's the philosophy "have something for everybody"
honestly I don't really have a problem with stuff like that as long as it 1. doesn't take a commonly used name and 2. doesn't replicate functionality
look at all the beginners here
now imagine you have to make them install stuff?
into environments?
that's the main argument for keeping the stdlib big and fat
that was a real quick edit
if at least it was complete, colorsys has like 6 functions
I'm sure I can name more color spaces than that
(nvm i can't)
that's a fairly silly one to have in the standard library because it's implemented in Python
it may cover some of the most heavily used colorsystems, but I'd expect just about any color conversion logic to be done in a loop, at which point having the whole thing implemented in Python rather than C is likely to quickly become a bottleneck
after all, who converts just one pixel? Heh
does anyone happen to have any historical insight into why python went with the fugly lambda x: x syntax instead of arrow syntax like most other languages?
even if it's not arrow, rust is like |x| x iirc, lambda x: is like have a sentence ffs
lambda calculus
Wanting lambda as a keyword might be one reason and to make it similar syntax to a function def
Lambdas have been part of Python since version 1.0, which was released in 94. I can imagine there wasn't really an accepted standard for what anonymous function syntax should look like back then.
I don't personally think it matters much, since lambdas aren't all that useful in Python.
Python usually has a preference for keywords over symbols (and for example). That's because they're more easily searchable and identifiable than a symbol.
And it leads to more natural language looking code
In the case of control structures and logical expressions, that holds true, but I don't think the word "lambda" fits naturally into most sentences.
Hello!
is it possible to change the color of the output of the ide 
@unkempt rock yes, the colorama module. secondly, this isn't a help channel
Doesn't matter, we prefer it that way than conversations happening in on topic channels
map(lambda x, y: x + y, list(1, 2, 3))```Could be read as "map the lambda function x + y to the list 1, 2, 3"
So I guess it can be inserted in some sentences?
But I agree with you, the lambda syntex isn't great
i've seen the different proposals for changes to the lambda syntax on python-ideas and the generator syntax was my favorite
(x + y for x, y)
or
(x + y from x, y)
and wouldn't need new keywords
Personally I prefer parameters first
me too
back to Haskell using the wrong order
đĽ´
but honestly that for thing looks pretty good
i agree ^
Idk if you can use with without breaking the parser
(with x, y: x + y)```
I would also like tuple destructuring in lambdas, as long as we're hoping
Idk if you can use
withwithout breaking the parser(with x, y: x + y)```
@languid dagger I was thinking more about the colon
because if you wanted arguments first you'd need something to separate arguments and body, right
colon is the most intuitive but I am not sure how that would work
use the -> from other languages
-> is already used for typing. => is pretty clear, seems pretty hard to mix it up with >=
Oh right I forgot that it's used for typing, perhaps they can reuse it then
use the
->from other languages
@feral cedar then no need for a keyword
just x, y -> x + y
honestly I would also like that for function typing
it's already there for type hints
imagine (int, str) -> bool instead of Callable[[int, str], bool]
yeah ig
whats the idea behind yield
that is infinitely nicer for typing
how does it work
As in why does Python have a yield?
What does it do?
When the parser sees yield in your function it creates it as a generator function instead
well, in simple terms, then, when your function hits yield, it pauses execution and returns control to whatever called it
Rather than a typical function, so the behavior is slightly different
parser being python?
but without releasing the variables that are in scope
compare that to a normal function, where all the variables in scope can be taken to disappear once return is hit
Yes, Python parses your code into bytecode. That's how you get syntax errors without running anyway
Then that bytecode is run in the Python interpreter
hmm so what happens if you return a gen comp
def something(x):
return (x*x for x in range(x))
idk if that even works
that would be a normal function, not a generator
so it exhausts the gen?
No, the generator is constructed but returned as is
>>> def a():
... print('called')
... return
...
>>> def b():
... print('called')
... yield
...
>>> a()
called
>>> b()
<generator object b at 0x00000279681AA1A8>
you see that 'called' is not printed when b is run
If you were to print it you'd see "generator object"
so its still "optimal code"?
I don't know what you mean by "optimal code"
compare to:
>>> def c():
... print('called')
... return (x for x in range(1))
...
>>> c()
called
<generator object c.<locals>.<genexpr> at 0x00000279682C7468>
no
why
Your function does not continue to the yield call until requested (i.e next is used)
when you call an ordinary function (with return), it starts execution at the head and runs until it hits an error or return.
shouldn't it go through first iteration by default?
no
wow this is some crazy stuff
def gen():
print('g 1')
yield 1
print('g 2')
yield 2
print('g 3')
>>> g = gen()
>>> next(g)
g 1
1
>>> next(g)
g 2
2
>>> next(g)
g 3
StopIteration```
yes
Yes, hence "generator" you can generate values
yes, the point of a generator is that you can pause execution and return to it, and each time it will yield a value
Usually they get exhausted eventually but they can be infinite
and the work done to produce the next value is only started when requested
going back to my code thingy:
itertools.cycle is one such
In [3]: def infinite():
...: n = 0
...: while True:
...: yield n
...: n += 1
...:
In [4]: a = infinite()
In [5]: next(a)
Out[5]: 0
In [6]: next(a)
Out[6]: 1
In [7]: next(a)
Out[7]: 2
def something(x):
yield (x*x for x in range(x))
what happens here?
You yield a generator object
in other words, something is a generator that produces a generator
so you can do?
for val in something(13254):
print(val)
as opposed to infinite, which is a generator that produces int
you can do that, but you're just going to get <generator object...
oh
!e
def f(x):
yield (x*x for x in range(x))
fgen = f(3)
print(fgen)
g = next(fgen)
print(g)
for i in g:
print(i)
@languid dagger :white_check_mark: Your eval job has completed with return code 0.
001 | <generator object f at 0x7f05db2b6890>
002 | 0
003 | 1
004 | 4
because now val is (x * x for x in range(x)
ok so nested for loop then?
but you could do:
for g in something(10):
for val in g:
print(val)
yeah
incidentally, you can flatten with yield from
!e
def f(x):
yield (x*x for x in range(x))
for gen in f(10):
for num in gen:
print(num)
You are not allowed to use that command here. Please use the #bot-commands channel instead.
WHAT
helper flex
def flatten(iterable):
for item in iterable:
if isinstance(item, list):
yield from item
else:
yield item
Given an iterable containing lists nested to any depth will give back a generator only containing the elements
So it removes all nesting regardless of depth
ok
Wait, no. Only 2d since it's not recursive
short hand for
yield from iterable
for ele in iterable:
yield ele```
it's actually better than that
wait how?
something something error catching
which is this case no?
and async
In [14]: list(flatten([[1, 2, 3], 2, 4, [5, 6, 7]]))
Out[14]: [1, 2, 3, 2, 4, 5, 6, 7]
that's flatten
did u use ur function?
yep
this is a bunch of generators to make ast trees:
https://github.com/salt-die/prettiest_ast/blob/master/prettiest_ast/prettiest_ast.py
so if i pass a nested list with lists randomly inside aswell, this function does that?
recursively
def flatten(iterable):
for item in iterable:
if isinstance(item, list):
yield from item
else:
yield item
no not this one
while 1 such blasphemy
while 1such blasphemy
@languid dagger what is that
that's for flavor
Just joking about this line https://github.com/salt-die/prettiest_ast/blob/master/prettiest_ast/prettiest_ast.py#L17
As opposed to while True which do the same thing
I wonder if there is a smaller way to define an infinite loop than while 1:
#esoteric-python could probably answer that
i don't think so
well
copy paste code until you hit infinity lines
anything smaller would have to use for since 1 is a single character
that's 0 chars in the while loop definition
and I don't think you can put a full condition in 4 characters...?
I'm pretty sure you just can't get shorter than while 1
while (1):
# yes write some code here u big brain boi yes u
that's not that much better than while True though
oh wow
that's not shorter though
it looks cooler
idk if it's just me but that looks vaguely inappropriate
the coolest throwaway variable is:
for {}[()] in range(100):
...
wtf is that
oh dear
I mean yeah
probably off-topic though
for _ in range(of_my_door):
...
that's a true throwaway, _ still stores the value, {}[()] should get gc'd as soon as the loop ends
discord bot handle api hto ?
whats {}[()]
apparently valid
empty dict literal, accessing its () (empty tuple) key
bruhhhh
it should only exist as long as the loop exists
so can you even access that thing
it's basically
for i in range(100):
d = {}
empty_tuple = ()
d[empty_tuple] = i
del i
del d
del empty_tuple
# ...do stuff...
from your code? nah
lol thats evil
it's a bit over the top compared to, say, py for _ in iterable: pass del _
but yeah, it's a true throwaway, unlike _
Have true throwaways been proposed as a language feature?
I'm not sure actually
_ acts as a true throwaway in the match-case pep
both for the default case and as filler variable
Are they throwaways? Or just wild card patterns
They're wild cards I believe
the other names get a value assigned to them, but _ are just ignored
so a mix of both I guess
Ya standard oattern match wildcard, but that doesnât mean they have âthrow awayâ semantics how would that work anyways?
I havenât paid much attention to the python pattern match thing so i could be very wrong
case Point(x, y) assigns the values to x and y
case Point(_, _) matches any Point
and throws away the values
Does it instantly gc x and y?
x and y stay valid names throughout the case body and after the match block too iirc
So it deletes x and y?
Does it instantly gc x and y?
@narrow kettle Why would they be cleaned up if they're still being referred to by the structure you're matching against?
My question exactly pure
I'm not sure I understand what you mean
Ya so itâs just a wildcard, Iâm not seeing how thatâs analogous to a throwaway variable
A throwaway or a discard is a variable that doesnât exist, itâs never actually allocated
Or itâs allocated and instance deleted
what are the usecases of that? Is it not roughly the same as just del?
like, the examples I can think of are using it in loops
and that only seems like a tiny advantage over the current method
Use case is that it allows you to be smarter with your allocations, which in normal py code isnât a big deal, but could prob be useful in an embedded system
and not worth introducing the extra complexity for
I gotta read the specification again
for an embedded system, you're already probably messing about with garbage collection and del
it seems like a mild convenience in some niche cases - but also another thing that people are forced to be aware of
which adds extra complexity to the language for not that much utility
I guess in that respect, it's kinda like the walrus - although throwaways seem far less relevant than the walrus
I think if _ is going to get special treatment in the pattern matching pep, we might as well make it an actual throwaway everywhere
But like Haskell has everything
it's not throwaway in pattern matching though
C# is a discard in pattern matching
I don't think it should be made into a real throwaway in all contexts, it's still a widely used name for things like i18n functions
Currently _ is a valid name, and any name other than _ gets values assigned to it, while _ is a wildcard that doesn't get assigned to, effectively discarding the value
I18n ?
internationalization
that could work
I'm not sure if extra builtin stuff like that is what python needs - operator/keyword soup has a real cost to beginners
then again, del _ isn't much of a hassle
Itâs not a pressing issue oc but it does make it easier to manage your memory
true
I mean beginners would never really touch this
at some point you have to touch this
This is more of a bone to embedded systems devs etc
and beginners will stumble across it
When you say _ doesn't get assigned to is this just for match statements?
I don't think adding this utility for a tiny % of people is worth the cost of adding another thing to the language
I mean they already stumble across _ =
@languid dagger yeah, in the context of match-case
This isnât really all that different practically
something having semantic meaning is different to something having syntactic meaning
It just has diff memory semantics
it's more easily ignored
But itâs not REALLY relevant to a beginner, you can explain them the same way
âItâs a throwaway valuesâ
I dunno - i'm not like super against it, it just doesn't seem to pose that much utility anywhere
and it does have a cost - it's not 0 cost
extra syntax is never free
What if they used Ellipsis instead? ... too annoying to type?
Where is it even used?
... is used as a filler for multidimensional slices
I don't think I've seen it anywhere outside of numpy slices and stub files tbh
pass is a keyword though, ... is an Ellipsis type which is treated as a constant
it already has meaning - I don't think that should be changed or built upon
and it gets used the same as Pass
But ... wasn't added for numpy, numpy would have just used it as a placeholder for its own syntax
The were no uses for ... in the stdlib until (relatively) recently AFAIK, it's used in typing and that's about it
https://docs.python.org/3/library/constants.html#Ellipsis
It's mostly used for slicing apparently
yeah, multidimensional slices
Hmm, so intended for custom containers
also - ... has completely different meanings in other languages - using it in python for throwaways just adds confusion when _ is the standard for throwaways
I think using * for throwaways could work
- is used for spreading
both throwaways and match-case wildcards
that would be terrible
how so?
it already has associated meaning with it
and it's not even close to the meaning of throwaways
why would you ever bother? _ has the semantics of a throwaway, just not the implementation - if you want a throwaway, that's the only sensible choice
or possibly doubling it to avoid breaking changes (although that doesn't stop breaking changes, so that doesn't help)
While I'm not against using _ as a throwaway, it's going to be a fairly breaking change and giving it special treatment in some contexts and not others feels way too inconsistent imho
that's literally what you're proposing with * though
it having multiple completely different meanings
I mean biting the bullet and saying make _ a true discard doesnât seem THAT bad
it already has several - it separates kw-only args from regular args, it's used for unpacking and is used for multiplication, which are all completely separate meanings
How often is one underscore being used as a variable anyway
using * is just straight up very confusing in some contexts
In [4]: a, **, b = [1,2,2,3] just looks silly
_ is a pretty standard throwaway syntax
and it's not at all clear what it's doing
and is a very common use of _ as a throwaway
having 2 of the same symbol next to each other - where they're doing completely different things - is unbelievably confusing and silly from a beginner's perspective
That is true
I'm just pressing the idea that we should either go all the way and make _ a true throwaway regardless of the context, or use something else entirely, as having it be a valid name in some cases and a special character in others feels inconsistent to me
I mean, you don't even need throwaway syntax in a pattern match, you can just use a is this value of class object match (iirc object() as per the PEP)
Hello, can someone explain this in simpler terms. I don't understand what np.linspace(0,5,10) actually does , Outputted array:
2.77777778, 3.33333333, 3.88888889, 4.44444444, 5. ])```
it creates a 10 elements long array such arr[0] is 0 and arr[-1] is 5 and differences of neighboring elements are equal
@unkempt rock the numpy documentation is sometimes hard to read, but if you make it all the way through one of their documentation pages it can be very rewarding
I live in numpy and am still learning new tricks with it
yep
i finally figured out how axis= works
or at least, in a way that sticks
plenty of lessons to be learned on language design here
This is some advanced stuff đ
is there anyone that knows about pillow?
Probably, but not me
is there a way to make a singleton WITHOUT having to call the class with ()```py
class Foo:
def init():
self.a = 1
print(Foo.a)
singletons are bad ideas đŚ
Probably, but not me
@pseudo cradle well....
in this case its for singleton of events
Why are singletons bad? It's a useful design structure
i don't know what that means?
class Events(metaclass= Singleton):
"""Class that defines what events are exposed at the bot level"""
@property
def on_broadcast_designated_channel(self):
"""
Published when a reqeust to broadcast a message to all registered channels
in all servers is sent
Args:
channel_type (str) The designated channel to broadcast the message to
message (union[embed, str]) the message to be sent to the channels
"""
return '_on_broadcast_designated_channel'
as an example
Classic singletons are classes that lie when you ask them to make an object.
these are all constants anyway
Even "just one object" classes that don't lie are hiding a global, with the usual problems.
can someone pls explain this code: "**" is unpacking. lambda *x, **y: self.do_response(self.init_response)
@narrow kettle maybe just define some variables in the module?
then i cant put pydoc comments on them
Or an Enum?
can you put pydoc comments on enums?
why call them singleton when you mean constants?
i did properties cuz thats the only thing vsc would show in the pydoc box
i mean its just one singleton
the events class
that contains many constants
essentially i want a way to write Events.on_some_event
so enum
but i didnt think you could put pydoc comments on enums
i'm not sure, you'd have to experiment.
Why are singletons bad? It's a useful design structure
@pseudo cradle singletons are only useful when you feel bad about making a global variable so you pretend it's not
@pseudo cradle tell us why it's useful
Okay, you're designing a class you only want one instance of
yep you cant
why not just make only one? Why does the class have to enforce it?
(Or better yet, design your program better)
class DesignatedChannels(Enum):
"""Enum that defines possible designated channels for the bot to use"""
@property
def message_log():
"""[summary]
"""
return auto()
print(DesignatedChannels.message_log)
So you don't have to worry about passing it around?
>>> <property object at 0x1070241d0>
Like, it's still a useful design structure that's taught in CS
that sounds like laziness
You can't just say "it's useful" you have to back it up
and "taught in CS" doesn't mean much
Laziness is a valid reason
I disagree
We already have more than enough issues in this industry with technical debt
Laziness should be eradicated
@pseudo cradle you had to have access to the class to call its constructor. However you got the class, just get the one object.
does anyone know how to attach a pydoc comment to a variable
thats basicalyl what i want
You had access to the class, you didn't necessarily have access to the object.
i want a way to document my constants
@pseudo cradle why didn't you have access to the object?
Why did you?
we're going in circles. write your program so that you have the object.
You can assign __doc__ if that's what you need
You said, "I don't want to pass it around" you don;'t have to,
Or use a singleton when it's valid
Can you give an example of a valid singleton?
We're disagreeing on design choices
I'm asking you to justify your choice
Let's say you have multiple people working on the code and you want to prevent more than one instance being generated
@pseudo cradle you said, "Okay, you're designing a class you only want one instance of". That means the user of the class wants only one. Why is that an essential characteristic of the class?
give them a convenient way to get the one instance. Why make it be a lying constructor?
generally id say make that a module then
constructing the class seems like a pretty convenient way to get the instance while also preventing more than instance from being made
MyClass.get_the_one() is also convenient.
and is clear what it's doing.
there's no reason to write lying constructors.
why hide that aspect of the class from your callers?
thats what i do for singletons generally
get_instance
class Foo:
@property
def bar():
return 1
print(Foo.bar)``` tho does anyone know how to make something like this work
this is basically what i want
Sure but MyClass.get_the_one() requires you to know that method, whereas someone with less knowledge/access can just create the class
@pseudo cradle your callers need to know how to use the class, absolutely.
when did you last write a lying constructor in Python?
class Foo:
__instance = None
@staticmethod
def get_instance():
""" Static access method. """
if Foo.__instance is None:
Foo()
return Foo().__instance
def __init__(self):
""" Virtually private constructor. """
if Foo.__instance is not None:
raise Exception("Foo is in singleton scope")
else:
Foo.__instance = self
what about something like asyncio's event loop or loggers? where you don't explicitly use the class, you call a function to get an instance?
there ya go, you enforced the singleton
@narrow kettle at least use @classmethod
@narrow kettle that will really suck to use.
(if people try to construct it)
loggers, caching, thread pools, config settings, device driver objects...
@pseudo cradle you've written those?
that will really suck to use.
how so
i mean how is that any diff then any other singleton wiht an explicit get method
Write I actually write in my day to day are algorithms
@narrow kettle sorry, if they try to use the constructor, since it will only work once
yes
But what I do in my day to day is irrelevant to this conversation
thats kinda the whole point
@pseudo cradle in Python, logging is: logger.getLogger(), not a constructor
you are enforcing that you DONT use the ctor
yes, i see, sorry
@pseudo cradle you seem convinced of the utility of singletons, so I'm asking for your personal experiences with them. where you have found them good.
@narrow kettle it's still a hidden global that makes things like isolated testing difficult.
Well, I've written drivers in ASM and have done config files in basically every language I've used
you gotta make some stuff global, esp configs
i find more and more that I can avoid that if i try
in the absence of DI in python your options are modules or a singleton
passing things around is a design choice, not one I'd always find optimal
yeah, that gets awkward
when everything is decouple thourghly attributes on a single class wont work super well
and passing things around is not fun, and is a ROYAL pain to refactor
Out of curiosity ned, how do you feel about factory design patterns?
it's also a pain to debug and test misused globals
if i was writing in say c#, id just inject an instance in singleton scope
easy peasy
i'm not sure what a factory pattern is in Python: every function returns objects.
my problem with patterns is that the gang of four wrote a book based on C++ and Java, and now everyone talks about those patterns as if they applied everywhere.
gang of four aside, because there's definitely valid criticisms against that book
ok, gang of four aside, tell me what a factory pattern is.
It's an interface for creating an instance of a class
class FooFactory:
def getFoo: return Foo1()
class Foo1:
pass
class Foo2:
pass
this concept works better with interfaces imo
good lord i think this might be an impossible task in python, static properties
Between this conversation here and the one in #ot1-perplexing-regexing I'm finding it hard to pull away and do work đŚ
(One guy convinced Python sucks and is arguing with everyone about it)
i think static properties are the first thing ive found that python cant do
thats impressive
you can do them with metaclasses
!e
class U(type):
@property
def prop(self):
return 7
class V(metaclass=U):
pass
print(V.prop)
@flat gazelle :white_check_mark: Your eval job has completed with return code 0.
7
ahhhhhhhh that works
ty @flat gazelle i was playing with something like that but didnt get it quite right, ty
python once again proves its the most flexible lang out there
@pseudo cradle @narrow kettle in the FooFactory example: why is it a class? why not just a function?
it could be just a function, i was jsut writing off the cuff, im used to c# which would oc need a class
I think functions that make objects are great. (it's what i was advocating for instead of lying constructors đ )
Idk, I'm all for an extra layer of fuckup protection
@pseudo cradle i just don't see how it prevents screwups to make things behave differently than they appear.
Does pathlib.Path.__new__ fit the Factory pattern?
that's a constructor (of sorts)
PurePath and Path are factories for the OS dependent path classes
is add(1, 2) a factory for 3?
Are you against design patterns fundamentally?
no, because add is not a class which creates different class instances depending on some condition
I donât think that fits a factory
No. I'm against doing Java things in Python when we don't have to.
Factory is essentially just a ctor abstraction
I think design patterns were created for very specific languages, and most of them do not fit most other languages
Make of that what you will
What nedbat said basically
Yeah, and it's all about using the tools we have at hand given a tool
The two classes I mentioned in particular look like factories to me, and are referred to as such in the PEP that proposed their implementation
Solid will never go out of style imo
In my code I have a line that's just None because I needed a place to put a breakpoint
what does the interpreter do when there's a line that does nothing?
you can use the dis module to see
Foo.bar = classmethod(lambda cls: "stubbed_name")
```is there a way to make this a coroutine
jay, it seems like you are working against the usual structure of classes
open is also a factory - it returns different types of objects depending on whether you want buffering, text mode or binary mode, and read or write.
The type of file object returned by the open() function depends on the mode. When open() is used to open a file in a text mode ('w', 'r', 'wt', 'rt', etc.), it returns a subclass of io.TextIOBase (specifically io.TextIOWrapper). When used to open a file in a binary mode with buffering, the returned class is a subclass of io.BufferedIOBase. The exact class varies: in read binary mode, it returns an io.BufferedReader; in write binary and append binary modes, it returns an io.BufferedWriter, and in read/write mode, it returns an io.BufferedRandom. When buffering is disabled, the raw stream, a subclass of io.RawIOBase, io.FileIO, is returned.
jay, it seems like you are working against the usual structure of classes
probably, im trying to mock an async def on an instance method
stumbling around in the dark tbh
@raven ridge how is a factory different than a function that returns objects?
It's a function that can return objects of different types.
a lot of functions do that
a lot of functions are factories đ
i have two checks that i need my mock to pass py if inspect.ismethod(obj): and if not asyncio.iscoroutinefunction(callback):
and i can not for the life of me figure out how
if there's a function where a) the primary purpose is to create a new object, and b) the type of new object that it returns can vary, that's a factory. They're not that uncommon, pathlib.Path() and open() are both excellent examples.
open is a little more clear, since it doesn't masquerade as a constructor.
@raven ridge but int() isn't a factory? In Python 2, it could return two different types.
i mean technically all classes are factories, as they are just generators for instances
No, I'd say that int is a factory, in Python 2. It meets that definition.
but not in python 3?
a factory is just an object creator that abstracts the user from the type of object they'll get. In Python 2, int did that.
in Python 3, it doesn't - it always returns an int.
the purpose of a factory is decoupling - you can assume that the objects returned to you implement some common interface (in Python, via duck typing, in Java, via an interface or base class), without knowing which specific type you'll get.
in java if it returned an Integer and not integer it would also be a factory
Jay, so your definition is a little different
as with all design pattern the concept itself is nebulous, but generally anything that returns an object would be considered a factory for that object in some way
that's not the normal definition of the factory pattern.
if it returns an object in such a way that you dont have to think about what actual class is being returned
thats a factory
but every function in python returns an object
which still works better with interfaces imo
Wikipedia goes with:
In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created.
It specifically needs to be for the specific purpose of creating a thing, and it specifically needs to be able to return different classes of objects.
@spark magnet have you seen the arguments that design patterns are indicative of design flaws in a language, common problems that are so common and with such non-obvious solutions that programmers are forced to memorize rote solutions for them?
but every function in python returns an object
@spark magnet except functions that don't return at all
those return None, which is an object.
no.
thats also an object lol
functions that don't return at all e.g. infinite loops
"hurrdurr but you can always have it throw"
or that exit
get out with your non total functions
which is why there is typing.NoReturn
thhose arent relevant then as they never finish
just for these cases
edge case but technically correct, which is the best kind of correct
sure. fine, fair enough. "The only thing a function can return is an object" is the more precise phrasing, I suppose.
perfect example of Smith's Law
but every function in python returns an object
@spark magnet but anyway before I derailed this discussion...I think it's about variability of type?
honestly I never really got the factory pattern (it's one of the holes in my knowledge since I don't have a CS education) but this is my guess
i think the key idea is "abstract away the specifics of the type returned."
I think it's about variability of type?
that's correct. If its primary purpose is creating things but it always returns the same type of thing, that's more like the "named constructor idiom".
that's things like datetime.date.today(), for instance.
design patterns have a bad reputation because the one that most people find easiest to name is the Singleton pattern, which is crap. It's a pattern whose entire purpose is to allow you to create a global variable in a language whose data model doesn't want you to have global variables.
i will say that often times factories are abused and they do always reuturn the same type -__-
my last job abused that
honestly I was under the impression that a factory method was one that performed argument preprocessing/resource acquisition etc. before calling the constructor
and the constructor (well, initialiser, like __init__) should only set instance attributes
what do you call that then
I'd call that an alternative constructor, or a named constructor
or a constructor method
and the constructor (well, initialiser, like
__init__) should only set instance attributes
@gleaming rover isn't this a pattern
like datetime.date?
the real constructor only takes year/month/day and stores them, and there's a class method called today that acts as an alternative constructor that looks up today's year/month/day and passes those as arguments to the real constructor
I don't know that there's any particular name for that design, though it's somewhat common.
something like that but a bit more involved, like:
class Storage:
def __init__(self, connection):
self._connection = connection
@classmethod
def create(cls, uri, username, password):
...create connection...
return cls(connection)
like there would be no public constructor
in an equivalent language
hm. I'd consider that an anti-pattern - at least in Python, where it's not possible to not have a public constructor.
(Though you can do it in Cython!)
in the general case
yeah, I mean in general
but its not ideal
with enough effort
in general, "named constructor" is what I'd call it.
i will agree that its better to have connection code etc in a seperate mthod
I don't think it's an antipattern though
requiring like SomeApiClass().Connect() is better imo then just SomeApiClass() because then you put your connection logic in the ctor
in line with "all consenting adults here"
this facilitates testing too
because then you can test the resource acquisition logic separately
on the testing front does anyone know how to mock a method that will pass both these checks ```py
if inspect.ismethod(obj):
and
if asyncio.iscoroutinefunction(callback):
@narrow kettle maybe it would be easier to implement a fake than a mock?
https://docs.python.org/3/library/asyncio-task.html#asyncio.iscoroutinefunction suggests that you can do it with the coroutine decorator, perhaps
maybe it would be easier to implement a fake than a mock?
can i still assert that it was called with a fake?
or rather assert it was awaited
@raven ridge forgive me but i dont see how that helps me?
you can do whatever you want with a fake
class MyFake:
def __init__(self):
self.times_called = 0
def method(self):
self.times_called += 1
In [1]: import asyncio
...: class C:
...: @asyncio.coroutine
...: def func():
...: yield from asyncio.sleep(1)
...:
In [2]: import inspect
In [3]: f = C().func
In [4]: inspect.ismethod(f)
Out[4]: True
In [5]: asyncio.iscoroutinefunction(f)
Out[5]: True
ahhok i see ned, and i can just assert the times called
yeah. Between what ned's saying and what I'm saying, you should have everything you need to make whatever assertions you want.
ya i think i can make this work, let me go look
yep that did it, thx i was making that way more complex then it needed to be
@pytest.mark.asyncio
async def test_publish_event_invokes_listener(self):
messenger = Messenger()
class Foo:
def __init__(self):
self.called = 0
async def async_mock(self):
self.called += 1
foo = Foo()
messenger.subscribe('bar', foo.async_mock)
await messenger.publish('bar')
assert foo.called == 1
you can even assert what it's called with, if you want, by calling a mock đ
ive been playing with mocks for the past 4 hrs lol
class Foo:
def __init__(self):
self.mock = unittest.mock.Mock()
async def async_mock(self, *args, **kwargs):
self.mock(*args, **kwargs)
foo = Foo()
messenger.subscribe('bar', foo.async_mock)
await messenger.publish('bar')
foo.mock.assert_called_once_with()
ohhh the mock IN the fake class
gotcha
that makes sense
nice, tysm @spark magnet @raven ridge
mmmm, green....
i want to add coverage too, but uhh, i dont think a coverage of like 10% will impress anyone đ¤Ł
i bet you have more like 35%
hopefully once i get finished writing all these lol
When you don't pass your tests, create new ones đ
Or the opposite, if you finally solve a bug that wasn't caught by your tests, add regression tests to make sure it doesn't pop up again. Writing tests is real programming.

@narrow kettle if you want a test suite out of hell I invite you to look at PyInstaller
It's a pain maintaining it
A test fails every few days on a dependency upgrade
The whole suite needs rewriting
i mean ya id imagine, tons of dependencies and platforms
Is cx_Freeze any better in that regard?
Has anyone here used 'ring central' to send text messages?
That is better suited for an off-topic channel
Hi, anyone can help me with autorun raspi?
why wasn't this accepted?
I feel like this would be good:
var = my_list[8] except KeyError with None
I think I agree with Guido on this one
That.... yeah I really don't like that
what do you hate most about it?
I feel like try except stuff should be very obvious and structured
Having it nestled in-line just feels... dirty, I guess
I mean it would have limited use but so does inline if else.
Sure but if/else don't typically handle things that would prevent the whole program from crashing.
It's already easy enough to accidently silence errors by having an empty exception. I can't imagine it would be very fun to have to hunt through everything to find one that's in-lined
I might just be weird about it, though
I'm not sure I understand how inline would make it harder to debug
I'm sure if it was a thing we'd get used to it, and like steler said it's probably not going to be used that often
broad exceptions that handle errors you didn't know you could get is problematic but I'm not sure that this would encourage people to do that.
i dont hate it
because you still can only use expressions in the with
can't use raise from et al
i suppose most use cases for it are already covered by getattr and .get
however you know what i really really want?
a type annotation stating what exceptions a function can raise
I'd probably prefer that in the docstrings, you can mostly control what types you return but (unexpected) exceptions can be introduced with changes to the code, some can be trigerred on any line etc.
@paper echo I've been thinking about that kind of thing. do you have a syntax for that in mind?
nope, no idea
def my_fun(x: int) -> float raises KeyError:
...
ehhhhhhhh
đ
def my_fun(x: int) -> Either[KeyError, float]:
...
if you're a type freak like myself
I feel like the implication in the first example is that the float somehow raises a key error
it could be
@raises(KeyError)
def my_fun(x: int) -> float:
...
im good with @raises
def my_func(x: int) -> float, t.Raises[KeyError, IndexError]:
...
the question is: what happens if a function called by my_fun raises the error?
it should probbaly not be recursive, right?
It absolutely should
I can't think of a reason to make it a decorator
decorators do stuff and type annotations don't
@final is a decorator đ¤
@flat gazelle but then aren't you basically looking at @raises(TypeError) on a lot of things that use built in functions?
and @typing.overload
I would like Raises[float, [TypeError]]
But it is useless otherwise
If it only tells me some exceptions
true
we should create a version of python that has no exceptions đ
Obviously you do not include exceptions that would happen if you break the type hint
the Go discord is that way đ
i don't find it that ugly i guees
var = Model.objects.get(*args, **kwargs) except Model.NotFoundError with Model.objects.create(*args, **kwargs)
try:
var = Model.objects.get(*args, **kwargs)
except Model.NotFoundError:
var = Model.objects.create(*args, **kwargs)
Cython--
except maybe that with doesn't feel right
it's like C++ but Python and has less than Cython
No exceptions are problematic. There is quite a bit of erroring state in a real language
we should create a version of python that has no exceptions
an error just turns into a SIGSEGV
Do you call MemoryError an exception
except maybe that
withdoesn't feel right
@brazen jacinthaswould give the false impression that it's the same asexcept x as e
Go and Rust just abort, but I do not consider that a great solution to memory errors
I meant that a language could be restructured so that only "critical" stuff raises some kind of error
but that probably doesn't play well with dynamic typing
Haskell does that somewhat, but Haskell errors are objectively terrible.
I haven't interacted with the IOErrors in haskell, but I've seen that it's not the most pleasant thing
I guess it's trying to tell people that it's kind of a last resort
does an exception itself being raised cause any significant overhead?
Stack trace gets handled by something lower level i imagine, but how big is this cost
if a[0]:
val = func(a[0])
else:
pass
try:
val = func(a[0])
except Exception:
pass
hypothetical situation
I guess the approach depends on how likely it is that an error occurs
Handling is somewhat expensive when exceptions occur, but takes almost no time when it doesn't
What even happens, you do something unexpected -> in some way it raises an exception -> the interpreter keeps track where it happened and bubbles up the exception to where it is caught, along with it stack trace info (or if uncaught - some low level signal handles the unhandled exception cleans up and exits) and then handles the control back to the program?
or is there something more that happens underneath when an exception occurs?
That's pretty much the gist of it.
Does python handle the memory, or does C do that
ik that memory location is decided at runtime, but im not sure if the python devs had to develop their own way of interacting with memory or if c handles all that
Which Python implementation are you using? CPython? PyPy? Jython? IronPython?
@modern frigate this article might be helpful https://realpython.com/python-memory-management/
That site is so good. I can't read enough of their articles.
Thanks!
That site is so good. I can't read enough of their articles.
@unkempt rock Its free articles are pretty good, but it quickly becomes money hungry
I didn't even know they had pay articles. I know that they have some sketchy webdev techniques, like demanding your email address before providing you with the link to their GitHub for resources used in in guides. Things like that irritate me about them.
But they write good articles.
I emailed dan bader, who made the site to ask a simple question about the topic. His reponse was pretty rude:
Hey, JetDeveloping.
The article doesn't cover this question.
But they write good articles
Yeah
thanks for the article btw đ
@modern frigate Out of curiosity, why do you ask about memory management? You can write Python for years without having to worry about it. You may just be getting ahead of yourself.
I'd also look at this https://github.com/python/cpython/blob/master/Objects/obmalloc.c#L733 and then the whole page here https://docs.python.org/3/c-api/memory.html#the-pymalloc-allocator (Linked to pymalloc which is used by default)
@modern frigate Out of curiosity, why do you ask about memory management? You can write Python for years without having to worry about it. You may just be getting ahead of yourself.
@tropic fulcrum just curious.
is codeacademy good for learning phyton?
Yeah, it seems pretty legit
ik that memory location is decided at runtime, but im not sure if the python devs had to develop their own way of interacting with memory or if c handles all that
Well, the OS handles that in the end :)
I think they're asking if the cpython devs use their own memory allocator
CPython does have its own memory allocator, to more efficently use the blocks of memory given to it by the OS.
It's got lots of tricks as well - for instance a certain number of tuples are kept around when destroyed, so they can be reused when another is required of the same size.
+= on a str also cheats and modifies it in place if there's only one reference.
(on the topic of the interpreter mutating immutable objects, though not directly related to memory management)
I think it was you that I've seen mention it here before as well, but that's obviously because there's a difference between being described as immutable on the level of Python and on the level of the underlying interpreter/C.
Well, it's the same as (a, b) = (b + a, a) not actually creating a tuple, I think
it's a different kind of optimization
is it safe to depend on the ordering of dicts now đ¤
I mean - i get it's there - but is it here to stay
maybe that's a "how long is a piece of string" question, I was unsure whether people usually took this as a side effect or as something which was a fixed part of the language now
Isn't it more of an implementation detail than an actual feature?
it's guaranteed semantics as of 3.7
@unkempt rock it's obvious that the interpreter can do it, it's an interesting optimization that it does.
it's guaranteed semantics as of 3.7
And it was made guaranteed semantics because it was assumed that people would begin to depend upon it either way, so it was better to guarantee it and commit to backwards compatibility on it.
It's also just a nice feature
I have no idea what I'm doing wrong.
So in views.py (I'm using django), I have a function that uses subprocess to run a java file (that returns a string "Hello World from Java"). I'm using subprocess.check_output because it returns output as a byte string.
def executeJava():
javaoutputstring = subprocess.check_output("javac HelloWorld.java;java HelloWorld", shell=True, cwd="../")
print(javaoutputstring.decode("utf-8"))
return javaoutputstring
So I have another function that executes executeJava() and is supposed to post some string statements onto an html page.
def form_submit(request)
#this works because I see the output in terminal, but I want it on the webpage
executeJava()
context = {
'string' : "This is the context string passed from the view",
#'string2' : javaoutputstring,
}
return render (request, 'templates/index.html', context)
How can I print javaoutputstring onto the html page? Putting {{string}} prints out the statement on the page just fine, but not for {{string2}}
oh wait, forgot to put into a help thread, I'll ask there
yea, realized it after I posted it, but I'm desperate for an answer
not really an excuse, but anyway
you're printing the decoded string, but returning what I assume is the encoded bytes object
that looks like the problem
also you don't seem to be assigning the result of your function to a variable...?
and you have executejava and executeJava
honestly everything kind f looks like a mess.
so javaoutstring isn't technically a "string", its still in bytes format is what you're saying
if you have further queries you should open a help channel
cool, I realized I put it in the wrong channel right after I posted it, but thx for the help anyways
I don't really see how having dicts remember their insertion order is that useful but I guess I just haven't come across a case where it's useful
I think I've only sorted a list of the k-v pairs to print them and that's about it.
I guess it's good for... I don't know, people who expect dicts to behave like an array/list?
Also, why doesn't python like having variables start with a number?
ambiguities
If you start a token with 0x it will be read as an integer in hex format
you could have 1 be a valid identifier, or 1e3, or 0x1
Or if you do b instead of x it's binary
it's simpler to disallow them entirely than to account for all edge cases
Lgneous is right. You can use e to make exponentials.
it's also a common convention, so it's not gonna catch people off guard
I didn't even know you couldn't start a variable with a number until I came across it in a help channel
sigh because I'm cruising help channels instead of working
it's a lot easier when you're parsing the language if variables can't start with numbers
I forgot the use case, but remembering their order was extremely important. I was quite happy that whatever version of Python had dicts remember their insertion order.
At this point I think the only use for ordered dict is that the order affects equality comparison
At this point anyway
I thought it was 3.6 when it started
no, it's also optimized for different operations. OrderedDict has operations specifically to support reordering, which are more efficient than if you were to reorder things in a regular dict by removing an element and then re-adding it. This makes OrderedDict more efficient as an LRU cache implementation, for instance.
It also has extra methods specifically to support that use case - unlike dict, the popitem method of OrderedDict allows you to choose whether you want to pop the earliest or the latest item, and it has a move_to_end method specifically to support reordering.
https://docs.python.org/3/library/collections.html#ordereddict-objects describes the remaining differences.
I don't really see how having dicts remember their insertion order is that useful
@boreal umbra There are scenarios where people want an ordered mapping, and where it's useful to perform operations either based on the key or based on the order (and not always the same operations). An LRU cache is the most common example - you want to be able to look up cached values by key, but drop the least recently inserted items when you need to make room. Another might be representing the columns in a SQL result set or an Excel spreadsheet or something - after aselect col1, col2 from tableit might be reasonable to want to support accessing columns from the result set by either index or name. If you want to pass around the dict and access them by name, you can. If you want to unpack the columns immediately into their own variables, you can:
!e ```python
import sqlite3
def dict_factory(cursor, row):
d = {}
for idx, col in enumerate(cursor.description):
d[col[0]] = row[idx]
return d
conn = sqlite3.connect(":memory:")
conn.row_factory = dict_factory
for row in conn.cursor().execute("select 1 as 'A', 2 as 'B'"):
a, b = row.values()
print(f"row={row} a={a} b={b}")
@raven ridge :white_check_mark: Your eval job has completed with return code 0.
row={'A': 1, 'B': 2} a=1 b=2
in older Python versions that unpacking wouldn't have been safe or sane, and now it is.
Basically...
I don't really see how having dicts remember their insertion order is that useful
It isn't if you were already going to be using a dict. It's useful in cases where previously you couldn't use a dict, because you needed an insertion order preserving data structure, and you wound up having to use something likecollections.OrderedDictor roll your own like https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.Headers or the like, and now, in some cases, you can avoid rolling your own because if you usedictjust so it can give you the guarantee you need with much less work than writing some alternative class that wraps a dict and adds an ordering yourself.
hey guys. I'm trying to fetch the github repo link for a python package. what website can I send a request to?
wrong chat. See #âď˝how-to-get-help
That's not to say that werkzeug.datastructures.Headers could be implemented as just a dict now - it still can't, because in addition to needing to preserve order, it needs another feature that dict doesn't provide - allowing multiple values for the same key (because HTTP headers are weird). But it's still a good example of a real-life scenario where an order-preserving mapping is needed.
different structures with different properties are for different tasks, if preserved order is built-in at no extra cost, all i see is a plus
Java offers HashMap vs TreeMap vs LinkedHashMap for example - merely structures with different properties, some offer ordering, some allow null values, some offer sync support for multiple threads etc
Hey @oblique wyvern!
It looks like you tried to attach file type(s) that we do not allow (.xlsx). We currently allow the following file types: .3gp, .3g2, .avi, .bmp, .gif, .h264, .jpg, .jpeg, .m4v, .mkv, .mov, .mp4, .mpeg, .mpg, .png, .tiff, .wmv, .svg, .psd, .ai, .aep, .xcf, .mp3, .wav, .ogg, .webm, .webp.
Feel free to ask in #community-meta if you think this is a mistake.
@oblique wyvern Not the right channel, check the channel topic đ also see #âď˝how-to-get-help if you need help, however we cant help you with graded work as part of rule 5
@oblique wyvern Not the right channel, check the channel topic đ also see #âď˝how-to-get-help if you need help, however we cant help you with graded work as part of rule 5
@radiant fulcrum Sure
Does python do runtime optimizations for list slicing in for loops?
example:
for x in arr[1:]:
print(x)
Would this be optimized, or would a new list be copied and gc'd right after the loop?
If so, what happens when this is a thing:
i = 1
for x in arr[1:]:
print(x)
arr[len(arr)-i] = "foo"
i += 1
I would assume that there is no optimization, but I can't know for sure
There is absolutely no optimalization in the case of a name, as there is no guarantee it is a list
You are not allowed to use that command here. Please use the #bot-commands channel instead.
I'm trying to find the source code for os.symlink in order to understand what is going on under the hood, specifically on the Windows platform. I quickly went into this file: https://github.com/python/cpython/blob/master/Lib/os.py ... but this does not define a symlink function/method, which leads me to believe the definition is in some c extension or similar. Can anyone explain to me how to navigate the code base?
As it is platform specific code, it definitely has to in some way interact with the os on a low level, on linux for example very likely to directly interact with low level system calls like symlink, so i definitely imagine it's written in C
It imports them from here https://github.com/python/cpython/blob/master/Modules/posixmodule.c with the star imports at line 55 and 75
@peak spoke Maybe this is a better channel for discussing the import stuff
It seemed like you meant that the path maybe wasn't defined there. However, if we consider that we do something like this:
import os
print(os.path)
# The main part of the program goes here.
import sys
In this scenario, python will execute the entire program without knowing the path
If, on top of that, we put an import for something that requires the path in between, we're out of luck
Something like this:
import os
print(os.path)
import something_in_the_same_dir
import sys
What do you mean it doesn't know the path? sys.path is initialized internally before your script can take control
@peak spoke I thought you said that the path was initialized after stdlib imports and that fact meant that it imported time instead of the local time?
Did some testing locally and when ran directly time was not in sys.modules, to me it looks like it may be a side effect of how C modules that don't share the exact name are exposed to the interpreter (timemodule.c in this case) but I don't know enough about the internals to be sure there.
But anything that is used by the interpreter on initialzation (sys, marshal, some os specific stuff, importlib, anything from site in most cases etc.) won't ever be executed by you on imports because it'll be cached in sys.modules.
sys.path is populated with some base things as a part of the initialization process when the interpreter is executed before much else happens and then if it's run with site that does other things; this all happens before python gets to actually executing your script and its imports. Then those imports first look into sys.modules and use the module there, for the aforementioned packages they'll always be there in a normal environment so the actual import machinery doesn't execute. Then if I deducted correctly it may look into some of the renamed C modules like time, but didn't investigate much there, and if that neither of those find the module (and maybe something else) it goes through your sys.path to find the module with the name you imported which usually contains the directory of the file itself
It imports them from here https://github.com/python/cpython/blob/master/Modules/posixmodule.c with the star imports at line 55 and 75
@peak spoke hey thanks, I see now! đ
Mhmm satisfying https://youtu.be/belS2Ek4-ow
Python has lots of amazing features, but to me, list comprehensions are #1.
Support this channel by supporting our sponsors.
Click links, get discount, buy stuff:
Eight Sleep: https://eightsleep.com/lex
@teal yacht This pep and its discussion may interest you, it'll remove some unecessary modules that are no longer useful. In its current form, wave will remain (if the pep goes through) for the reason they gave in it
!pep 594
đ
and yeah i wasn't necessarily talking about wav, that's just the first i remembered from that section, i was more thinking about the sun au format or like colorsys
In the end those modules don't affect the user in almost any way beyond the stdlib list being a bit messy
and add maintenance burden to the python core devs
Haven't looked at other modules, but the last commit to wave specifically was a typo fix more than half a year ago, so not a huge burden there
plus some of them are outright redundant or obsolete or both
wave isn't on the removal list
(The first message was as a response in #python-discussion for why wave (and others) is in the stdlib so looked at that)
Some of those definitely are redundant at this point, but there was quite a bit of discussion in the mailing list for keeping some of the modules that are currently proposed to be removed in the PEP
ah, yeah
(here's the image I posted, wav is highlighted because I used control-f, I was referring to the entire section, not wav specifically, and in fact most of these modules are proposed to be removed in that exact pep)
all except wav and colorsys are in the pep
It makes sense.
Hello. I wanted some help understanding cython. I want to make my code run faster and cython is the recommended way to go. However, I can't seem to find any suitable tutorials for it. And I don't see any tutorials that show how we can deal with dictionaries, lists, tuples and numpy in cython
have you looked at https://cython.readthedocs.io/en/latest/src/tutorial/cython_tutorial.html ?
(also I think the preferred channel would be #c-extensions )
https://cython.readthedocs.io/en/latest/src/tutorial/ more tutorials here
@subtle whale https://github.com/cython/cython/wiki
This seems to mention to quite a few of those you mentioned.
What pros and cons do ORMs have? I have never tried using them, and the idea of it seems a bit weird architecturally to me.
it allows you to abstract over rows in your database by referring to entities/objects instead of doing database queries everywhere
really full-featured ORMs like django actually set up and manage database tables for you
sqlalchemy is a little more flexible, it can do things like generate classes based on an existing database
it can also abstract over specific quirks in your chosen rdbms and avoid writing raw sql, but that's arguably a downside and not a benefit depending on your attitude and needs
i've managed to avoid sql for so long and now i'm scared to try, ignorance is bliss, maybe
its a big topic but its not that bad
the hardest part is learning about the different kinds of joins, and muddling through some of the terminology
it's one of those must have skills for almost any kind of technical role
that too
especially since you're a data guy @magic python
i use sqlite for ad-hoc data stuff all the time
and ive used postgres for some pretty big data storage/processing
Postgres is â¤ď¸
@paper echo yea, it's bad. All I ever need is select * from blah then I'm in pandas... Data isn't large (survey), but it's negligence not too have spent time with it.
if you can do select and join you're not doing bad
I've been tracking some big parse trees from bs4 that weren't being collected by the gc (Looks like it's because of bs4's design if I didn't miss anything) and found out that a manual call to gc.collect removes them right away. How does gc itself work with the automatic collections? Thought that things like that would be caught by it
@peak spoke gc is for collecting cyclic structures (A refers to B, which refers to A, but nothing else refers to either of them)
Yep, but as I understood it it runs automatically in the background, why is a manual call to collect necessary?
it runs periodically
In that case, is collect more thorough than the periodic checks?
it's not more thorough, but it's happening sooner.
I let the app sit for a few minutes, with nothing happening; then the manual call immediately cleared it up
it's not time-based, it's based on how many allocations and deallocations have happened.
It's an async app so it is doing some things in the background during that time, if I don't figure out how to prevent the reference cycles (they're inherent to the lib for example) would I just be stuck with calling it manually or is there a better alternative
@peak spoke first, do you have to do anything?
Yes, it's leaving up to 50 MB uncollected for each object
but what is the actual problem? What bad thing happens?
Well, it can lead to running out of memory if left alone
but the gc should kick in if left alone.
Doesn't seem to want to do that
Well, I'll see how it goes; the project is local so I'll be able to deal with it manually when it starts becoming an issue
Is there some kind of document I could read into for how gc works internally or would the source code be the best place for that?
Context? Which gc are we talking about? Pythons?
@peak spoke the gc page in the docs has some details.
whats better to start coding? powershell or python?
Depends on the task.
python for sure
But, Python has a much larger reach.
powershell will be too much investment for the stuff you will learn
i mean.. you would never architect object oriented stuff in powershel
You actually would
powershell was designed to be an OOP alternative to other shells
It's just a shell script language, so you would typically not write as big programs as you would in python or some other general purpose PL
so you would typically not write as big programs
corporations: "LALALLALALAL i cant hear you -_-"
large begrudgingly open source projects as well, I've seen some doozies
What are the hardest python lines of code you can think of?
@tardy geode what do you mean?
I mean code is code, some is simple and some is hard.. so what's the hardest code block you can think of right now?
goto #esoteric-python
Results, Rounds: 1000
json | DUMPS: 0.0042ms, LOADS: 0.0038ms
ujson | DUMPS: 0.0014ms, LOADS: 0.0012ms
orjson | DUMPS: 0.0009ms, LOADS: 0.0012ms
hyperjson | DUMPS: 0.0022ms, LOADS: 0.0029ms```
hard to... read-write, understand..?
Interesting to see ujson's serialization is quicker than its deserialization while all the others are the other way round
What about BSON?
What's that? Binary json?
Sounds like it
There's nothing more obnoxious than dealing with a binary file you don't have a parser for
(I'm not saying it's the case here, I just meant in general)
msgpack đ
