#internals-and-peps

1 messages ยท Page 79 of 1

prisma cypress
#

Would you write the OOP part too and then implement it later?

smoky turret
#

consider if its an OOP kinda problem, or what parts are well suited for OOP

#

stubbing the objects is easy

#

generally, if you're gonna use OOP, you'll probably want to map out how those will work earlier rather than later

prisma cypress
#

Ahh okay okay.

smoky turret
#

I wont say one way or the other, you have to figure that out for your problem. The general advice is start from the top down

prisma cypress
#

I think it's a good starting point to follow, and I think I'll go top down too.

#

I do have a bit more questions.

So originally I was thinking of writing the main function and then substitute the OOP part in to encapsulate the logic at certain parts.

#

Because I'm not too sure how to plan out the OOP part. Any suggestions there?

#

In my head I want to use OOP because it's better for scaling.

#

And also better understanding of the code due to the encapsulation.

smoky turret
#

OOP should be used in python when theres good reason for it, so if you have parts sticking out as "Should be a class" then really figure out what the heart of that is. Using OOP for the sake of OOP isnt particularly helpful in python

#

You dont have to know every single method, mind you, just the responsibility of the object

#

implement methods when they are needed

prisma cypress
#

@smoky turret thank you so much, that helps a lot.

smoky turret
#

np

raven ridge
#

@prisma cypress also, it's not clear from your question if your input and output formats are fixed, but if not, start there. Design the database schema first, and the structure of a lot of your code for interacting with that database falls out naturally from there. Likewise for your inputs, on the opposite side, especially for a service or message queue listener or pub/sub subscriber or something. Design schemas before designing code.

feral heath
#

Hi, is there a way or an implementation that allow us to create a function object from a string ?

function = mystery_function("(async) def function():\n...")
#

Thank you in advance for your answer

sacred yew
#

yes

#

but why

#

its called exec

#

@feral heath

feral heath
#

I know exec

#

But when I use exec I need to retrieve the function's name

winter zenith
#

does anyone know cs here

#

simple cs

feral heath
#

C Sharp ?

winter zenith
#

computer science theory on resolution images

true ridge
#

But when I use exec I need to retrieve the function's name
@feral heath Well, if you are sure that there are only 1 functions in the given string, and if you don't know the name. In theory, the given locals namespace should only contain that function so that you can easily access

#
>>> source
'def x(): pass'
>>> local_ns = {}
>>> exec(source, globals(), local_ns)
>>> local_ns.popitem()
('x', <function x at 0x7f35cf863a50>)
junior moat
#

TIL: if you have a class that derive int and ABC, all abstract* decorators do not work ๐Ÿ™‚

true ridge
#

but for being sure, I would probably go and parse the source with ast and get the name of the function

feral heath
#

Let's assume I create the function in a local environment

#

If I use exec, wouldn't it create the function in a global environmment ?

#

Anyway thank you for your help

#

I'm gonna dig this solution

west nymph
#

@feral heath What do you mean by "local environment"?

feral heath
#

If I use exec in a function

true ridge
#

If I use exec, wouldn't it create the function in a global environmment ?
@feral heath exec is going to assume you are in a different module level when you pass both globals and locals. And in the module scope, the function will be in both globals ad locals

#
def make_function(source):
    local_ns = {}
    exec(source, globals(), local_ns)
    assert len(local_ns) == 1
    return local_ns.popitem()

func_name, function = make_function("def bruh(): print('hey')")
function()
feral heath
#

What is assert for ?

true ridge
#

ensuring there is nothing else in the locals

feral heath
#

Otherwise it creates an Error ?

true ridge
#

No, otherwise you can't know what will happen

feral heath
#

Thank you

feral cedar
#

bruh()

prisma cypress
#

Hey @raven ridge Iโ€™m not super sure what does fixes input output mean.

Originally what I was planning on doing was to gather the html and send it to MongoDB, then grab it from MongoDB to extract the text to send it to something like postgresql.

Itโ€™s just a simple pipeline, but I want to write it in a structure way and reusable along with repeatable results.

unkempt rock
#

Anyone knows a good website for python exercises?

feral cedar
#

codewars

#

in the future, this isn't the channel for those types of questions, it'd be better suited for #python-discussion @unkempt rock

violet jetty
#

Hi there!
I'm really new to Python but I want to invite people to take interest in a ML/NLP project. I want us to figure out how to digitize The Turing Digital Archive (http://www.turingarchive.org/) into easy-to-read text.
I'm not sure what the best tool is for the project, so I'm posting this to make interested friends who want to help.
To begin, I was looking at EasyOCR (https://github.com/JaidedAI/EasyOCR) but I don't know if it's the right tool for the job.
We'll be working in conda with Python for this; I personally will be using Windows 10; apart from the experience itself, I think creating one document containing all of Alan Turing's writings will be it's own reward.

undone hare
#

Or are you looking for recruitment?

violet jetty
#

I can't fathom why it would be against the rules. I'm not looking for "a helper" I'm fishing for interested people who would like to help people with a simple-ish project.

gloomy rain
#

Finding people to collaborate with is not against the rules, but this channel is not the place to do it.

violet jetty
#

I thought this was more of an advanced topic channel? @gloomy rain Isn't general a little too fast paced for this?

gloomy rain
#

The topic of the channel is:

Discussion on the use cases, implementation and future of the Python programming language including PEPs, advanced language concepts, new releases, the standard library, and the overall design of the language.

#

It's a discussion channel for advanced Python concepts.

#

So, not the place to find people for your project.

violet jetty
#

Isn't ML advanced? I'm confused.

gloomy rain
#

Even if it was, this is a discussion channel.

#

It's not a project board.

#

But, again, see the topic I quoted above.

violet jetty
#

Can we discuss how to go about making a project work?

gloomy rain
#

ML is an application of Python, not an aspect of the language itself.

violet jetty
#

Topically speaking where does my post fall under?

gloomy rain
#

If you want to discuss different approaches to solving a problem related to your project, or have a discussion about architecture or design of your Python project, that might be appropriate for this channel.

violet jetty
#

No

#

that's not a topic.

#

etc

gloomy rain
violet jetty
#

well... that was my question

gloomy rain
#

If you prefer that.

violet jetty
#

๐Ÿคทโ€โ™€๏ธ

#

I do

gloomy rain
#

There you go then.

violet jetty
#

kinda don't want my post getting drowned in general

#

@gloomy rain ```If you want to discuss different approaches to solving a problem related to your project, or have a discussion about architecture or design of your Python project, that might be appropriate for this channel.

#

example: "idk what tool to use"

#

it's all wrapped up in one post

gloomy rain
#

Basic questions with concrete objective answers should go in #python-discussion, a topical help channel or a general help channel.

#

If you want to discuss more subjective, vague, high-level topics, that's fine, but you need to actually bring up a subject in that case.

violet jetty
#

I'm discussing how to design a project, which is what you said would make the post relevant to this channel.

#

Make it make sense?

gloomy rain
#

Again, you need a bring up an actual concrete question in that case.

#

If you're unsure, don't post it here.

violet jetty
#

I was sure, you injected the uncertanty.

gloomy rain
#

Good, because you were off-topic.

#

Anyway, if you'd like to continue this discussion, please move to #community-meta or DM @summer lichen.

violet jetty
#

I don't know how to reconcile your dual insistance that discussing "vague" topics is "fine" and simultenous insistance of being "concrete" but I did move the post to #data-science-and-ml so I hope you're satisfied.

grave jolt
#

While it may be hard to describe exactly what this channel is for, it's definitely not for looking for collaborators.

gloomy rain
#

@unkempt rock Refrain from posting random nonsense in here.

unkempt rock
#

my bad

#

i didnt mean sth sorry im a little blind

unkempt rock
peak spoke
#

No, isinstance checks whether the first argument is an instance of the second one; the type bool is not an instance of the int type

unkempt rock
#

yep, but afaik mro list all the superclasses of an object, no?

peak spoke
#

You'd have to use issubclass, or create an instance of the bool type

unkempt rock
#

oh yeah

#

i completely forgot about issubclass

unkempt rock
#

does anyone have any good python book please?

boreal umbra
#

!resources @unkempt rock

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.

boreal umbra
#

However this channel is for advanced discussion so please stick to the channel topic going forward. Thanks!

red root
#

hello can someone look over my code it has errors that im not sure how to fix up?

gleaming rover
boreal umbra
#

can you get a recursion error if your call stack gets too high, even if they're not recursive calls to the same function?

raven ridge
#

yes.

boreal umbra
#

This code appears to prove as much

#
def my_func():
    def _new_func():
        return my_func()
    _new_func()

try:
    my_func()
except RecursionError:
    print('yes')
raven ridge
#

RecursionError is really more of an exception raised for stack overflows (or, Python raises it before a stack overflow occurs, to try to prevent a stack overflow)

#

!d sys.getrecursionlimit

fallen slateBOT
#
sys.getrecursionlimit()```
Return the current value of the recursion limit, the maximum depth of the Python interpreter stack. This limit prevents infinite recursion from causing an overflow of the C stack and crashing Python. It can be set by [`setrecursionlimit()`](#sys.setrecursionlimit "sys.setrecursionlimit").
raven ridge
#

It's not intrinsically tied to recursion, that's just by far the most likely way of triggering it.

livid mason
#

can someone p=welp me with multiple string matching in python

#

like I have a string "xyz"

#

and I want to compare the string with a list like ["abc","xyz"]

#

If the string is there then it should return true

#

it should also be like if the list is ["abc","xyz"] and the string is "xyzz" then it should return that the string is a close match

visual shadow
livid mason
#

because xyzz is similar to xyz

#

@visual shadow

#

could u pls help me

keen sentinel
#

Well I'm looking for a meaning/root of a name

lyric marsh
#

how to loop through a loop then another

stable grail
#

#python-discussion is a discussion channel, not a help channel. if you need help with a question you have @keen sentinel you can use our help system.

#

this channel is also a discussion channel, but for more high level python concepts and such. like the topic describes

keen sentinel
#

@stable grail I've been in this server for a long time, Ik that. It was more like a question with a one-word answer. Like what is int short form of? integer. It's not good to occupy a help channel for such thing

stable grail
#

no, python-general is perfect for that if someone answers

#

but if its very crowded, questions get lost in the flow

#

if you see me online, you can always just ask me in a help channel and ill answer if i know it ๐Ÿ˜„

keen sentinel
#

Ik, that python-general is good for that and it wasn't much crowded at that time

#

And 'bout you, I don't think if it's good to mention you. You've works to do.

#

Also, why don't I see sublime in your rich presence, lol

stable grail
#

you can mention me as long as i have given you permission to do so ๐Ÿ˜„

keen sentinel
#

๐Ÿ™

stable grail
#

ill just not answer if im unavailable

#

i have moved over to pycharm

keen sentinel
#

I see, logical

#

Finally

stable grail
#

have not setup rich presence

keen sentinel
#

๐Ÿ‘

fleet night
#

Thanks

dusky kettle
#

does anyone know abt a simple python program to create an interesting output?

#

hmm..u guys r taking more than 10 seconds for this question...haha

feral cedar
dusky kettle
#

oh okay..sorry..am kinda new here

#

pls forgive me guys

unreal basalt
#

Folks, Python 3.9 is here!๐Ÿ๐Ÿฅณ We've compiled some of the amazing features it brings, check it out!

#

Sorry I sent the link because a bot is not allowing me to send the pdf ๐Ÿ˜ฆ

unkempt rock
#

@unreal basalt I wasnโ€™t able to see your 6 other infographics, but for your merging dictionary you said that | is a new operator. Itโ€™s not. Itโ€™s called the bitwise or operator and it already existed before. https://wiki.python.org/moin/BitwiseOperators

boreal umbra
#

@unreal basalt you can definitely talk about the changes in 3.9 here (we're excited too!) but this server isn't a place for self-promotion. Thanks!

cursive berry
#

@unkempt rock |= is a new operator in 3.9 it's for dictionary concatenation but I have a bad memory so please double check xD

peak spoke
#

the operator is not new, its behaviour with dicts is

unkempt rock
#

He wasnโ€™t talking about |= he was talking about |

cursive berry
#

Okay, it was mentioned on real python website so

#

ยฏ\_(ใƒ„)_/ยฏ

boreal umbra
#

@cursive berry the pipe operator has existed for a long time. You can also use it for set union.

cursive berry
#

Didn't know, thanks a ton

boreal umbra
#

all the operators have an in-place variant

teal yacht
#

the | token itself isn't new, the fact that it can be used for dict union is

boreal umbra
#

except for super meta ones like the dot operator, I guess

cursive berry
#

What about the walrus operator

boreal umbra
#

inb4 __igetattr__

#

@cursive berry the walrus operator doesn't really act on objects, for the most part. it's part of the language for assigning variables.

unkempt rock
#

I feel like python should have a function composition operator like haskell does to avoid the amount of closing brackets

boreal umbra
#

@unkempt rock it absolutely does and I'll never stop fighting for it

true ridge
#

We already have too many features in the language ๐Ÿ˜‹

boreal umbra
#

@true ridge but we don't have function composition

true ridge
#

Every new feature = tons of complexity and maintenance cost

unkempt rock
#

I just started learning haskell and thought of implementing it in python. I made a simple decorator (without ast.Nodetransformer because I still have to learn that) that behaved like that. It just doesnโ€™t function properly many times so Iโ€™m trying to find a fix for that

boreal umbra
#

sorted(set(list(sum(matrix_data.keys(), ())))) could be made (sorted @ set @ list @ sum)(matrix_data.keys(), ())

#

so much better

unkempt rock
#

Yep

teal yacht
#

sum(matrix_data.keys(), ()) you ok my dude

#

is that actual code

boreal umbra
#

yes

teal yacht
#

no i mean, do you have that in your codebase

boreal umbra
#

yes

teal yacht
#

sorted(set(matrix_data))

true ridge
#

It looks like a great thing to collect data on, will return with stats about how much of top pypi projects return nested calls at which depth!

cursive berry
#

You can sort sets???? Wtf

teal yacht
#

no it returns a list

boreal umbra
#

@cursive berry if you sort a set, you get a list

#

you can't have an ordered set

cursive berry
#

Oh, that makes sense

#

I swear I've read it's unordered

boreal umbra
#

you did, and you're right ๐Ÿ˜„

teal yacht
#

unless i'm very mistaken, set(list(sum(matrix_data.keys(), ())) is strictly equivalent to set(matrix_data)

  • assuming dict
feral cedar
#

cause it is

teal yacht
#

oh wait no you have to make it an actual iterable

boreal umbra
#

@teal yacht matrix_data is Dict[Tuple[str, str], int]

#

so I have to flatten out the tuples into a sorted list of unique elements

mint forge
#

May I ask use case of @staticmethod in this channel?

teal yacht
#

it's for using classes as namespaces

boreal umbra
#

@mint forge I suppose. It creates a method that does not act on an instance of the class.

teal yacht
#

generally speaking a bad idea

boreal umbra
#

So you're just using the class as a namespace for a function.

mint forge
#

@mint forge I suppose. It creates a method that does not act on an instance of the class.
@boreal umbra that i do know, but like in what situations would u use it

boreal umbra
#

well, you usually don't

#

I heard Guido even regrets having added it

mint forge
#

then why does it exist?

peak spoke
#

I quite like it in some cases, don't understand the aversion some people have to it

mint forge
#

ohh

teal yacht
#

because consistency with other oop languages and @classmethod

#

if a function is unrelated to a class, why should it be inside it ? @peak spoke

mint forge
#

so that u can call that function inside that class?

teal yacht
#

just define it outside

boreal umbra
#

if you ever have a method that doesn't act on an instance of a class, but for whatever reason you feel it needs to be included in the class, you have that option with @staticmethod

#

but I usually define methods like that outside the class

#

with a leading underscore if they're just helper functions for that class.

mint forge
#

right, well I was thiking of using staticmethod i guess i will define it outside

#

@boreal umbra what are helper functions

boreal umbra
#

an informal term for functions that help you do the things a class is visibly meant to do.

#

but which aren't part of the class's interface

mint forge
#

i see, and what would that look like

boreal umbra
#
def _helper_function(a, b):
    """this does file IO or something"""
   ...

class Dog:
    def bark(self): ...
    def wag_tail(self): ...
mint forge
#

i see, wouldn't helper functions go against PeP 8

#

cause of _

peak spoke
#

If it's a helper that's strictly useful only in that class in your app, I don't see a reason to define it outside

boreal umbra
#

@mint forge nope, you use a leading underscore to say "don't worry about this, nothing to see here"

mint forge
#

ohh ok Thx for your explanation

#

i appreciate it

boreal umbra
#

@peak spoke if someone goes to the source code for your class, they probably just want to see what they can do with it

gloomy rain
#

I also like using static methods for class-related helper functions. I don't think it makes a big difference whether you put it inside or not.

#

Maybe for the sake of language purity, it would've been better not to add it in the first place, but it's not going anywhere now, and I don't think there's any serious disadvantage to using it.

sacred yew
#

usually i use static methods for factory functions

teal yacht
#

you should use class methods for that

sacred yew
#

oh

gloomy rain
#

!tempmute 379004908243910657 7d You're blatantly trying to circumvent the voicegate by adding bullshit remarks in various channels. Stop that.

fallen slateBOT
#

:incoming_envelope: :ok_hand: applied mute to @frigid vortex until 2020-10-27 14:11 (6 days and 23 hours).

sacred yew
#

yeah that

boreal umbra
#

I guess I'm glad we have static methods because if I ever feel the uncontrollable urge to namespace some functions in the same file, I have that option. And I like having options.

#

defining a few functions before defining a class is a pretty common pattern in my code though.

peak spoke
#

I had a nice example use for it that I liked but looks like I overwrote it with some features

true ridge
#

It looks like a great thing to collect data on, will return with stats about how much of top pypi projects return nested calls at which depth!
@true ridge so far, the results are;

Results: Counter({2: 157567, 3: 8542, 4: 413, 5: 21, 8: 10, 10: 9, 7: 3, 6: 3})

2 => A(B(*x, *y))
5 => A(B(C(D(E(*x, *y)))))

#

Looks like the composition only goes up to 3 calls usually

#

for some rare cases 4, and then it gets into 2-digit numbers

peak spoke
#

Do you have an example of the 10 nested calls?

true ridge
#

let me get it

peak spoke
#

Just wondering if it's just some toy project or actual production code

true ridge
#

Just wondering if it's just some toy project or actual production code
@peak spoke apparently its from a test case

10 disk/rawdata/clean/graphql/utils/tests/test_build_client_schema.pyGraphQLField(GraphQLList(GraphQLList(GraphQLList(GraphQLList(GraphQLList(GraphQLList(GraphQLList(GraphQLList(GraphQLNonNull(GraphQLString))))))))))
gloomy rain
#

Looks like declaratively building a data structure.

solar grove
#

yea just chaining lists

#

like a russian nesting doll lol

unkempt rock
#

@supple quiver @gritty canopy This isn't a help channel, it's for the discussion of the language itself. You should claim a channel. #โ“๏ฝœhow-to-get-help

gritty canopy
#

@unkempt rock Sorry I saw the "use case" in the topic header and I thought maybe I could ask here. I have removed my message

unkempt rock
#

All good

manic hatch
flat gazelle
#

@manic hatch do not advertise your help channels in other channels

uncut sun
#

I feel like I am done with basic python.. Any clue where I can start learning "Advanced Python"?

gloomy rain
#

@uncut sun If you feel like you have a decent grasp of the fundamentals, the natural next step would be to start working on your own projects. There's no better way to learn and develop than by putting your skills into practice.

#

!projects Here are some ideas.

fallen slateBOT
#

Kindling Projects

The Kindling projects page on Ned Batchelder's website contains a list of projects and ideas programmers can tackle to build their skills and knowledge.

uncut sun
#

Tysm!

#

Also what does advanced python even have apart from like machine learning. Also do databases count as advanced?

spice pecan
#

This channel in particular is more centered towards advanced features of the language, not advanced applications/libraries/use cases

#

A good example would be meta-classes

gloomy rain
#

Also, it's more aimed at discussions like high-level design and architecture of your codebase, competing definitions of best practices, etc. Questions that don't have a cut and dry objectively right answer. In relation to Python.

uncut sun
#

Oh ok sorry

gloomy rain
exotic arrow
#

@gloomy rain Mine also?

gloomy rain
#

If your question has a single concrete objective answer, it probably doesn't belong here.

molten onyx
unkempt rock
#

hello how i do when someone react to a message the bot copy his id and add to a database?

grave jolt
unkempt rock
#

ok but ho can help me

gloomy rain
#

!tempmute 639896103130628186 1d This is the second time you post the exact same question in here and I told you last time this is not the right place, so it seems like you're blatantly ignoring staff instruction. Please reread the rules before you come back.

fallen slateBOT
#

:incoming_envelope: :ok_hand: applied mute to @unkempt rock until 2020-10-21 19:40 (23 hours and 59 minutes).

spark magnet
#

This might also be wrong for this channel, I'll delete if so: anyone have a Windows dev machine and want to try reproducing a funky virtualenv bug in the coverage.py test suite? https://github.com/pypa/virtualenv/issues/1990

gloomy rain
#

I think analyzing funky bugs in widely used Python tooling falls within the scope of this channel.

spark magnet
#

now we just have to get someone to try it ๐Ÿ™‚

charred wagon
#

Gave it a shot but setuptools fails to find MSVC so it fails. Probably can't test this since Python has never been able to detect MSVC for me.

cloud crypt
#

it looks for something specific

spark magnet
#

@charred wagon hmm, thanks anyway

cloud crypt
#

but like, not sure

#

(talking about python and MSVC)

frosty panther
#

how do i convert NAN to float/int

cloud crypt
#

what type is you NaN in?

#

python's NaN is float already

frosty panther
#

then my error is indescribable

#

lmfao

charred wagon
#

@spark magnet Everything passes for me. Tested on 3.7; can't easily test 3.8 right now.

#

(I managed to fix the MSVC issue)

cloud crypt
#

oh nice

radiant fulcrum
#

@spark magnet I take it we do not need to setup a virtual environment for this?

spark magnet
#

@spark magnet Everything passes for me. Tested on 3.7; can't easily test 3.8 right now.
@charred wagon Hmm, thanks for doing it, but I'm disappointed that it didn't reproduce.

#

@spark magnet I take it we do not need to setup a virtual environment for this?
@radiant fulcrum You don't need to, though I am in the habit of always making virtualenvs for things like this.

radiant fulcrum
#

Okay so with Python 3.8.2 32bit I pass that test without it getting stuck

#

I fail others but 890 passes

spark magnet
#

Okay so with Python 3.8.2 32bit I pass that test without it getting stuck
@radiant fulcrum OK, thanks so much for trying it.

low lagoon
#

@gusty sail If you're not happy about something, please contact @summer lichen.

desert peak
gleaming rover
#

what's the relevance of the second part of your message?

desert peak
#

that any "real" discussion about python tends to happen here

gleaming rover
#

that any "real" discussion about python tends to happen here
@desert peak yup; #python-discussion is the first channel that most people see, so lower-level discussion tends to go there

#

along with small questions

desert peak
#

the python subreddit has the same problem

gleaming rover
#

I think it's a natural tendency to drift towards the lowest common denominator, which gets more basic as communities grow bigger

deft pagoda
#

in any case, this is a meta discussion not really an advanced python one

gleaming rover
#

yup

desert peak
#

real discussion: looks like py310 will cache opcodes called 900+ times resulting in gains up to 10%

blazing crater
#

I managed to stumble upon this by accident and I really agree with most of it and just wanted to share https://github.com/markshannon/pep622-critique
@molten onyx
Ouch, that was harsh. But, i strongly agree with it too

desert peak
#

I heavily disagree with it. PEP 622 is powerful and I think other languages having pattern matching is evidence for that

#

I think most of the criticisms aren't problems with the PEP but with Python itself

hollow crane
#

right but what do you do about that

#

i think python's rather sparse syntax makes it very prone to people suggesting not terribly well thought out ideas

#

because there's a lot of room for syntax

peak spoke
#

Personally I don't find the feature that fitting into the language

desert peak
#

really? I feel myself missing a switch-like statement all the time

#

especially with enums.

spark magnet
#

i find Python's enums clumsy and mostly not worth the trouble

radiant garden
#

have to agree there

desert peak
#

they're clunky because they were added on as an afterthought to extend classes instead of a powerful thing on their own merit

spark magnet
#

they're clunky because they were added on as an afterthought to extend classes instead of a powerful thing on their own merit
@desert peak right, and isn't it possible that pattern matching tacked on after 30 years might produce a not-great fit also?

desert peak
#

enums are a great fit in any programming language... you're taking one bad implementation and using that as a blanket exception

spark magnet
#

tbh, i don't know much about the 622 design. My point is that great features from other languages don't always land well in python.

gleaming rover
#

enums are a great fit in any programming language... you're taking one bad implementation and using that as a blanket exception
@desert peak how would you have implemented them then

desert peak
#

as a first-class citizen instead of an extension. algebraic enums are perhaps the most powerful thing I've seen in a language

hollow crane
#

i've yet to see an implementation of pattern matching in python that isn't just like you bolted random bits of other languages on

#

which isn't to say it can't be done

spark magnet
#

new keywords are difficult

hollow crane
#

and yes a lot of them introduce new keywords which the author seems to have intended to do whatever the user wants in that particular circumstance

#

and then designed the actual syntax around a few examples

desert peak
#

using the age of the language as an argument against isn't really a valid argument @spark magnet considering the py2/3 split that was just a decade or so ago.

#

python is still actively developed

spark magnet
#

@desert peak ok, forget the age. adding features is a tradeoff, and it sometimes comes out clumsy

#

Python values backward compatibility, so new keywords are nearly impossible

desert peak
#

so because enums were incompetently implemented, we should never have new features?

#

because that's what your argument sounds like

spark magnet
#

no, i'm saying sometimes the compromises are unfortunate and maybe not worth it.

hollow crane
#

from what i've seen, pattern matching in languages similar to python ends up as a core language feature

#

i.e. the entire language is built around it

#

python's way of doing things seems to pretty fundamentally conflict with the pattern-matching approach, and given that introducing pattern matching in such a way would require a completely new paradigm of functionality, I don't see that it's a very good fit for python

desert peak
#

I mean, C# is an example of pattern matching implemented "late" and doing very well

hollow crane
#

c# has many more keywords though

#

and more of that c 'magic syntax' thing

desert peak
#

? explain

hollow crane
#

well

#

python's layout and the way its syntax is constructed is in general very coherent

#

and follows a pretty limited set of modes of behaviour

#

things like comprehensions are a bit of a leap from this, but imo they manage the tradeoff well

#

if you were to implement pattern-matching in a similar way, you essentially introduce firstly a whole load of different syntax that's conceptually incompatible with most of existing python

#

and secondly introduce a load of situations in which a variable could be treated as a pattern matching parameter, or a pattern literal

desert peak
#

every person I've worked with has had to have comprehensions explained to them in depth more than once because of how much syntax sugar is packed in

spark magnet
#

i'm not sure how that relates to 622

gleaming rover
#

really?

desert peak
#

we're talking about "magic" right now

peak spoke
#

the syntax of comprehensions/genexps is trivial compared to the currently proposed pattern matching syntax

gleaming rover
#

I don't find comprehensions particularly sugary or incomprehensible

desert peak
#

@peak spoke what is your specific complaint with what's proposed as-is? I didn't realize literally every PEP was so controversial. it's like the community is full of C89 devs

boreal umbra
#

@desert peak every change to the language is controversial, it seems.

desert peak
#

I just went to look for discussion around None-aware syntax and the community scared away the devs because None isn't "special enough"

#

really bummed me out

#

dealing with null is a headache and a half

boreal umbra
#

What is it that you do that would benefit from them?

desert peak
#

anything that is optional

gleaming rover
#

None-aware operators are really nice

#

basically Option.map but not

desert peak
#

even javascript saw the value of null-aware syntax

gleaming rover
#

I must say TypeScript is really pulling ahead

blazing crater
#

I believe the thing about the PEP isn't the feature, it's because it was poorly designed

gleaming rover
#

^

peak spoke
#

I think it's a big addition, in some cases with noisy syntax, without bringing that much into the language

grave jolt
desert peak
#

what am I looking at

grave jolt
#

I have no remorse

#

but making all of these features work with this exact syntax required dynamically creating a metaclass and a metametaclass

desert peak
#

I'm serious though, what am I looking for

gleaming rover
#

basically enum.Enum but with tuple values...?

#

i.e. sum types

grave jolt
#

yep

desert peak
#

I'm unfamiliar with the concept

gleaming rover
#

I have no remorse
@grave jolt I support this

#

still waiting for destructuring though...

#

honestly I wouldn't mind giving up pattern matching for just destructuring

grave jolt
#

@desert peak oh, I thought you meant you hated me for creating it, sorry :)

Basically, a sum type (also called disjoint union) is a type that consists of different "variants", each with its own set of fields.

#

So, like a Union of several namedtuples

gleaming rover
#

how did you get that to work?

#

did you hook NameError?

grave jolt
#

So, like a Union of several namedtuples
For example, if you want to encode a JSON data structure, you can do

// Rust
enum JSON { 
    Str(String);
    Num(f64);
    List(Vec<JSON>);
    Object(Vec<(String, JSON)>);
}
gleaming rover
#

ooh Rust is so ugly

#

I love it

grave jolt
#

๐Ÿ˜ฆ

gleaming rover
#

I mean it IS

#

but not in a bad way

desert peak
#

@grave jolt reminds me of Rust

#

oh it is rust lol

gleaming rover
#

wait so how did you define each case

desert peak
#

I thought that was called an algebraic enum?

grave jolt
#

@gleaming rover I hooked __getattr__ for SumTypeMeta, the metaclass of SumType. Since in the scope of a class definition, it accesses the class attributes

gleaming rover
#

did you catch NameError?

#

it does?

#

TIL

grave jolt
#

@desert peak They are also called algebraic datatypes. Maybe they're also called algebraic enums. They probably have more names

gleaming rover
#

I thought that was called an algebraic enum?
@desert peak I wasn't sure what you meant when you said "algebraic enum" TBH

desert peak
#

gotcha. that's probably my favorite feature in Rust

gleaming rover
#

but I believe algebraic data type (and in this case, specifically sum type) is the more common term

desert peak
#

TIL

grave jolt
#

I should probably add comments

#

One important distinction from NamedTuples is that equality comparison is strongly typed, i.e. Json.Str("hi") != ("hi",)

desert peak
#

dooooes it tho

#

one thing I'm sad about is slow adoption of features to popular frameworks in the name of backwards compatibility

#

as we talk about new features

spark magnet
#

@desert peak it's a tough balance. if Django wants to run on 3.6, it can't use features that only work on 3.8

desert peak
#

@spark magnet it is. I wish there was a better way for features to work

spark magnet
#

i guess something like JS's thing (babel?) for compiling back to older versions

desert peak
#

might not be such a bad idea. but also have you seen the macros idea?

spark magnet
radiant garden
#

Hmm, good question. Is there a way to polyfill AST with newer python features to earlier versions of python?

spark magnet
#

Hmm, good question. Is there a way to polyfill AST with newer python features to earlier versions of python?
@radiant garden i don't know of a way

radiant garden
#

Doubtlessly there's nothing as robust as babel

#

But there's also less of a dependency on extreme backwards compatibility, since python apps doesn't have to support decade-old browsers

#

(or the converse)

desert peak
#

most web code doesn't anymore either, tbh

#

I really wish Win7 would die as a bit of off-topic

spark magnet
#

I also got a bug report recently about IE 11.

gleaming rover
#

I was browsing PEP 638 and realised it said this:

We would like that ability in Python, without the many parentheses that characterize lisp.
that's pretty savage I have to say

#

incidentally, I believe there is some way to specify a custom parser for a Python module, but I'm not sure if I'm remembering wrongly

#

anyone know anything about this?

visual shadow
#

Friendly reminder to stay on topic: this is not #python-discussion
Discussion on the use cases, implementation and future of the Python programming language including PEPs, advanced language concepts, new releases, the standard library, and the overall design of the language.

boreal umbra
#

There are three off-topic channels. If you'd like to discuss the structure of the server some more, check out #community-meta. Otherwise let's quickly return to the topic of this channel. Thanks!

smoky thicket
hallow pilot
#

@smoky thicket check the URL/TSL

#

or it might be from the server itself

grave jolt
unkempt rock
#

Can someone figure out how to resolve this error. Thanks in advance!!
@smoky thicket this error comes when you are not connected to internet, this happens to me also

junior moat
#

Hello folks, I've a question: how would you look for thousands of strings within a file ?
would you build a big regexp ? another way ?

flat gazelle
junior moat
#

it was more of a design question than an help one but fair enough

#

algo-and-data-structs seems more appropriate

flat gazelle
#

Ye

wide totem
lyric marsh
#

hi

frozen abyss
near stream
#

I'm familiar with LISP languages (CL, Clojure).

#

(callback (now) my-func (+ i 1))))) : more precisely, this line of code is the tricky part! (first example)

#

Temporal recursion is a not so well known technique most often used for strict-timing / real-time timing in audio/visual applications. In my case, approaching realtime is enough so I guess Python can do it efficiently

#

I moved my question here following @unkempt rock directions

unkempt rock
#

yea i thought here would be better than a help channel. seems pretty involved

spark magnet
#

for me, the tricky part is reading that linked page... Anyone ever heard of styling and max-width? ๐Ÿ™‚

near stream
#

I believe that this webpage was directly exported to HTML through org-mode. I guess that at least it's lightweight and can be saved as a file on your computer. Pretty cool for research purposes

#

Zooming like crazy makes it easier to read

spark magnet
#

i wish I could find a proxy that would re-serve a page with some css applied to it.

fallow bramble
#

Hi !!!! I'm a French Engineer Students and for an English homework I need to ask some questions
to a English Speaker who works in a company.
For that I send you the question in a pdf and you answers in an audio file. It will take less than 10 min for you .
Please send me an private message if you or someone in your entourage can help me , I will answer you very as soon as possible.
Thank for Your Attention.

grave jolt
#

@fallow bramble This is off-topic for this channel, and requests for help with your non-Python research project are not for this server.

grave gale
#

@spark magnet give "dark mode theme" extension a try, it's better than raw html

fallow bramble
#

Ok sorry ๐Ÿ˜”

spark magnet
#

@spark magnet give "dark mode theme" extension a try, it's better than raw html
@grave gale i know dark mode is all the rage these days, but 1) I prefer light, and 2) it's got nothing to do with the width of the text.

grave gale
#

I see, that's another matter then

near stream
#

Anyway, to get back to my question, looks like there is Clojure package that does pretty much the same thing:
https://github.com/overtone/at-at

However, the description for what is achieved is different even though the technique of temporal recursion is definitely still there:
Simple ahead-of-time function scheduler. Allows you to schedule the execution of an anonymous function for a point in the future.

#

Internally, it uses a Java ThreadPoolExecutor. Sounds like concurrent.futures, am I right?

lyric marsh
#

does anyone know tech with tim in real life

unkempt rock
lyric marsh
#

k

desert void
#

does anyone work on a mypy plugin? I'm trying to make a plugin that works like this:

A = strawberry.union("Name", (str, int))
reveal_type(A) # Union[str, int]

I could use annotated, but I'd like to check if I can do this first

faint compass
#

Anyone here super-familiar with PyTest? I'm wondering if I'm going down the wrong path trying to make a fixture that automatically monkeypatch/mock the XMLRPC ServerProxy class. My thinking is - I can just include the fixture and have it automagically replace all XMLRPC calls behind the scenes - however I'm having trouble getting it to work. My feeling is that the monkeypatch is not continued between fixtures

sullen owl
#

It's common to monkeypatch something as a fixture. There's no such concept in pytest like continuity between fixtures. Instead you may choose different scope for a fixture, like class, module, or even whole test session. Or you can make one fixture dependent on the other. But I don't get how it's related to monkeypatching itself.

faint compass
#

If I have Fixture A that includes a monkey patch, and Fixture B that uses Fixture A . Will the monkeypatch still apply in Fixture B?

sullen owl
#

Yes, fixture B uses fixture A, so your test requires both A and B, and monkeypatch will be applied.

faint compass
#

OK cool so it's likely some coding issue on my end that I'm running into - I'm just going to try and create a super basic example to test it out

sullen owl
faint compass
#

yeah that's what I'm using - which the rollback part may be what I'm running into if it's being done early

raven ridge
#

incidentally, I believe there is some way to specify a custom parser for a Python module, but I'm not sure if I'm remembering wrongly
@gleaming rover there's a hack for it: you can use a coding comment as the top of a file to declare the codec to use for decoding the source code into Unicode. It's meant to say "this code is in Latin-1" or "this code is in UTF-16", but there also exist codecs that take input in UTF-8 and produce different, rewritten output in UTF-8, which has been used to add macros or new language features, etc.

teal yacht
#

<insert mandatory "don't do that tho">

desert peak
#

@faint compass Fixtures work where you include them

#

you can also choose to scope them for auto-includes

sullen owl
#

Most likely it's not the problem of rollback machinery, but problem of monkeypatching itself. E.g. you have two modules:

abc.py:

a = 5

xyz.py

from abc import a

Then you monkeypatch abc.a and set it to 8. Here xyz.a will still be 5, since you're monkeypatching property of abc module, i.e. all accesses of abc.a, but you don't affect xyz.a accesses. @faint compass

faint compass
#

that's probably exactly what is happening

desert peak
#

yeah, monkeypatching takes some experimentation

#

it's rather annoying

faint compass
#

I put all the mocking into it's own module for reuse and to keep things tidy

#

I just did a test all in one file and it appears to be working like expected

sullen owl
#

from abc import a basically does

import abc
a = abc.a

it puts old object of abc.a into the module xyz, before you monkeypatch abc

#

Yep, sometimes you have to reorganize the code to make it testable.

faint compass
#

Well this will be a bit tricky - but just means that the testing code will be more complex - as I need the tests first before I can re-organizing the legacy code (even to make it testable haha)

sullen owl
#

Alternatively you may apply several monkeypatches, abc.a and xyz.a. Little bit more work, but requires no modifications in legacy code.

faint compass
#

@sullen owl you have read my mind as I was just trying that out now

sullen owl
#

One extra trick on monkeypatching ๐Ÿ™‚ I'm still afraid to use it in production code, but it seems to be working anyway.

>>> def fn(a, b):
...   return a + b
... 
>>> def new_fn(a, b):
...   return a * b
... 
>>> fn(3, 8)
11
>>> fn.__code__ = new_fn.__code__
>>> fn(3, 8)
24
desert peak
#

@faint compass personally, I dump all my fixtures in conftest.py

unkempt rock
#

what do you guys think about import typing as t ? I found it browsing at github an found it very clean

sacred tinsel
#

I like it a lot and use it everywhere

#

we call it 't-dot' notation lol

grave jolt
#

!e

def f():
    return 42

f.__code__ = f.__code__.replace(co_consts=())

f()
fallen slateBOT
#

@grave jolt :warning: Your eval job has completed with return code 139 (SIGSEGV).

[No output]
grave jolt
#

reminds me of this

desert peak
#

I don't like renaming stdlib symbols. It makes looking through import intellisense non-sensical @unkempt rock

#

if I need things to be shorter, I'll just import the symbol directly, i.e., from typing import Optional

flat gazelle
#

you can get really long import lines from that

desert peak
#

you can but your files might be too long if that's a problem first

flat gazelle
#

some things just have really distinct types

peak spoke
#

The builtin generics ought to help with it, but I don't think renaming typing to t is that big of a difference as you don't use it in the working part of usual code

unkempt rock
#

sometimes you can have 10+ typing imports, that's why i found it nice

undone hare
#

Thanks to autocompletion, I prefer to use from imports for typing, since it keeps my import statements clean automatically, and it makes my signature way more readable

unkempt rock
#

if you need typing, just use the t.object

undone hare
#

I don't like importing it as t though

unkempt rock
#

i found it pretty readable

undone hare
#

Or any alias imports for that matter

teal yacht
#

with 3.10 we'll have both builtins as generics and |, no more 20 imports for builtins

flat gazelle
#

would be nice if we could do

a: typing.(Optional[Sequence[int]])
teal yacht
#

ocaml boi

undone hare
#

Generic builtins in 3.9 are already really good

torpid elk
#

I'm participating in a competition.
I need to come up with some innovative ideas to make a safe college campus during this period of covid19

#

Do you have some ideas?

undone hare
#

!projects maybe you could take at this list of projects, but it isn't the right channel for that

fallen slateBOT
#

Kindling Projects

The Kindling projects page on Ned Batchelder's website contains a list of projects and ideas programmers can tackle to build their skills and knowledge.

#

Kindling Projects

The Kindling projects page on Ned Batchelder's website contains a list of projects and ideas programmers can tackle to build their skills and knowledge.

desert peak
#

@teal yacht 3.9 already has generics for builtins

teal yacht
#

yes, but with addition to 3.10's |, it reduces verbosity even further

desert peak
#

agreed. won't need Union and that added syntax anymore

#

if we had null syntax.... we wouldn't need optional either

radiant fulcrum
#

well all optional is Union[Type, None] so ig you can use the | system like that

desert peak
#

yes, you can, but it starts feeling verbose over just Optional[T]

#

maybe verbose isn't the right word, but less clear

teal yacht
#

at least Optional is optional (hehe) for function parameters (if =None is provided)

desert peak
#

it is?

teal yacht
#

yeah

desert peak
#

I swear intellij has still complained to me if I annotate a type that has =None

#

without being optional

teal yacht
#

--no-implicit-optional you can disable it

#

not sure why anyone would do that given how easy it is to properly infer

#

(that's a mypy flag, idk about other weird checkers)

#
HP :: ~/Projects/PythonPlayground % cat __main__.py                                                                         
def foo(x: int = None) -> float:
  return .0 if x is None else float(x)
HP :: ~/Projects/PythonPlayground % mypy __main__.py                                                                        
Success: no issues found in 1 source file
HP :: ~/Projects/PythonPlayground % mypy __main__.py --no-implicit-optional                                                 
__main__.py:1: error: Incompatible default for argument "x" (default has type "None", argument has type "int")
Found 1 error in 1 file (checked 1 source file)```
desert peak
#

yeah, I don't use mypy in my ci/cd or anything, just editor

#

my team would have an aneurism if I enforced it in the pipeline

sacred tinsel
#

I think there is a proposal to use ? in some way to express optional

desert peak
#

there is, but it has been shelved because people argued None isn't "special enough" is the gist I got from the conversation @sacred tinsel

sacred tinsel
#

interesting

#

it's special enough to warrant Optional

desert peak
#

right?

#

it's also special enough to have special syntax in basically every other major language these days

teal yacht
#

it's also special enough that we use None instead of NoneType in annotations

lunar panther
#

Hello, I've got a numpy array of (16,) : it's just a list of elements like this one : python [A, B, C, D, E, F, G]
My goal is to get this list : python [(A,B), (B,C), (C,D), (D,E), (E,F), (F,G)]
I've got an idea of how to do it. It can be done in two steps :

  1. double interelements :
    (This is where I need help)
    I need to go from the base list to python [A, B, B, C, C, D, D, E, E, F, F, G]

  2. I just need to reshape with (-1, 2)

#

I think the doubling could be easier by just ignoring the first and last elements before, then the problem is just to get from :

[B, C, D, E...]
to
[B,B, C,C, D,D, E,E...]

(as functionnal as possible)

flat gazelle
#

I would use one of the stack functions

raven ridge
#

Optional seems to cause a lot of confusion, honestly, because the typing meaning of Optional (the given type or None) doesn't align with typical English meaning of "optional" (doesn't need to be given)

#

Which means functions can have required but Optional arguments, which seems to confuse just about everyone.

teal yacht
#

I don't think people would be happy with Maybe[T]

raven ridge
#

I might actually switch from Optional[T] to T|None in the future. It's both shorter and harder to misunderstand.

teal yacht
#

I'd expect anyone even remotely used to python to know that Optional is about None and not keyword arguments, it's mentioned everywhere, has entries on the mypy website, the official docs etc

raven ridge
#

Well, anecdotally, your expectation doesn't hold. I've seen people incorrectly annotate in both directions multiple times.

#

"Both directions" meaning arguments with non-None default values being incorrectly typed as Optional because they're not required, even though they don't accept None, and required arguments that accept None not being typed as Optional

#

I've gotten PRs on projects I own trying to introduce both of those bugs, in fact!

#

people were so convinced that it was wrong that they were willing to put in a PR to change it to be incorrect, heh

teal yacht
#

I acknowledge there's a problem, and I wouldn't mind other solutions, but I still think I'd raise an eyebrow if someone tried to PR that at my workplace

#

I just think we should write code like we do presentations, as in, we should tailor our code to the target audience, not who we think is the average reader

raven ridge
#

do you have other backend languages at your workplace? And are your Python programmers ones who grew up with typing, or ones who have been doing Python since long before typing existed?

teal yacht
#

Not backend, mostly data scientists coming from Matlab and R, and some other languages for some of them

#

Most of them are not by any means "python experts" (nor do they proclaim to be one)

raven ridge
#

could be my workplace is an outlier here - we're working on pushing C++ programmers to start writing more Python, meaning they're people who are largely picking up the language on the fly. But, I've definitely seen multiple developers get confused by optional-but-not-Optional and Optional-but-not-optional parameters.

#

And I think that confusion would actually be alleviated if people standardized on using None|T instead of Optional[T]. It's a nice thing to find something that's both less code and easier to read correctly.

teal yacht
#

Yeah yeah I agree that someone who is not used to the language can and will make that mistake

#

I was referring to an actual "python user"

#

whatever that means

raven ridge
#

"no true Scotsman"

teal yacht
#

Not someone that picked up the language a week ago

raven ridge
#

in my case we're talking about someone who picked up the language a year ago, on average, give or take.

teal yacht
#

yeah I think it's unacceptable then

raven ridge
#

๐Ÿ™‚

prime hornet
#

From the output of 'sar 1 5' linux command I want to take 3 colums and check if their values are above 5. What is the best way to do this in python? Using regex?

raven ridge
#

If we don't want people to make that mistake, then we should make it harder to make that mistake by picking names where the most intuitive meaning matches their actual purpose.

teal yacht
#

Yeah I agree with that

raven ridge
#

As it is, I think it's an extremely understandable mistake. And I don't think I've had to correct anyone on it twice, but we have a lot of developers.

teal yacht
#

But I still think Optional is basically hello world level for the usage of typing

#

But I also get that many people haven't picked up on typing yet too

#

In which case it's ok, make that mistake once, then move on

#

Which is also why I would be surprised someone would actually make a PR trying to correct someone else's code, assuming they were a beginner (w.r.t typing)

#

Maybe I don't have that kind of confidence

raven ridge
#

well, Optional[T] meaning "T or None" is definitely "hello world" level usage of typing, I agree there. And people don't seem to have any trouble remembering that when it comes to typing variables, or return types. But they seem to forget that when typing function parameters, presumably because it's common to describe parameters with default values as "optional", and they forget that Optional[T] means "T or None" as soon as this other meaning of "optional" enters the mix.

#

and it's even worse when you mix Sphinx in, because Sphinx has historically used count (int, optional): How many spam to buy as its syntax for a not-required parameter

#

so now, I've got docstrings that say count (int, optional) and I've got type hints that say count: int=42 and people are confused why it says "optional" in one spot and not "Optional" in the other.

#

I definitely agree that people should know their tools, but that doesn't absolve the tools from considering how easy it is to learn and remember and consistently apply something. ๐Ÿคท

signal tide
#

Imo part of the issue is most people that haven't learnt a statically typed language won't/don't see a need to approach it

#

Typing that is

desert peak
#

Optional wasn't the least bit confusing to me. T | None is more confusing imo for intention.

sacred yew
desert peak
#

@signal tide that is an atrocious thought that people have never even attempted statically typed langs

lunar panther
#

Hello, so I've got a working code for my problem above : ```python
array = np.array(times, dtype=dt)
s = array[0] # Save the start of the array
e = array[-1] # Save the end of the array
array = array[1:array.shape[0]-2] # Remove the first and the last element
array = np.array( # Convert the list back to np.array
[s]+ # Introduce back first element
list( # Convert to list
map(lambda x: x[0], # Function to convert [[(a,b)],[(c,d)]] to [(a,b),(c,d)]
np.dstack((array, array.copy()))[0].reshape(-1,1))) # Make a copy and zip the original with the copy
+[e] # Introduce back the last element
, dtype=dt # The actual type of the data
) # Magick to double the elements and introduce back the first and last elements
print(array.reshape(-1,2)) # Reshape the double elements

I'm fine with it, I'm just wondering if you have better ideas? I'm not really proud of the ndarray to map to list and back to nd array conversion
raven ridge
#

Optional wasn't the least bit confusing to me. T | None is more confusing imo for intention.
@desert peak why is None | int confusing? Do you also find float | int confusing?

peak spoke
#

I haven't worked with statically typed langs that much since pretty much all I do fits python nicely, but I still use typing pretty much everywhere because of what it brings to tools that read it and more documentation for the user

blazing current
#

So, in 3.9 they made typing easier with tuple, list and so on, but is there alternative for Union[A,B]? You mention A | B, is this valid to use it there now? Also, what about more rare types like Callable?

proven sleet
#

.

desert peak
#

@raven ridge Because of context and intention. Optional communicates a very specific idea.

raven ridge
#

@desert peak isn't it exactly the same idea as None | int communicates, with less linguistic baggage?

sacred yew
#

isnt optional standard programming terminology?

desert peak
#

Optional is more of a Maybe type to me, while None | int is a nullable value.

raven ridge
#

But the two types are identical. Both are aliases for Union[None, int]

desert peak
#

I know that, but this is about communicating ideas

#

intentions

sacred yew
#

optional suggests "int that can be None", while the other one suggests "int or None"

raven ridge
#

Ok... But if it's important to communicate those intentions, shouldn't different types be used?

sacred yew
#

which are 2 similar but related concepts

desert peak
#

Optional communicates null by default to me, tbh

#

because that's how it's used

raven ridge
#

But that's not what it means

desert peak
#

it literally is

#

lol

sacred yew
#

hm why doesnt python have real optional/maybe yet

desert peak
#

because python doesn't even have real enums

sacred yew
#

like at least a concrete class that does something

#

doesnt have to need first-class support

desert peak
#

it's not difficult to write, I'd just steal the API from Rust's Option type

quaint sentinel
#

Lol ok

raven ridge
#

it literally is
@desert peak No, Optional[T] is literally an alias for Union[T, None]

desert peak
#

@raven ridge you keep misunderstanding my words, so please drop it.

raven ridge
#

Union[T, None], Optional[T], and now T | None are identical as far as the type system is concerned. All 3 of them are aliases for the same exact semantic concept, and it seems strange to ascribe some higher meaning towards which spelling the user uses when all of them are defined to mean exactly the same thing.

desert peak
#

They do not communicate the same intention

raven ridge
#

I kinda buy the argument that perhaps there ought to be two different concepts that are distinct and have different types here, but if so they ought to be different to the type system, too

sacred yew
#

insert something about regexes and raw strings

raven ridge
#

that is: if it's true that they represent different intentions, then the type system ought to be able to preserve that intention and carry it along.

#

as it is, the type system is within its rights to collapse Optional[T] to Union[T, None] and lose whatever extra information was meant to be implicit in the spelling.

#

as far as the subjective connotations go: Do Union[int, None] and int | None mean the same thing to you, and it's only Optional[int] that carries a different connotation?

desert peak
#

Yes, @raven ridge

#

I see Optional as a Maybe or Option type from other languages, even if it's not an actual type of its own

raven ridge
#

interestingly, it could be reused to mean that for real if we can get everyone to stop using it for the current Union[..., None] meaning.

desert peak
#

my team does use it that way ๐Ÿคท

#

but I drive my team's practices, so that may be a part of it ๐Ÿค”

#

pattern matching and null syntax are something I dream of having in Python, but it seems people are opposed to both ideas for the language

raven ridge
#

so if you have something like:

def greet(name=None):
    if name is not None:
        print(f"Hi, {name}!")
    else:
        print("Hi!")

You would type name as Union[str, None] or as Optional[str]?

desert peak
#

I'd give it an option

raven ridge
#

and what's the case where you'd instead use Union[str, None]?

desert peak
#

no one would ever call your function with None

raven ridge
#

got it - so if None wasn't the default, but just happened to be an acceptable value, you'd use Union?

desert peak
#

I never use the 2 arg variant, it's usually a list of types, but that's almost always a sign something is wrong, though

#

Yeah, exactly

teal yacht
#
def greet(name: str = None):
  ...```
#

let the type checker infer all that

desert peak
#

that triggers errors in intj for me @teal yacht

teal yacht
#

get an actual static type checker ๐Ÿ™ƒ

#

(or maybe remove some default flags)

desert peak
#

I use the tools my job gives me ๐Ÿคท

#

although I haven't dug into non-default flags

#

JB products are just infamously opinionated so I assumed it wasn't an option

sacred yew
#

use vscode

raven ridge
#

If the type checker infers it, then we also lose whatever different connotation is meant to be conveyed by the use of Union[..., None] vs Optional, because it can't tell the difference.

desert peak
#

I have vscode, but the intellisense sucks in my experience

#

it dies a lot for some reason

#

I haven't tried the Pylance LSP yet, though

teal yacht
#

idk if there is actually a flag for that in JB products

desert peak
#

@raven ridge my intellisense window usually shows me the implementation example where Optional is still captured

raven ridge
#

Note that PEP 484 explicitly disallows the behavior of inferring Optional from an =None

desert peak
#

wellllll tell JB that lol

#

let me launch a JB session really quick

#

oof. my local copy is still on 2018. updating

raven ridge
#

https://www.python.org/dev/peps/pep-0484/#union-types

A past version of this PEP allowed type checkers to assume an optional type when the default value is None, as in this code:
def handle_employee(e: Employee = None): ...
This would have been treated as equivalent to:
def handle_employee(e: Optional[Employee] = None) -> None: ...
This is no longer the recommended behavior. Type checkers should move towards requiring the optional type to be made explicit.

#

So, mypy is going against the spec if it's still defaulting to --implicit-optional

#

and relying on that means that you're depending on the implementation behavior of a specific type checker to infer the write types despite your incorrect hints.

desert peak
#

oh, you're talking about ig's input

raven ridge
#

yep.

teal yacht
#

oh i didn't know about that

raven ridge
#

I have no particular thoughts on whether "if you don't provide this it will be None" ought to be a thing that it's worth capturing in the type hints, but I strongly feel that if it is then it ought to also be preserved, rather than simply being treated as in every way an alias for Union[..., None]

#

!e ```python
from typing import Optional, get_type_hints

def greet(name: Optional[str]=None) -> None:
if name:
print(f"Hi, {name}!")
else:
print("Hi!")

print(get_type_hints(greet))

fallen slateBOT
#

@raven ridge :white_check_mark: Your eval job has completed with return code 0.

{'name': typing.Union[str, NoneType], 'return': <class 'NoneType'>}
raven ridge
#

Given that the typing module does this ^ it seems unwise to ascribe special meaning to Optional above and beyond what Union[..., None] means

#

And that happens even with from __future__ import annotations; I've just checked.

atomic cape
#

Is it okay to post my problems here?

raven ridge
#

To me this seems like using single quotes to mean something different than double quotes, or using 5.00 to mean something different than 5.0 to me - if the language throws away the extra information that you were trying to convey, that seems... well, bad.

desert peak
raven ridge
atomic cape
#

I did it says cooldown now and i don't know how to get my response

desert peak
#

@raven ridge see my last message. afk a bit

atomic cape
#

oh wait

#

Im so dumb

#

sorry man

#

my bad lmao

raven ridge
#

I see it mburszley, but it doesn't really change anything from my POV - if that were instead name: str="Dave" vs name: str='Dave', sure, the IDE's popup can show you which one was used by showing you the source, but it doesn't change that the language interprets them identically

grave jolt
#
def greet(name: str = None):
    ...

well... that's a lie, a type checker should't let that slide!

#

Unless the type checker allows sneaking in None in place of any type, which is evil

raven ridge
#

mypy used to allow that, too, at one point, IIRC.

teal yacht
#

when will python type checkers support global type inference ๐Ÿ˜”

charred wagon
#

You mean without having to import?

#

Wouldn't that lead to ambiguity unless you use fully qualified names (which would be ugly)

#

If you just mean not having to use the __future__ import anymore, that'll be in 3.10

teal yacht
#

are you referring to me ?

charred wagon
#

yes

teal yacht
#

no, type inference is the ability to know and verify types without them being explicitly stated

#

it was meant as a joke, as it is not possible with the current state of python and likely never will be

charred wagon
#

What would "global" mean then in that context

teal yacht
#

any symbol can be inferred in any context

#

unlike for example c++ which has auto for only certain places (called local type inference)

desert peak
#

@teal yacht too much runtime BS in pretty much any popular python package

#

for static inference to be of any use

#

is there a list of protocols and their dunder methods somewhere for Python?

teal yacht
#

There are also some other dunder that are defined by standard libraries (copy) and 3rd party libraries (numpy) that aren't referenced here

sacred yew
#

like haskell?

teal yacht
#

yes, or any other type system based on HM

gleaming rover
#

@gleaming rover there's a hack for it: you can use a coding comment as the top of a file to declare the codec to use for decoding the source code into Unicode. It's meant to say "this code is in Latin-1" or "this code is in UTF-16", but there also exist codecs that take input in UTF-8 and produce different, rewritten output in UTF-8, which has been used to add macros or new language features, etc.
@raven ridge yeah, I got my question answered in #esoteric-python, but thanks!

desert peak
#

@teal yacht nice, this has a lot of them. I wish there was a page that had all the "protocols" laid out, like Iterable, Collection, etc.

raven ridge
desert peak
#

PEP 544 is what I'm thinking of

#

@raven ridge ah, perfect

#

between these two pages, I believe I have the information I want

teal yacht
#

oh i misunderstood you

desert peak
#

Python lacks the common word I want, which would be INTERFACES

#

It also lacks the syntax to express what I want but ๐Ÿคท

boreal umbra
#

@desert peak what is it that you want to do?

west nymph
#

I don't understand, isn't typing.Protocol exactly what you wanted to express?

desert peak
#

@west nymph what is the way to say what Protocols my type implements, is there such a thing?

#

in other languages, it's codified in the type

#

I think calling them Protocols instead of Interfaces was a weird choice

zenith topaz
#

You inherit from them.

desert peak
#

ah, so you would implement the abc essentially?

zenith topaz
#

wait, nvm

desert peak
civic flicker
#

i have a easy question for programmers, i selected dates from october to march.

ret_df[~((ret_df.index.month > 3) & (ret_df.index.month < 10))].dropna()```

 how can i select the other dates of the year? like april september
zenith topaz
civic flicker
#

it is an advanced discussion

#

maybe some people here are advanced in python

zenith topaz
#

Discussion on the use cases, implementation and future of the Python programming language including PEPs, advanced language concepts, new releases, the standard library, and the overall design of the language. is the topic of this channel.

desert peak
#

@zenith topaz So which is more "correct" - implement the ABC Iterable or the Typing Iterable?

#

It looks like 3.9 kind of gets rid of many uses of typing

gleaming rover
#

it is an advanced discussion
@civic flicker honestly, that's a very simple pandas question, and in any case this channel is for discussion of the language. if you want pandas help, you can try #data-science-and-ml.

zenith topaz
#

@desert peak typing.Iterable is deprecated

desert peak
#

only in 3.9+ - I'm stuck on 3.7 for the foreseeable future

zenith topaz
west nymph
#

@desert peak For protocol you don't have to declare it. It's duck typing, you just implement it.

#

Though you can inherit from it if you want to be explicit about it.

desert peak
#

@west nymph but how do you introspect that something quacks? I'm not so fond of the runtime exceptions

west nymph
#

@desert peak The primary use case for protocols is static typing, so the type checker does it for you.

#

If you use an ABC and mark your interface properly with the appropriate decorators, anything that inherits from the ABC but doesn't implement the interface will fail at class creation time, if that is more your speed.

desert peak
#

that is indeed what I'm looking for

charred wagon
#

To be clear, it fails at class instantiation, not at class definition

#

Which is an important distinction if you're trying to add static abstract functions

#

And then see it doesn't work like you expected ๐Ÿ˜ฆ

west nymph
#

What is the difference?

charred wagon
#

Well, if I have a class of purely static abstract functions, then there's no need to ever instantiate that class. therefore, the abstract checks will never fire off and fail

#

Unless I instantiate it somewhere just for the sake of triggering that once

west nymph
#

Oh you mean like at construction of an instance?

charred wagon
#

Yes

west nymph
#

Hmm. I never use this myself, I thought it was done through metaclasses specifically for the purpose of making it fail when the class is defined.

charred wagon
#

Yeah it's likely a niche use case, but I ran into it earlier this week

#

In fairness, the docs do state the checks only happen when its instantiated

west nymph
#

They say "class instantiation" and are referring to something that is accomplished via a metaclass.

#

I read that is "when we make an instance of the metaclass", but maybe I'm just not familiar with the term "class instantiation" and it's unambiguous to me.

charred wagon
#

I think this line from the docs is clearer on the wording

A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and properties are overridden.

#

That's from the abstractmethod decorator docs

west nymph
#

That sounds like it's saying you can't define the class.

charred wagon
#

It says the class cannot be instantiated, not that it cannot be defined.

west nymph
#

There's other stuff in here that suggests that it should fail at class creation, like if that's not the case, why are dynamically overridden properties and methods unsupported?

charred wagon
#

My guess is probably because it just doesn't run those checks once the instance is made

west nymph
#

The way I read that it reads like you cannot instantiate the class, meaning to create an instance of the metaclass.

#

I recognize that that reading is incorrect, but it feels ambiguous to me.

#

I checked just now and you are right, you can't construct and instance even though you can define it.

I still don't understand the dynamic method thing, though.

import abc
class A(metaclass=abc.ABCMeta):
    @abc.abstracmethod
    def m(self):
        pass

def free_m(self):
    print("hi")

class B(A):
    pass

B.m = free_m
B()  # Raises TypeError
#

I would expect it to either be OK with what I did there or to not be OK with the class B(A): pass part.

charred wagon
#

Ah that's what you mean. I thought you meant adding more abstract methods to the base class dynamically

#

yeah, I'm not sure why that's the case

#

It's hard for me to understand the implementation since most of it is in C

#

The idea was to initially have the metaclass implement __setattr__ to keep track of this stuff but they went with a helper method instead for whatever reason

west nymph
#

Wow, even .register() doesn't do the checks.

#

I wonder why not.

dire hull
#

if we make python statically typed will it run as fast as C?

#

what would not work if we do that?

#

or maybe we could static type partially?

#

like if i do n =1 i could just static type n but leave other stuff dynamic

#

i know cython could do this but its kinda not ideal

boreal umbra
#

@dire hull that's hard to answer because dynamic typing is fundamental to so much of the language's design that a statically typed Python-like language wouldn't really resemble Python.

dire hull
#

so lets say we have classes, loops and if else

#

if we make those partial static typed changes or fully static what would be impacted?

#

in terms of those 3 things or structures

safe hedge
#

As Stelercus say that's just such a fundamental change to the language that it's barely worth considering

dire hull
#

do we just get java

boreal umbra
#

@dire hull you can make a statically typed language that isn't Java.

#

and you're not required to shoehorn esoteric ideas about OOP into the language for it to be statically typed.

desert peak
#

cough C, C++, C#, Rust, TypeScript, others cough

boreal umbra
#

I heard Julia is a statically typed language with whitespace syntax.

desert peak
#

I've heard Julia is a compiled Python

boreal umbra
#

I don't think that's right

desert peak
#

Probably not, but a lot of data science people make comparisons between the two

boreal umbra
#

well, considering that data science people are mostly using Python libraries that are C under the hood...

dire hull
#

so how much faster is it to actually just directly using those C libs with C

#

than from python

#

or is it not faster at all?

boreal umbra
#

slower because you'd waste your life trying to do it in C

dire hull
#

in terms of execution time?

desert peak
#

there's a reason Python has the adoption it does

#

In author time.

dire hull
#

yeah but like what if in execution time

#

cuz i found this

desert peak
#

there's basically no difference in executing C code from Python vs. C

#

because C has a stable ABI, etc. etc.

dire hull
#

but what about the type that we are not declaring

#

does the C lib need to guess the type?

desert peak
#

no. the library authors handle that.

#

see: ctypes

dire hull
#

ohhh

#

so basically its the same

boreal umbra
#

say you're doing matrix stuff in Numpy. I think for sufficiently large matrices, the execution time of the Python portion is negligible.

dire hull
#

ah isee

safe hedge
#

The point is that it's all relative

dire hull
#

so i dont need to learn C

boreal umbra
#

I wouldn't learn C unless you want to do low-level stuff

desert peak
#

C is a valuable language to learn no matter what language you're using

safe hedge
#

At what point do you care about execution time differences

dire hull
#

its just too hard

desert peak
#

many, many languages utilize C's ABI to interop

dire hull
#

cuz training NNs takes hours on some smol training sets

#

fine tuning excuse me

#

with Titan

#

and i was wondering if i could accelerate it by moving to C

desert peak
#

oh, no.

#

people far smarter have already done the work

safe hedge
#

Isn't most python ML stuff already just wrappers around C code?

desert peak
#

correct

boreal umbra
#

yes

dire hull
#

i was worried if i do n = 1 in python then execute this in the wrapped C lib

#

would be slower than to to int n = 1 in C with C lib

safe hedge
#

And that's sort of my point. At some point complex stuff is just slow

dire hull
#

and stuff like this

#

cuz of the type

desert peak
#

eliminate as much IO as you can and let the CPU go brrrr

boreal umbra
#

well, the integer 1 is actually pre-allocated when the interpreter starts

dire hull
#

not just int but for all types

#

i have no idea if this is even a thing to consider

#

because we are just doing massive gradient matrix ops

#

which i have no idea how they were implemented in C lel

radiant garden
#

Choice of algorithm matters more than overhead

dire hull
#

so for exmaple if i loop execute some custom class operations 1000000 times with a C lib

#

would there be a dif in execution time between calling the wrapped C lib in python and calling the C lib directly in C?

safe hedge
#

If you don't know whether to consider it you probably just shouldn't worry about it

dire hull
#

im curious

#

just trying to understand lol

safe hedge
#

Optimise what you do understand first

dire hull
#

i think in theory it should

#

i do agree with you welsh but as i said i am just curious and would like to know

gleaming rover
#

I heard Julia is a statically typed language with whitespace syntax.
@boreal umbra it's dynamically typed, but typing has a runtime benefit

dire hull
#

not trying to optimize anything yet lol

boreal umbra
#

oh cool

#

that's something I wish python had, but only in the sense that it sounds nice and I don't want to think about the downstream consequences.

brave badger
#

would there be a dif in execution time between calling the wrapped C lib in python and calling the C lib directly in C?
@dire hull If there was, I'd believe it would be insignificant at best

dire hull
#

i see

#

thank lol

desert peak
#

@boreal umbra I mean, FastAPI uses type annotations to automatically generate OpenAPI definitions and stuff. It's very cool.

boreal umbra
#

@desert peak is that just for docs?

gleaming rover
#

that's something I wish python had, but only in the sense that it sounds nice and I don't want to think about the downstream consequences.
@boreal umbra it's quite different because Julia JIT compiles methods

desert peak
#

@boreal umbra no, it has runtime effects like schema validation and more

#

also: your pycharm shows up as a game in discord? that's weird

gleaming rover
#

IIRC a plugin is needed

#

but it's p cool, yeah

boreal umbra
#

yeah, it's a pycharm plugin

desert peak
#

huh, interesting

boreal umbra
#

I figured people would think I'm cool if they see me working on python code while on python discord

#

I need people to think I'm cool so I feel better about myself as a person

desert peak
#

ahahah, no doubt. especially during COVID days when everyone is kind of being terrible publicly

boreal umbra
#

let's head to an OT channel

#

if we want to go down that vein

raven ridge
#

We've got #c-extensions if you want to chat about using C to optimize things, @dire hull. But the handwavy answer is that the thing that the biggest thing that makes Python slow, at least in a single threaded context, is constant getattr calls and isinstance checks, which can be avoided by moving things into C by doing those once at the start and then caching the results for future calls.

#

Approximately, more or less, etc, etc.

dire hull
#

yeah that was what i wanted to know much thank

#

and aparrently using C++ api is faster than using python api at least for tensorflow lol

raven ridge
#

generally if something provides both a Python and a C or C++ API, it's because the latter is faster, so - yeah, that tracks.

#

if it weren't faster, they wouldn't bother maintaining it ๐Ÿ™‚

boreal umbra
#

@raven ridge why is getattr called so extensively?

#

isn't it basically a wrapper around x.__dict__.__getitem__?

desert peak
#

if performance really matters, wouldn't they use __slots__ ?

raven ridge
#

if you have py x = 1 y = 2 and you want to do ```py
z = x + y

that essentially boils down to `z = x.__add__(y)` which requires a dynamic attribute lookup on `x`.
#

__slots__ doesn't help performance that much. A bit, but it helps memory usage much more than performance.

#

Even with __slots__, you still need to ask the class which index corresponds to which attribute name.

#

which is a dynamic lookup each time x.y is used.

desert peak
#

sounds wildly inefficient

raven ridge
#

yeah, it is.

#

Python is not at all a fast language. It makes up for that in flexibility, but if you're looking for speed it's not great.

desert peak
#

it's interesting that it has so many web frameworks with some reaching nodejs perf

raven ridge
#

hand-waving again: the things that are fast are things that drop down to C (or some other compiled language) for the performance-sensitive parts.

desert peak
#

idk, things like Flask are built entirely in Python to my knowledge. I don't know about the next-gen stuff like Starlette

raven ridge
#

flask is built entirely in Python, yeah - but it usually goes along with something like uwsgi, which is implemented in C

#

and (continuing to hand wave, heh) the socket management, request processing, and response delivery (which is the part the WSGI server handles) is the slow part that benefits more from optimizing (and that can be done without holding the GIL)

desert peak
#

then I point to gunicorn which is the more popular web server implementation and is also all Python

raven ridge
#

actually calling the user's request handler is less work, and the GIL needs to be held, so there's not much benefit from dropping to C for that.

desert peak
#

so like most web stuff, IO tends to be the slow part, eh?

raven ridge
#

yep. IO is the slow stuff in big systems in general, generally - outside the number-crunching realm, at least

#

the reason Python is a good language despite its slowness is that most programs spend most of their time waiting for databases or filesystem or web services or whatever. Python can wait as fast as anything else, and the amount of time a program spends doing interesting work is often a small fraction of its runtime

#

and generally also a small fraction of the codebase, which can be implemented in a faster language and then interfaced with Python instead.

#

(Cython is pretty magical)

desert peak
#

I started learning about the ASGI protocol this weekend and am consistently pretty impressed with the people in the Python community

#

very smart folks

#

I just wish they weren't so change-averse

#

found my first use of an ellipses that is not in the stdlib, FastAPI uses it to initialize a model if a value is mandatory. neat.

raven ridge
#

it's used in mypy type stubs and with the @overload decorator pretty commonly

#

using it for a sentinel is clever, though.

#

But doesn't work for Python 2, sadly. ๐Ÿ˜ฆ

desert peak
#

well fastapi is async-only and only works on 3.5+ I think (whenever the coroutines were introduced)

raven ridge
#

yeah, that tracks.

#

I work on an infrastructure team making libraries that other developers use. For lots of libraries I'm stuck supporting Python 2 until the last users move off it.

#

I've got probably another 2 years of Python 2 support ahead of me, heh. But that's a clever use of Ellipsis once I can do it...

desert peak
#

ouch ๐Ÿ˜ฆ I work in voice infra, but our vendor products are appliances so I don't have to worry about their py version

#

most of my work involves creation automation for people

#

automating reports, DB stuff with voice infra, doing stuff for voice engineers, etc.

#

always seemed weird to me that python doesn't have a syntactical range operator like 1...3 over range(1, 3)

#

all of the builtin functions feel like they have a "dated" design with being global functions

raven ridge
#

that topic comes up in this channel weekly.

#

the set of builtins is a weird set.

#

there are many, many builtins that are only used in niche cases and probably don't deserve to be builtins.

desert peak
#

I feel like Guido might have been targeting a certain set of people with his decisions

#

they're very friendly builtins for people learning the language

#

ngl I just learned about ipython last week after exploring notebooks for the first time after three years of writing python professionally and I wish it was the default REPL

raven ridge
#

hm. counterpoint: making it the default REPL would mean shipping it with the interpreter, which corresponds to much less freedom to innovate, more risk aversion, and less regular releases.

desert peak
#

I feel like that's true in any language, but with enough adoption, it becomes true by default for the maintainer anyways. With Python moving to a yearly release model, might not be so bad, but it would also involve losing control of the project for maintainers

shy sphinx
#

Is lua easier to use than python

raven ridge
#

my impression is that when 3rd party libraries become part of the stdlib, the maintainers often come with them and become core developers.

#

@shy sphinx They're fairly similar languages. Python is larger. So, depends what you mean.

#

Lua is probably easier to learn in its totality, because it's smaller and comes with less stuff. Python is probably easier to write real applications with, because it has a better library ecosystem.

sacred yew
#

ipython seems like a large dep tho:

$ apt show libpython3.8-stdlib|grep Size

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Installed-Size: 8,114 kB
Download-Size: 1,720 kB
$ apt show libpython3.8-minimal |grep Size

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Installed-Size: 4,889 kB
Download-Size: 761 kB
$ apt show python3-ipython | grep Size

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Installed-Size: 2,585 kB
Download-Size: 515 kB
#

plus that doesnt include ipython's dependencies

raven ridge
#

it doesn't include libpython3.8-minimal's, either.

sacred yew
#

that only depends on libc and libssl

#

libpython3.8-stdlib depends on a bunch of non-python libs

raven ridge
#

the interpreter plus the stdlib is about 80MB all together

sacred yew
#

yeah most of that is the c files i think

raven ridge
#

sure, compiled stuff will be larger than Python sources.

sacred yew
#

still,

#

ipython is half of the minimal stdlib's size

#

plus its deps

#
$ apt show python3-pygments|grep Size

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Installed-Size: 3,253 kB
Download-Size: 596 kB
$ apt show python3-jedi|grep Size

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Installed-Size: 4,131 kB
Download-Size: 523 kB
#

theres like 5 more deps too

raven ridge
#
$ du -sh /usr/lib/python3.8/
34M     /usr/lib/python3.8/
#

that's a fresh install with nothing in site-packages... your apt show is missing some space somewhere.

sacred yew
#
224K    _pydecimal.py
288K    urllib
304K    logging
316K    importlib
360K    http
460K    unittest
548K    test
576K    multiprocessing
612K    xml
788K    email
852K    lib2to3
932K    asyncio
1.1M    pydoc_data
1.3M    distutils
2.3M    encodings
2.8M    lib-dynload
3.6M    __pycache__
18M     config-3.8-x86_64-linux-gnu

bottom few from du -sh * | sort -h

peak spoke
#

The size isn't really that big of a problem I think, but locking down development of new features to python alphas and going with the release cycle really restricts packages

sacred yew
#

yeah most of it is from libpython3.8-dev

hallow pilot
#

hello there

safe hedge
#

What even is the purpose of iPython?

wild kraken
#

@safe hedge a better repl

#

and with a lot of cool features

safe hedge
#

Better how...

wild kraken
#

like you can interact with the shell directly, and re-run previous inputs

#

and more

safe hedge
#

I don't really understand how that is "better" than just using the actual interpreter

#

Or you know, writing some code and running it...

raven ridge
#

Tab completion, syntax highlighting, the ability to await async functions without manually starting an event loop, multiline editing, the ability to recall entire blocks from history rather than one line at a time

#

The ability to compile code with cython on the fly and immediately interact with the globals it produces

#

You can paste code in with any leading indent, or even repl prompts, and it'll automatically be stopped and do the right thing.

safe hedge
#

Do you people not have tab-completion in your interpreter?

#

Again that just seems like an unnecessary combination of editor and interpreter tbh

#

Bit like IDEs

raven ridge
#

the point of it is to be an interactive environment. All the features I just named are ones that are intended to work nicely for experimenting with stuff.

proven dirge
#

Can anyone answer this?

raven ridge
smoky turret
#

cpython's repl does have tab completion, but it relies on gnu readlines, and the windows equivalent, pyreadline, hasn't been maintained, so to get it to kinda work requires you to tweak some things in the source

#

theres a stackoverflow post about it

raven ridge
#

yeah, I forgot that was eventually added to the vanilla Python repl; should've left that off. Though IPython's tab completion is smarter.

safe hedge
#

Just another reason to be thankful COVID means my new workplace let me work on my own machine and not some company windows laptop

proven dirge
#

@raven ridge this never helped me

smoky turret
#

Im not entirely sure what the whole deal is with the readline stuff, seems like a pep and some development could be in order

#

tab completion in the repl for windows should def ship by default

raven ridge
#

๐Ÿคท Set aside tab completion then - all the others I named are things that the regular Python repl doesn't have.

safe hedge
#

This just feels like my experience with RStudio tbh

#

I started with the basic interpreter/shell and I just can't get my head around half the bells and whistles

#

Perhaps they are useful to some but it just seems unnecessary extra things to learn.

smoky turret
#

Well, theres a reason why its popular in the data science world, its good for exploration and rapidly trying lots of different things

raven ridge
#

being able to recall a block from history instead of a line, and then be able to edit any line of that block, strikes me as an obviously useful feature that everyone would benefit from. But ๐Ÿคท if you're not interested I can't force you to check it out.

smoky turret
#

which are the kinds of things a regular dev dont usually need

raven ridge
safe hedge
#

Notebooks are whole other level of "why?" for me

#

Although I don't write anything in Cython so ๐Ÿคทโ€โ™‚๏ธ

raven ridge
#

Yeah, I don't go in for notebooks either. They seem like a lot of overhead for me. And I still switch back and forth between the Python repl and IPython just because of muscle memory. But, other than taking a few extra seconds to start up, an IPython repl offers a strictly better experience than a Python repl, so I'm trying to work on remembering to start it by default

#

If I start a repl instead of just writing code in a file, it's because I want to experiment with something. And IPython is better for experimenting.

safe hedge
#

But it also isn't how your code will be run in reality

raven ridge
#

Sure, but neither is any repl

#

Repls are always about trying things out, experimenting, and iterating.

smoky turret
#

I suppose what I have would count as a sort of compromise. I have repl_startup.py file with a couple things

print("(repl_startup.py)")

import collections, datetime, itertools, math, os, pprint, re, sys, time
print("(imported collections, datetime, itertools, math, os, pprint, re, sys, time)")

pp = pprint.pprint

def paste():
    import textwrap
    exec(textwrap.dedent(sys.stdin.read()), globals())
raven ridge
#

Ooh, the IPython timeit magic is pretty cool, too, now that I think of it. It's much easier to iterate on a command I want to time in a REPL than it is in a shell, since often I make some mistake or other on the first try.

grave gale
#

I believe that notebooks are useful when you want to save your experimenting session for future refernce

safe hedge
#

How is that better than just writing a script/module?

raven ridge
#

I personally have never wanted or needed that one. My repl sessions terms to be relatively short experimentation sessions.

safe hedge
#

If anything it just seems like a faf for code-sharing

#

Because now the person you're sharing with requires an extra dependency/setup

#

Beyond standard python

gleaming rover
#

Notebooks are whole other level of "why?" for me
@safe hedge notebooks are really useful for data analysis

raven ridge
#

Because now the person you're sharing with requires an extra dependency/setup
Yeah, though in some domains everyone uses notebooks, so that's not a practical concern

gleaming rover
#

especially where you want to experiment with tweaking specific parameters and seeing how it affects the result

#

as well as when you want to visualise things

raven ridge
#

Notebooks do seem handy for iterating on graphs.