#internals-and-peps

1 messages · Page 67 of 1

safe linden
#

so my issue is this current line I just wrote

from .ccd_collection.helper_functions import low_pass_filter
#

hmm

gleaming rover
#

doesn't look that bad to me

north root
#

yeah

#

helper_functions is usually just named helpers though

#

or utils

gleaming rover
north root
#

hahah, interesting

gleaming rover
#

but I suppose "utils" isn't much better

#

I do it too

#

but I have recently been trying to have more descriptive names for my utils

#

like functional, datetime, etc.

north root
#

i'd put something like low_pass_filter in a filters.py

gleaming rover
#

then there's a tradeoff between flatness (flat...ness?) and descriptiveness

north root
#

i assume you have something like high_pass_filter too

pseudo cradle
#

shrugs

north root
#

i typically have a utils folder, instead of just a utils file

safe linden
#

always love some good koans.

uhh, it is interesting. high_pass_filters are used somewhere else entirely

pseudo cradle
#

@safe linden DSP Engineer?

safe linden
#

I'm just an undergrad XD, this is for a physics lab code refactor

pseudo cradle
#

Gotcha

#

sounds fun

#

(it doesn't)

safe linden
#

Learning a lot. Came in telling them I felt comfortable with c++ and x86, so they have me doing python architecture now

pseudo cradle
#

sounds legit

#

(it doesn't)

safe linden
#

but on the pep8 thing. I am hearing that it is fine to import functions like that then. And I could probably name helper_functions to helpers

#

my main issue with naming it something clearer is I really don't know what most of this code is supposed to do

#

so I figured helpers would be vague enough to be accurate but clear enough to be structurally helpful

swift imp
#

Anyone ever use behave module?

pseudo cradle
#

Sounds like some Austin Powers shit

safe linden
#

so would you use this instead of say pytest?

swift imp
#

I have no idea but its under the Contributors Guide for python pptx and I'm trying to understand it

gleaming rover
#

oh, you know what module other than logging uses camel case?

#

unittest 😦

#

literally the only reason I use pytest

north root
#

what hurts the most is when i see the setUp method

#

everytime

gleaming rover
#

just stop

#

please

north root
#

getLogger

gleaming rover
#

although honestly I do really prefer pytest

north root
#

:(

#

i haven't used much pytest, mostly unittest

gleaming rover
#

I briefly considered writing a script that would add snake_case bindings to a module with camelCase names

#

after some time I realised that I was just avoiding work

north root
#

hahahah

#

aren't we all

pseudo cradle
#

😄

gleaming rover
#

what version does everyone use in the shell

#

I realise mine is 3.7

#

even though all my new virtual envs use 3.8

north root
#

(use pyenv)

gleaming rover
#

not like venv, virtual envs in general

north root
#

pyenv manages your python versions

gleaming rover
#

but yeah I've been meaning to look @ it

#

oh

#

okay I mixed it up with something else

#

that looks cool

#

man I remember once @ somewhere I used to work this dude said "I really am not impressed with Python's dependency management"

north root
#

pyenv is very handy

grave jolt
#

!e

import re


def ensnake(attrmapping):
    class _SnakeCaseProxy:
        def __getattr__(self, attr: str):
            try:
                return getattr(attrmapping, attr)
            except AttributeError:
                snake_case_attr = attr
                camel_case_attr = re.sub(r"_(.)", lambda m: m[1].upper(), snake_case_attr)
                return getattr(attrmapping, camel_case_attr)
    _SnakeCaseProxy.__name__ = _SnakeCaseProxy.__qualname__ =\
        f"_SnakeCaseProxy<{getattr(attrmapping, '__name__', repr(attrmapping))}>"
    return _SnakeCaseProxy()


###
            
import logging

class IReallyLoveJava:
    def helloWorld(self):
        return "C#"
javaLover = IReallyLoveJava()
java_lover = ensnake(javaLover)

snake_logging = ensnake(logging)

print(java_lover.hello_world())
print(snake_logging.get_logger())
fallen slateBOT
#

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

001 | C#
002 | <RootLogger root (WARNING)>
north root
#

nice

grave jolt
#

yes, I am avoiding work as well, at scale

gleaming rover
#

a few days later..."why did you upgrade npm and node? our stack only works with node version 10" 🤔

north root
#

lol

#

use nvm

gleaming rover
#

ensnake is a great name

grave jolt
#

enSnake

#

suffer

gleaming rover
#

stop 🥴

grave jolt
#

oKay

gleaming rover
#

well I suppose there is merit to camel case

#

the i_phone wouldn't have sold that well

north root
#

lol

gleaming rover
#

do you think

#

there is significant overlap

#

between namedtuple and dataclass?

#

the problem, I guess, is that Python doesn't have...named destructuring? not sure what to call it

north root
#

i would say so yeah

gleaming rover
#

like the thing in pattern matching

#

in other languages

north root
#

like match in rust?

#

yeah

gleaming rover
#

not familiar with Rust's implementation but probably?

north root
#

or switch in C/C++

#

what was that python pep for that

gleaming rover
#

like

class NT(NamedTuple):
    a: int
    b: str

t = NT(1, 'a)
NT(a, b) = t

assert a == 1
assert b == 'a'
#

somewhere in the 6 region I think

north root
#

!pep 622

fallen slateBOT
#
**PEP 622 - Structural Pattern Matching**
Status

Draft

Python-Version

3.10

Created

23-Jun-2020

Type

Standards Track

north root
#

yeeep

grave jolt
north root
#

lmao

pseudo cradle
#

😄

gleaming rover
#

hm

#

is it possible to do this?

#

NT(a, b) = t

north root
#

i'm gonna say no to that one

gleaming rover
#

I'm like 20% sure there is some black magic that will allow that (without a custom parser)

#

let me think

grave jolt
#

no there isn't, it's invalid syntax

#

but

gleaming rover
#

yeah, it is

grave jolt
#

what about

(a, b):NT = destructure(t)
north root
#

can't be annotated

grave jolt
#

Huh?

gleaming rover
#

you can't annotate tuples

#

in assignment statements

grave jolt
#

oh yes

#

what about

NT,(a, b) = match(t)
#

or simply

(a, b) = match[NT](t)

but this is a bit meh

gleaming rover
#

wouldn't you override the constructor then

north root
#

the former works, but ^

gleaming rover
#

unless you're saying

#

you return type(t) or something?

#

as the first element

#

but then if you matched the wrong thing your reference would be gone

brave badger
#

lemon_thinking

mFoo = matchmaker(Foo, "a", "b")
(a, b) = mFoo(foo)
gleaming rover
#

mFoo

#

put it in the corner with logging and unittest

#

why it's not named unitTest is beyond me

grave jolt
#

m_Foo

#

@brave badger that's 2 lines

gleaming rover
#

literally unusuable

grave jolt
#

NT;(a, b) = match(t)

#

ooh

(a, b) = NT.__destr__
#

since NT needs some kind of magic method, it could inherit from a magic class which would define a __destr__ proprety that would access NT's __match__ method

brave badger
#

I should write a library out of it lemon_thinking

gloomy rain
#

@swift jackal This is a channel for indepth discussion about the Python language. If you need help, please check out #❓|how-to-get-help.

cloud crypt
#

^

swift jackal
#

Alrigjt

cloud crypt
#

for some reason I can't stop thinking about rust-like macros in python, haha

#
macro map_property($attr: ident, $name: ident, $key: expr, $type: expr, $default: expr, $doc: expr):
    def get_$name(self) -> $type:
        return self.$attr.get($key, $default)

    def set_$name(self, value: $type) -> None:
        self.$attr[$key] = value

    def delete_$name(self) -> None:
        try:
            del self.$attr[$key]
        except KeyError:
            pass

    $name = property(get_$name, set_$name, delete_$name)

class Test:
    def __init__(self, **kwargs) -> None:
        self.data = kwargs

    map_property!(data, test, "test_key", int, 0, "Test description.")

test = Test(test_key=42)
assert test.test == 42``` I had been working with classes that required to be based on an arbitrary mapping, and so something like this could be useful for quickly writing all of attributes out instead of generating code and running exec()
flat gazelle
#

wouldn't something like

def __init__(self, **kwargs) -> None:
    self.data = kwargs
    for k in self.data:
        def get(self,k=k):
            return self.data.get(k, default)
        def set(self, v, k=k):
            self.data[k] = v
        def del_(self, k=k):
            del self.data[k]
        setattr(type(self), k, property(get, set, del_))
```be about the same
cloud crypt
#

yeah but I was reusing it quite a lot with different dict attributes and other stuff

#

besides, it brings overhead of loading all the names

flat gazelle
#

on second thought, this is pretty weird. You are assigning class attributes based on a value the instance initializer receives.

#

ah no, I see.

dense robin
#

nice pfp, makise kurisu

cloud crypt
#
from typing import Any, Dict, Optional, Type, TypeVar, Union

T = TypeVar("T")
U = TypeVar("U")
V = TypeVar("V")

TEMPLATE = """
def get_{name}(self) -> Optional[TYPE]:
    return self.{attr}.get({key!r}, {default})


def set_{name}(self, {name}: TYPE) -> None:
    self.{attr}[{key!r}] = {name}


def delete_{name}(self) -> None:
    try:
        del self.{attr}[{key!r}]

    except KeyError:
        pass


{name} = property(get_{name}, set_{name}, delete_{name})
"""


def map_property(
    name: str,
    attr: str,
    key: T,  # such that eval(repr(key)) == key
    *,
    type: Any = Any,
    # code to run, or an object such that eval(str(default)) == default
    default: Optional[Union[str, U]] = None,
    doc: Optional[str] = None,
    # namespace to use, tries to fetch from caller frame if not given
    namespace: Optional[Dict[str, V]] = None,
) -> property:
    env: Dict[str, Any] = {}

    if namespace is None:
        namespace = {}

        try:  # ayy frame hacks!
            frame = sys._getframe(1)

            namespace.update(frame.f_globals)
            namespace.update(frame.f_locals)

            del frame

        except (AttributeError, ValueError):
            pass

    env.update(namespace, TYPE=type, Optional=Optional)

    code = TEMPLATE.format(name=name, attr=attr, default=default, key=key)

    exec(code, env)

    some_property = env[name]
    some_property.__doc__ = doc

    return some_property``` well I made _something_ as an attempt
#

okay that was a large piece of code haha

flat gazelle
#

still seems like something better handled by metaprogramming in python. Would probably require a metaclass or __init_subclass__

cloud crypt
#

you can definitely write it in a nicer way

#

but it brings overhead by loading global values like key

#

or if you replace self.{attr} with getattr(self, attr), function calls don't make it better here

flat gazelle
#

!e

class MapProperty:
    def __init__(self, attr, k):
        self.attr = attr
        self.k = k
    def __get__(self, obj, type=None):
        return getattr(obj, self.attr)[self.k]
    def __set__(self, obj, v):
        getattr(obj, self.attr)[self.k] = v
    def __delete__(self, obj, v):
        del getattr(obj, self.attr)[self.k]

class Test:
    def __init__(self, **kwargs):
        self.data = kwargs
    test = MapProperty('data', 'test_key')

test = Test(test_key=42)
assert test.test == 42
fallen slateBOT
#

@flat gazelle :warning: Your eval job has completed with return code 0.

[No output]
flat gazelle
#

a custom descriptor is probably the neater way

cloud crypt
#

overhead by loading global values like key
I wanted less overhead because iterating over a lot of objects and their properties, even with current version I made, is pretty slow

flat gazelle
#

did you try __slots__?

cloud crypt
#

hm, actually interesting idea

#

but this will speedup both of our versions, so mine is still going to be faster :p

flat gazelle
#

it will be pretty minor. properties have the additional level of indirection as they have to call the functions you pass them, which is probably about as expensive as a getattr call

cloud crypt
#

when unsure, time it! -- and gotta do just that

#
>>> timeit.repeat("test.test", globals=globals())
[0.20965709999995852, 0.20878179999999702, 0.20550529999997025, 0.2064856000000077, 0.2059263000000442]
>>> timeit.repeat("desc_test.test", globals=globals())
[0.3471633000000338, 0.2668077999999241, 0.265926899999954, 0.3632896000000301, 0.3051882999999407]
>>> ```
@flat gazelle here is what we have, without slots
#

test is using my map_property, desc_test is using your MapProperty

flat gazelle
#

huh, did not expect that

sacred tinsel
#

given the following:

Capsule = namedtuple("Capsule", ["in_list"])
capsules = [Capsule([1, 2]), Capsule([3, 4])]

does a nice, declarative approach exist to flatten capsules into [1, 2, 3, 4]? the attribute lookup is making this oddly difficult

pearl river
#

Hmm, can't namedtuples be indexed by position? If they can, the standard

flat = [el for sublst in capsules for el in sublst]

would work.

#

Ah, I see, one more layer to unwrap

sacred tinsel
#

mm yea you're right but in my case Capsule has more than one attribute

#

and I only want to get in_list

#

sorry that was a bad example

pearl river
#
flat = [el for cap in capsules for el in cap.in_list]

works for that

sacred tinsel
#

beautiful thanks 💜

#

I thought you wouldn't be able to access the attribute in the comprehension

coarse shard
#

Hi, how can I extract integers from a sqlite database to a list?

radiant fulcrum
#

thats not really a topic for this channel

loud summit
coarse shard
#

ok

spark parcel
#

I left an idea in python-ideas, but am not quite sure what the person who responded mean by the answer. I hope this is enough of a discussion about the actual python language to fit here. If a help channel would be more applicable, I'll claim one instead

#

It's a question of circular imports and files trying to import themselves

raven ridge
#

Their point is that the error doesn't always mean that the module was trying to import itself. It can mean that, but that's not the only way to get that error.

#

Another way to get that error is to have module A import module B, and have module B import module A.

#

Your proposed wording would be incorrect for that case

#

You're proposing:

"ImportError: partially initialized module 'A' can't import itself"
But it isn't importing itself. It's importing B.

spark parcel
#

Aah, alright. I get it now

#

Thanks. Just didn't understand his example

raven ridge
#

There might be clearer wording that is correct, though...

spark parcel
#

Ahah yeah. Both his explanation and my proposed wording

#

Ohh, I misread what you wrote

plain marsh
#

hii

spark parcel
#

Yes. I think either having a new wording that is correct in both cases or having a special message for when it tries importing itself, could work. I'm leaning toward having a special wording for when the program tries to import itself

raven ridge
#

That's another option, yeah - you can propose splitting the error message into two paths depending on whether the import that failed was the trying to import a module with the same name as the one that's calling import

#

It is a common mistake for learners, and performance on error handling paths is generally ignored, so you may get some traction with that.

flat gazelle
#
#gui.py
import autotkinter as tk
tk.Label(text="Hello World").pack()
#autotkinter.py
from tkinter import *
class StopFinder:
    def __del__(*_):
        mainloop()
_END_CHECK = StopFinder()
```I wonder how fragile this is.
spark parcel
#

@raven ridge How do you mean with splitting the error message into two paths?

boreal umbra
#

@flat gazelle I thought the only potential fragility with __del__ is that any exceptions that aren't handled before the end of __del__ just get suppressed

flat gazelle
#

well, I am more worried about GC order. It is very possible other __del__ get called first and the program is left in an invalid state afterwards

raven ridge
#

@raven ridge How do you mean with splitting the error message into two paths?
@spark parcel suggest that the existing message be used when the last import statement came from a different module than the one being imported, but your message be used when we can detect that a module directly imported itself

spark parcel
#

Right, yeah. I think that would probably be the best way

#

I'll send another message in the thread about that

worldly shard
spark venture
#

thats ascii right?

slim island
#

@worldly shard you're gonna find it much easier if you take the time to properly ask than just throwing it in random channels that you see. If you read #❓|how-to-get-help it explains the process for asking quesions. Make sure you include some detail about exactly what is expected, such as whether that's text based or image based.

spark venture
#

is it possible to use a python function in C#?

#

like if i want to call a function at a particular event in C# from python (as a private void function), will it work?

spice pecan
#

Look into pythonnet, it's a library that allows for Python/C# interop

#

You can use python modules in C# and vice-versa

spark venture
#

example:

# MainPage.py

WebPage = WebView(Source="https://google.com/")
WebPage.ContextFlyout = MenuFlyout()
def WebPage_ContextRequested(sender, e):
    ContextMenu.ShowAt(UIElement(sender), e.GetPosition(UIElement(sender)))
WebPage.ContextRequested = WebPage_ContextRequested

should be something like:

<!-- MainPage.xaml -->

<WebView Source="https://google.com/" ...>
  <WebView.ContextFlyout>
    <MenuFlyout />
  </WebView.ContextFlyout>
</WebView>

and

// MainPage.xaml.cs

private void WebPage_ContextRequested(WebView sender, ContextRequestedEventArgs e /* or whatever the default args are */)
{
    ContextMenu.ShowAt(sender as UIElement, e.GetPosition(sender as UIElement))
}

will pythonnet do that @spice pecan ?

spice pecan
#

You should be able to do something similar to that, yeah

spark venture
#

oh thanks a lot!

tough snow
#

hi

true hollow
#

hello!

nimble elm
#

Is that for python or general discussion?

flat gazelle
#

Read the channel topic

proven iris
#

I want to learn to encrypted messages using python

mighty hound
#

can anyone tell me what is the use of listener in pynput

undone hare
#

3.5.10rc1 is released yay!

#

Yay...

#

Y.. Ay....

gleaming rover
#

I feel like when beginners start with the REPL

#

it's not so clear for them that the values of expressions are automatically printed

#

which leads to confusion regarding print vs return

undone hare
#

Yeah, IDLE is pretty misleading because of that

brazen jacinth
#

read-evaluate-print-loop 🤷‍♂️

strange sky
#

hey, im working with dlls and the ctypes library, so i thought this question would be appropriate in this channel.

#

so basically i have a dll, i created using cpp, but i compiled it to C language, i u guys understand what i mean

#

this dll has some functions i wanted to run in python, one of them returns a var with HANDLE datatype

#

but when python receives it, it converts it to a plain int, if im right.

#

Is there any way to store that HANDLE inside a python var, without it losing its content?

flat gazelle
#

what kind of type is HANDLE, a struct?

strange sky
#

typedef void *HANDLE;

#

void pointer

flat gazelle
#

then you should get a ctypes.c_void_p as a result when calling from python

strange sky
#

hmmm so if i would do type(myReturn) , it should return ctypes.c_void_p

#

?

#

because it returns me <class 'int'>

undone hare
#

!d ctypes.c_void_p

fallen slateBOT
#
class ctypes.c_void_p```
Represents the C `void *` type. The value is represented as integer. The constructor accepts an optional integer initializer.
undone hare
#

^ it is interpreted by an integer

flat gazelle
#

how do you do the call?

strange sky
#

how do you do the call?
@flat gazelle wdym by that?

#

^
@undone hare ohh okay, so if i will give my returnedHandleInPython as an argument inside a cpp func it will treat it like an integer?

undone hare
#

I don't know anything about the C API tbh, I've just looked up the docs haha

flat gazelle
#

haven't done CFFI in a while, but IIRC you created a c function type where you described its type

strange sky
#

ohh okay, well ill look into it again. Thank you guys.

strange sky
#

hmm ive got a new idea

#

do you guys think i can pass a pointer

#

and then giving the pointer as the argument

#

and then ill just extract the HANDLE value from the pointers adress

#

or is this too ambitious?

unkempt rock
#

!subscribe

wide shuttle
#

Hello, @unkempt rock, you can run bot commands in #bot-commands

boreal umbra
#

how do we feel about __contains__ doing the job of isinstance for type?

#
>>> 'hi' in str
True
#

!e

print(str in 'hi'.__mro__)
#

oh no did I break the bot

#

guess only the class has that

#

On one hand I'm not sure that thinking of instances as being "in" in their class is very intuitive

#

at the same time I feel like type checking should be part of the grammar rather than the vocabulary, so to speak.

grave jolt
#

Well, it fits nicely with the idea that types model sets

#
>>>  'hi'str
True
spice pecan
#

I'm not sure if in is the best candidate for that, but a way to typecheck other than isinstance(obj, type) would be really nice

grave jolt
#

But 'hi' in (str, int) is weird

#

maybe 'hi' in (str | int)

spice pecan
#

There was a pep that proposed using | to form Union[type1, type2]

raven ridge
#

What's wrong with isinstance and issubclass?

#

Just that they're wordy?

spice pecan
#

I wouldn't say there's something inherently wrong with them, but something along the lines of var is_of_type type feels easier to comprehend

#

The infix form is more readable IMO

slim island
#

Somewhere or other, I remember seeing isa suggested as a new keyword. I think that's much clearer than isinstance, or in

spice pecan
#

Heavily inspired by @fix error's custom operator class, ```py
class CustomOperator:
def init(self, func):
self.func = func
self.lhs = ()
def gt(self, other):
if self.lhs:
lhs, rhs = *self.lhs, other
self.lhs = ()
return self.func(lhs, rhs)
self.lhs = other,
return True # Must be truthy to eval both parts of chained comp
def call(self, lhs, rhs):
return self.func(lhs, rhs)

isinstance = CustomOperator(isinstance)
print('hello' <isinstance> str)
print(isinstance('hello', str))

slim island
grave jolt
#

@spice pecan oh, I remember that 🙂

slim island
#

it also suggests your hting of in as a better option

spice pecan
#

isa sounds good, similar to C#'s var is Type

slim island
#

I prefer isa because it's more intuitive

raven ridge
#

Hm. It's not an operation I need frequently - I write an isinstance check maybe once every hundred or two hundred lines of code, and don't think I've ever used issubclass. I'd strongly oppose overloading in for this. With the new parser, I bet isinstance could be made an infix operator in addition to a built-in function...

slim island
#

if type(a_variable) == list is something beginners often do, and they don't realise that is or why it is wrong

#

I feel like in or isa could help with that

raven ridge
#

In beginners' code, that's probably not wrong. Beginners don't deal with much subclassing...

slim island
#

it's poor practice though. I feel like the semantics of isa are immediately clear, and it's pretty natural. But you're right that this isn't exactly a major problem that comes up often

raven ridge
#

I don't hate isa, but if it's possible I'd prefer an infix instanceof operator over an isa operator - adding another word to the grammar seems worse than reusing one in a novel way.

grave jolt
#

!e

class SupportsInMeta(type):
    def __contains__(cls, obj):
        return cls.__class_contains__(obj)

class Str(str, metaclass=SupportsInMeta):
    @staticmethod
    def __class_contains__(obj):
        return isinstance(obj, str)

print(42 in Str)
print("hi" in Str)
fallen slateBOT
#

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

001 | False
002 | True
raven ridge
#

I also can't help but feel that isa and that proposed overload of in will both be really hard to Google about, and isa in particular will not be obvious to people who don't know English well since it's two short words crammed into one operator name.

slim island
#

yeah, I think you're right about that. isa is also very commonly used as an acronym for lots of different things which isn't great

crystal kindle
#

I have a pyObject - (blender KDTree) I need to store it each frame and then recover it somehow

#

does anyone know a good method for this?

#

(I actually only need to store it 1 time, and then read it each frame)

paper echo
#

Pickle i guess

crystal kindle
paper echo
#

But yuck to that

crystal kindle
#

yeah sounds super slow

#

someone suggest a memory map and using numpy

#

but posted no code and I don't really understand it

paper echo
#

That's a good idea depending on how the object is implemented

#

How is the data in the KDTree actually stored

crystal kindle
#

it's a C object I think that py is wrapping

#

mathutils.kdtree.KDTree

#

I am trying to bring it to the viewport too

#

this looks good -mmappickle: Python 3 module to store memory-mapped
numpy array in pickle format

undone hare
#

Why not simply store it as csv file?

#

Someone could tamper with the pickle file and execute code inside the game

pearl river
#

uhh, why store a numpy array as pickle when numpy has a perfectly good save function that saves in numpy's binary npz format?

crystal kindle
#

I don't even need a nparray

#

I need to store a blender kdtree

#

I don't care how really as long as it's fast

#

invoke modal operator needs to store a kdtree when it invokes and use the kdtree each time the modal operator repeats

#

in bge I can do

own['kd']=kdTree

#

and it works fine

#

in bpy though all properties are assumed to want to be saved forever and I don't see any sort of global area to store data for addons to share

paper echo
#

It might be faster to serialize to and deserialize from numpy than to pickle and unpickle

#

Is there a way to memmap a binary file without numpy?

grave jolt
#

Why is heapq made as a collection of functions and not a separate Heap class?

peak spoke
#

old api and maybe easier to do the c implementation I'd guess

raven ridge
#

flexibility, I suspect - this allows it to be used with any sequence type.

#

any mutable sequence type, at least.

peak spoke
#

Not many cases where you wouldn't use a list

raven ridge
#

I can see why it might be useful for subclasses of list, at least

peak spoke
#

Would still probably be easier to use a class with a changeable heap through an init arg or subclass instead of passing it everywhere

charred wagon
#

@paper echo mmap - standard library

raven ridge
#

Old API might be part of it, but heaps aren't particularly useful by themselves - they're usually used as part of other data structures, like a priority queue

paper echo
#

my guess is that it was one of those 3rd party libraries that got subsumed into the stdlib

spark parcel
#

How does an idea go from the python ideas list to being implemented?

cloud crypt
#

Well python ideas is mostly about discussing afaik

spark magnet
#

usually, a PEP gets written

cloud crypt
#

Then you can write a PEP proposing your idea if it is large

#

yeah

#

And then, after it gets approved, it is being implemented iirc

spark parcel
#

Right

#

I started a thread about giving some message when python tries to import the running file (this one: #mailing-lists message). I think one of the later options discussed would be great to have. How exactly would that continue? Do I write a PEP? Does someone else propose that they’ll write one?

spark magnet
#

I'm not sure that change would be large enough to need a PEP

#

which proposal did you like?

spark parcel
#

I’m not 100% sure. The one about a warning would probably be best, but could add unnecessary slowness. However, I’d say that getting an added message when an error occurs would be almost necessary

#

I do think the warning would be optimal, though

teal yacht
#

you need a core contributor to "endorse" you iirc to submit a pep

spark parcel
#

I'm not sure that change would be large enough to need a PEP
@spark magnet if it isn’t large enough for a pep, what happens then?

teal yacht
#

If one or more of the PEP's co-authors are core developers, they are responsible for following the process outlined below. Otherwise (i.e. none of the co-authors are core developers), then the PEP author(s) will need to find a sponsor for the PEP.

spark parcel
#

Right, yeah

teal yacht
#

the smaller version of a pep would be an issue basically

#

these are the bpo you see in pull requests on github and in the changelogs

#

can range from bugfixes to changes in documentation etc

spark parcel
#

So, it’s basically either a PEP or an issue?

teal yacht
#

afaik yes

spark parcel
#

Alright. @spark magnet would you say that opening an issue on the issue tracker would be the best way forward, since you didn’t seem to think it was big enough for a PEP?

spark magnet
#

If the Python-Ideas thread seems to reach a positive proposal, then you can ask on the thread, or open a bpo.

spark parcel
#

Alright. Sounds good

#

Thanks for the help :)

cloud crypt
#

What is the correct way to annotate callable that takes no arguments? Callable[[], T]?

red solar
#

Yup 👍

cloud crypt
#

alrighty!

pearl river
spark magnet
#

@pearl river probably just history.

cloud crypt
#

I feel like that's not the case and they are intentionally positional

#

well, what you have sent should be possible under 3.8 if _operator does not exist, heh

#

Are there any interesting solutions to make importing a library faster?

gleaming rover
#

@pearl river probably just history.
@spark magnet they were changed in 3.8, I believe

#

I feel like that's not the case and they are intentionally positional
@cloud crypt the parameters for most of the operator functions have no true meaning => positional-only

#

PEP 570 talks about it

pearl river
#

well, what you have sent should be possible under 3.8
@cloud crypt nah, unless I missed something, I had to settle with lambda x: x-1.

teal yacht
#

~~just do (-1).__add__ ~~

raven ridge
#

@cloud crypt nah, unless I missed something
@pearl river You quoted half of what gm said and changed the meaning, because presumably you do have the _operator module.

cloud crypt
#

that's what I've said

pearl river
#

ah, I see, I didn't quite get the second half. What's the difference between them? _operator is the CPython-specific one?

cloud crypt
#

well, let’s see if PyPy has one

gleaming rover
#

basically a C implementation of the operator functions I believe

#

to avoid Python function call overhead

pearl river
#

ah, right, and when possible (depending on the implementation) operator imports everything from _operator to provide said speedup?

gleaming rover
#

seems like it

cloud crypt
#

yeah

pearl river
#

so essentially the reason is that the C-based functions of _operator don't support keyword arguments like that. Interesting, thanks.

cloud crypt
#

well, _operator could support keyword-args

raven ridge
#

supporting keyword arguments is more expensive, though, and in this case they chose not to because they felt that it didn't add enough benefit to justify the extra cost (since the extra cost applies even to calls that don't use keyword arguments)

#

(or, possibly it's so old that it predates the introduction of keyword arguments - that'd be the other possibility)

gleaming rover
#

so essentially the reason is that the C-based functions of _operator don't support keyword arguments like that. Interesting, thanks.
@pearl river but also that they would have no real meaning in many cases

#

def add(arg1, arg2) <- ???

teal yacht
#

tbh, you could have lhs,rhs for the binary operations

pearl river
#

well, it's less that I care about whether it has keyword args, and more that I want to use functools.partial to apply the second argument of a positional-only function 🙂

cloud crypt
#

better use lambda tbh

#

Still __call__ 2 times, and even less overhead with lambdas then partial

gleaming rover
#

well, it's less that I care about whether it has keyword args, and more that I want to use functools.partial to apply the second argument of a positional-only function 🙂
@pearl river not really meant for that case, I guess...

pearl river
#

Still __call__ 2 times, and even less overhead with lambdas then partial
@cloud crypt oh, that actually does look to be the case.

In [223]: add1 = functools.partial(operator.add,1)

In [224]: add1_2 = lambda x: x+1

In [225]: %timeit list(map(add1,range(10000)))
1.17 ms + 19.5 чs per loop (mean + std. dev. of 7 runs, 1000 loops each)

In [226]: %timeit list(map(add1_2,range(10000)))
1.19 ms + 32.6 чs per loop (mean + std. dev. of 7 runs, 1000 loops each)

So much for speedup 😅

cloud crypt
#

hmmm

final whale
#

if you want to take it even further, [*map()] is very slightly faster than list() when the amount of item isn't too high

swift imp
#

Anyone else hugely disappointed by functools.partialmethod?

#

The fact that it doesnt store the wrapped method's __doc__ is a huge let down imo

dusty verge
#

You could probably monkeypatch it

#

I don't think it would be too hard to write your own partialmethod

crystal kindle
#

modal operator in blender 2.9x viewport

paper echo
#

@swift imp is that different from functools.partial?

cloud lion
#

What is callback function and class?

swift imp
#

@paper echo yes partial can actually transfers the docstring

unkempt rock
#

So, ultimaytly, I learned exe conversion using cx_Freeze, should I move to setuptools or keep using it.

#

Ive heard back and forth on it and want to know what yall think.

#

@brave badger ^?

brave badger
#

Not really on-topic for this channel but I suggest PyInstaller for easier deployment

unkempt rock
#

Fair enough.

crystal kindle
#

new blender is much easier to use pip right in the application

#

{all my clients are artists / typically admin of their own system}

sterile garden
#

does new blender make it easier to run blender scripts without having the gui up?

undone hare
#

It is probably off topic, but you can run scripts without the GUI iirc

paper echo
#

@swift imp seems like an oversight or bug

#

idk how to correctly file issues w/ the python bugtracker

undone hare
#

@paper echo you need to login and then press the "create new" button in the left navbar

swift imp
#

@paper echo its not. I've read SO post on it, its meant to do this

paper echo
#

its mean to not preserve the docstring? @swift imp

#

that is weird

#

@undone hare yeah i just dont know if theres additional procedure or specific decorum that needs to be respected

swift imp
#

@paper echo partial preserves the docstring, partialmethod does not, and this is the design

paper echo
#

huh. why?

swift imp
#

apparently its something about docstrings for class instance methods working differently than docstrings for functions

#

and as such partialmethod is a class and it just doesnt transfer

#

I don't really get it but yeah, doesn't work

undone hare
paper echo
#

oh nice thanks

#

@swift imp weird, thanks. you cant manually assign __doc__ to it either?

#

ahhhh i see

#

That's because partialmethod is a class written in Python, and instances of classes get their docstring from the class's __doc__, not from a __doc__ attribute on the instances. Functions behave differently, with the __doc__ attribute of the function object being looked at.

#

!e ```python
class WeirdThing:
""" doc 1 """
@property
def doc(self):
return 'doc 2'

print(WeirdThing.doc)
print(WeirdThing().doc)

fallen slateBOT
#

@paper echo :white_check_mark: Your eval job has completed with return code 0.

001 | <property object at 0x7fe4604124a0>
002 | doc 2
paper echo
#

!e ```python
class WeirdThing:
""" doc 1 """
@property
def doc(self):
return 'doc 2'

help(WeirdThing)
help(WeirdThing())

fallen slateBOT
#

@paper echo :white_check_mark: Your eval job has completed with return code 0.

001 | Help on class WeirdThing in module __main__:
002 | 
003 | class WeirdThing(builtins.object)
004 |  |  Data descriptors defined here:
005 |  |  
006 |  |  __dict__
007 |  |      dictionary for instance variables (if defined)
008 |  |  
009 |  |  __weakref__
010 |  |      list of weak references to the object (if defined)
011 | 
... (truncated - too many lines)

Full output: https://paste.pythondiscord.com/ecadirujuq

paper echo
#

ok i just tested in in python

#

it does in fact work if you set __doc__ as a property

#

so maybe that could be the hack? not sure if that would break things if it were added to the stdlib

#

!e ```python
from functools import partialmethod

class partialmethod2(partialmethod):
@property
def doc(self):
return self.func.doc

class WeirdThing:
def f(self, x):
return x

f1 = partialmethod2(f, 1.0)

w = WeirdThing()
print(w.f1.doc)

fallen slateBOT
#

@paper echo :white_check_mark: Your eval job has completed with return code 0.

001 | partial(func, *args, **keywords) - new function with partial application
002 |     of the given arguments and keywords.
paper echo
#

hmm

#

aha i got it

fallen slateBOT
#

@paper echo :white_check_mark: Your eval job has completed with return code 0.

 f() documentation 
paper echo
#

seems like a pretty quick fix

#

easy PR?

#

!e ```python
from functools import partialmethod, wraps

class WeirdThing:
def f(self, x):
""" f() documentation """
return x

f1 = wraps(f)(partialmethod(f, 1.0))

w = WeirdThing()
print(w.f1.doc)

fallen slateBOT
#

@paper echo :white_check_mark: Your eval job has completed with return code 0.

001 | partial(func, *args, **keywords) - new function with partial application
002 |     of the given arguments and keywords.
paper echo
#

well it looks like manually assigning doc works

#

ah, yeah. wraps wouldnt make sense

plain skiff
#

hello

#

have a nice day everybody

#

ı have a questions about xbee and python

#

can anyone help me ?

spark parcel
#

@plain skiff I'd recommend getting a help channel for that (#❓|how-to-get-help). Also, read the description for this channel. That question doesn't fit here.

cloud crypt
#

what is the correct way to annotate an argument of slice type?

pearl river
#

slice?

cloud crypt
#

yeah

pearl river
#

Does cur_slice: slice not work?

cloud crypt
#

well it does

#

but is there a better way?

pearl river
#

looks like it went nowhere, but was brought up in the past.

undone hare
#

Interesting, I didn't know there was a typing repo

paper echo
#

is there some interoperability between ABCs and Protocols?

#

like, can i generate a protocol from an ABC or vice versa? i started putting together some code to do this by hand, but i realized that _ProtocolMeta (the metaclass for Protocol) is a subclass of ABCMeta, and that gave me pause

#
In [93]: print(inspect.getsource(_ProtocolMeta))
class _ProtocolMeta(ABCMeta):
    # This metaclass is really unfortunate and exists only because of
    # the lack of __instancehook__.

oh dear lol

grave jolt
#

It's metaclasses all the way down

gleaming rover
#

how would you feel about slice notation being applicable to iterators

#

and having the effect of islice?

paper echo
#

i like it

#

but im sure somewhere out there someone has implemented iterators that also support custom __getitem__ lookups

#

so it would probably break backward compatibility unless you did it yourself

grave jolt
#

yes, we did that in this channel, I believe

paper echo
#
from __future__ import annotations
import collections.abc
from itertools import islice
from typing import Generic, Iterable, Iterator, TypeVar, Union

_T = TypeVar('_T')

class IndexableIteratorWrapper(collections.abc.Iterator, Generic[_T]):
    self.iterator: Iterator[_T]

    def __init__(self, iterator: Iterable[_T]):
        self.iterator = iter(iterator)

    def __getitem__(self, subscript: Union[int, slice]) -> Iterator[_T]:
        return islice(self.iterator, subscript)

    def __iter__(self) -> IndexableIteratorWrapper[_T]:
        return self

    def __next__(self) -> _T:
        return next(self.iterator)

like this i guess

#

that peekable is more complicated

#

with caching and whatnot

grave jolt
#

oh, right

paper echo
#

also why are we defining inline types? lmao

#

that implementation is uh

#

interesting

grave jolt
paper echo
#

indeed

gleaming rover
#

missing a from __future__ import annotations

paper echo
#

heh good catch

grave jolt
gleaming rover
#

sorry, I feel squicky when I see string annotations

paper echo
#

me too

#

@grave jolt thats fine, im not good enough to play multiplayer anyway

grave jolt
#

come on, just a little bit of lambda calculus knowledge is required...

grave jolt
#

more-itertools -> even-more-itertools -> even-more-itertools-extras

paper echo
#

iterstuff 😎

grave jolt
paper echo
#

nahh for real im not gonna mess with the esoteric stuff

#

im also gonna just sign up for my own paid account. they've earned my money

#

is using x &= y on bools instead of x = x and y considered bad style / hacky?

grave jolt
#

I find it readable but surprising

paper echo
#

and i think my reaction was the same as yours

#

maybe ill rewrite with and

#
x and= y

one for the new parser? 👀

grave jolt
#

actually, in that context &= looks fine. I just forgot that some operations on bools return bools, not ints.

paper echo
#

hm

#

if im a member of one team, i can also be members of other teams right?

#

what does being a team member imply?

grave jolt
#

you can edit the team's repls (and see its private .env files)

paper echo
#

ah, ok

grave jolt
#

and create new ones

paper echo
#

alright why not 😄

grave jolt
#

It's pretty buggy though, I wasn't able to add IFcoltransG for a while, and now they're in the team and have a pending invite

#

sent an invite

paper echo
#

it looks like im in

#

thanks!

grave jolt
#

👍

paper echo
#

i have so many repls... i gotta curate / delete them one day

#

keep the useful things and throw out the random one-offs i made to help people

#

this is veering into offtopic but the last thing i will say is... i wish repl.it supported filetype-specific editor settings. i saw your 4 space indents in the clojure code, im sorry for your loss

grave jolt
#

my loss?

Yep, It's a horrible transgression. I also put the closing parentheses in the wrong place

#

(I actually wrote the server in vscode, so I am to blame here)

cloud crypt
#

allows using T in the class afaik

swift imp
#
from __future__ import annotations
import collections.abc
from itertools import islice
from typing import Generic, Iterable, Iterator, TypeVar, Union

_T = TypeVar('_T')

class IndexableIteratorWrapper(collections.abc.Iterator, Generic[_T]):
    self.iterator: Iterator[_T]

    def __init__(self, iterator: Iterable[_T]):
        self.iterator = iter(iterator)

    def __getitem__(self, subscript: Union[int, slice]) -> Iterator[_T]:
        return islice(self.iterator, subscript)

    def __iter__(self) -> IndexableIteratorWrapper[_T]:
        return self

    def __next__(self) -> _T:
        return next(self.iterator)

like this i guess
@paper echo what does subclassing Generic[_T] do?

cloud crypt
#
class Test(Generic[T]):
    def __init__(self, test: T) -> None:
        self.test = test

    def get_test(self) -> T:
        return self.test``` basically binds T inside a class
#
test: Test[int] = Test(42)
result = test.get_test()  # -> int```
swift imp
#

Aren't TypeVar completely cosmetic?

cloud crypt
#

not really

#

they can bind to things

swift imp
#

What do they do?

cloud crypt
#

well, indicate something of the same type

swift imp
#

Guessing im revealing my lack of knowledge on typing

cloud crypt
#

they have different uses tbh

#

lemme pull up a simple example

grave jolt
#

Usually it doesn't do anything at runtime. But it helps with type checking (and documenting methods) when using polymorphic containers.

#
class Pair(Generic[A, B]):
    def __init__(self, left: A, right: B):
        self.left = left
        self.right = right

def f(p: Pair[int, str]):
    x = p.right # x is inferred to be `str` (hopefully)
cloud crypt
#
AnyStr = TypeVar("AnyStr", bytes, str)  # this is actually typing.AnyStr, by the way

def concat(x: AnyStr, y: AnyStr) -> AnyStr:
    return x + y

byte_string: bytes = concat(b"lemon", b"eivl")  # fine

string: str = concat("joe", "ves")

concat(b"broken", "really")  # error at runtime and in typechecker``` also this I guess
#

@grave jolt A and B are unusual typevar name choices, haha lemon_sweat

grave jolt
#

I think it makes sense when you have more than one parameter

cloud crypt
#

T, U, V for me

#

doesn’t get further than that most of the time

paper echo
#

A and B are typical from Haskell

cloud crypt
#

or T1, T2, ..., TN, I have seen

grave jolt
#

at least I'm not using lowercase names 🙂

swift imp
#

Wait so

cloud crypt
#

and KT, VT for mappings, for example

swift imp
#

mypy is the typechecker right?

cloud crypt
#

yeah

paper echo
#

its the original one

grave jolt
#

It's a typechecker

paper echo
#

there are others now

swift imp
#

what are the others?

paper echo
#

pyre, pyright, pytypes

cloud crypt
#

it's the deadly typechecker

swift imp
#

why is it deadly?

grave jolt
#

I'm just using K and V for mappings

paper echo
#

wait nvm pytypes is something else

cloud crypt
#

well it uh

#

is rather strict but partially stupid to some point

paper echo
#

they all are more or less equally strict and stupid

swift imp
#

are they worth using?

grave jolt
#

pyright is better at type inference as far as I can tell

paper echo
#

i use them all the time @swift imp

#

type checking helps catch an entire category of bugs that otherwise wouldnt be easy to catch

cloud crypt
#

I feel like typed code looks better

paper echo
#

that too

swift imp
#

I think it does too

cloud crypt
#

even with Any

paper echo
#

self-documenting

#

Q: why wasnt namedtuple -> NamedTuple included in pep 585?

grave jolt
#

yeah, just put Any everywhere so that it typecheks

swift imp
#

This guy at worrk doesnt like it bc we primarily use Pandas and Pandas doesnt support it

#

but im just, well who cares if it doesnt

paper echo
#

pandas does support it

swift imp
#

Since when?

paper echo
#

you just cant parameterize on colum/series names

swift imp
#

Oh

cloud crypt
#

@grave jolt just put # type: ignore on top of each file

swift imp
#

True, thats what i mean

paper echo
#
y: pd.Series = ...
cloud crypt
paper echo
swift imp
#

I wish you could parameterize columns/dtype

paper echo
#

but its mostly for numpy right now

cloud crypt
#

Optional[Union[Callable[[], T], T]] gets hard to read tbh

swift imp
#

Ive read through some of the Pandas issues, going back to 2018 they were talking about parameterizing . Wonder whats taking them so long

paper echo
#

@cloud crypt i usually give types like that a name

cloud crypt
#

yeah I do that if it repeats

paper echo
#

@swift imp low motivation i guess? idk. you'd think that one of the big python data science shops would be invested in donating some dev time for it

grave jolt
#

Some type relationships are very hard or impossible to specify, so annotating the entire codebase might be too ambitious (especially if you use some magical frameworks)

paper echo
#

eg. facebook developed pyre but isnt developing pandas type stubs? they must not use pandas internally

cloud crypt
#

btw how do you declare your package as typed? add py.typed to package data?

paper echo
#

i think so, i guess you have to include it in MANFEST.in as well?

cloud crypt
#

yeah if you are using include_package_data, that is

paper echo
#

what is the poetry equivalent of MANIFEST.in anyway?

swift imp
#

when you say typed do you mean like you annotated everything?

#

or typing works for your stuff

paper echo
#

mypy won't check a package that doesn't have the py.typed file in it

cloud crypt
#

@paper echo something in pyproject.toml ig

swift imp
#

ah and py.typed indicates how to check it?

#

God theres still so much to Python I have to learn...

cloud crypt
#

okay is it fine if I have # type: ignore on top in 2 of my 80 files? haha

grave jolt
#

at some point you just gave up...

paper echo
#

no, the existence of py.typed tells mypy to use the annotations in the package, when it's imported into another package

cloud crypt
#

I was developing something similar to attrs in a way

#

and mypy went like fuck you, I don’t get it

#

and I said okay, happens to the best of us, and smashed # type: ignore in :p

paper echo
#

also on the topic of types, why wasnt namedtuple/NamedTuple included in pep 585?

#

id love to see NamedTuple moved to collections

#

with a DeprecationWarning for typing.NamedTuple

swift imp
#

Why?

#

DataClasses are better?

paper echo
#

@swift imp no, because typing.NamedTuple is not used only for type checking but can actually be used to define namedtuples. therefore imo it never belonged in typing

#

as it is, it's an objectively more useful way to construct namedtuples, since it supports both the "functional" style and the new "declarative" style

#

it completely subsumes collections.namedtuple and i dont understand why it was added to typing and not collections

#

go ahead and leave collections.namedtuple as an alias of it

swift imp
#

oh, I get you. Yeah thats weird.

#

Didn't they rework typings to get rid of List ,etc ?

paper echo
#

If you use setuptools, you must pass the option zip_safe=False to setup(), or mypy will not be able to find the installed package.
huh i didnt actually realize this about mypy

#

yeah thats pep 585

#

coming to python in 3.9

swift imp
#

Was that 3.8

#

oh

paper echo
#

and i was hoping 585 would include something about namedtuples, but it doesnt

#

maybe that could be a pep of its own

swift imp
#

make a pep then LOL

paper echo
#

deprecate typing.NamedTuple, move it to collections.NamedTuple, and discourage future use of collections.namedtuple (but don't actually deprecate it)

#

ill post to the python discourse forum and see what people say

swift imp
#

No they should deprecate collections.namedtuple only if because of what has become customary to naming classes

paper echo
#

guido's stance on that historically has been "no"

#

thats why we still have logging.getLogger and datetime.datetime

#

i would love to see datetime.DateTime added as an alias for datetime.datetime

#

but actually deprecating datetime.datetime is unnecessary imo

swift imp
#

I dont get it, if they deprecate it and give developers 5 years isnt that enough?

#

how hard is a god damn sed

paper echo
#

its just an unnecessary backward compatibility break

#

theres python 3.3 code that still runs today

#

hell theres even some 2.6 code that still runs

teal yacht
#

i find it weird that their stance on it is very inconsistent in general

#

they are deprecating typing.List and other containers for example

#

and it will be deleted entirely 5 years after 3.9

paper echo
#

i think it's ok because those are only used in relatively new code

#

and were only "popular" for a short time

teal yacht
#

well, yeah, but in 5 years it won't be

paper echo
#

i think the idea is that it's not entrenched yet

#

and that people using typing are still willing guinea pigs to some extent

#

for contrast, look at asyncio, there are < 3 year old APIs that are already set in stone due to backward compatibility reasons

grave jolt
#

int, float, complex, bool, list, str, set, dict, frozenset, bytes, bytearray are also classes with lowercase names, will they be renamed? 👀

paper echo
#

if you wanna get real weird, lets talk about why frozenset is a builtin

#

or why id is a builtin

grave jolt
#

you mean, not in collections?

paper echo
#

yes

grave jolt
#

Yeah, id is weird

paper echo
#

and id should be in inspect

#

or dis even...

#

the answer is definitely just "backward compat"

teal yacht
#

i'd rather we ditch is and keep id a builtin tbh

paper echo
#

i wonder how much of this dates back to python 1.x

#

ive barely even seen 1.x code

grave jolt
#

that's an interesting suggestion

#

I don't think I've seen a use case for is

paper echo
#

and from what i have seen of "old" python, like < 2.7, its a wonder anyone ever used this language at all for anything other than toy projects

#

is True reads better than == True to me

#

but thats because i'm a native english speaker

grave jolt
#

ah, well, yes

#

also is None

paper echo
#

yeah

teal yacht
#

every other languages in existence do fine with == True, I'm sure we can live with that

grave jolt
#

== True

#

is can be confusing to beginners

#

when they are trying to use it to compare stuff

paper echo
#

oh i know where i use is, i use it for checking singletons as created with boltons.typeutils.make_sentinel

teal yacht
#

is/id has some legitimate use-case, every mutable container needs it to handle cycles

paper echo
#

yeah but as a binary operator baked into the language spec?

teal yacht
#

it's just not very common to implement containers

grave jolt
#

when they are trying to use it to compare stuff
Especially when they are native English speakers.

teal yacht
#

oh no, I definitely think is has no place in the language

paper echo
#

i agree it was probably a poor choice of language design

teal yacht
#

especially if we have a function already

swift imp
#

I really think they need a isa

paper echo
#

now that would be nice

swift imp
#

and I totally hate is

paper echo
#

or if is was just isinstance(...)

teal yacht
#

isa for isinstance right ?

swift imp
#

yes

#

is was so fucking confusing when i first started, especially bc it worked for strings

teal yacht
#

hmm, unsure about that

raven ridge
#

It definitely confuses people with small integers, too.

grave jolt
#

Javascript has instanceof as an operator.

swift imp
#

that is way too long

grave jolt
#

agree

#

but not as cryptic as isa

teal yacht
#

I mean, it's definitely clearer than isa

swift imp
#

I mean is a would benice but that couldnt work

grave jolt
#

And still shorter than isinstance. However, would it also support a tuple as its right operand?

paper echo
#

why not?

teal yacht
#

it's ambiguous

paper echo
#
if x isa (float, int):
    # ...
elif x isa (bytes, str):
    # ...
teal yacht
#

ah, i thought you were referring to the is a

swift imp
#

That is ambiguous

grave jolt
#

It's not ambiguous, it would just make a not a usable variable name

teal yacht
#

it is 100% ambiguous

paper echo
#

i dont like is a, too sql-ey

teal yacht
#
x is a (int)```
#

is it x isa int or x is a(int)

paper echo
#

not to mention the fact that you don't want to make a a reserved keyword

grave jolt
#

@paper echo or maybe COBOL

paper echo
#

heh yeah

swift imp
#

how about istype

teal yacht
#

ah, well if we reserve a i guess it works, but that's a terrible idea

#

I just don't see the problem with isinstance ngl

swift imp
#

yes reserving a is terrible

feral cedar
#

it just looks bad

raven ridge
#

instanceof is needed much less frequently than is, I think...

teal yacht
#

not in my experience

swift imp
#

I disagree

teal yacht
#

i use isinstance tens times more than is

swift imp
#

isinstance was found to be used quite a bit iirc, some code analysis that Guido did, like one of the most used

teal yacht
#

possibly hundreds

raven ridge
#

hm. I'm backing this up with a grep through the CPython codebase - isinstance seems to be used much, much less than is

grave jolt
#
SET VARIABLE a TO 1;
SET VARIABLE b TO 2;
WHILE CONDITION (b LESS THAN 1000) IS TRUE BEGIN CODE BLOCK
    PRINT a;
    PUT RVALUES b, a+b INTO LVALUES a, b;
END CODE BLOCK
teal yacht
#

what grep command did you use

#

also, is has a niche in containers, which the python stdlib is full of

paper echo
#

but why does is need to be a binary operator

#

and not just a function

teal yacht
#

to get relevant results, you'd need to verify all github repos imo

#

or most of them at least

swift imp
#

Yeah, I don't think core is good example

raven ridge
#

rg --type py '\bisinstance\b' | grep -v '^[^:]*: *#' | wc -l
vs
rg --type py '\bis\b.*:' | grep -v '^[^:]*: *#' | wc -l

paper echo
#

core is still relevant because core needs to do core things

swift imp
#

Python is used a lot for making an ez to use interface or glueing stuff together. The repos are gonna show how most people are using it. I think anything thats acting as an API of sorts would use isinstance a shit ton

raven ridge
#

there's an extra filter on the is one to try to remove places where it's used in English prose, in docstrings. Even with that extra filter, it's used ~2x as often as isinstance

#

isinstance is pretty rare, I think... you need it in places where duck typing doesn't work, which is itself pretty rare...

teal yacht
#

i still stand by the idea that is is overused in the stdlib compared to other places

#

and isinstance is underused

swift imp
#

⬆️

paper echo
#

i wouldnt be surprised if that were true

#

again i think we can all agree that is(a, b) is better than a is b because the former doesn't require a special keyword

teal yacht
#

(yeah i'm just speculating, but really i would be surprised)

#

i just think we should use id(a) == id(b)

boreal umbra
#

I like is as an infix operator because it's chainable

swift imp
#

I wish I could find the source but I swear I read a pep of Guido doing a code analysis of Google and finding isinstance to be one of the most used things

boreal umbra
#

a is b is c is d is ...

teal yacht
#

id(a) == id(b) == id(c) UmaruCool

boreal umbra
#

is is also faster than == because it can't be overloaded, so the interpreter doesn't spend any time finding the right implementation of __eq__

paper echo
#

@boreal umbra that might also be true about is()

teal yacht
#

the speed difference is generally insignificant

paper echo
#

where a function call lookup is slower than a hard coded binary operator

#

might be significant if implementing a low level container type @teal yacht

boreal umbra
#

wouldn't list.__eq__ be O(n) but is would always be O(1)?

teal yacht
#

low level as in done in C ? because then it doesn't use either

#

id returns an int

#

not to mention it's trivial to optimize

boreal umbra
#

let's see, does operator have is_?

grave jolt
boreal umbra
#

interesting

grave jolt
#

it's not trivial to optimize because id can be redefined

teal yacht
#

it is still trivial to find where it is not redefined

grave jolt
#

how would you do that?

raven ridge
#

I just checked a bunch of first party code my company has written and got pretty similar results. is is used more frequently in my codebases than isinstance is.

teal yacht
#

if there is no id = ... ?

#

or id in parameters

#

you can remove the optimization when a branch may redefine it

grave jolt
#

@teal yacht

# module.py

id = "spam"
# main.py
from module import *

def f():
    return id(4)
teal yacht
#

yeah, that would be a case where there would be no optimization

grave jolt
#

so if you have a star import, it throws away an optimization? that's weird

raven ridge
#

I'd be in favor of removing id from builtins, but removing is seems like a terrible idea to me.

teal yacht
#

really is is used only for is None and is <bool> and these can be pretty much replaced by == is 99% of cases

grave jolt
#

Also, what about globals

teal yacht
#

messing with globals would also remove the optimization

raven ridge
#

It's also used for is (some singleton)

grave jolt
#

@teal yacht How would you know that you're messing with globals? 🙂

teal yacht
#

if the code invokes globals() as some point

swift imp
#

Ive never used a singleton other than the builtins

teal yacht
#

really you're just pointing out all bad practices in python

#

allowing these are part of why python is so slow, there's no assumption you can make in all cases

raven ridge
#

Ive never used a singleton other than the builtins
@swift imp enum.Enum ?

grave jolt
#

Well, doing such optimization would break backwards compatibility, even if no reasonable person would redefine id in globals

teal yacht
#

what does that have to do with backward compat 🤔

swift imp
#

Guess the code type I work on has nevver had a need for enum

#

good night

grave jolt
#

according to the language semantics as they are now, this optimization should be impossible because there's a million ways to redefine id without it being detectable by a static checker

#

it's just a part of python and yes, it makes it slow

teal yacht
#

I'm not saying the optimization will trigger most of the time

#

But it's definitely something that's doable, you could argue it's not useful because it will be disabled in most cases however

grave jolt
#

well, the user of a module can redefine that module's globals

#
# module.py

def f():
    print(id(4))
# main.py
import module

module.id = "spam"
#

outside of that, there's fun stuff like

def f():
    lo = "lo"
    exec(f"g{lo}bals()['id']='spam'")
teal yacht
#

right i didn't think of the redefining from external sources

#

but yeah, eval/exec would also disable it

boreal umbra
teal yacht
#

thank you for reminding me why i barely tolerate the language 🙃

grave jolt
#

I sometimes do javascript just to remind myself that it could be worse 😄

#

...and my favourite

import asyncio

async def daemon():
    global id
    n = 1
    while True:
        if not (await collatz_conjecture_is_right_for(n)):
            id = "spam"
        n += 1
        await asyncio.sleep(0.0000001)

async def other_task():
    while True:
        print(id(4))
        await asyncio.sleep(0.1)

async def main():
    await asyncio.gather(other_task(), daemon())

asyncio.run(main())
#

pretty hard to prove whether it will redefine id

teal yacht
#

you don't have to prove that it will redefine

grave jolt
#

well, yes, if global id is used anywhere, disabling the optimization is totally reasonable

raven ridge
#

I wonder if removing ~50% of the stuff from builtins could ever be possible... Most of that stuff doesn't belong, but it's hard to see a way for the benefit of removing rarely used builtins to outweigh the backwards incompatibility issues it would cause...

teal yacht
#

you just have to prove that it may redefine it, if there is any branch that can redefine it, it would not do any optimization

#

a lot of the builtins have no place imo i agree

raven ridge
#

the cost of that check might outweigh the benefit of the optimization.

grave jolt
#

but the optimization would be at compile time

teal yacht
#

but your example modifying from an external module basically put it in the trash dw

grave jolt
#

maybe there will be another breaking release that will just cut out most of the stdlib

raven ridge
#

in order to get some of its performance benefits, Cython defaults to assuming that builtins cannot be redefined.

#

(after the point where the Cython extension module is first imported)

edgy lake
#

Figured this was more suited to advanced rather then getting buried in general:

This conversation can get a bit off topic so ima try to keep it about Python. I want to make a simple andriod app that will detect objects with my phone. Is it worth using something like Kivy for making the app using python or will that be more of a headache then just getting used to Java again (last time I really used Java was in HS and a bit in College)? I've done object recognition with python before in University so that would be a good headstart, I'll just have to learn how to train my own classifier. I dont keep discord open so feel free to @ me as I put more research into the answer.

winged ridge
#

hi everyone, had a doubt regarding static methods. Should i call static methods using the instance of a class or directly using the class name?.
!e

class Test:
  @staticmethod
  def staticmethod():
    print(hey)
  def callmethod(self):
    # calling using instance
    self.staticmethod()
    # or
    # calling using class
    Test.staticmethod()
test = Test()
test.callmethod()

Is there any diff in either methods?

gleaming rover
#

no

#

well, the overhead of an additional function call

#

which is negligible

winged ridge
#

which one is more pythonic?

gleaming rover
#

the former IMO

#

the point of a static method is that it belongs to a class, not an instance

winged ridge
#

so isnt Test.staticmethod() more understandable ?

#

@gleaming rover

gleaming rover
#

oh

#

I was looking at your code

#

and Test.staticmethod() was first

#

yeah, that's what I meant

winged ridge
#

okay cool thanks @gleaming rover

swift lily
#

wow looks... very "techy"

raven ridge
#

The most Pythonic approach is not to use @staticmethod at all.

#

Guido has said that he regrets adding it to the language, and that it was only added because he misunderstood the problem that he was trying to solve

winged ridge
#

The most Pythonic approach is not to use @staticmethod at all.
@raven ridge so whats the best alternative. just remove the saticmethod decorator?

raven ridge
#

no, make it a function, not part of a class.

floral grove
#

damn hella staff on this server XD

raven ridge
#

a "method" that has nothing to do with the class shouldn't be a part of the class

winged ridge
#

but what if the method is related to the class and it will be easier to understand if written inside the class?

no, make it a function, not part of a class.
@raven ridge

raven ridge
#

it will not be.

winged ridge
#

if i write an employee class and have a method that calculates the total pay wont it be better to write it inside the class than as a separate function outside.

raven ridge
#

no, it won't that's what I'm saying.

#

the very fact that it is not so closely related to the class that it needs access to instance data, class data, instance methods, or class methods means that putting it into the class makes it harder to read.

#

if it does need access to some of those things, then it should either be an instance method or a class method.

winged ridge
#

is there any advantage in using class method over static?

flat gazelle
#

inheritance works correctly with them

raven ridge
#

they do different things. A class method gets a reference to the class that it's called on - you'll want a class method if you want to create instances, or access class attributes, or call class methods. It will be able to know whether it's called on a parent class or subclass.

winged ridge
#

but what if my method doesn;t access any class of instance values? wont static be the best choice?

raven ridge
#

a static method is a function in disguise. It doesn't have access to an instance, or to the class of an instance. The only thing that makes it a method is that it lives inside a class - and because it doesn't play nicely with subclassing, that's not a useful place for it to be.

#

no.

winged ridge
#

so static method can mess with inheritance ?

#

did not know that. I will do some research on that

raven ridge
#

they simply don't participate in inheritance, in the same way as a function that's outside the class entirely doesn't.

#

I'm not making this up on the fly - the general guidance is that if you need access to an instance, you should be an instance method. If you need access to the class (for instance, to construct instances or to call other class methods), you should be a class method. If you need neither of those things, you should be a function.

winged ridge
#

that makes sense.

I'm not making this up on the fly - the general guidance is that if you need access to an instance, you should be an instance method. If you need access to the class (for instance, to construct instances or to call other class methods), you should be a class method. If you need neither of those things, you should be a function.
@raven ridge

raven ridge
#

they simply don't participate in inheritance, in the same way as a function that's outside the class entirely doesn't.
To be clear - they can be called on the parent class or on the subclass, but they can't be usefully overridden in subclasses, since you'll get a different version of the function depending on which class you call it on - which means it actually does depend on the class, but it can't figure out which class it was called on.

brazen jacinth
#

the very fact that it is not so closely related to the class that it needs access to instance data, class data, instance methods, or class methods means that putting it into the class makes it harder to read.
debatable honestly

raven ridge
#

debatable, yes, but has been debated, and is the consensus opinion of the Python community, and the question was about what's Pythonic.

brazen jacinth
#

fair, but let's say for example you have a django model and a service class that basically interacts with the model in various ways

#

it makes sense for those functions in the service layer to be static, they're nicely encapsulated in the class as service methods, but need not be on the model itself

#

they can be as model methods, but that results in fat models, which i'd argue makes them less readable and clunked up

raven ridge
#

Why couldn't they just be global functions in the module that defines the model?

brazen jacinth
#

fat models they're called

#

you can

#

but, many argue it's less readable

raven ridge
#

you said making them model methods makes them fat models, and you also said that making them global functions in the model's module makes them fat models - which is it?

brazen jacinth
#

oh mybad, misread

#

the former makes them fat, the latter kinda serves the same functions as static methods in a class though, but in a static method you can at least clump them togheter to make it easily known what you want

#

for example if you have 3 service classes, each with their own part in busienss logic

raven ridge
#

the Python primitive for namespacing stuff is modules

brazen jacinth
#

you imediately know what they do, depending on which service class they belong to

#

you could also make 3 modules sure 🤷‍♂️

#

but im arguing you are doing the same thing in a different format

raven ridge
#

yes - exactly!

brazen jacinth
#

both are viable, but you can't just discard the other

raven ridge
#

sure you can 😛

brazen jacinth
#

😄

raven ridge
#

if there are two approaches that can be used to accomplish exactly the same thing, it's reasonable for one of them to be the canonical way to do that thing.

#

str(x) and type(x).__str__(x) do exactly the same thing, but we only recommend one of them.

brazen jacinth
#

fair, but do you need 3 modules, when you can have a module representing business logic with 3 seperate classes being responsible for their own part in that logic

#

i mean fair, you can make a package handling that logic, and making 3 seperate modules for it

#

maybe you convinced me, im not sure yet 😄

#

if there are two approaches that can be used to accomplish exactly the same thing, it's reasonable for one of them to be the canonical way to do that thing.
@raven ridge i definitely agree with that, but im not sure this is a case where one is canonical and the other isn't

#

apparently based on the python community, it is 🤷‍♂️

undone hare
#

str(x) and type(x).__str__(x) do exactly the same thing, but we only recommend one of them.
@raven ridge I was told that there's a subtle difference (which I don't remember of course, I'm à dumb dumb), but I don't think it matters in this case

raven ridge
#

hm - if there is one I can't currently think of it, but maybe.

#

"A foolish consistency is the hobgoblin of little minds" - it's entirely possible that there are some cases where static methods improve readability and where class methods aren't a more correct substitute. I accept that such cases might exist, but I can't think of any.

undone hare
#

!zen 12

fallen slateBOT
#
The Zen of Python (line 12):

There should be one-- and preferably only one --obvious way to do it.

undone hare
#

I doubt, refer to the zen lemon_fingerguns

brazen jacinth
#

honestly i'd prefer less files and more classes - just for keeping the namespace tidy if not for anythign else, a stupid reason or not 😛

#

but you definitely made me think about it more

raven ridge
#

using classes for namespacing isn't the canonical way to do namespacing in Python - modules are.

undone hare
#

Kotlin made me change my mind about having too many imports haha

raven ridge
#

as opposed to Java, for instance, where classes are the canonical way of doing namespacing.

brazen jacinth
#

again ..true

#

maybe you convinced me

#

Didn't know staticmethod were frowned upon though

raven ridge
#

🤷‍♂️ - you know both ways now. Try writing things using global functions instead of static methods going forward, and see if you ever hit a problem where you think that the static method would be a better option.

#

I'm betting you won't - but if you do I'll be curious to hear about it 🙂

brazen jacinth
#

👍

brazen jacinth
#

ah, now i see why i was hardwired for this

#

at work we use this intermediate service layer as classes instead of as modules

#

it's clean, but not canonical as you put it

#

now i get it 😄

#

backwards compatibility, that's one reason to do it 🤷‍♂️

#

but yea, otherwise then that, i really don't see how a static function could do something a module global function couldn't

somber python
#

In terms of best practice, if I want to populate a list with a function, is it better to pass an empty list as a function argument and append or make my function return the populated list?

gleaming rover
#

In terms of best practice, if I want to populate a list with a function, is it better to pass an empty list as a function argument and append or make my function return the populated list?
@somber python the latter IMO

#

the former is a very C thing to do

final whale
#

how about yielding and unpacking ?

gloomy rain
#

If it's a finite list that can be cheaply precomputed, there's no reason to create a generator, I think.

#

Generators are good if computing each element is expensive and you don't want to store it all in memory at the same time.

wide shuttle
#

@civic dune If you're looking for a dedicated channel for a help conversation, check out our help channels. You can claim one for yourself. See #❓|how-to-get-help.

civic dune
#

will do, capitan!

wide shuttle
#

Hello, this channel is meant to discuss the Python programming language itself, from a higher-level perspective. Think of things like the future of the language, PEPs, the advanced language concepts, new releases, and so on. It's not for help questions.

chrome sequoia
#

Many people advanced in Python, also know Javascipt, that is why I asked here

wide shuttle
#

My point is that this is specifically meant as a discussion channel to discuss the Python programming language itself. We have up to 32 help channels and several topical channels for other conversations (in addition to #python-discussion), but we do try to have at least one place on the server where more advanced discussions of Python itself is the topic.

chrome sequoia
#

Sure, my intention wasn't to offend anyone.

wide shuttle
#

No offense taken, I'm just trying to explain why we're stricter about the "on topic" rule in this specific channel. It appears to be difficult to give such conversations a home, but we try.

chrome sequoia
#

Noted! I'll ask in general now.

half wolf
#

@brazen jacinth I am against fat models because it makes code less isolated and harder to reason about and delete.

brazen jacinth
#

yea agree, that's why we use a intermediary service layer

mighty oasis
#

Can somone help me with auto-py-to-exe

zenith shadow
#

I feel like this is the right channel for this question: What is the difference between is and ==?

brazen jacinth
#

one checks for identity, the other for equality,

zenith shadow
#

What do you mean?

brazen jacinth
#
>>> a = [1,2,3]
>>> b = [1,2,3]
>>> a is b
False
>>> a == b
True
>>> a = b
>>> a is b
True
>>>  
peak spoke
#

== invokes the __eq__ special method on the objects which returns a bool depending on their equality from values, is compares if they are the exact same object

zenith shadow
#

Ahh that makes sense.

#

Thanks @brazen jacinth @peak spoke .

full jay
#

Which is why singletons like None work so well when using is

#

Because there's only ever one instance of it

zenith shadow
#

@full jay What's a singleton?

full jay
#

Essentially an object that you can only ever have one of

#

All references point to that one object

brazen jacinth
#

so, technically are digits from -5 to 255 singletons?

full jay
#

I think so but that's an implementation detail rather than a language specification

brazen jacinth
#

true

zenith shadow
#

All references point to that one object
@full jay Ohhh ok, that makes sense, thank you.

proven iris
#

AES algorithm in python

#

I want to make a secure communication app so this is important for me

brazen jacinth
#

then use tried and tested tools for encrpytion and you'll be fine

boreal umbra
#

I think so but that's an implementation detail rather than a language specification
@full jay aren't you not supposed to use is between integers, even if they're both non literals?

#

I think I remember reading that it's never guaranteed that an integer will be a specific memory location.

brazen jacinth
#

comparing integers by identity will definitely leave suprises if you don't know the implemntation specs

gleaming rover
#

yeah, that's why it's an implementation detail

#

it happens to work for that set of common integers in CPython

brazen jacinth
#

still intrigued why the -5

boreal umbra
#

I'm thinking

a = b = 450635863
peak spoke
#

It should always work for the cached ints, but you shouldn't rely on implementation details and if it goes out of the range you won't get the desired behaviour

boreal umbra
#

My understanding is that a is b isn't guaranteed here.

gleaming rover
#

yes

#

it's not

peak spoke
#

It should be

brazen jacinth
#

in this example it will be

peak spoke
#

You only evaluate the int expression once, and the result of that is assigned to both a and b

gleaming rover
#

oh, yeah, in this case it will be

#

but in general a == b does not imply a is b

brazen jacinth
#

in general, that implies to most imutables, right?

#

wait, brainfart, not imutables

#

objects in general 🤷‍♂️

tired epoch
#

isnt a is b more like a===b?

peak spoke
#

Immutable literals will be the same objects as they're constants during compilation, but anything created dynamically that isn't some sort of a special value or interned manually will be a separate object

brazen jacinth
#

if you mean by types, no

tired epoch
#

point to the same address of the value

#

?

brazen jacinth
#

what do you mean by ===?

gleaming rover
#

isnt a is b more like a===b?
@tired epoch nope

#

if you mean the JS ===

tired epoch
#

ye i got confused

grave jolt
#

=== is a hack that was put into JS because == did too much coercion.

brazen jacinth
#

php has it aswell iirc

grave jolt
#

== checks for equality of values (e.g. "hello" == "".join("he", "llo")
is checks that two objects are actually the same object (checks the equality of identity).

tired epoch
#

but is is more like pointing to the same adress of the value?

grave jolt
#

Yes.

#

!e

x = [1, 2, 3]
y = [1, 2, 3]
print(x == y)
print(x is y)
fallen slateBOT
#

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

001 | True
002 | False
brazen jacinth
#

basically

id(x) == id(y)
gleaming rover
#

a is b implies id(a) == id(b)

tired epoch
#

just wanted to refresh it

grave jolt
#

...and in CPython id actually stores the address of the object

tired epoch
#

i think i got it

#

its what i knew it ws

#

thnx for clarifying it guys

full jay
#

@full jay aren't you not supposed to use is between integers, even if they're both non literals?
@boreal umbra Right that was partly my point

half wolf
#

@brazen jacinth I don't see how a service layer helps in principle. You can still end up with tons of single use functions int he service layer for example. Or almost the same functionality because the layer is too bloated to reuse.

brazen jacinth
#

what do you propose as a replacement

#

Thats why you make reusable components in the service layer though

#

But id be happy to hear of any alternatives

half wolf
#

My primary defense is to keep code as far out to the leaves in the tree as possible (views in this case). Only after you know you need the code in multiple places you move it up.

The thin views camp moves things to the trunk (models or service layer) for everything always.

#

I prefer having a service layer or similar to polluting the models, but that's orthogonal.

#

Not polluting the models is more about keeping separete that which is different.

astral hollow
#

Wow

brazen jacinth
#

so basically, no replacement?

#

you gotta have it one way or the other 🤷‍♂️

#

but yea, agreed, no need to abstract untill there is reason for it

#

rather duplicate than incorrectly abstract

paper echo
#

s a n s i o

tawdry sky
#

GWsetmyxPeepoWeird @paper echo when u gonna release a kustom fork for sansio bro

paper echo
tawdry sky
#

GWcmeisterPeepoE jane v2 fork... when...

paper echo
unkempt rock
#

Hello friends, Could someone create a Discord Bot that can send messages and has a ReactionRoles function and do that so that he can also send pictures. If yes please send me a dm thank you

boreal umbra
#

@unkempt rock I would ask in #discord-bots; we try to keep this channel especially on topic.

orchid flame
#

why dont type hints support unpacking? is it because its new and there are bigger fish to fry or is there a fundamental reason

flat gazelle
#

well, the type is already known form the tuple you are unpacking

orchid flame
#

i mean like x, y: int