#internals-and-peps

1 messages · Page 60 of 1

brazen jacinth
#

don't we all 😛

paper echo
#

But yes I still like __all__ for indicating "use this"

#

That said i dont mind using underscores for typevars, its less about cluttering the namespace for imports and more about being visually distinct

boreal umbra
#

What do you do if you're in a generator and you realize you can't yeild anything from that iteration?

#

Can you just do a blank yeild?

#

Or yield

#

I can never remember the order of the e and i

flat gazelle
#

if you just do yield it is the same as yield None

boreal umbra
#

Damn

flat gazelle
#

well, if you yield there has to be some value. You could just do continue and go to the next iteration perhaps

boreal umbra
#

Would be nice if you could somehow pull the next item that the caller would have given you

deft pagoda
#

you can send to generators

boreal umbra
#

This is an issue I'm having at the lowest level generator

#

I think

deft pagoda
#

continue?

#

hard to guess your use-case

boreal umbra
deft pagoda
#

whenever i see something like this:

    for token in arg1_topk_tokens:
        new_sent = text[:arg1_start] + token + text[arg1_end:]
        new_arg1 = copy(rel.arg1)
        new_arg1.spans = [(arg1_start, arg1_start + len(token))]
        new_arg1.mention = token

        new_offset = len(token) - len(rel.arg1.mention)

        new_arg2 = copy(rel.arg2)
        new_arg2.spans = [(arg2_start + new_offset, arg2_end + new_offset)]

        new_rel = brat_data.Relation(rel.relation, new_arg1, new_arg2)
        yield PseudoSentence(new_rel, new_sent)

    for token in arg2_topk_tokens:
        new_sent = text[:arg2_start] + token + text[arg2_end:]
        new_arg2 = copy(rel.arg2)
        new_arg2.spans = [(arg1_start, arg1_start + len(token))]
        new_arg2.mention = token

        new_offset = len(token) - len(rel.arg2.mention)

        new_arg1 = copy(rel.arg1)
        new_arg1.spans = [(arg2_start + new_offset, arg2_end + new_offset)]

        new_rel = brat_data.Relation(rel.relation, new_arg1, new_arg2)
        yield PseudoSentence(new_rel, new_sent)

i immediately want to shrink it -- repeated code

boreal umbra
#

That's part of my plan

#

I just didn't want to think that hard about it yet.

deft pagoda
#

is that where you want to skip something or from the yield from

boreal umbra
#

See new_sent? If the word represented by token is the wrong part of speech then I can't use it.

#

So there could potentially be nothing to yield in a given call

deft pagoda
#

do you want to check PseudoSentence?

#
if yielded_something := PseudoSentenct(...)
    yield yielded_something
#

might need a __bool__ method on PsuedoSentence then i guess

boreal umbra
#

I think it would be True by default

deft pagoda
#

yes, by default

boreal umbra
#

It's a dataclass

deft pagoda
#

you can add a __bool__ method though

boreal umbra
#

Oh I sre

#

Hmm

#

I guess I could also yield the nones and filter them latet

#

Later

deft pagoda
#

can even use filter with None as first argument

boreal umbra
#

Also the yield from statement wasn't working as expected

deft pagoda
#

ever used .send for a non-coroutine?

boreal umbra
#

If you yield from another generator, isn't that the same as yielding each of the items it generates individually, so that you just have one stream

#

Never used it at all.

deft pagoda
#

i used it when iterating over ordered ranges

#
def replace_least_upper(self_set, other_set):
    """A helper iterator for the __and__, __or__, and __xor__ methods of RangeSet, this will call next
    on the correct RangeSet iterator (the one that last yielded the range with the least `upper` bound).
    This incurs some overhead, as we repeat comparisons, but it hopefully makes RangeSet dunders easier to
    follow.
    """
    self_ranges = iter(self_set)
    other_ranges = iter(other_set)

    self_range = next(self_ranges, None)
    other_range = next(other_ranges, None)

    carry_over = yield self_range, other_range

    while self_range and other_range:
        if self_range.upper == other_range.upper:
            self_range = next(self_ranges, None)
            other_range = next(other_ranges, None)
        elif self_range.upper < other_range.upper:
            self_range = next(self_ranges, None)
            if carry_over:
                other_range = carry_over
                yield
        else:
            other_range = next(other_ranges, None)
            if carry_over:
                self_range = carry_over
                yield

        carry_over = yield self_range, other_range # send range that needs to be carried

    if self_range:
        yield self_range
        yield from self_ranges
    elif other_range:
        yield other_range
        yield from other_ranges
boreal umbra
#

I have to step out but I'll take a look at this 👍

torpid narwhal
#

Is there a reason why python doesn’t support tail call optimization? Most of the reasons I read are, “well, it’s my pythonic to do for or while loops instead of recursion.” To be honest, that seems like a lazy response.

grave jolt
#

Third, I don't believe in recursion as the basis of all programming. This is a fundamental belief of certain computer scientists, especially those who love Scheme and like to teach programming by starting with a "cons" cell and recursion. But to me, seeing recursion as the basis of everything else is just a nice theoretical approach to fundamental mathematics (turtles all the way down), not a day-to-day tool.

#

Although recursion is useful sometimes. One of my favourite tail-recursive functions is the basic regex matcher from K&R.

torpid narwhal
#

Oh. It’s not appropriate for all use cases. But there are times where it does the trick.

grave jolt
#

True.

#

Although, funnily enough, the C compiler doesn't eliminate tail recursion there

torpid narwhal
#

Great article! Thank you.

#

I was worried when the short answer was “it’s not pythonic”, but it won me over after that.

grave jolt
#

I myself don't really like this term. It's like shutting down the argument by calling someone an *-ist. But sometimes it is appropriate
rhettinger shows a good example in this talk: https://www.youtube.com/watch?v=wf-BqAjZb8M

#

TL;DW: even though a piece of code complies with PEP8, it's a clumsy interface that can utilize some features of python; so it's better to write a wrapper and unjava that library

torpid narwhal
#

I was doing some heavy computation work in computer vision for my old company, and there was a function that has recursion based. Every alternative couldn’t deliver the performance not accuracy we wanted. In a perfect world (with no deadlines), I would have found an alternative solution. But given the deadline, I left that code in.

I’ve just been thinking about that code lately and how “un-pythonic” it was, and tryin to reconcile what I know now. I was a super junior dev who learned Python by a lot of code camps and what not where things were simple. OOP code was the way to go and the only way to go. However, as a more experienced dev who has seen more stuff, I’ve come to appreciate the approaches that are “not pythonic.” I’ve at least learned some interesting tricks.

grave jolt
#

haskell is not very pythonic, and I love it for some of that

torpid narwhal
#

Yeah. I get that! I’ve just done a lot of thinking back on my journey with Python. Currently interested in Functional programming (my current job is doing a lot of ETL pipelines concurrently, and hoe to run all these jobs efficiently and utilize parallelism), and taking what I have learned and apply it to Python.

#

I am personally happy about the pep about pattern matching. I’ve seen it in other languages, and I think it’s super cool. But, a large (at least the loudest) dissent to that pep is that it’s “not pythonic”.

#

^I would claim a help channel.

grave jolt
oak stirrup
#

okay thank you

charred barn
#

i was super interested in the pattern matching pep but was disappointed the matches aren't block scoped and that it's not an expression. i guess that's consistent with python though

torpid narwhal
#

I’ve heard that criticism too. And it’s very valid. I definitely see those benefits.

charred barn
#

like it feels really gross to me that matches conditionally bind and leak passed the pattern match

#

seems like list comprehension variables leaking all over again

grave jolt
#

!e

e = 1
try:
    1/0
except Exception as e:
    pass
print(e)
fallen slateBOT
#

@grave jolt :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 6, in <module>
003 | NameError: name 'e' is not defined
torpid narwhal
#

Oof.

charred barn
#

specifically i think this is a mistake

match greeting:
    case "":
        print("Hello!")
    case name:
        print(f"Hi {name}!")
if name == "Santa":      # <-- might raise UnboundLocalError
    ...                  # but works fine if greeting was not empty
torpid narwhal
#

Weird.

tawny shoal
#

@torpid narwhal If you're interested in non-pythonic ways of doing things I recommend taking a look at data-oriented programming and composition over inheritance

#

Basically, check out Rust lol

torpid narwhal
#

I like...how bold it is. I don’t mind switch statements (many articles on dev.to are all about hating them), but I don’t think that’s powerful enough for it to be added to python. But pattern matching seems very powerful and bold. I like that though process of thinking about more bold things.

#

The data oriented part is cool. I try to not do inheritance.

tawny shoal
#

Yeah exactly

#

Rust doesn't do inheritance

charred barn
#

without being an expression i'm curious how useful these will be in practice

tawny shoal
#

It does composition instead

charred barn
#

all the examples are just printing

#

or returning from a function

grave jolt
#

!e

# PEP8 thrown out of the window for compactness
class LinkedList:
    def __init__(self, value, rest):
        self.value, self.rest = value, rest

    @staticmethod
    def from_iterable(iterable):
        acc = None
        for x in iterable: acc = LinkedList(x, rest=acc)
        return acc

def my_sum(list_, default=0):
    if not list_:
        return ("return", default)
    return ("call", list_.rest, default + list_.value)

def tail_call(f, *args):
    command, *args = ("call", *args)
    while command != "return": command, *args = f(*args)
    return args[0]

ll = LinkedList.from_iterable(range(3000))

print(tail_call(my_sum, ll))
charred barn
#

i guess you can just wrap the match in a function with returns to make it act like an expression

fallen slateBOT
#

@grave jolt :white_check_mark: Your eval job has completed with return code 0.

4498500
grave jolt
#

Actually, tail-recursive functions might play nicely with the async world.

#

If you have a tail-recursive function, you can make it less blocking by awaiting on each step.

#

So you can run a few of them concurrently.

#

I remember how I reinvented coroutines while making a game in Python. My enemies used A* for pathfinding, and running it for multiple enemies at the same time was expensive. So I made the algorithm yield on each step. This way I was able to control how fast the pathfinding is happening. I actually turned it into a feature: more 'intelligent' enemies were finding the path to you faster.

#

so if you do

async def tail_call(f, *args):
    command, *args = ("call", *args)
    while command != "return":
        await asyncio.sleep(0)
        command, *args = f(*args)
    return args[0]

your blocking tail-recursive function is now automagically not so blocking

tawny shoal
#

I do that in production code actually

#

But I definitely plan to get rid of it ^^'

grave jolt
#

👀

grave jolt
#

@torpid narwhal I'm filing a DMCA complaint 👀

torpid narwhal
#

Lol

#

You said it so succinctly

unkempt rock
#

whats the difference between repr and str__

last pollen
narrow kettle
#

man what a section

#

" i do not believe in debuggers"

raven ridge
#

It's an entirely fair point that debuggers are only handy for failures you can reproduce, and that logging allows you to diagnose errors that happen sporadically or under unknown conditions

narrow kettle
#

that part isnt wrong, the "i dont know how to use one and dont use one"

#

is the problem

raven ridge
#

yeah.... that's not ideal, heh

paper echo
#

How often is a failure truly non reproducible?

raven ridge
#

oh, rarely, but it's really common that a failure has occurred and you haven't yet figured out how to reproduce it yourself.

narrow kettle
#

logging is great lol, its a necessity

#

logging and debugging solve two different problems imo

torpid narwhal
#

I don't use a debugger and don't know how to use the big ones for Python. I remember using them for C# and VBA when I was in school. Not gonna lie, python is pretty well designed to get yourself out of jams. print statements and logging can get you a lot of the way there. And, I find python exceptions to be pretty good. (I get more annoyed when I deal with extensions compiled in C, but thats another story.) For 80-85% of my use case, I have never felt like I needed a debugger.

#

And the times I do, I feel like I can get there with other means. Oh...I love ipython3 (ipython > python's built in repl). Load up the code that is iffy and walk through it there.

narrow kettle
#

man not using the debugger in c# code sounds like a 7th layer of hell

#

but fr, learn the debugger

#

it is your friend

#

prints dont really help you when stdout is flying by anyway

#

i dont understand the aversion to debugging, its literally pausing your code and reading variables, the same thing that prints do. just way faster and easier

torpid narwhal
#

Its more or less not an aversion to it, than learning something new that might improve my efficiency for a few use cases when I can do other things that get me there.

narrow kettle
#

it will 100% improve your effeciency

#

print statements cant come close to inspecting an entire objects nested structure

torpid narwhal
#

I am not saying I will never use one. But, I haven't personally found a situation where I was so stumped where I needed to take time out of my schedule to learn it.

narrow kettle
#

i mean if your just writing scripts then ya i get that. but for any program debugging is going to be invaluable

spiral willow
#

I do it all the time. Even to just pick through Class returns

torpid narwhal
#

I am open to it, and I will keep it on the table. But, I can get buy with simple stuff.

narrow kettle
#

i debug constantly, its so much easier to read all the objects

torpid narwhal
#

Really, as long as I use the logger and print the line and class/func name, I get where I need to go.

narrow kettle
#

tbh alot of the bugs i fix now woudnt really be possible with print statemnets

torpid narwhal
#

I am glad that workflow works for you.

narrow kettle
#

just for sure learn the debugger at some point, its quite literalyl walking through your code line by line

raven ridge
#

If you use the breakpoint() call in your code to drop into the debugger at a particular point, the only commands you need to know are p to print stuff and c to continue execution.

#

It's not a ton to learn

gleaming rover
#

i dont understand the aversion to debugging, its literally pausing your code and reading variables, the same thing that prints do. just way faster and easier
@narrow kettle same logic as manual testing instead of writing tests IMO

swift imp
#

How do you append to the docstring of a module

gleaming rover
#

uh

#

module.__doc__ += 'something'?

narrow kettle
#

@gleaming rover i KINDA get that cuz writing tests is boring and time consuming, the debugger is LITERALLY both faster and more comprehensive then print statements

swift imp
#

Oh so module is a thing in the module

gleaming rover
#

no

torpid narwhal
#

For me....its just so low on the stack of things to read/learn that I have never gotten around to it.

gleaming rover
#

module is a reference to the module

narrow kettle
#

i mean you could learn it in about 5 mins @torpid narwhal its literally just set a breakpoint and click run, the mouse over variables

#

thats it

gleaming rover
#

How do you append to the docstring of a module
@swift imp maybe you wanna tell us more about your problem

narrow kettle
#

way faster then writing a print statement then searching through std out for that print

torpid narwhal
#

I don't print much to std out. Since, that isn't a realistic problem for me.

narrow kettle
#

i mean you dont even have to look through your logs

#

its instant, its quite literally the simplest thing you could imagine

swift imp
#

Basically I have a bunch of int sub classes for constants, so that they have doc strings and I want to append each of those doc strings to the module docstring at the end of module so that they show up in help()

#

Rather than me typing out the same doc string twice

#

Get what I'm saying?

narrow kettle
#

you could never log all this

gleaming rover
#

Basically I have a bunch of int sub classes for constants, so that they have doc strings and I want to append each of those doc strings to the module docstring at the end of module so that they show up in help()
@swift imp yeah, just __doc__

#

an object's __doc__ attribute holds its docstring

swift imp
#

But is __doc__ in the namespace of the module ?

gleaming rover
#

perform whatever preprocessing you think is necessary in the module itself, then just assign the result to __doc__

#

...yes?

swift imp
#

I wasn't sure if you had to access it through like vars() or something

#

I've never done it before

torpid narwhal
#

nope. <your object>.__doc__.

#

Pretty nice actually.

swift imp
#

So at the module level module.__doc__, cool, thanks

gleaming rover
#

no, just __doc__

swift imp
#

Oh

gleaming rover
#

because it is an attribute of the module itself

swift imp
#

Even bettet

gleaming rover
#

just like if you wanted to have a module attribute some_attribute in a module my_module, in my_module.py you would execute some_attribute = 1, not my_module.some_attribute = 1

torpid narwhal
#

yeah. I was a bit confused on where you wanted to access it. But, its pretty simple.

swift imp
#

Cool

#

Wish python made it easier to document variables but whatever

torpid narwhal
#

What do you mean?

swift imp
#

At least with respect to help but I understand why variables don't have doc strings

gleaming rover
#

huh

swift imp
#

Like you can't add a docstring to a variable and have it show up in help()

#

I wish you could

narrow kettle
#

ya i have also wanted that

#

i just use properties

swift imp
#

Yeah but in my case I have literal constants

#

Singleton's if you will

narrow kettle
#

uhh

#

thats not a singleton

swift imp
#

But they're special constants

narrow kettle
#

i dont follow

#

you just said a bunch of stuff that doesnt make sense in context lol

swift imp
#

Like at work we literally have a module of conversion factors , and special constants, think like accerlation of gravity or km/s to knots

gleaming rover
#

I think the point is more that

#

those aren't really what one would normally understand as "singletons"

swift imp
#

Well I've pretty much made a Singleton

narrow kettle
#

is it a class?

swift imp
#

Class

narrow kettle
#

so its a singleton class

#

with constant variables inside?

swift imp
#

Just to encapsulate that constant and it has a docstring

narrow kettle
#

is that what your saying?

swift imp
#

Yes

narrow kettle
#

ya just use properties

#

thats what i do

#

docstring works here

gleaming rover
#

Well I've pretty much made a Singleton
@swift imp but why?

swift imp
#

Yeah but then you have to use a dot access

#

Bc I want it to act like a float or int

#

I don't want to have to access it through dot access

#

I don't think I'm explaining myself clearly

narrow kettle
#

Yeah but then you have to use a dot access
you have to do this for the variables anyway

#

usage wise a property would change nothing

#

you would consume the class in exactly the same way

#

i dont fully understand what you are saying, if its a class you have to do .constant anyway

swift imp
#

No you don't

narrow kettle
#

...yes oyu do

swift imp
#

You store the constant and use __new__ to return it

#

No dot access at all

narrow kettle
#

show an example

gleaming rover
#

^

narrow kettle
#

something feels weird about this

gleaming rover
#

I feel like words are being used in ways that do not comport with their commonplace meanings

#

@unkempt rock try a help channel.

narrow kettle
unkempt rock
#

Oh

#

okay

swift imp
#

Except I'm hardcoding the value in __new__

gleaming rover
#

so basically you're saying something like from module import ConversionFactor and then ConversionFactor() * some_value?

swift imp
#

It's not exactly a Singleton but pretty much

raven ridge
#

so... it's a singleton instance of some class?

narrow kettle
#

ehhhh, idk if id call that a singleton

#

maybe kinda?

swift imp
#

It's almost, pretty much

narrow kettle
#

why not just add the doc string to the class then?

swift imp
#

I do

#

But Im also instantiating the Singleton in the module

narrow kettle
#

class FloatWithUnit(float):
    def __new__(cls, val, unit):
        return float.__new__(cls, val)
    def __init__(self, val, unit):
        self.unit = unit
    def __str__(self):  
        return '%g %s' % (self, self.unit)
    def __repr__(self):
        return self.__str__()

foo = FloatWithUnit(..)
^ you want the docstring on this?
raven ridge
#

but at that point what you have is an instance, and an instance doesn't have a docstring.

narrow kettle
#

is that what your saying?

raven ridge
#

a class has a docstring, but once you've called the class to instantiate it, you've got an instance, and if you keep the instance around but not the class you've thrown your docstring away.

#

Sphinx lets you document globals and attributes, though, even though they can't have docstrings.

swift imp
#

But since I have like 20 of these classes, the doc string of the module is really long, since they're subclass of float, I want the data info at the top of the help. Hence I want to iterate over all the classes in the module and programmatically append their docstring to the module docstring

gleaming rover
#

more accurately, string literals occurring after top-level assignments are termed "attribute docstrings" and not recognised by the Python compiler

#

but may be used by third-party tools

swift imp
#

I'm pretty sure I can accomplish what I want

#

It's just hackish

gleaming rover
#

yes, just add to __doc__

raven ridge
#

Hence I want to iterate over all the classes in the module and programmatically append their docstring to the module docstring
you can do that, though depending on which tool you're using it's entirely possible that it won't be able to deal with the non-constant __doc__. It might show up in help(), but other tools may not be able to find it.

#

depends how they work, and whether they execute the code or merely parse it.

swift imp
#

I would hope spinx executes it

raven ridge
#

it does not.

swift imp
#

Well that sucks

raven ridge
#

well, actually - scratch that, it deends.

swift imp
#

Stack overflow says it does

raven ridge
#

sphinx autodoc does import the module, so whatever you do at import time should be reflected.

swift imp
#

Cool

#

So then it will work

#

I figured as long as I don't do it inside function calls or methods it would work

raven ridge
#

though again - sphinx autodoc supports docs on global variables, too

#

so your hack to get it into the module's __doc__ is unnecessary if it's Sphinx that you're worried about.

swift imp
#

No it's help

#

It's alphabetized so Data section comes after Classes

#

And I have a butt load of float subclasses

#

So you have to scroll super far down to see the constants

#

I want them at the top

raven ridge
#

help isn't very heavily used.

swift imp
#

I use it all the time

raven ridge
#

modifying __doc__ will be reflected by it, but most people will never, ever run it. 🙂

swift imp
#

Idk I prefer help

#

It's fast

raven ridge
#

I mean, that's cool, and I'm not telling you not to, and if it's for you that's fine. I'm just saying that most people don't use it, or even know it exists.

swift imp
#

I should also note, I work on a system not connected to the internet

#

So it's faster than going over to a different station that has internet

#

Now that I'm thinking about it

raven ridge
#

even on a system like that I'd sooner use Sphinx and http.server - but, shrug

swift imp
#

Would I be able to generate pandas documentation

#

Like the html

#

Bc we have Firefox to browse html

raven ridge
#

yep

swift imp
#

Fuck

#

Lol

#

I'm gonna have to talk to someone at work about this

raven ridge
#

actually, shouldn't even need http.server, you can just use ff with a file:// URL

#

looks like it's just clone the repo, and make doc

swift imp
#

Oh so if I have the package through say anaconda, I can't make it?

raven ridge
rigid snow
#

Has anyone here used Rdpy?

#

ttps://libraries.io/pypi/rdpy

#

Please @ me

mint forge
#

!library

#

!resources

fallen slateBOT
#
Resources

The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.

grave jolt
#

!e

async def main():
    await ~f
fallen slateBOT
#

@grave jolt :x: Your eval job has completed with return code 1.

001 |   File "<string>", line 2
002 |     await ~f
003 |           ^
004 | SyntaxError: invalid syntax
grave jolt
#

Why is that a syntax error?

#

!e

async def main():
    await (~f)
fallen slateBOT
#

@grave jolt :warning: Your eval job has completed with return code 0.

[No output]
grave jolt
#

but this works

torpid bridge
#

does await bind harder than ~?

north root
#

await probably has higher precedence, yeah

torpid bridge
#

it does

#

only things await is weaker than is indexing and function calls

grave jolt
#

but return ~f works

torpid bridge
#

return isn't an operator

grave jolt
#

true

torpid bridge
#

lambda ~f works, but that's because lambda is low pref

grave jolt
torpid bridge
#

The power operator binds more tightly than unary operators on its left; it binds less tightly than unary operators on its right., this is weird

#

It makes sense, but still wierd

#

means -4**3 is -64, but 4**-1 is -4

foggy swift
#

is the third line here wrong

#

?

torpid bridge
foggy swift
#

oh

#

ok

#

tysm

slim island
#

@torpid bridge neither of those examples is correct. You'd need to do 4^0. 25 to get root 2 out. AFAIK it behaves the same way you'd expect ^ to in normal maths

pseudo cradle
#

Yeah, that's confusing

pearl river
#

@slim island 4**0.5 is 2.0. Because, well, that's what the square root of 4 is.

slim island
#

Yeah. I realised and changed it

torpid bridge
#

ah, bleh

pseudo cradle
#

Let's get into imaginary numbers!

pearl river
#

4**-4 is 1/(4**4)=0.00390625, though, yeah.

torpid bridge
#

fixed

pearl river
#

4**-3 isn't sqrt(2) either 😛

pseudo cradle
#

I was about to say

torpid bridge
#

right

#

that's 4**1/3

slim island
#

N^-K is the same as 1/(n^k)

pearl river
#

no?

#

sqrt(2) would be 4**(1/4)

torpid bridge
#
>>> 4** (1/3)
1.5874010519681994
pearl river
#
In [64]: 1.5874010519681994**2
Out[64]: 2.519842099789746
torpid bridge
#

oh, bleh

pseudo cradle
#

It's okay, life math is hell

torpid bridge
#

yeah ._.

slim island
#

You've got the cube root

torpid bridge
#

I should just use !e next time

slim island
#

I did have to go to bot commands to make sure I understood correctly myself

unkempt rock
#

im following Automate the boring stuff with python course he wrote this program so i copied it and it says this

torpid bridge
#

@unkempt rock you'd be better served asking in a help channel via #❓|how-to-get-help . This channel is for more advanced discussion relating to the python language itself

unkempt rock
#

ok

grave jolt
#

@unkempt rock You are missing a closing parenthesis ) at the end. If you have some quick question, you can also ask in #python-discussion, although you might be buried in the traffic

unkempt rock
#

yay it works now

snow perch
#

hellp

#
class foodAd:
    def__init__(self,tybef='VitaminC',helpWith=["CoronaVirus"]):
        self.__tybe=tybef
        self.__helpWith=helpWith
    def__str__(self):
        return('Use'+self.__tybe+'to help with'+ str(self.__helpWith))
    def addHelp(self,malady):
        self.__helpWith.append(malady)
a=foodAd()
a.addHelp('Cpld')
print(a)
#

this code

#

the output is error

#

because of the a???

pearl river
grave jolt
#

Just wanted to throw a quick idea

#
from typing_extensions import TypedDict as D
SqlParam = Union[Dict[str, Any], Tuple[Any, ...], D]

Q = TypeVar("Q", bound=SqlParam)
U = TypeVar("U", bound=Optional[tuple])
class Query(str, Generic[Q, U]): pass

GET_USER = Query[Tuple[str], Tuple[int]]("SELECT uid FROM users WHERE name=%s")
GET_NAME = Query[D("", {"uid": int}), Tuple[str]]("SELECT name FROM users WHERE uid=%(uid)s")

def do_stuff(q: Query[Q, U], arg: U) -> U:
    ...
radiant fulcrum
#

wouldnt that be harder than just making a set of constant queries

grave jolt
#

What do you mean?

#

The queries are constant.

#

It's just that the linter is able to ensure that you're passing the correct parameters in the correct order.

#

Or perform type inference and infer the return type from the query you're using

#

So this will typecheck:

(user_uid,) = do_stuff(GET_USER, ("alice",))
(name,) = do_stuff(GET_NAME, {"uid": 42})

(and in addition user_uid and name are inferred to be int and str respectively)
and this won't:

(user_uid,) = do_stuff(GET_USER, (111,))
(name,) = do_stuff(GET_NAME, {"uid": "bob"})
zealous oriole
#

apparently this:```py
def file_paths(directory, match_string, extension):
for root, sub_dirs, files in os.walk(directory):
for file in files:
if fnmatch.fnmatch(file, f"{match_string}.{extension}"):
yield os.path.join(root, file)

is faster than this:```py
def files(directory, extension, keyword=""):
    for file_path in glob.iglob(f"{directory}\\**\\*{keyword}*.{extension}", recursive=True):
        yield file_path
#

0.0027390999999999943
0.0016957000000000083

#

are the respective times

tawny shoal
#

makes sense to me

zealous oriole
#

why

tawny shoal
#

iglob is powerful but not necessarily as fast as fnmatch

zealous oriole
#

oh so fnmatch is pulling the speed here?

tawny shoal
#

wait it's the other way around... okay, I'm confused too

zealous oriole
#

cuz os is a big lib

tawny shoal
#

Idk if that's the issue

zealous oriole
#

hmm ok

#

u can test it too

tawny shoal
#

Python doesn't really care about the size of a package a function comes from

zealous oriole
#

i used this to time it:

start_time = time.perf_counter()
# run your code
end_time = time.perf_counter()
print(end_time-start_time)
pearl river
#

that's very inaccurate

zealous oriole
#

??

pearl river
#

single run, no way to tell what part of that is random variation.

brazen jacinth
#

do those few ms matter, or is this mostly education?

zealous oriole
#

education

pearl river
#

there's a reason timeit does many runs and averages the results.

brazen jacinth
#

true, but probably still not that inaccurate

zealous oriole
#

0.0027390999999999943
0.0016957000000000083
those look pretty accurate to me tho

tawny shoal
#

Still bad idea to only run it once

brazen jacinth
#

iglob uses fnmatch and os.listdir underneath anyway

zealous oriole
#

wait iglob does?

brazen jacinth
#

yea, you can't tell how accurate it is by looking at those numbers

pearl river
#

those look pretty accurate to me tho
😩

brazen jacinth
#

precise measurement is a complex subject

zealous oriole
#

ok sorry reptile

#

can i call you reptile

pearl river
#

Suppose I measure something roughly and it's around 3 seconds. If I write this number as 3.000000, does that mean the measurement has suddenly gotten more accurate?

zealous oriole
#

no

#

2.9358784534 would be more accurate

brazen jacinth
#

what about 3.00000000000000000000000004 😋

flat gazelle
#
In [33]: %timeit all(file_paths_walk('.SpaceVim', '', '.vim'))
28.3 ms ± 891 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [34]: %timeit all(files('.SpaceVim', '', '.vim'))
27.2 ms ± 996 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
``` they are about the same
pearl river
#

even for stuff like multiplication, timeit returns something like:

197 ns + 5.77 ns per loop (mean + std. dev. of 7 runs, 10000000 loops each)
zealous oriole
#

that is also accurate

pearl river
#

so as you can see, the variation can easily be around 10%

zealous oriole
#

ok fine then

brazen jacinth
#

other factors weigh in when it comes to measurement, measuring something once is not enough

glossy trail
#

Hi i am new to this discord server and so am i to python. i started a project in repl.it a few weeks ago and now i am having a problem. Pyflakes tells a message which states - [pyflakes] unindent does not match any outer indentation level

#

Please help me with this problem thanks !

spark parcel
glossy trail
#

ight thx

worthy jasper
#

sorry I never coded on python, can anyone teach me?

spark parcel
#

!resources

fallen slateBOT
#
Resources

The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.

spark parcel
#

@worthy jasper there should be a lot of great resources there

sullen widget
#
#

there seems to be a very wierd use of this where it looks to me like the returning result points to a freed pointer as a result of this

#

but the code where it is used is confusing with a lack of a better word so i can very well be completely wrong

regal bison
#

Hello a werid question which i don't think it's possible

#

can i delete a variable

spice pecan
#

You can remove a reference with del

regal bison
#

it work for dict will it work for var ?

spice pecan
#

The actual object will be deleted once there are no references to it left and the garbage collector picks it up

#

it will work for regular names, yes

regal bison
#

Oh

spice pecan
#
a = 10
del a
regal bison
#

lol idk yet that we can delete variables

#

ok thanks

spice pecan
#

Just keep in mind that it doesn't immediately delete the object, it simply removes a reference

paper echo
regal bison
#

Ok i thought so but it was kinda related to dicussion so i thought no to occupie a channel for that

paper echo
#

that's ok. we have plenty of channels

#

@sullen widget the 2nd one is the header? or wrong link

sullen widget
#

yes the second on is the header

#

the header declares that param 1 is source and param 2 is destination, while the actual code is the opposite

paper echo
#

oh wat

sullen widget
#

yeah

paper echo
#

i suspect that's a typo

sullen widget
#

well yeah proably lol

paper echo
#

uhh what does a C compiler do in that case

sullen widget
#

it just accepts it

#

but for a programmer it can be very confusing

paper echo
#

so does the compiler prioritize names or positions?

sullen widget
#

the compiler does not care about the names

paper echo
#

ah ok

#

so

void f(int x, float y);

void f(float y, int x) {
  ...
}

would be an error

sullen widget
#

yeah exactly

#

well no

#

it would just confuse hell out of the programmer

#

aslong as the types are correct

paper echo
#

but you now have 2 different signatures for the same function

sullen widget
#

acutally yeah that would give an error

paper echo
#
void f(int x, float y);

void f(int y, float x) {
  ...
}

would be ok, right?

sullen widget
#

since its int, float and float, int

#

yeah that would be ok i think

paper echo
#

ok

sullen widget
#

let me just double check, not used to writing code like that 😄

paper echo
#

the real problem is: what animal decided that "dst" goes first

sullen widget
#

hahaha

paper echo
#

oh god that's what memcpy does

sullen widget
#

well the thing is, since the function is used. It can cause logic error

paper echo
#

and therefore all of C basically needs to follow that dst-first convention...

sullen widget
#

where people thing it is the other way around, and so they copy from the the destionation rather from the source

paper echo
#

right

sullen widget
#

which would reuslt in dangling pointers

#

which results in RCE

paper echo
#

yeah

#

header lies to programmer -> programmer does the wrong thing

sullen widget
#

yeah exactly

paper echo
#

-> runtime crash because C bad

sullen widget
#

hahah

#

if you are lucky

#

if you are not lucky, people get shell on your computer

#

jesus i cant spell today

paper echo
#

having a convention like "dst goes first" i guess helps

#

so if you see src first, you scratch your head instead of saying "ok sure"

sullen widget
#

yep, idk if there is a standard for it in python but it seems to be needed

paper echo
#

why doesnt the compiler care about parameter names though 😦

#

is there a GCC extension for that

#

is that even in the C spec at all?

sullen widget
#

yeah compiles completely fine

#

but if int square(int a, float b) is the only thing you see then yeah

paper echo
#

right

limpid light
#

hi i gotta question

#

The break used in for and while but the best use in while

#

why is that

brazen jacinth
#

well usualy, when you're in a for loop, you know how far you're going

#

when in a while loop, you usually don't (usually)

#

so you break out

#

but they're both equivlent, they're both a loop, and you can break out of a loop whenever you define

limpid light
#

thx alot

brazen jacinth
#

oopsie, this isn't #python-discussion, in the future try that channel or the defined help channels

#

im glad i could help though

torpid plinth
#

have you guys heard about ursina ???

#

its so sick

hearty trench
#

can someone explain why do we use docker? it seems like a virtual environment does the same thing as docker..

boreal umbra
hearty trench
#

ok, thanks

magic python
#

what are opinions on pylint R0903: Too few public methods

#

I think it's giving me a warning for an attrs class that just has some data, but i was under the impression that this was a valid use

paper echo
#

🤔

#

what code

#
@attr.s(slots=True)
class X:
    a = attr.ib()

this causes it?

#

if so, tell pylint to fuck off

magic python
#

😄 yeah it's gone in the ignores - i will try and reproduce with an example tho

peak spoke
#

I had a linter that complained about the number of methods before, which I just ignored

magic python
#

just wondered if it was something that most did

#

yeah - i'm gradually just ignoring stuff as i found i was trying to please the robot more than i was actually doing useful stuff

paper echo
#

yep it reproduces

magic python
#

I've already got

def f():
    """Docstring."""
    ...

docstrings all over the place

#

🤦‍♂️

paper echo
#

just turn it off

magic python
#

I have now 🙃

#

so now i have that an inconsistency ✨

paper echo
#

that said, are you really that incapable of writing an explanatory docstring?

#

😉

#

jk there are plenty of times you dont need one

magic python
#

Maybe my code is so good it doesn' need it 😤

paper echo
#

this is why i dont use linters like this

peak spoke
#

Docstrings are good(although I myself struggle with wording them) but things like that which nobody will care about just go ignored

paper echo
#

i let the IDE give me an indicator on the side

#

i dont want a wall of actual errors

magic python
#

this is mainly via pre-commit

peak spoke
#

It's more important for collaborative projects

paper echo
#

stuff like this is stupid too imo

silly.py:4:0: C0103: Class name "X" doesn't conform to PascalCase naming style (invalid-name)
silly.py:5:4: C0103: Attribute name "a" doesn't conform to snake_case naming style (invalid-name)
#

yeah i agree its more important there

#

but still its frustrating to go around disabling a dozen individual warnings

peak spoke
#

Not that many cases where you'd need a one letter class name, but that seems like a bad implementation of the checks

paper echo
#

yeah

#

maybe in a big project the frustration is worth it?

#

a "don't use one-letter names" warning seems in order

peak spoke
#

They'd hopefully be configured properly by the maintainers (or you if you're that)

paper echo
#

right

magic python
#

@paper echo i get told to write docstring in imperitive case 😄

peak spoke
#

For example enforcing doc strings everywhere is easier than just writing it somewhere, leaving the evaluation of how it's needed to individual coders and reviewers then having to point out where they are necessary

magic python
#

i had to google what that was

#

i've been trying to use darglint recently - not sure if i like it or not yet

wide shuttle
#

I like linters. I do like to be consistent, but I also know that I sometimes cut corners, especially when hacking around to test something. If I then stumble on a version I actually want to use, my linter helps me identify the parts I need to unify quickly without me having to worry about it.

pseudo cradle
#

A one letter class name, holy shit

wide shuttle
#

But, yeah, they are just tools

pseudo cradle
#

I'll use one letter indices, that's about it

wide shuttle
#

And you should be able to tell your tool to shut up

paper echo
#

@pseudo cradle i was just testing the linter 😆

import attr

@attr.s(slots=True)
class X:
    a = attr.ib()

this is the entire file

pseudo cradle
#

Yeah, sometimes I cut corners and it bites me in the ass

#

Like right now >.>

magic python
#

@wide shuttle yeah exactly - sometimes it felt like it was just calling nonsense out rather than helping me maintain a standard or whatever, but things can be ignored until there's a decent balance

pseudo cradle
#

I'm having to go back and round my corners

#

Based on this context, is a linter just something that enforces pep standards?

brazen jacinth
#

Name change i see

pseudo cradle
#

Yeah

paper echo
#

not just pep standards, but yes

#

enforces code style

brazen jacinth
#

Based on this context, is a linter just something that enforces pep standards?
@pseudo cradle yes and more, highly configurable

peak spoke
#

Not just pep standards, but standardising the style in general

paper echo
pseudo cradle
#

Gotcha

magic python
#

anyone got any tools other than black / pylint / isort/ darglint that they make good use of ?

paper echo
#

pyflakes

pseudo cradle
#

PyCharm seems like it has a built in linter

paper echo
#

its an alternative to pylint anyway

#

yeah i think pycharm bundles pylint, pyflakes, et alia

magic python
#

oh right, not used pyflakes

paper echo
#

theres mypy of course 🙂

pseudo cradle
#

I don't know what PyCharm actually uses though

magic python
#

yeah - haven't bothered with typing yet

paper echo
#

mypy/pyre/pyright/pytype

#

i just use mypy but pyre and pyright do look interesting

#

pytype seems like a toy project

peak spoke
#

I think jetbrains use their own linters

magic python
#

i bumped into wemake-python recently - i didn't like their f-string approach tho

paper echo
#

what is that

peak spoke
#

What was that approach?

paper echo
#

do not tell me it was a build tool using f strings

magic python
#

don't use f-strings because they're hard to lint

#

🙃

peak spoke
#

That's just stupid

magic python
#

I don't see any reasons why we should use them.

🤔

pseudo cradle
#

f strings are useful but they just like... it feels weird using them because nothing else behaves that way

#

So I just use format str

#

str.format, rather

magic python
#

you can do f"{2 + 2 = }" now i think

peak spoke
#

They are a great improvement to readability because of the lack of a function call, you immediately know what belongs where

paper echo
flat gazelle
#

they make it much more obvious what is where, but they can get horribly confusing once you start nesting

#

though doing the things with nesting with .format is no less confusing

paper echo
#

well, it is a very highly opinionated tool

#

The strictest and most opinionated python linter ever!

#

"opinionated" does not mean "authoritative" or "correct"

magic python
#

I don't mind that - i just don't agree with their opinion

#

so i hate them

#

I love using black

full jay
#

nothing else behaves that way
How do you mean?

#

There's plenty of instances of string interpolation across various languages

peak spoke
#

Nesting stuff in general is horrible once it gets deeper ( in the case of f strings one level)

full jay
#

True enough.

magic python
#

that's why everythign should just method chain

#

why can't we have list().len() or something

full jay
#

Because then you'd have to apply it across all things? Rather than just having to implement one magic method

paper echo
#

javascript is that way 👉

magic python
#

across all things is good 🙂

paper echo
#

@full jay fwiw you do have __len__

full jay
#

That's what I mean

paper echo
#

you mean, there's a fallback len() implementation for when nobody implemented .len()?

pseudo cradle
#

@full jay Nothing else in Python behaves that way

full jay
#

@paper echo Correct

#

@pseudo cradle Ah, fair

#

That's the point of a lot of things, convenient redundancy

paper echo
#

@full jay this is one argument in favor of languages that don't have traditional dot-access methods, e.g. R and Julia

peak spoke
#

I don't like chaining in python, only a few cases where it'd help and a lot more where people would create unreadable chains if accesses

paper echo
#

dot-access methods are just a special syntax for single dispatch

pseudo cradle
#

Yeah, I've had to parse some pretty crazy nested strings

magic python
#

@paper echo is that why R pipes work so well?

paper echo
#

partly yes

#

and other functional languages like F#

magic python
#

if python had pipes it'd be amazing

flat gazelle
#

Python is not meant to allow for long expressions

pseudo cradle
#

round pipes work well because of how pressure is distributed across the circumference

#

😄

flat gazelle
#

it follows the algol tradition which is more statement based

paper echo
#

@flat gazelle i tend to agree, don't try to force a language to look different from how it's intended

pseudo cradle
#

.format().split().split().join().format()

flat gazelle
#

I do love kotlins abominations of oneliners, but they should not be in python

paper echo
#

that said pipes are not native to R, but the language is homoiconic and wildly dynamic so you can implement your own pipe operator

full jay
#

The more languages I learn, the less I care about one language having something while another doesn't

#

Each language is tailored to its own strengths, and that's where the focus should be

pseudo cradle
#

I still have my pet peeves though

magic python
#

sure - if python had pipes it'd be great tho

full jay
#

Would it?

magic python
#

yes

paper echo
#

the one thing i dislike is that lambda syntax in python is kludgy

pseudo cradle
#

yeah

full jay
#

Sure but it's meant to be used sparingly

paper echo
#

typing out lambda makes me sad

#

if it were easier to type it would be used more frequently

full jay
#

You're supposed to feel dirty

paper echo
#

a list comprehension is just a lambda in disguise

magic python
#

can you alias lamda to l

paper echo
#

no @magic python

pseudo cradle
#

I have like three pet peeves about the python language but all the benefits it brings is more than enough to compensate

flat gazelle
#

lambda is a great way to get horribly messy expression

paper echo
#

you'd have to modify cpython itself and recompile to change lambda

full jay
#

a list comprehension is just a lambda in disguise
@paper echo With added optimizations in the background, sure

pseudo cradle
#

Yeah, I don't like using lambdas either

flat gazelle
#

especially in a language like python which has terrible expression handling when compared to others

paper echo
#

and yes, with lambdas being clunky i just write more named functions. not a bad outcome

peak spoke
#

The if is also a big thing you won't have with s lambda

full jay
#

I'm trying to think of situations where pipes would be really beneficial to Python code and I'm just not seeing it

#

It's just not built with that in mind, and doesn't feel like it'd be clean

paper echo
#

i agree its not important

#

people only want it for dataframes because they're used to it from R

#

i don't even like them that much in R

full jay
#

I get them for primarily functional languages

paper echo
#

i usually end up refactoring my R code away from pipes..

#

harder to debug

undone hare
#

I like the way kotlin handles things, where you can insert some pretty functional code inside imperative code, I think it works pretty nicely and that would also fit python

full jay
#

Do you have a snippit example?

undone hare
#

Yeah, hang on

full jay
#

Isn't the primary concept of a functional paradigm just that you have functions without side-effects? Or rather, is completely cut off from state influence?

#

X input will always be Y output?

flat gazelle
#

pure function are a big part of FP indeed

full jay
#

Or is that vastly oversimplifying it

flat gazelle
#

but you can have HOFs that just take impure functions

#

such as kotlins .apply

full jay
#

Ah okay

undone hare
#
suspend fun Member.getTopRole(): Role? = this.roles.toList().max()```Small function stolen from our kotlin bot
full jay
#

I'm thinking back to Elm where everything relies on the current state of the document, but the change functionality is always consistent in its behavior regardless of that

flat gazelle
#

ye, the main merit of pipes and such would probably be that you get to not read code from the center out to either side

full jay
#

It just doesn't feel overly needed

#

Like yeah it'd be cool but it'd feel forced in

#

I'm kind of feeling that way with the pattern matching PEP, sadly

spice pecan
#

The pattern matching feels like a gamechanger

full jay
#

I want it to be, but it doesn't feel like.... I don't know, it doesn't feel as versatile as I was hoping? As odd as that sounds

undone hare
#

I'm personally glad to see that the language is evolving and not staying on its functionalities from the 80s

full jay
#

Because from my loose understanding of it, it's primarily about deconstructing containers or something to that effect

#

@undone hare Sure, and I'm down for that. I'm not saying it should stagnate

spice pecan
#

Deconstruction is its main purpose, but it can still function like a switch-case kind of thing as well as do typechecks

flat gazelle
#

ye. Which is something I have wanted for a while tbh. I often find myself just writing attr = onename.attr anotherattr = onename.anotherattr

full jay
#

It can but within the PEP it's suggested that it's not used for it

flat gazelle
#

similar with dicts

full jay
#

Yeah that's fair

#

I think this'll have to be like the walrus; I'll have to see it in action to appreciate it

pseudo cradle
#

=3

full jay
#

But currently it's like JUST out of reach of what I want it to be

flat gazelle
#

I feel like just Point(x, y) = point_object may be more convenient, but I am sure that will be a PEP at some point as well

paper echo
#

the pattern matching idea is nice but it opens up several very nasty cans of worms

full jay
#

Oh actually yeah, that'd be interesting

#

A way to dictate how decon' works

paper echo
#

the edge cases are enough to make me think it's not worth bothering with

undone hare
#

The pattern matching PEP will not break any existing code, right?

raven ridge
#

Pattern matching seems to add more terseness, but not more expressiveness... It doesn't let you do anything new, it just lets youwrite a bit less code to do stuff you could already do. I still think it's going to hurt maintainability.

full jay
#

I think that's my beef with it

peak spoke
#

Does it introduce new keywords?

full jay
#

It just doesn't feel like it's something easily maintainable

flat gazelle
#

math and case afaik

paper echo
#

it introduces new syntax

#

symbols and stuff

#

very unpleasant and very unpythonic imo

full jay
#

It feels like it's something just tacked on from MyPy

paper echo
#

give me none-aware operators instead

peak spoke
#

The pep for that was deferred I think

full jay
#

We've been consistently told that type-hinting wasn't going to be something enforceable within the language, and I feel like the pattern matching goes against that

#

I might be 100% off base, though

raven ridge
#

It introduces new soft keywords that are only keywords in specific contexts.

peak spoke
#

Shouldn't break much existing code then, right?

paper echo
#

yes but that is a really unpleasant idea to me

#

at least with is usable everywhere and as is always context-dependent

full jay
#

Shit, I think I'd kill for an option() wrapper

paper echo
#

option?

full jay
#

Essentially.....

#

Option<T>: None | Some(T)

#

I THINK I wrote that vaguely right

#

No idea

magic python
#

@full jay do you do much data processing

full jay
#

I do not

flat gazelle
#

in python, I generally just see None or the value itself being passed

full jay
#

Sure, and this wouldn't really work well without some sort of switch or match casing

magic python
#

Maybe that's why pipes don't feel so natural idk

paper echo
#

@magic python i do a lot of data processing, i dont ever need pipes

full jay
#

@magic python No I'm okay with pipes, I just don't see them being overly beneficial in Python specifically

strange fog
#

Option<T>: None | Some(T)
is this not typing.Optional?

magic python
#

Need != Nice

full jay
#

@strange fog Yes..... yes it is.... You ever forget something exists?

paper echo
#
def clean_string(s):
    s = s.replace('-', '_')
    s = re.sub(r'\s+', ' ', s)
    return s
#

clean enough for me

flat gazelle
#
match possibly_none:
    case None:
        print('is none')
    case a:
        print('the value is', a)
``` it works just fine with pattern matching, no?
magic python
#

Assignment of s twice tho

strange fog
#

@full jay 😄 more regularly than i'd like...

full jay
#

So?

paper echo
#

🤷‍♂️ who cares

#

let pypy's JIT optimize it 😛

magic python
#

Me obviously 😄

full jay
#

Re-assigning over something doesn't matter if it's still the same thing

magic python
#

Dry

#

It's redundant, pipes would remove this

peak spoke
#

I don't think I'd accept it as s there, but the reassignment is fine imo

#

(different names for the accepted and modified)

full jay
#

And hurt clarity for folks used to Python. Yes that'd be something to get over eventually, but a quick reassignment like that is common in many languages

#

True, Num

#

But it's also not outright objectionable

flat gazelle
#

even rust allows it, including changing the type of the binding while keeping the type immutable

magic python
#

Now we're naming things differently when we probably don't care about the interim names

#

It's just a nag that is obviously solved by pipes

full jay
#

"obviously" seems like a stretch.

magic python
#

You want one thing to be the result of a series of processes, a pipe is more natural than multiple reassignment

full jay
#

In languages that focus on such behavior, sure

magic python
#

Yes, which is why I said I think python would be great if it had it

full jay
#

I'm not 100% sold but I'm not overly against either

#

My worry would be consistency throughout a codebase

magic python
#

Obviously it's not a deal breaker,I just think it's a valid pattern for this kinda scenario

full jay
#

Sure but the other is just as usable and useful

#

Especially for debugging purposes where you might have to pick it apart

magic python
#

Imo the pipe makes more sense, the other works ofc, but the reuse of variables like that isn't as clear

full jay
#

I'd agree if the reassignment was miles apart, but they're right next to each other and only local to that function

flat gazelle
#

pipes also introduce fun problems with operator precedence

magic python
#

I often have a few lines and it just feels daft reassigning to me

#

Oh, I am not aware lak 🤔

flat gazelle
#

2 and 5 |> add(-5) is this 0 or False?

pseudo cradle
#

Yes, it is

magic python
#

Why is that the pipes fault

#

It'll be add( true, -5)

paper echo
#

i always wondered why it was |> in some languages and not ->

magic python
#

Bash?

paper echo
#

does the latter lead to ambiguity with math syntax?

#

i guess

#

but it's not | so who cares

flat gazelle
#

|> is F# and Elm

full jay
#

Also sometimes used for saying what the return type is

paper echo
#

i guess you still want to use the "pipe" mnemonic

magic python
#

I don't see the issue there tho @flat gazelle

#

Where's the ambiguity? Unless I've fully missed it

full jay
#

It's not 100% clear with a quick glance

#

At least not by Python pickiness

magic python
#

It is though

flat gazelle
#

(2 and 5) |> add(-5) -> 0
2 and (5 |> add(-5)) -> False

#

and honestly, even just the syntax for partial expressions in troublesome. Unlike elm/F#/haskell you have no currying

full jay
#

Not without Partials

#

But you'd have to do that every single time

flat gazelle
#

and a |> b is just b(a) it becomes pretty much worthless

magic python
#

I don't have much appreciation for this stuff @flat gazelle , so I'm probably missing a lot. All I know it's that for repeated assignment pipes seem a lot more natural to me

full jay
#

You get to a point where to implement one part of pipes you end up having to change a huge amount of stuff in the background

magic python
#

Why would pipes be enforced?

#

You can use pipes when they suit

#

B(a) would be used

#

If pathlib can overload / then maybe 🙃

full jay
#

But I think lak made a good point about the currying, that's a huge hinge point on making pipes work properly, or at least better than for one purpose

flat gazelle
#

in order for pipes to work, you need to able to create an expression that can accept a pipe

#

the only existing mechanism python for this is functions, which are a pita to create inplace

magic python
#

Hmm, I don't know enough to consider implementation, only usage

full jay
#

It ends up being a huge web of things that'd need to be implemented or changed

magic python
#

Right, but I don't think that changes my opinion, just that the language would struggle to accommodate it

flat gazelle
#

a similar mechanism to pipes are clojure arrow macros, which have 3 variants and only work because clojure, as a "lisp" has all expressions in a consistent format.

(->
  8
  (+ 3)) ;becomes (+ 8 3)
(->>
  8
  (+ 3)) ;becomes (+ 3 8)
(as-> $
  8
  (+ $ 3)) ;$ gets assigned to the last result
``` F# and elm have currying. Not sure what R does
paper echo
#

what's a use case for name mangling with __?

#

@flat gazelle R has no currying but you can easily implement partial function application or "expression capturing" like in the clojure case with as-> $:

x %>% f(1, ., 9)

where . is a placeholder for the piped value

flat gazelle
#

ah

paper echo
#

but again %>% is not part of the language, it's from a 3rd party library

#

which is pretty cool imo

raven ridge
#

Adding a new private attribute or method to a class that may have been subclassed by someone else who also added a private attribute or method of the same name to their subclass. That's pretty much the only use case for name mangling, and doesn't come up much.

flat gazelle
#

languages with fully custom operators are cool

paper echo
#

@raven ridge i see. that's a bit of an odd case

#

so what, some methods/attributes would have __ and others would have _?

#

yeah @flat gazelle R also allows "non syntactic" names too, like in SQL

#

and has a few interesting bits of syntactic sugar built in

#

like you can write names(mydata) <- c('a', 'b') which is special syntax that calls a function called names<-

#

in general a function like func<-(obj, val) can be called as func(obj) <- val

#

and any function of the form %func% is automatically a binary operator, as in %>%

#

or %*% for matrix multiplication

#

and you use backticks ` to "quote" such non-syntactic names where needed

raven ridge
#

so what, some methods/attributes would have __ and others would have _?
@paper echo yep. The purpose of __ is to allow you to extend the "private" stuff of a base class without breaking a derived class that may have added its own private stuff. Or, alternatively, to add private stuff to the subclass that won't break if the parent class is later extended to add private stuff with the same name.

paper echo
#
`%custom_addition%` <- function(x, y) x + y
x %custom_addition% y
#

ok that makes more sense @raven ridge

#

the latter use case is something ive wondered about in the past

spark parcel
#

Seems like advanced chat is back. What’s the actual use case of it? Is it just discussing things about python that seem to be too advanced for #python-discussion?

near coral
#

a more apt name, nice

#

I'm mediocre though, so bye for now 😁

raven ridge
#

It's for discussion about the language itself, rather than about how to solve some particular problem with it. Like "why would you use mangled __foo names" or "should Python have a pipe operator" or "what are the pros and cons of the proposal to add pattern matching to the language"

spark parcel
#

Okay, perfect. It was called something along the lines of “python-language” yesterday. Why was it changed back?

#

It sounds more like “meta python” or “language discussion” or similar to me. At least if I got the right idea of what meta means

wide shuttle
#

This is a new name, but this channel is plagued by people asking for help while it's one of the very few channels that we have that is not for help questions.

#

python-language did not filter out those people. We tried advanced-python in the past, but we hope that the "discussion" suffix will help with indicating that it's not a help channel, but a discussion channel.

spark parcel
#

Yeah, you’re right about that

#

I’m not sure this will work either, though. Maybe something like “language-discussion” would be even better

#

I personally thought it was similar to #python-discussion, but just for advanced questions. Either way, I hope this name filters out the questions

spice pecan
#

I second the "python-meta" thing

raven ridge
#

I'm pretty sure that nothing short of moving this out of the "Discussion" folder and into "Topical Chat" will do the trick. But that's all off-topic for this channel. 😉

spark parcel
#

Yeah, I’ve been thinking about that as well. Either way, #community-meta is probably a prettier channel for this discussion

paper echo
#

subjectively i saw a significantly larger number of "lost users" when it was #python-language than when it was #advanced-python

tawny shoal
#

Let's kick off this channel: thoughts on async lambda?

peak spoke
#

Feels like the only proper use for that would be a callback, which you could do with a normal coro wrapper

tawny shoal
#

I feel like you can also use it to launch a bunch of tasks

#
async for item in iterable:
    asyncio.create_task(async lambda: await item.do_something())
peak spoke
#

You can't really do much async there because of the expression limitation, and beyond things like the above would be too complex for python's lambdas

wide shuttle
#

What's the purpose of the async lambda here? Can you just not create a task for the coro item.do_something() returns?

#

I've never had a situation in which I missed an async lambda

peak spoke
#

I'd rather see a wrapper with a descriptive name for the callable pattern.
Something like partial if that can't handle async in a nice manner

radiant fulcrum
#

yeah

#

that method could just be

async for item in iterable:
    asyncio.create_task(item.do_something())```
tawny shoal
#

you're right

radiant fulcrum
#

Remember that unlike sync functions you can call them and pass any items and it wont call the function directly

#

it will make a future object and wont be called until you await it

tawny shoal
#

yeah I'm a bit slow rn, my apologies

#

Hmm

radiant fulcrum
#

the only time ive found where it would be nice is when ive been doing my ASGI wrapper

tawny shoal
#

Could you do something like ```py
async for item in iterable:
asyncio.create_task(lambda: item.do_something())

assuming `item.do_something()` returns a coroutine?
radiant fulcrum
#

where i send back a dud future object that does nothing

#

item.do_something() could be a coro in itself

tawny shoal
#

I mean coroutine object, not coroutine function

radiant fulcrum
#

it could be

tawny shoal
#

coroutines are callable?

radiant fulcrum
#

its the same principle that lets you do await some_object() and have a __call__ method work still

#

you can call a coro when ever, you wont get the result until you await it tho

tawny shoal
#

Yeah I meant coroutine, not coroutine function ^^'

#

Like what you get when you do

res = asyncio.sleep(1)
#

you can't do res() here, can you?

radiant fulcrum
#

no iirc

#

because you've then made a future object

tawny shoal
#

yeah that's what I meant, never seen a coroutine that is callable

#

Isn't that a Coroutine rather than a Future?

wide shuttle
#

But, you can pass that res directly to a create_task

tawny shoal
#

yeah

wide shuttle
#

That is basically what happens

tawny shoal
#

I was just wondering what happens when you do res() cause I never heard of Coroutine objects being callable

wide shuttle
#

It will probably complain about not being callable

tawny shoal
#

yeah that's what had me confused

#

wait a minute

#

its the same principle that lets you do await some_object() and have a __call__ method work still
@radiant fulcrum does this mean I can have a function do something different depending on whether I do

res = await my_func()

vs

res = my_func()

?

radiant fulcrum
#

like a callable class for example

tawny shoal
#

So In theory, could I just write a function that acts synchronously or asynchronously depending on whether the user tries to await it?

radiant fulcrum
#

ig? tho you wouldnt have any method of knowing

#

not easily atleast

tawny shoal
#

knowing what?

peak spoke
#

You wouldn't have that information, you just return the awaitable and then awaiting happens after that

radiant fulcrum
#
class Foo:
  def __call__(*args, **kwargs):
      # stuff
      return coro(*args, **kwargs)
peak spoke
#

You can delay the awaiting and do arbitrary things when the awaitable is created but you only return and pass it as any other object

tawny shoal
#

Ah I thought __await__ was the key here

radiant fulcrum
#

__await__ is things like

class RandomProducer:

    def __await__(self):
        return self.producer().__await__()

    async def producer(self):
        sleep = random.random()
        value = random.randint(0, 9)
        return await asyncio.sleep(sleep, result=value)

async def main():
    producer = RandomProducer()
    while True:
        print(await producer)```
#

so ig you could?? do something like that

#

but you still wouldnt know if its going to be awaited or not

tawny shoal
#

I see

sacred tinsel
#

in the simplest case you can have

>>> class Cat:
...     def __call__(self): print("I have been called!")
...     def __await__(self): print("I have been awaited!"); return iter(())
... 
>>> cat = Cat()
>>> cat()
I have been called!
>>> await cat
I have been awaited!
#

just keep in mind that the __await__ must always return an iterator

twilit rain
#

@sacred tinsel If you return an awaitable from __call__ can you await cat() ?

tawny shoal
#

Ohh I see

sacred tinsel
#

like so?

>>> class Cat:
...     def __call__(self): return self
...     def __await__(self): return iter(())
... 
>>> await Cat()()
twilit rain
#

Pretty neat. I have no use for it, just like finding fun things that can be done.

sacred tinsel
#

yeah asyncio is cool

#

i'm not very experienced with it, but I find it fascinating

twilit rain
tawny shoal
twilit rain
#

I have to be a lot more focused to grok async stuff

tawny shoal
#

Allows me to do this:

class MyModel(Model):
    something_else = ForeignKey(SomethingElseModel, on_delete=CASCADE)
my_thing = MyModel(something_else=my_something_else)
x = await something_else.x  # await necessary since we're in an async context
#

I don't particularly like it but it works

#

using it to use Django's ORM in an async program

twilit rain
#

How does that differ from the stuff I've seen in sqlalchemy?

#

Ah gotcha

radiant fulcrum
#

Django's orm is Next level to alchemu

#

tho Django's orm lacks in that its all sync based

tawny shoal
#

Does sqlalchemy also make you await foreign key attribute access?

radiant fulcrum
#

Alchemy doesnt support async

tawny shoal
#

Ah

twilit rain
#

I just picked up on the class attribute tidbits to define relations, glossed over the await part I guess 😕

tawny shoal
#

yeah I wrote my stuff in an effort to make Django's ORM play nicely with asyncio

#

I'll be gone for a bit but will respond to any @s

flat gazelle
#

There is asgiref.sync_to_async, but I couldn't tell you what exactly it does

radiant fulcrum
#

The amount of async orms is low, Ive made a PyMongo style Postgre orm, theres one called databases which is a async implementation of alchemy core

tawny shoal
#

That's what I'm using a lot too @flat gazelle

#

If you want to you can check out the rest of my """""django asyncio port""""", I linked my code above

radiant fulcrum
#

Im pretty sure it executors it

peak spoke
#

Await periodically?

tawny shoal
#

I would love to find a better approach

peak spoke
#

Feels like it wouldn't be necessary if it throws it into an executor

radiant fulcrum
#

Django's Asgi seems to executor everything sync based which is why they stress so hard is making sure you make sure any async stuff is threadsafe

tawny shoal
#

Yee

#

I just throw all the sync Django ORM stuff that actually operates on the DB into sync_to_async with thread_safe=True

vivid crest
#

@sacred tinsel This didn't work.

forest flicker
#

cython looks like a magical performance enhancer for python. What kind of python code can and cannot be enhanced by cython? what to look out to take advantage of cython when writing python code?

tawny shoal
#

Basically anything can be made faster by cython, just a matter of asking yourself if Python is the right language if you write everything in Cython

#

also I'm not sure about asyncio support

#

side note, PyPy might be worth checking out

raven ridge
#

there's things you lose by using Cython - it runs faster, but it's harder to debug and introspect.

pseudo cradle
#

^

#

Don't fall into debug hell

raven ridge
#

Cython is great, and magical, but like any other optimization technique you should use it where it will give the most benefit.

tawny shoal
#

Can only agree ^

raven ridge
#

oh, and test! it's harder to test, as well.

celest raven
#

ok

brave badger
#

cython looks like a magical performance enhancer for python. What kind of python code can and cannot be enhanced by cython? what to look out to take advantage of cython when writing python code?
@forest flicker To be more specific, it also optimizes a lot of C-style code written in Python, as well as applying CPython optimizations like constants and such

forest flicker
#

there's things you lose by using Cython - it runs faster, but it's harder to debug and introspect.
@raven ridge I've seen python code that need not be changed when using Cython. The code simply add some kind of decorator on top on the python code. This shouldn't make code harder to debug

#

oh, and test! it's harder to test, as well.
@raven ridge to test, one can simply remove cython temporarily.

brave badger
#

Producing binary extensions definitely make code harder to debug, especially in the context of Python

raven ridge
#

Removing Cython means what you're testing isn't what you're shipping, which drastically reduces the utility of automated tests

forest flicker
#

that's true. I didn't know there's a prominent risk that the same python code with and without cython can behave differently.

#

is it possible to step through python code enabled with cython?

raven ridge
#

Not as Python code, because it isn't Python code, it's C or C++ code. You can step through it with a C debugger

forest flicker
#

oh dear. does it mean I can no longer use pycharm to debug cython "python" code?

raven ridge
#

I'm not sure, I don't know PyCharm. I doubt it integrates with a C debugger, but I don't know.

sharp gale
#

hlooo

#

just suggest some django beginner level projects

charred barn
#

Make a web page where people can submit and vote on beginner level projects

pseudo cradle
#

😄

boreal umbra
#

CLion would presumably have a visual debugger for C and C++ and I assume IntelliJ ultimate would have it all

sharp gale
#

@charred barn ok i will do that

sweet lotus
#

do anyone how get python program out put in flask ? like plane thing where you can see your program out via web dashboard instead of ssh to cloud vm & seeing? (i don't wan't code flask inside of that program)

radiant fulcrum
#

you should setup some Fileserver or something

#

I tend to use github but i also have a ftp server i can use to move to my servers

zealous oriole
#

how does int() work

#

like whats the idea behind the builtin

#

function

peak spoke
#

Work in what way? The implementation or its behaviour?

zealous oriole
#

both i guess

flat gazelle
#
In [32]: int?
Init signature: int(self, /, *args, **kwargs)
Docstring:
int([x]) -> integer
int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is a number, return x.__int__().  For floating point
numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base.  The literal can be preceded by '+' or '-' and be surrounded
by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4
Type:           type
Subclasses:     bool, IntEnum, IntFlag, _NamedIntConstant, Handle
peak spoke
#

Is the length hint dunder used somewhere in the stdlib?

zealous oriole
#

wow

#

such a simple use case

#

monstrous code in the background

true hollow
#

1 line of python code has behind 1000 lines of C code :)

brazen jacinth
#

technically just the ceval switch is 1500 lines

sonic girder
#

Doesn't it depend a lot? Like x = a + b cant be more than like 3

peak spoke
#

There are a lot of things in the background to accomodate add for arbitrary objects

sonic girder
#

Oh I forgot it has to check type

#

Hmm then it must be a lot...

#

What about a = 2

spark magnet
#

Python gets compiled to bytecode, which is then interpreted. There are a lot of lines of C involved in even the simplest statement.

flat gazelle
#
x = a + b

assuming a and b are int

lookup names a and b
  - check local scopes
  - check module scope
decide the destination of x
  - was global/nonlocal used
see if the object under a has __add__
it does, call it with a, b
check if it did not return NotImplemented - it did not
assign the result of __add__ to x
``` and that is skipping all the complexity of `__add__` on two ints
#

(has to check for MemoryError, RecursionError, acquire the GIL, make sure references are properly counted, ...)

grave jolt
#

Well, technically, for CPython, scope resolution is done at compile time, and it loads different instructions for local, closure and global variables.

#

but these lines are still executed

#

so we need to also factor in the lines it takes to compile x = a + b, and there's probably more

cyan pollen
#

Guys, not sure where to put this, but how do you decide what projects or functionalities to open source? I really want to give back to the community that has given me so much, but I also want to protect my future ability to provide, so yeah, how do you guys do it?

narrow kettle
#

I just open source everything that i write

#

Idk what protect my future ability to provide means

brazen jacinth
#

well, obviously you won't open source things you use to earn a living

grave jolt
#

(unless you make a living making open-source software)

brazen jacinth
#

but, that still leaves plenty of wiggle room for projects you're not using profesionally

#

fair hehe

narrow kettle
#

I mean obviously you don’t open source your companies code

#

That’s a great way to get fired

#

I meant everything that i write

spiral willow
#

Jay, MIT license it

#

Which means you can port it to closed source

narrow kettle
#

I mean all MY stuff is mit oc

unkempt rock
#

Hi, realistically can we ever have a Python compiler? I know it's not what the Python core development team which is strange given the advantages of compiled code. I think MyPyC is a great concept, pity development here is slow. Anyone knows of something similar to MyPyC? Cython is not convincing.

narrow kettle
#

I was referring to proprietary company code

#

I mean pypy is a jit compiler

grave jolt
#

i think they mean a native compiler

full jay
#

Cython kind of is?

grave jolt
#

Theoretically a compiler can trust type hints/type inference.

#

but that won't be python, that will be a language with different semantics, I guess

frail geyser
#

does anyone know if there's an option in pip's pypirc to enable the new resolver (as of 20.2) by default?

spark magnet
#

@unkempt rock have you tried PyPy?

flat gazelle
#

numba can compile some subset of python

spark magnet
#

@flat gazelle btw, in response to my tweet of your code:

>>> fib = lambda n:[(a:=0),(b:=1)]+[(c:=a)+(a:=b)+(b:=a+c)-a-c for _ in range(n-2)]
>>> fib(6)
[0, 1, 1, 2, 3, 5]
flat gazelle
#

that has the requirement of a third variable, which is inconvenient

spark magnet
#

i think there are about 10 things wrong with it, not sure "third variable" even makes the list! 🙂

brazen jacinth
#

I imagine if you write some kind of translation from bytecode to llvm IR you could get some kind of compiled py

flat gazelle
#

that is pretty much what numba does. It is even faster than pypy and in some cases cython because it errors when it cannot compile and does not care about being functionally identical to python code

brazen jacinth
#

Numba acts as a jit though, plus alot of code it cant work with

#

But yea youre right, probably the closest living thing to it

timid bramble
#

@frail geyser yes but in pip.conf, not pypirc (that file is for upload tools)

unkempt rock
#

Im giving pypy a shot and see if this works well in our project.

spark magnet
#

@unkempt rock what kind of work is your project doing, and what is too slow about it?

unkempt rock
#

Hmm, pypy still not supporting python 3.7

pseudo cradle
#

sad

spark magnet
#

they will get there

unkempt rock
#

its not really that the project is too slow, just want to experiment and see whether in this case using a jit compiler would result in a faster runtime

#

but something like from future import annotations seems to be incompatible with current pypy release

spark magnet
#

yes

grave jolt
#

Is CPython bytecode compatible with PyPy?