#internals-and-peps

1 messages · Page 72 of 1

gleaming rover
#

that's life...

frank siren
#

I could rant all day about 484

supple pawn
#

anyone have good resources for learning how to handle data streaming?

paper echo
#

would that work with attrs?

#

or a dataclass

unkempt rock
#

Can u change the type of a class?

#

i mean like type(my_class) shud return <class 'str'>

grave jolt
#

why would you need that?

#

A class must be an instance of type

#

You can change the class of which a class is an instance by using metaclasses.

#

!e

class A:
    pass

class MyMeta(type):
    pass

class B(metaclass=MyMeta):
    pass

print(A, type(A))
print(B, type(B))
fallen slateBOT
#

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

001 | <class '__main__.A'> <class 'type'>
002 | <class '__main__.B'> <class '__main__.MyMeta'>
unkempt rock
#

Can i have it <class 'MyMeta'> instead of <class '__main__.MyMeta'>

gleaming rover
#

Can i have it <class 'MyMeta'> instead of <class '__main__.MyMeta'>
@unkempt rock why do you want that?

unkempt rock
#

Simply im making a new object type so i want it to display like this

Can i have it <class 'MyMeta'> instead of <class '__main__.MyMeta'>
@unkempt rock

gleaming rover
#

@unkempt rock like I said, why do you want that?

#

in Python, (almost) all things are possible, but not all things are desirable.

unkempt rock
#

Oh

deft pagoda
#
In [1]: class TestMeta(type):
   ...:     def __prepare__(*args):
   ...:         return {'__name__': 'whatever'}
   ...:

In [2]: class Test(metaclass=TestMeta):
   ...:     ...
   ...:

In [3]: type(Test())
Out[3]: whatever.Test
#

i think you might need to remove __qualname__

#

no, still get whatever.Test

unkempt rock
#

Thanks a lot @deft pagoda

grave jolt
#

You know what dunder we're missing?

__rcontains__
spice pecan
#

that would be weird to say the least

#

but honestly? I'm down

languid dagger
#

I can't say I agree with that. __contains__ is item in my sequence, but then with __rcontains__ you are then suggesting that if the first is not supported then instead do sequence in my item?

flat gazelle
#

what would be an item that knows better than a data structure whether it is contained?

spice pecan
#

I could see it being useful in some sort of a proxy-ish object, but objectively it shouldn't really be a thing

#

Like something akin to AllOf(*items) in container could return all(item in container for item in items), but that would require container to return NotImplemented to fall back to AllOf.__rcontains__

flat gazelle
#

that seems not better than AllOf(items, container)

languid dagger
#

Why can't you just do all(item in container for item in items) instead of having an AllOf?

spice pecan
#

You can indeed

#

Objectively I don't see a reason for it to be a thing, but I wouldn't mind it for fun projects

half wolf
#

What is rcontains supposed to be? "reverse contains"? Like.. it's in the container but.. eh.. from the right instead of left? That seems like the same thing.

flat gazelle
#

@half wolf a in b is approx. b.__contains__(a), this would make a in b a.__rcontains__(b)

undone hare
#

Bypassing captchas is against rule 5 @unkempt rock

half wolf
#

ugh

unkempt rock
#

i know im dumb

buoyant skiff
#

I want to store a value in a variable "save_it" . It default 0. whenever I run the colab file it increase by 1. That mean save_it=1. If I open the colab file a week after the variable value still 1. If I again run it it increase by 1. Is there any way to solve this help me please ?

flat gazelle
#

You need to put it in a file

deft pagoda
half wolf
#

Seems like he should propose those changes to dataclasses.

spice pecan
#

Othe.rs migh.t help.fully sugg.est usag.e of the attr.s libr.ary.
Well played

paper echo
#

@spice pecan fwiw attrs doesnt use annotations at all, cluegen is more explicitly a dataclasses replacement

#

and also you can from attrs import attrs, attrib 😛

torpid bridge
#

The optional issue with dataclasses irritates me

paper echo
#
from attrs import attrs, attrib

@attrs
class Foo:
    x = attrib()
    y = attrib()

but i like the attr namespace, its cute and i need to have some fun while im writing boring code

#

@torpid bridge what issue?

torpid bridge
#

This:

deft pagoda
paper echo
#

their point about dataclass being slow and clunky is valid. but their criticism of the attrs api is a little silly

#

i'd be curious to see if attrs classes are slower than cluegen classes

torpid bridge
#

!e ```py
from dataclasses import dataclass

@dataclass
class Node:
type: int = 1

@dataclass
class LeafNode(Node):
contents: str

fallen slateBOT
#

@torpid bridge :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 8, in <module>
003 |   File "/usr/local/lib/python3.8/dataclasses.py", line 1000, in dataclass
004 |     return wrap(cls)
005 |   File "/usr/local/lib/python3.8/dataclasses.py", line 992, in wrap
006 |     return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
007 |   File "/usr/local/lib/python3.8/dataclasses.py", line 909, in _process_class
008 |     _init_fn(flds,
009 |   File "/usr/local/lib/python3.8/dataclasses.py", line 501, in _init_fn
010 |     raise TypeError(f'non-default argument {f.name!r} '
011 | TypeError: non-default argument 'contents' follows default argument
deft pagoda
paper echo
#

ah yuck

deft pagoda
#

beazley isn't some random though

paper echo
#

of course not

#

guy is a wizard

torpid bridge
#

I have a perhaps unwise urge to monkeypatch _init_fn to fix that issue

paper echo
#

i dont have anything against cluegen, i just want to see a more fair comparison with attrs instead of with dataclasses

torpid bridge
#

I understand why it throws that error, I'm just not sure how to go about the process of changing the opinion of the library so that it reorders them intelligently instead of just erroring, so I'll probably just fork it

#

The number one thing that stands out ot me about attrs is the extra writing

#
@attr.s
class MyClass:
  a: int = attr.ib()
  b: int = attr.ib()
  c: int = attr.ib(default=0)

#vs 

@dataclass
class MyClass:
  a: int
  b: int
  c: int = 0
#

its like, twice the code

deft pagoda
#

need a metaattrs to reduce attrs boilerplate

torpid bridge
#

oh, I see

#
>>> @attr.s(auto_attribs=True)
... class SomeClass:
...     a_number: int = 42
...     list_of_numbers: typing.List[int] = attr.Factory(list)

#

from their docs

#

its still a lot though, and it makes me feel like I'm interacting with an orm

paper echo
#

personally i like the explicitness

torpid bridge
#

Ah

paper echo
#

i strongly feel that annotations alone should not be used for anything at runtime

#

so i prefer having a runtime spec as well as an annotation

#

plus sometimes i have class variables and instance variables that should not be part of the init signature

torpid bridge
#

I hold the opposite opinion, but I understand

paper echo
#

yeah its good that there is something for everyone 🙂

torpid bridge
#

And that is certainly true

paper echo
#

yeah so personally i think attrs is the right balance of boilerplate reduction without using too much implicit magic

#

if you like the implicit stuff then definitely use cluegen

torpid bridge
#

what I really want is an xml serializer that uses annotations to generate

#

what are they called..

#

dtd's

#

IMO xml does have a lot of mistakes but I just cannot get into json for data storage. It feels oddly constrained and difficult to parse visually even if it is somewhat more space efficient

deft pagoda
#

beazley had a talk where he used import hooks to import xml into python classes

torpid bridge
#

Do you have a link? That sounds really interesting

deft pagoda
#

i might be able to find it

torpid bridge
deft pagoda
torpid bridge
#

ty!

teal yacht
#

I get that this is interesting but I can't help but cringe when I think about how impossible it is to use static analysis tools with these kind of practices

#

That's a big reason why many optimizations and verifications are impossible in python

frank siren
#

should there be a special form in the typing module for the type of current class?

from typing import Self

Scalar = TypeVar("Scalar")
class Vector3(Generic[Scalar]):
    # ...
    def __xor__(self, other: Self[Scalar]) -> Self[Scalar]:
        if not isinstance(other, type(self)):
            raise OperandTypeError("^", self, other)
        return Vector3(self.y*other.z-self.z*other.y,
                       self.z*other.x-self.x*other.z,
                       self.x*other.y-self.y*other.x)
    # ...
teal yacht
#

Same with metaclasses, descriptors, getattr/setattr etc etc

frank siren
#

I know you can use "Vector3[Scalar]" as the type, but it looks weird

deft pagoda
#

if they had structural typing it could just be numeric and iterable

torpid bridge
#

Don't we already have those?

#

the numbers module, I mean?

grave jolt
torpid bridge
#

<

deft pagoda
#

do you still have to inherit the abc?

#

or does it check for methods

torpid bridge
#
from typing import Self
from numbers import Real

class Vector3(Container[Real]):
    # ...
    def __xor__(self, other: Self[Real]) -> Self[Real]:
        if not isinstance(other, type(self)):
            raise OperandTypeError("^", self, other)
        return Vector3(self.y*other.z-self.z*other.y,
                       self.z*other.x-self.x*other.z,
                       self.x*other.y-self.y*other.x)
teal yacht
#

the question was more in relation to the Self iirc

#

(which doesn't exist as of now)

torpid bridge
#

( That may not be quite right but the parts are right )

teal yacht
#

You could emulate it with a TypeVar I suppose but ugh

torpid bridge
#

I could swear that you could use Self

frank siren
#

@torpid bridge actually the type var scalar is just a suggestion, if you put Vector3 instead you get matrix multiplication for free

#

wait does that actually exist

teal yacht
#

no

#

not in typing at least

frank siren
teal yacht
#

and since it'd require special support, probably not anywhere

willow loom
#

how can i change color of print?

torpid bridge
#

Yeah, looks like there just isn't one

#

The pep suggests just using the class name, and I agree that's the next best thing

undone hare
#

That’s a bit less precise for subclasses, but I don’t see how that can actually affect you

teal yacht
#

@frank siren the advertised solution

class Base(Generic[T]):
    Q = TypeVar('Q', bound='Base[T]')

    def __init__(self, item: T) -> None:
        self.item = item

    @classmethod
    def make_pair(cls: Type[Q], item: T) -> Tuple[Q, Q]:
        return cls(item), cls(item)```
frank siren
#

oh nice

frank siren
teal yacht
#

ah, first difference between mypy and other type checkers i see

frank siren
#

maybe I'll omit the brackets

teal yacht
#

yeah it'll work, you'll have to do Self[Scalar] tho

frank siren
#

I wish f# or other functional language had libraries for symbolic math

#

so I wouldn't need to use python guido

teal yacht
#

i tell myself that every single day

grave jolt
#

just make a sympy interop 🙂

frank siren
#

TypeError: 'Mul' object is not subscriptable intensifies

teal yacht
#

might as well use SymEngine directly

frank siren
#

also sympy straight gave up with type hints from what I could read on their github

teal yacht
#

don't bind to sympy, bind to symengine

#

it'll be much easier in the first place to interop with c++ than python, most likely

frank siren
#

I think there's a shim for haskell

teal yacht
#

official repo even

frank siren
#

does it have support for integral transforms?

teal yacht
#

It's basically empty lol, it's a bunch of c ffi definitions and nothing else

#

even the readme is not finished

frank siren
#

does it have support for integral transforms?
@frank siren tbh sympy only has algorithms for the most simplest forms

grave jolt
#

is that pyright?

frank siren
#

ye

grave jolt
#

hm

frank siren
#

it's more of an autocomplete aid than a strict type checker

grave jolt
#

if that's a bug, you could submit it to github or ask in gitter

frank siren
#

I don't think it's expected to know how to resolve many of those types

#

It's quite loose compared to mypy

deft pagoda
#

made this more diabolical -- add this to cluegen:

class AnnDefaultDict(dict):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self['__annotations__'] = {}

    def __missing__(self, key):
        if key.startswith('__') or key == 'cluegen':
            raise KeyError(key)
        self['__annotations__'][key] = None


class DatumMeta(type):
    def __prepare__(*args):
        return AnnDefaultDict()

and we can make classes with least boilerplate:

class Coordinates(Datum):
    x, y
grave jolt
#

In my experience, pyright has better type inference than mypy, though

frank siren
#

same here, it handles some loose cases better, but mypy complains when it cannot deduce stuff

grave jolt
#

it also added recursive aliases recently

#

does mypy have that?

paper echo
#

is there an example of something pyright can handle that mypy cant?

#

and what is a recursive alias?

grave jolt
#
Path = Union[str, List["Path"]]
#
-> Path = str | List[str | List[str | List[str | ...]]]
paper echo
#

ahh

boreal umbra
#

@grave jolt I don't hate that syntax, but that would require creating a class_or dunder that could thenceforth (I got to say it) never do anything else.

grave jolt
#

What do you mean @boreal umbra ?

paper echo
#

i didnt know about __prepare__ @deft pagoda

#

im reading pep 3115 and still not totally clear on what it does

#

__prepare__ returns a dictionary-like object which is used to store the class member definitions during evaluation of the class body. In other words, the class body is evaluated as a function block (just like it is now), except that the local variables dictionary is replaced by the dictionary returned from __prepare__. This dictionary object can be a regular dictionary or a custom mapping type.

deft pagoda
#

it mostly replaces the __dict__ object somewhere

#

it's cool to use defaultdict-likes and ChainMaps

paper echo
#

i see. i presume it's what's passed to the type's __new__ method?

deft pagoda
#

yeah, it gets reconverted back to a mapping somewhere

paper echo
#

e.g. the return value from MyClass.__prepare__ gets passed to type(MyClass).__new__?

deft pagoda
#

mappyingproxy*

#

yeah, it's what's passed to new

paper echo
#

ahh very clever

#

ive never actually used chainmap

#

!e ```python
from collections import ChainMap
baseline = {'music': 'bach', 'art': 'rembrandt'}
adjustments = {'art': 'van gogh', 'opera': 'carmen'}
print( dict(ChainMap(adjustments, baseline)) )

fallen slateBOT
#

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

{'music': 'bach', 'art': 'van gogh', 'opera': 'carmen'}
deft pagoda
#

ChainMaps really neat for passing around default arguments with kwargs

#

oh, that's mentioned in the docs

paper echo
#

i dont see that

#

oh right below

#

derp

modern frigate
#

How does Python remove unneeded space? Does is deallocate it once the variable goes out of scope?

#

via a garbage collector or smth

spice pecan
#

The garbage collector picks up objects that have no references pointing to them

modern frigate
#

ah ok

#

it makes the language more simple, fs, but slower. imo, rusts ownership system is big brain, but confusing af to learn

paper echo
#

@deft pagoda wait this is kind of ingenious. using __prepare__ to create a whole namespace... could use this for custom DSLs

charred wagon
modern frigate
#

Ok! Thanks @paper echo

worn hinge
#

anyone use eks and python?

swift imp
#

I'm failing to see the use cases of __prepare__

red solar
#

wow so this whole time there's been extra stuff i didn't know about

#

damn

raven ridge
#

Only for types with Py_TPFLAGS_HAVE_GC

red solar
#

is that a default flag?

raven ridge
#

No - it's your responsibility to set it if your extension class is able to participate in a reference cycle.

red solar
#

oh well at least now ik to never do that

unkempt rock
#

How does del work?

>>> a=[1]
>>> b=a
>>> b[0]=0
>>> a
[0]
>>> del b
>>> b
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    b
NameError: name 'b' is not defined
>>> a
[0]
>>> 
flat gazelle
#

In this case, it just removes the name b

unkempt rock
#

Oh

raven ridge
#

what do you mean by "how"?

mystic cargo
#

but in ALL other cases it will modify a? What are the other scenarios where a will not be modified even ifb is linked to it?

raven ridge
#

del, __delattr__, __delitem__, =, __setattr__, and __setitem__ are manipulating references. They're changing which names are bound to what objects.

#

in the case of del var, it un-binds a name, removing one reference to an object but leaving any others that might exist unchanged.

raven ridge
#

in the case of the code pasted above, b[0] = 0 isn't really changing b, it's changing the list that b refers to, which is the same list as a refers to. Later on when you print a you see those changes, because a is another name for the list that was changed.

unkempt rock
#

in the case of the code pasted above, b[0] = 0 isn't really changing b, it's changing the list that b refers to, which is the same list as a refers to. Later on when you print a you see those changes, because a is another name for the list that was changed.
thanks a lot 🙂

raven ridge
#

and del b makes it so that b no longer refers to that list, but a still does.

unkempt rock
#

I understand now

>>> a=[1]
>>> b=a
>>> del b[0]
>>> b
[]
>>> 
>>> a
[]
>>> 
#

@raven ridge So del b means the same thing the red line is doing in this picture? (im terrible at drawing)

raven ridge
#

yes.

unkempt rock
#

Ok thanks i get it now

trail stratus
#

why do we use child class?

half wolf
#

@trail stratus try a beginner help channel. This is "advanced discussion".

merry yoke
#

@trail stratus it enable code reuse of parent classes and adding more features in the child class.

trail stratus
#

i see thx

merry yoke
#

@half wolf can you point me to the beginner's channel?

pallid meteor
unkempt rock
#

Anyone have Plotly Express experience?

#

The documentation is a dead end honestly

loud summit
#

This channel is for talks regarding Python itself, not help with plotly @unkempt rock

unkempt rock
#

ah, I thought it was more advanced stuff within python like obscure libraries

#

My bad

merry yoke
#

@unkempt rock try your luck in the #data-science-and-ml channel. Plotly is iften used by data scientist.

half wolf
#

Discord really needs a way to move messages to the right place. It's frustrating that this channel is just 90% off topic.

pseudo cradle
boreal umbra
#

Well, there aren't any "beginner" channels. There are just channels that have topics. We've discussed a lot what the name of this channel should be but it's not called "advanced discussion" specifically to filter out individuals, just topics.

#

frankly I don't think the question about why one should use a child class is off topic for this channel, necessarily. we could have a great discussion about when to use inheritance in Python.

#

@trail stratus if you're still here, the answer has to do with the method resolution order.

trail stratus
#

i am here

#

wdym by method resolution order

boreal umbra
#

well, there are a few aspects of inheritance, but the method resolution order is one of them.

#

are you familiar with methods?

trail stratus
#

yes like __init__ right?

#

or __iter__

boreal umbra
#

that's one method, yeah

#

those two are specifically dunder methods

trail stratus
#

idk what dunder is just learnign classes

boreal umbra
#

"dunder" just means "double under[score]"

#

so you would read __init__ as "dunder init" when you speak it aloud.

trail stratus
#

i see, are there methods that donnt have dunder

boreal umbra
#

yeah

trail stratus
#

i.e

boreal umbra
#

you can define any method you'd like

trail stratus
#

wdym, how

boreal umbra
#

for example, list objects have an append method

trail stratus
#

ooh append is a method

#

i thought it was a function

boreal umbra
#

well, it's both

#

methods are functions

#

but specifically, they're functions that belong to a class

#

in this case, the list class

trail stratus
#

oohh list is a class?

boreal umbra
#

and by default, methods act upon an instance of a class

#

ye

trail stratus
#

ohh i thought it was a primmittive data type

boreal umbra
#

well, everything in Python is an instance of a class

#

except keywords like for and def, I guess.

#

even classes are instances of a class

#

doesn't that just blow your mind?!

trail stratus
#

oohh but when we already have a class why would we need to add a child class instead of adding on to the same class

merry yoke
#

@trail stratus In Python, everything is an object. there are no primitive types

trail stratus
#

ye it does

#

i see

boreal umbra
#

🤯

#

that's my mind

#

anyway

trail stratus
#

oohh but when we already have a class why would we need to add a child class instead of adding on to the same class
?

boreal umbra
#

I'm not sure what you mean by that

#

consider this example

#
my_list = [1, 2]
my_list.append(4)
print(my_list)
trail stratus
#

i mean why do we need child class when we have the parent class

boreal umbra
#

I thought I had used the !e flag

#

ah

#

well, each class has a method resolution order

#

which is the order in which it will look for methods

#

so suppose you have a Bird class. You wouldn't want to implement a fly() method for that class because there are birds that can't fly

trail stratus
#

You may want add methods or override them.
@warped yew but cant we do that in the parent class

boreal umbra
#

but if you make a subclass called FlyingBird, you can create a fly method for it

trail stratus
#

oooh i kinda get it

#

ye

boreal umbra
#

but

#

suppose there's a subclass of flying birds

#

idk, red birds? Assume that in real life, all red birds can fly, and that there's a meaningful distinction between birds that are red and birds that aren't.

#

when you have the RedBird class, which is a subclass of FlyingBird, you can do one of two things

#

you can define a fly method, or you can not define one

trail stratus
#

i see

#

cause not all red birds can fly

#

right

boreal umbra
#

no

trail stratus
#

ohh

boreal umbra
#

RedBird would be a subclass of FlyingBird

trail stratus
#

ye

boreal umbra
#

so if you don't define a fly method for RedBird, it would just use the fly method defined in FlyingBird

#

because RedBird would "inherit" that method.

trail stratus
#

thats why its called inheritance

boreal umbra
#

!e

class Bird:
    pass

class FlyingBird(Bird):
    def fly(self):
        print("The bird is flying")

class RedBird(FlyingBird):
    pass

cardinal = RedBird()
cardinal.fly()
#

wow

grave jolt
#

s/def/class

trail stratus
#

lol

fallen slateBOT
#

@boreal umbra :white_check_mark: Your eval job has completed with return code 0.

The bird is flying
trail stratus
#

i see

boreal umbra
#

it's really late for me so give me a break

trail stratus
#

ye

grave jolt
#
break
#

take it

boreal umbra
#

I accept

#

thanks!

grave jolt
#

please no space between ! and accept

boreal umbra
#

that's a capital i, not an exclamation point

trail stratus
#

but u didnt define a fly method in redbrid @boreal umbra

grave jolt
#

see, you mistyped !

boreal umbra
#

no, I was stating that I accept

#

don't gaslight me when I'm tired

raven ridge
#

there's some nice examples in the standard library. Maybe the best example is collections.OrderedDict - it's a dictionary that's optimized for letting you change its iteration order. As such, it's a subclass of dict

grave jolt
#

@trail stratus That's right -- subclasses inherit all the methods from their parent class(es)

trail stratus
#

well i understand why we use subclass so I got my answer thx guys

boreal umbra
#

but u didnt define a fly method in redbrid @boreal umbra
@trail stratus that's the point. There's no fly method for RedBird, so when Python can't find that method in the RedBird class, it goes to the next class in the method resolution order.

trail stratus
#

ye

#

classes are fun and confusing

grave jolt
#

wait until you get to multiple inheritance

boreal umbra
#

multiple inheritance isn't necessarily confusing because there's always a linear MRO

#

also if it's not like that don't tell me

raven ridge
#

it is like that. 🙂

flat gazelle
#

I wonder if you could make a metaclass that would use a different mro

gleaming rover
#

if there isn't you get an error when creating the class

boreal umbra
#

@flat gazelle I would ask salt-die

trail stratus
#

Well, there aren't any "beginner" channels. There are just channels that have topics. We've discussed a lot what the name of this channel should be but it's not called "advanced discussion" specifically to filter out individuals, just topics.
Youu should make it as "language discussion"instead of advanced

flat gazelle
#

Language discussion doesn't imply python

boreal umbra
#

@trail stratus trust me, we've discussed numerous possibilities for what to call this channel. The problem is that we can't force tens of thousands of people to read the channel description.

trail stratus
#

ye and it is kinda condusing as well

#

the description

#

i meant confusing not condusing

grave jolt
#

Well, you can usually scroll through a channel to see what sort of things are discussed here

#

it's very hard to create an accurate description

merry yoke
#

@trail stratus you will also have to decide between inheritance or composition. Inheritance is 'IS A' relation like a lion is an animal. Composition is 'HAS A' relation. A lion has 4 legs and tail.

grave jolt
teal yacht
#

I wonder if you could make a metaclass that would use a different mro
@flat gazelle yes, just have to redefine .mro()

grave jolt
#

There's also a very useful rule called Liskov Substitution Principle. It's pretty intuitive to me.

If a type T satisfies some property, then its subtype S also satisfies that property

Example from mathematics: if a function f works with all real numbers, it also works with all integers. That makes sense because integers are a subset of real numbers.

flat gazelle
#

That would be __mro__ and the issue is that has to be a tuple

#

Which is not always applicable

gleaming rover
#

mro is a method that generates the __mro__.

teal yacht
#

No, mro works fine

flat gazelle
#

Huh

gleaming rover
#

they're two different things

half wolf
#

Of course there are valid cases when a subclass violates that, and that's fine. Don't be too hung up on the theory.

boreal umbra
#

@grave jolt I like how the name of it makes it sound really advanced

deft pagoda
#

@swift imp
Say one is developing a framework with a extremely numerous list of properties:
IntProperty, FloatProperty, StringProperty, ...

Before defining a class one would normally need to import whatever properties you'd use:

from MyFrameworkProperties import IntProperty
from MyFramework import Widget

class MyWidget(Widget):
    width = IntProperty()
    height = IntProperty()

But what one could do, if you don't mind the magic, is define a metaclass that injects all the properties into a Widget's namespace,
so that they're available without importing them:

import MyFrameworkProperties

all_properties = {name: getattr(MyFrameworkProperties, name) for name in MyFrameworkProperties.__all__}

class WidgetMeta(type):
    def __prepare__(*args):
        return ChainMap({}, all_properties)
    
    def __new__(meta, name, bases, methods):
        methods = methods.maps[0]  # removing properties from the widget's namespace
        return super().__new__(meta, name, bases, methods)

class Widget(metaclass=WidgetMeta):
    ...

Now we can define MyWidget as above, but we never have to worry about importing the properties we need while inside the class body!
Note I submitted exactly this hack to kivy: https://github.com/kivy/kivy/pull/6877 and was quickly rejected! Not everyone is a fan of this much magic.

gleaming rover
#

@teal yacht is right

grave jolt
#

Well, it's not a commandment, that's why you can, for example, override methods

raven ridge
#

It's possible to override methods without violating Liskov substitutability.

gleaming rover
#

@grave jolt I like how the name of it makes it sound really advanced
@boreal umbra it does get a bit advanced when you start talking about variance

half wolf
#

@deft pagoda well that is truly nasty yea :P In iommi we go around this by having (let's take forms as an example) one Field class, but it has multiple constructors:

class MyForm(Form):
    foo = Field.integer()
    bar = Field.float()

I think this is a lot cleaner than having IntegerField, FloatField, etc

raven ridge
#

I'd go so far as to say that anything that violates Liskov substitutability never belongs in production code (but might be OK for testing)

half wolf
#

@raven ridge as long as you define the properties of the parent class to be an empty set, you can do whatever you want and never violate it! :P

gleaming rover
#

I'd go so far as to say that anything that violates Liskov substitutability never belongs in production code (but might be OK for testing)
@raven ridge this ("never") seems a bit extreme

deft pagoda
#

that's not a bad idea to have one constructor, kivy has a ton of individual properties

half wolf
#

@deft pagoda we have some other cool things in iommi that really cuts down on code, increases flexibility and just makes everything more readable and workable

raven ridge
#

@raven ridge as long as you define the properties of the parent class to be an empty set, you can do whatever you want and never violate it! :P
@half wolf Sure, and there's nothing wrong with that. The problems with violating it come from violating user's expectations about how something that isinstance says is an instance of that parent class will behave. If users can't make any assumptions about how the parent class will behave, you can't violate them.

half wolf
#

like those constructors are really just a little pile of default constructor arguments

raven ridge
#

constructors don't factor in to Liskov substitutability

gleaming rover
#

think they were talking about iommi

raven ridge
#

ah, I can see how that might be the case.

#

at the same time, it's not obvious that Liskov Substitutability doesn't say anything at all about constructors, so it's worth pointing out anyway 🙂

gleaming rover
#

at the same time, it's not obvious that Liskov Substitutability doesn't say anything at all about constructors, so it's worth pointing out anyway 🙂
@raven ridge for clarity, I agree

grave jolt
#

what are some examples of LSP violation being reasonable?

gleaming rover
#

although - correct me if I'm wrong - the LSP constrains applications of functions to objects of a specific type, right?

#

which doesn't apply to constructors

#

therefore, by definition...

half wolf
#

yea, you guys got confused by two topics being discussed at the same time :P

grave jolt
#

concurrency issues

gleaming rover
#

there was a pretty good Stack Overflow thread on the LSP once

half wolf
#

more on iommi: we actually don't need subclasses to implement any specific field types like say django or wtforms does, because we've made sure the Field type has all the required flexibility. Then you just need to pass the right arguments to make it behave like an integer field, or email field or whatever.

raven ridge
#

although - correct me if I'm wrong - the LSP constrains applications of functions to objects of a specific type, right?
@gleaming rover When it's stated formally, it may be obvious "by definition" as you say. When you learn the principle from a blog, maybe not so much 🙂

half wolf
#

This ensures we have a very general design that can be highly customized

gleaming rover
#

@gleaming rover When it's stated formally, it may be obvious "by definition" as you say. When you learn the principle from a blog, maybe not so much 🙂
@raven ridge yup, that's what I did, actually

#

I don't have a CS background

#

but this stuff is interesting

#

I never thought about constructors until it was mentioned earlier

grave jolt
#

Well, it a class is supposed to be passed around, maybe LSP does apply? Since classes are first-class objects

#

but that would be super weird

half wolf
#

Not very weird. A class is just a function that produces an object :P

#

(in js quite literally 🤮)

boreal umbra
#

Is it though?

gleaming rover
#

Well, it a class is supposed to be passed around, maybe LSP does apply? Since classes are first-class objects
@grave jolt it would apply to the metaclass

half wolf
#

haha only serious type thing

gleaming rover
#

since the constructor is a method of the metaclass

#

wait, do you mean the class constructor or the instance constructor

half wolf
#

a class is a factory producing instances of the class...

grave jolt
#

Well, it a class is supposed to be passed around, maybe LSP does apply? Since classes are first-class objects
but that would be super weird
I meant stuff like this

class foo(k: Type[Foo]):
    return k.from_spam("ham")
half wolf
#

(it's more obviously but...)

grave jolt
#

Well, now we can name classes like AnimalInstanceFactory

#

and metaclasses like InstanceFactoryFactory

deft pagoda
#

metaclasses aren't like factories though, since they're meant to be inherited

grave jolt
#

Well, you can call a metaclass to create a class, right?

deft pagoda
#

you could, but one never sees that

#

I don't think I've ever instantiated a metaclass except for type

#

and that was the 3-arg form

grave jolt
#

does a tree make a sound...

#

alright, I already feel guilty for instantiating an ivory tower discussion 👍

#

I am an IvoryTowerDiscussionFactory then

#

I have an idea for a paradox

deft pagoda
#

I tried to create a metaclass that would allow me to construct properties like this:

x = int(Property)
y = str(Property)

but forgot that int and str error if they don't get the right types back

#

damn you, python

grave jolt
#

how about inт

#

Sophism/paradox:
The only property of type T is that it violates LSP.
Suppose that S is a subtype of T.
a) S violates LSP -- then it has all the same properties as T and therefore doesn't violate LSP;
b) S doesn't violate LSP -- then it violates LSP by not having a property of violating LSP.

deft pagoda
#

the barber shaves himself!

grave jolt
#

yeah, it seems to be the same kind of thing thinkmon

slender solar
#

how do I share my code to others so they can use them like apps

#

i asked it in help channel but no one knew about it

#

they said it is not easy

#

so I came here

boreal umbra
#

@slender solar this is specifically a discussion channel, but I would look into git and github. You can also ask on #tools-and-devops

cloud lion
#

how to debug python module in termux, (i also have to pass arguments) ?

boreal umbra
deft pagoda
#

!e

import sys
print(sys.meta_path)
fallen slateBOT
#

@deft pagoda :white_check_mark: Your eval job has completed with return code 0.

[<class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]
zenith topaz
#

It's a terminal emulator for android. wihout external tools you can always use the build in python debugger.

deft pagoda
#

do you think it will allow me to append my own import hook

sly junco
#

Hey y'all, I have a funky question / discussion topic: what is called when you raise an error? I have implemented a couple custom exception in my source, and what I want is to check the type of __context__ when raise <error> from <other error> is used, and if it is of a certain type, do some extra logic before the exception is actually raised.

#

I've googled and I can't find anything on this

#

It seems I'll have to pass it into the initializer for the custom exception, but I'd really like to leverge the raise ... from ... syntax

deft pagoda
#

!e

class MyImporter:
    @staticmethod
    def find_module(fullname, path):
        print(fullname, path)
import sys
sys.meta_path.append(MyImporter)
import numpy
fallen slateBOT
#

@deft pagoda :white_check_mark: Your eval job has completed with return code 0.

001 | nt None
002 | nt None
003 | nt None
004 | nt None
005 | pickle5 None
006 | org None
007 | backports_abc None
deft pagoda
#

alright, what can we do with this

swift ingot
#

hi everyone, can u help me wit this thing?

#

whats that error?

boreal umbra
#

@cloud lion please take a look at my previous message about that.

unkempt rock
#

Hello, can someone help me with joining a branch on gitlab using the git checkout command?

boreal umbra
unkempt rock
#

Ok thank you 🙂

modern frigate
#

Is everything in python stored on the heap, or are strings and stuff stored on the stack, since they are immutable

peak spoke
#

The best way to look at memory in python is that it all happens automagically. I think in cpython it's all in the heap with the vm working with a stack

paper echo
#

@sly junco you want to be able to create the error as if you had used raise from, without actually raising it? is that right?

#

i think this was discussed here previously but i can't remember what the solution was

#

!e ```python
try:
raise Exception('one')
except Exception as exc1:
exc2 = Exception('two')
exc2.context = exc1

raise exc2

fallen slateBOT
#

@paper echo :x: Your eval job has completed with return code 1.

001 | Traceback (most recent call last):
002 |   File "<string>", line 2, in <module>
003 | Exception: one
004 | 
005 | During handling of the above exception, another exception occurred:
006 | 
007 | Traceback (most recent call last):
008 |   File "<string>", line 7, in <module>
009 | Exception: two
paper echo
#

@sly junco ^ does that do you what you want? just manually assigning to __context__

teal yacht
#

yes every object is on the heap @modern frigate, strings are interned but still on the heap, since the python interpreter itself can't know the size of a string literal before actually running and reading the python file, in addition to that, each object contains a bunch of methods and attributes, given how small the typical stack is, it'd be trivial to crash the interpreter if objects were on it

pseudo cradle
#

Yeah

#

Stack is small

modern frigate
#

Oh that makes sense since there is no compilation 🙂

#

so it doesnt realize the size until runtime

teal yacht
#

i guess with VLAs that would be possible, but that opens the door to even more UBs and crashes

modern frigate
#

Probably not memory safe, though, lol

#

Well....

red solar
#

cpython is written for C89 (with a select few extra features), and VLAs were introduced in C99, so they wouldn’t be used

teal yacht
#

good, VLAs shouldn't be used anyway

paper echo
#

CPython usually pre-allocates memory for containers right

undone hare
#

I don't think so

#

Well, certain containers like dict may have some prebuild slots

#

But in most cases, nope

paper echo
#

I think I saw a blog post showing that it did for lists... but maybe im thinking of R

undone hare
#

If you don't initialize it with some values, it won't pre-allocate some slots iirc

peak spoke
#

lists will resize in jumps when their limit is reached, but afaik it won't guess the length or anything to allocate a larger array for it but goes through the normal machinery

paper echo
#

That's what I was wondering I think

#

Like it's not trying to guess the size based on the data

#

Now that I think of it, I don't even know how lists are implemented in cpython

peak spoke
#

Looks like extend uses the length hint in some cases and there are some bytecode instructions that take a known length

modern frigate
#

Why is string concatenation so slow, and how do f-strings work. I always thought that the .format method and f strings just used string concatenation, haha

radiant fulcrum
#

okay so lets take this class and instance method:

def test_wrap(func):
    print(repr(func))


class Abc:
    def __init__(self):
        pass

    @test_wrap
    def test(self):
        pass```

If we run this code we get 
```py
>>> <function Abc.test at 0x0106BF10>

Makes sense right? Sure, but how can we locate Abc.test by itself? Basically trying to get the parent class of a method if applicable which im not sure how to because inspect (unless im missing something) doesnt have this ability.

#

im suprised there isnt some dunder for getting the parent class tbh

peak spoke
#

I'm not sure there is a way without looking into the frames or something, since it is just an ordinary function and the magic happens on access

paper echo
#

@modern frigate its in the cpython source... somewhere 😛 if you find it (or an explanation of it) im sure others would be interested to see it posted here

#

@radiant fulcrum i tried to do this once, i might have ended up having to parse __name__ or something really ugly

peak spoke
#

For concat it has to do individually for each intermediary result and create a new object for it, while f strings can do it in one pass

radiant fulcrum
#

looking at getting the current frame seems to work actually

modern frigate
#

okay so lets take this class and instance method:

def test_wrap(func):
    print(repr(func))


class Abc:
    def __init__(self):
        pass

    @test_wrap
    def test(self):
        pass```

If we run this code we get 
```py
>>> <function Abc.test at 0x0106BF10>

Makes sense right? Sure, but how can we locate Abc.test by itself? Basically trying to get the parent class of a method if applicable which im not sure how to because inspect (unless im missing something) doesnt have this ability.
@radiant fulcrum do you mean finding the name of the actual name. So getting Abc as a string. If so, you can do Class.__class__.__name__ or Class.__name__

paper echo
#

@modern frigate they want to get the class that Abc.test is "attached" to

modern frigate
#

For concat it has to do individually for each intermediary result and create a new object for it, while f strings can do it in one pass
@peak spoke Ah!

paper echo
#

@radiant fulcrum yeah but that's specific to class definition time. i feel like there should be a more general solution anyway

modern frigate
#

Oh... Yeah, i think parsing .__name__ is how you do it 😦

radiant fulcrum
#

yeah

#

i feel like it would certainly have its uses for stuff

paper echo
#

apparently cpython itself parses the fully qualified name

#

yikes

peak spoke
#

There may be more to it, like f strings being one bytecode instruction, but not having to create to create unnecessary strings saves a lot

paper echo
#
def get_class_that_defined_method(meth):
    if inspect.isfunction(meth):
        return getattr(inspect.getmodule(meth),
                       meth.__qualname__.split('.<locals>', 1)[0].rsplit('.', 1)[0],
                       None)
    return None  # not required since None would have been implicitly returned anyway

yikes yikes yikes

#

does CPython actually do this internally??

#

there isn't even a function in inspect for it

#

i dont hate the fact that it parses the qualname

peak spoke
#

I think that's just their implementation, can't see a reason for why cpython would need this

paper echo
#

what i do hate is that theres no exposed functionality for it, at all

#

@peak spoke i guess that's true, when you instantiate a class, the class knows its own methods and can bind them accordingly

modern frigate
#

dang

paper echo
#

that said, i still prefer this to manually inspecting the stack

modern frigate
#

lol

peak spoke
#

Is the removal of unbound methods documented somewhere cleanly to see its reasoning?

radiant fulcrum
#

okay

#

so it is more awkward todo

outer granite
#

I'm trying SQL(python) on Windows 7 (using Spyder anaconda) installed everything but it says"no connection could me made because target machine actively refused it"

radiant fulcrum
#

because the system gets affected by the imports

#

you essentially have to import the file, reload it then can extract the things from it

paper echo
#

@peak spoke there are links to guido's mailing list messages (i think) in the stackoverflow thread

radiant fulcrum
#
def get_parent_class(func):
    class_name, func_name = func.__qualname__.split(".", maxsplit=1)
    cl = _extract_class(func, class_name)
    return cl


def _extract_class(func, target_name):
    for name, obj in inspect.getmembers(sys.modules[func.__module__]):
        if inspect.isclass(obj):
            if name == target_name:
                return obj```
#

So this system^^ will only be able to grab a class if the class is imported and then reloaded

#

for some reason

pliant tusk
#
def get_parent_class(func):
    for cls in (l:=lambda o=object:sum([l(c)for c in type.__subclasses__(o)],[o]))():
        if func in vars(cls).values():
            return cls``` @radiant fulcrum that will work (the weird bit is incase the parent class could be a subclass of anything other than `object`)
radiant fulcrum
#

that is quite the incredible for loop

signal tide
#

I like how it’s comprehensibly’s pythonic and logical until you only look at the last bit In the loop

magic python
#

i'm wondering which style is considered best:

if condition: 
    return 1
else:
    return 0

or

if condition:
    return 1
return 0
spice pecan
#

The second is really common practice and in general reducing indentation in these ways is considered acceptable if not preferable

boreal umbra
#

@magic python I would do return 1 if condition else 0 if it's something that brief

magic python
#

sure it's not a 1 liner tho

boreal umbra
#

I prefer the second one

spice pecan
#

A similar construct is sometimes (although not as often as the return one) used in loops to reduce indentation, something along the lines of

while condition:  # Also works for "for" loops, obviously
    if other_condition:
        do_thing
        continue
    do_other_thing
boreal umbra
#

My favorite if statements are the ones that don't have an else or any kind of exiting statement

#

that is, those that just handle non-default cases in such a way that the rest of that block can just continue as normal

prisma kelp
#

Admitedly stupid concept but how large is the minimum example for sys.exit() having different practical behaviour whether you imported it or not?

#

I often write sys.exit() as a shorthand for a breakpoint if I'm being lazy without actually importing sys.exit because I didn't notice

sacred tinsel
#

Not sure if I understand, are you asking what's the difference between sys.exit() with having imported sys and without?

#

if the name wasn't imported it will raise NameError

#

which can be handled

#

if you just want to raise an exception, you can do raise Exception

#

it's the same as if you were to suddenly call big_green_goblin() without importing it (the sys.exit() without importing sys)

#

here's a practical example:

>>> try:
...     sys.exit()
... except NameError:
...     print("Nothing happened :)")
... 
Nothing happened :)
>>> 
>>> import sys
>>> 
>>> try:
...     sys.exit()
... except NameError:
...     print("Nothing happened :)")
... 
[kwzrd@kwzrd-thinkpad ryan]$ 
prisma kelp
#

Oh I'm aware! Sorry I'm more making a kind of tongue in cheek comment that sys.exit() seems to do basically the same thing as writing utter nonsense on the line you want the program to quit on

#

and I was curious other than for syntatic sugar if in a large project there was a purpose to write sys.exit() and not nonsense

sacred tinsel
#

I don't think serious projects will use sys.exit() anywhere (apart from producing a non-0 exit code at the very end)

#

it's unpredictable and there's no way to recover from it

#

don't think I've ever seen it in production code

#

as I said, you can just raise Exception("Manual intercept") or something

prisma kelp
#

huh interesting thanks!

sacred tinsel
#

yeah

#

if sys isn't imported into the scope it doesn't matter whether you do sys.exit() or abcd124

#

both will produce the same error that, if unhandled, will cause the program to stop

#

but if the end goal is to raise an exception, it's better to just do it explicitly

#

because then it's obvious what you're doing, otherwise it may look like a bug to others

peak spoke
#

The status code can be important if you have a cli app to get the -1 without stderr output or other codes, but beyond that there's not much use for it

magic python
magic python
#

why can't ipdb / pdb access variables when they're used within list comprehensions?

safe hedge
#

it's unpredictable and there's no way to recover from it
@sacred tinsel Care to expand on this?

sacred tinsel
#

I was wrong, I think it can be recovered from actually

#

what I meant by unpredictable is that when you call some function, you expect it to either return something or raise an exception

#

sys.exit does neither, it raises SystemExit which is not an Exception subclass

#

its more similar to KeyboardInterrupt

#

you can catch it & recover but you just dont expect code to raise it, unless something very critical happens

paper echo
#

@magic python third option

if condition: 
    result = 1
else:
    result = 0
return result
magic python
#

@paper echo yea, hrm - do you think this is cleaner?

paper echo
#

some people believe strongly in having exactly 1 return point from any function (that isnt explicitly a coroutine)

magic python
#

by clean i guess i mean easier to follow, read, and maintain

#

some people believe strongly in having exactly 1 return point from any function
i originally thought this, but couldn't really argue it, so kinda stopped

paper echo
#

iirc some languages actually enforce single returns

#

maybe rust does it, i cant remember

#

personally i advocate for early returns if there is a lot of junk left after the return

#

but at "the end" of a function i prefer the "single point" return i demonstrated

magic python
#

idk how you can have both - it's either one or the other surely?

#

there can't be anything after the return if there's a single return 🤔

south ferry
#

Anyone want free help on homework?

magic python
#

@south ferry read the rules

paper echo
#
def foo(x):
    if invalid_state(x):
        raise ValueError("bad")

    # lots of code

    if no_data_left:
        return None

    # more code

    if some_final_check:
        result = 3
    else:
        result = 4

    return result
south ferry
#

I have read the rules lol

#

Just trying to help

magic python
#

ok just no then , lol, try general, lol

south ferry
#

lol, lol

safe hedge
#

you can catch it & recover but you just dont expect code to raise it, unless something very critical happens
@sacred tinsel That's basically the point of using it though. Use it to actually exit where the user should not be catching an exception because the problem is entirely unrecoverable. And you'd mainly use it in the CLI part of any code

magic python
#

hrm ok salt, that makes sense.... a part of me feels that a function should have a single exit point (? idk if that's a phrase), but I see it done a lot (multiple returns that is), so have just used them now

paper echo
#

@magic python also the "inside" of a list comprehension has its own scope

safe hedge
#

I use the third option style when I have lots more code inside one of the if/else parts

magic python
#

yeah - but why doesn't a debugging session have access to that scope?

paper echo
#

you need to step into or out of the scope

magic python
#

no i mean when you're just messing about with vars, sometimes it's not possible to use them in list / dict comps and stuf

#

like in an interactive ipdb/pdb session

safe hedge
#

This is your fault for using a debugger instead of just scattering around print everywhere lol

magic python
#

😦

safe hedge
#

*I am of course joking

magic python
#

yeah all good 😄

safe hedge
#

What is the use case and purpose of a "__main__.py" file?

cobalt cobalt
#

@XAshwin#4194 you said you could help with homework?

safe hedge
#

Pretty sure that guy got yeeted from the server

cobalt cobalt
#

Why

safe hedge
#

!rule 5

fallen slateBOT
#

5. Do not provide or request help on projects that may break laws, breach terms of services, be considered malicious/inappropriate or be for graded coursework/exams.

sacred yew
#

@safe hedge __main__.py gets called when you run a module like python3 -m module_name

#

assuming __main__.py is within module_name

safe hedge
#

I think you mean package_name

#

__main__.py would be a module

sacred yew
#

oops

safe hedge
#

I was considering using it to provide a top level access to some scripts I wrote that I wanted to bundle as a toolkit, but I just found myself writing:

if __name__ == '__main__':
    parser = get_parser()
    args, rem = parser.parse_known_args()
    sys.argv = sys.argv[:1]+rem
    TOOLS[args.tool]()

And the sys.argv manipulation made me think this is a terrible idea

sacred yew
#

isn't that just sys.argv[0]

#

but you can't you just pass args and rem to the tool?

safe hedge
#

Well basically I just imported the scripts and made:

TOOLS = {
    'tool1': tool1.main
}
#

The idea was that this wouldn't require any changes to the existing tool scripts

#

Which themselves contain argparsers which do parser.parse_args , which by default reads sys.argv

#

I'm pretty sure there must be a better way to achieve what I want

grave jolt
#

@rustic portal This is a discussion channel, not a help channel (see the channel description). See #❓|how-to-get-help

rustic portal
#

my bad

boreal umbra
#

__main__.py would be a module
@safe hedge isn't the package the top-level module, but each directory is a module and each file in it is also a module (and it's recursive?)

safe hedge
#

I don’t know how interchangeable the terminology is tbh

boreal umbra
#

because if you import a module by the name of a directory, you get a namespace for what's in the init file, and I don't think any distinction is made between that and the namespace you get for importing .py files by their names.

safe hedge
#

I was under the impression it was package —> (subpackage) —> module

#

And that __init__.py was kind of a special case

bronze anchor
#

are there any disadvantages for creating a queue for each thread? Or am I creating a lot of unneeded overhead?

eternal plover
#

anyone know how to make python output priority in Blender headless?

#

I'm trying to read the output from a Python script in Blender headless, but all the messages end up being shoved to the bottom

boreal umbra
#

I can't remember who it was (pretty sure it was another staff member) who mentioned ... from x as an alternative to lambdas

#

so lambda x: x ** 2 would be x ** 2 from x

#

was it you godlygeek?

raven ridge
#

Wasn't me

boreal umbra
#

you should have claimed credit

raven ridge
#

And I don't like it 😄

boreal umbra
#

why

raven ridge
#

Difficult to parse, both for a computer and a human. And difficult to nest. And... Weird

boreal umbra
#

I don't really think they should do it because it just locks down the language spec even more

#

but I would have preferred it to lambda if they could start over

#

I dunno about difficulty to parse; Guido was pretty confident that we could get rid of parens for function calls with the new parser if we wanted

raven ridge
#

that's relatively easy to parse, by comparison. 2 names in a row.

#

as opposed to indefinite lookahead for a from statement that may or may not come, and having the entire parse up until it arrives be speculative

safe hedge
#

So a package is a module

boreal umbra
#

yes

safe hedge
#

I think that's confusing nomenclature.

half wolf
#

It is what is is.

boreal umbra
#

a package is the whole thing. modules are recursive

#

a module can have other modules

raven ridge
#

modules are things that can be imported. A package is a thing that can be imported, so it's a module. It's a special type of module, in that it's allowed to have modules below it (including other packages)

safe hedge
#

But technically I can import a class right?

boreal umbra
#

well, not all modules that have modules below it are packages

half wolf
#

And people will use those words incorrectly so that definition, while true, isn't going to be something you can trust when reading.

boreal umbra
#

I think a module is only a package if it's top level

raven ridge
#

you can import a class from a module, but you can't give a class to an import statement directly.

half wolf
#

Like arguments vs parameters. Very few people use the terms correctly.

safe hedge
#

Also namespace packages are definitely not modules imo

boreal umbra
#

what do you mean?

raven ridge
#

they are, because they're importable things, and every thing that's importable is a module, by definition.

safe hedge
#

I mean they are under these rules, but they are fundamentally quite different

boreal umbra
#

this isn't really a case where you can decide what does or doesn't belong to a certain category

#

modules have a specific definition in Python

raven ridge
safe hedge
#

Yes I know. And what I'm saying is I think that's confusing

boreal umbra
raven ridge
#

os.path is a package, and not top-level

boreal umbra
#

interesting

safe hedge
#

Like, referring to a namespace package - which doesn't have a physical representation - as a module as if it is the same as a module in a package is inherently confusing imo

boreal umbra
#

is there a specific term for when it's top level?

half wolf
#

Python is like physics: it mostly looks nice and simple until you look closely and it's complex and weird :)

raven ridge
#

@safe hedge - you're proposing dividing the terminology into (a single file that can be imported) versus (an importable thing that can contain other importable things), but in order to do that you'd need to introduce an entirely new term for any importable thing, or constantly say "module or package"

safe hedge
#

just call it an importable

grave jolt
#

x ** 2 from x
*screaming noises*

#

I have an improvement

boreal umbra
#

I wouldn't mind them being called importables if we had it to do over but I'm not sure that there are any miscommunications happening because packages are a subset of modules.

grave jolt
#
squared_numbers = map(SELECT x**2 FROM x, numbers)
boreal umbra
#

I think losing the distinction between arguments and parameters causes miscommunications though.

raven ridge
#

"arguments" being the things that are passed to a function, and "parameters" being what a function is defined to be able to accept?

half wolf
boreal umbra
#

@raven ridge basically. I think of parameters as slots and arguments as things that go in them

safe hedge
#

I wouldn't mind them being called importables if we had it to do over but I'm not sure that there are any miscommunications happening because packages are a subset of modules.
@boreal umbra maybe not. Doesn't mean you couldn't change it imo

boreal umbra
#

sometimes it doesn't matter which one you're talking about

#

because there's enough context to establish it

half wolf
#

The standard library docs plays fast and loose with arguments vs parameters :/

raven ridge
#

changing terminology in a language that millions of people know is not a great idea. How often have you found it difficult to express something because of a package being a type of module?

half wolf
#

But mostly context does handle it yes.

grave jolt
#

@half wolf elixir.replace("ruby", "python")? 🙂

boreal umbra
#

@raven ridge well, you can't change terminology in a language used by millions of people

#

they're already using it

raven ridge
#

you can change the "official" terminology, but yeah.

half wolf
#

@grave jolt I constantly miss multi line anonymous functions though.

#

(And some other features in mochi)

safe hedge
#

changing terminology in a language that millions of people know is not a great idea. How often have you found it difficult to express something because of a package being a type of module?
@raven ridge Anytime I try to google packaging

#

Python packaging is a sodding nightmare

#

Everytime I think I've solved it I find someone else doing or suggesting something different

half wolf
#

The problems with python packaging have nothing to do with the nomenclature imo.

raven ridge
#

it is - but not because of the fact that an importable package is a type of importable module.

boreal umbra
#

right. this is sort of a separate soap box, but organizations like Académie Française are meaningless. A bunch of people sitting in a room deciding what is or isn't correct language use doesn't actually mean anything.

raven ridge
#

the fact that "package" the importable thing and "package" the library of code you download from pypi share a name is unfortunate.

half wolf
#

And it's improving now that we're moving forward in time and aren't stuck with 2.7

raven ridge
#

some of us aren't, heh

safe hedge
#

right. this is sort of a separate soap box, but organizations like Académie Française are meaningless. A bunch of people sitting in a room deciding what is or isn't correct language use doesn't actually mean anything.
@boreal umbra Except that it gives a point of truth if you want that

raven ridge
#

that is, a pypi package can contain a module that is not a package. that's weird.

cloud crypt
#

package is a weird word

#

especially in terms of PyPI

half wolf
#

Well that name is older and bigger than python so it is bedrock imo

raven ridge
#

yeah. but I personally have had much more trouble expressing myself in a conversation because of the ambiguity between "pypi package" and "importable package" than I ever have because of the ambiguity between "module" and "non-package module"

safe hedge
#

I see library used a lot

#

To effectively mean top-level package

raven ridge
#

"the name of a package doesn't always match the name of the package it provides" is a terrible sentence to have to explain to people. 😦

safe hedge
#

Looking at you beautifulsoup

hallow ivy
#

I've been programming with python for the past 3 years and the next step for me is to try to learn how to structure very large projects. Can anyone give me any suggestions or resources? I have published a few small python packages that I use personally but nothing big.

paper echo
#

I hate hate hate the python use of the term "package"

#

Arguably the worst design flaw of Python

#

It's just a damn module that also can have submodules

#

@hallow ivy maybe look at some existing large python projects

#

There are a handful of different styles and patterns people use

boreal umbra
#

I hate hate hate the python use of the term "package"
@paper echo I figure the reason might be that a top-level module isn't guaranteed to be "top-level" in any meaningful way. You can have a directory of python code that isn't installable

#

But then again I guess "package" is always thought of as something that is installable

paper echo
#

im not sure what you mean by that

#

a package (in python) is a special kind of module that contains other modules, and happens to correspond to a different arrangement of source files

#

as far as im concerned, with a.py and b/__init__.py, a and b should both just be called modules; maybe "single-file modules" and "directory modules" for when you need to distinguish

#

i understand that the naming is probably an historical accident or just a short-sighted decision or both. but its really unfortunate

boreal umbra
#

If I made a directory of python code that's structured like a stand alone thing but don't make a way to install it, you'd have to jump through some hoops to import it, but in that case there wouldn't be anything forcing you to think of it as one unit.

#

But the definition of module that you describe is the one I usually think of

paper echo
#

i guess i dont see how that supports calling a "directory module" a "package"

boreal umbra
#

I sort of forgot my point but I think it might have been that "modules having other modules" is a feature of the language whereas "packages" are a language feature to a lesser extent

paper echo
#

i think what happened is that the idea of a named distribution -- the thing you install from pypi -- didnt exist at one point

#

you just downloaded a package and either dropped it in the right place or used easy_install

#

so a "package" was the same thing as a software package

safe hedge
#

You don't actually need an __init__.py anymore though do you

paper echo
#

whereas with setuptools and pip/pypi you can have situations like beautiful soup, where the name of the "distribution" is not the same as the name of the primary/top-level package

#

yes you do, without __init__.py it's an "implicit namespace package" which is not the same thing

#

rather, technically you dont need it, but you should use it because you dont want to confuse the living hell out of people

safe hedge
#

But the point that someone made earlier was saying that was still a module

#

Since anything that is importable is a module

paper echo
#

yes

safe hedge
#

Which again I think is confusing as hell

paper echo
#

what do you mean

#

a "package" in python terminology is a module that happens to contain other modules

safe hedge
#

as in an implicit namespace package is in fact still a module

paper echo
#

an implicit namespace package is just a module that happens to contain other modules and is defined implicitly and for the sole purpose of being a namespace

#

the main use is to be able to distribute foo.a and foo.b in two separate distributions/libraries

#

e.g. we did this at work, where pretty much all of our internal tools were namespaced like big_corp.text_utils and big_corp.hierarchical_logistic_regression but those were two totally unrelated projects maintained and developed independently

safe hedge
#

I get the purpose

#

But allowing that namespace to be called a module is imo confusing

paper echo
#

but from the perspective of python it is a module

#

it's just another way to define a module

#

so we have three ways:

  1. single file foo.py
  2. directory foo/__init__.py
  3. implicit namespace
safe hedge
#

Right. And the fact that I can call any of those a module without any qualification and be correct is somewhat confusing imo

boreal umbra
#

But you don't always need to know

paper echo
#

thats fair

#

but i agree with what stelercus said, the point is that you arent supposed to be able to tell the difference from inside a python program

#

that's by design, they're all just "modules" and they all behave the same

safe hedge
#

You can also split 2) into 2 subsets

#

Because you can have a namespace package created with an __init__.py but it can only have very specific content in that file

paper echo
#

i dont even consider those relevant anymore 😛

#

but i'd call that 4)

#

explicit namespace

#

(and there are several ways to do it iirc)

#

(and all of them involve ugly hacks)

#

i know zope does it that way, because their project i think predates implicit namespaces

boreal umbra
#

In my experience I've never needed to distinguish between the different types of modules. Just knowing that I can import it and get stuff is enough

#

But I don't think it's difficult to distinguish when need be

safe hedge
#

I don't think it's a problem when using them tbh

boreal umbra
#

Are people often assuming that something is a specific type of module?

safe hedge
#

"I want to write a module"

paper echo
#

you know where things get weird?

src/
  foo/
    __init__.py
    a/
      __init__.py
    a.py
safe hedge
#

What does that statement mean?

paper echo
#

it means "i want to write python code that is importable from a python program"

#

you start as a .py file, and refactor to a directory as needed

safe hedge
#

Come on you know that's being a bit simplistic.

paper echo
#

is it? thats exactly how i would approach it in a help session

boreal umbra
#

You're right that it could, in theory, be a redundant way of saying that they want to write python in general

safe hedge
#

There is a fairly big difference between writing a single importable .py and have a well structured "package" with many modules and optional installs

paper echo
#

sure, thats why you need to clarify what someone is asking for

boreal umbra
#

But I don't think anyone would say they want to "write a module" if they weren't interested in the reusability

safe hedge
#

"I have a problem with my python module"

gleaming rover
#

I thought strictly speaking "module" means ".py file"

boreal umbra
#

@gleaming rover yes

gleaming rover
#

(which is pretty weird IMO but whatevz)

paper echo
#

well a package is also a module

boreal umbra
#

Though it can also be groups of files

paper echo
#

its more like ".py file means module"

#

the other way around

#

@safe hedge i guess? but i think if you are at the point where you're having problem "with my module" you clearly are not writing a big program

safe hedge
#

Erm dunno

paper echo
#

otherwise you'd say "i have a problem with my program" / "i have a problem with my library" / etc

#

practically what i often see in this server (and elsewhere) is "all my code is just a mess of .py files how do i clean all this up for reusability"

safe hedge
#

A "library" isn't even a term is it?

gleaming rover
#

"all my code is just a mess in one .py file" 🥴

paper echo
#

not a technical term in python no

gleaming rover
#

A "library" isn't even a term is it?
@safe hedge not in Python

paper echo
#

yes lol gm

boreal umbra
#

"I have a problem with my python module"
@safe hedge this wouldn't be enough information to know the scope of the problem regardless

safe hedge
#

My biggest trouble in python is proper packaging tbh

paper echo
#

anyway im not terribly concerned about what kind of source files someone means when they are talking about a "module" because a module is a python concept and not a files-on-disk concept

#

its a mess honestly

#

python has really bad package management tools

safe hedge
#

It's a "files on disk" concept when you are trying to properly package your code no?

paper echo
#

and the mess of misleading terminology that we have been discussing makes it hard to even talk about, not to mention teach

safe hedge
#

I never know how much I should put in my __init__ files for example

paper echo
#

sure, but that is a more specific question anyway. i would hate to choose terminology solely on the basis of being easier to succinctly ask questions about it in discord

#

(where most people need to give more info anyway)

gleaming rover
#

hm

#

what do you all put in __init__?

safe hedge
#

And I still think I'm doing something wrong when I end up with being able to do mypkg.mysubpkg.mymodule.os.path.join

paper echo
#

i think thats up to you. a lot of projects tend to leave __init__ relatively empty. i see it used mostly for bookkeeping tasks

#

hah, boxed hates that about python

gleaming rover
#

I generally put nothing in except __all__ and imports

paper echo
#

same

gleaming rover
#

unless I have some code that needs to be run on first import, then that's in the parent __init__

#

but otherwise no function definitions etc.

paper echo
#

^

gleaming rover
#

hah, boxed hates that about python
@paper echo so do I

#

it screws with autoimport

safe hedge
#

Do you mean the import thing I put?

paper echo
#

yeah

gleaming rover
#

from mypackage.mymodule.mysubmodule import os

#

😡

safe hedge
#

It's especially annoying when you have multiple modules with the same stdlib deps

#

Or modules with lots of imports

paper echo
#

can you override __dir__ at the module level

#

ah yes you can

safe hedge
#

I thought I once found I couldn't import a module if I didn't import it in the init but then that turned out to not be true

paper echo
#
import os

a = 1
foo = 2

def __dir__():
    return [
        'a',
        'foo',
    ]

the docs suggest that this would fix it

safe hedge
#

Then I go and look at big projects that seem to solve these problems and they have massive __init__.py and loads of convoluted stuff going on

raven ridge
#

There is a fairly big difference between writing a single importable .py and have a well structured "package" with many modules and optional installs
@safe hedge true, but you can start with one and refactor into the other later, transparently for your users.

paper echo
#

@safe hedge there are some strange and ill-behaved projects that do all kinds of weird shit

#

a lot of it i think is legacy hacks left in place for backward compat and to prevent needless refactoring

raven ridge
#

I generally have a lot of stuff in my __init__.py files. It seems to annoy some of my co-workers, though. 🤷‍♂️

paper echo
#

personally i find it an unintuitive place to keep code

raven ridge
#

Making it contain only imports just adds an unnecessary layer of indirection. It doesn't make the project smaller, or more maintainable, or more navigable, or more discoverable...

paper echo
#

e.g. i also usually have cli.py and in __main__.py i do from myproject.cli import run_cli; run_cli()

safe hedge
#

So this is one of the things I've been wrangling with

raven ridge
#

a/__init__.py defines the namespace a. I find it unintuitive to keep the code for a anywhere else!

paper echo
#

i guess i just think of __init__.py as a place for "organizational" work. but i wouldnt really be annoyed if someone put a bunch of logic in there

gleaming rover
#

^

#

like right now I'm working on a Django project

#

I have like models packages, views packages, etc.

safe hedge
#

I want to have a bunch of modules that are basically standalone scripts but also provide the ability to install them as a package with an overarching cli

paper echo
#

(it also depends on what exactly a does)

safe hedge
#

And I have no idea how to structure it

gleaming rover
#

I have too many models/views to keep in one file, but by definition there aren't models/views that belong in __init__.py

safe hedge
#

I sometimes define things like a simple Client class in an __init__.py, where it is composed of other classes from separate modules

raven ridge
#

@safe hedge if they're really independent, you could do something like git does. Its approach to discovering commands makes it pluggable.

paper echo
#

i was going to suggest a plug-in system. but that's even more complexity

#

to get started you can just do this

src/
  welshwizard/
    __init__.py
    __main__.py
    cli.py
    plugin_helpers.py
    plugins/
      __init__.py
      a.py
      b.py
      c.py
safe hedge
#

They're basically like:

-package
 -grp1
  -tool1
  -tool2
  -shared_code
 -grp2
   -tool1
raven ridge
#

git foo searches $PATH for git-foo and runs it.

safe hedge
#

Where the tool scripts are currently just run directly and have their own argparsers and main()

paper echo
#

but you want to combine them into a single cli?

#

i think you can nest argparsers

#

i dont remember how to do it but im pretty sure theres a way to do it

safe hedge
#

Ideally I wanted to allow them to be run standalone if you really want

paper echo
#

in order to use one argparser as a "subcommand" parser for another argparser

safe hedge
#

But to provide an installable cli wrapper effectively

#

I think I could maybe use click but I really dislike adding non-stdlib deps

#

I'm intrigued by @raven ridge suggestion

paper echo
#

yeah it definitely sounds like you want some kind of plugin interface

safe hedge
#

That sounds sort of ideal. I wanted it so you could just drop in new scripts and have to change as little code as possible

paper echo
#

click is great, a lot easier to use (imo) than argparse

safe hedge
#

It's based on a deprecated lib though lol

paper echo
#

click is based on a deprecated library?

safe hedge
#

Yeah it's based on optparse:

Deprecated since version 3.2: The optparse module is deprecated and will not be developed further; development will continue with the argparse module.

#

So looking at their codebase they actually have removed that dep lol

paper echo
#

pretty sure click is just modeled after optparse

#

i seriously doubt it actually uses optparse internally

safe hedge
#

But they still claim in their "why not argparse" section that it was internally using optparse

#

They copy-pasted optparse apparently lol

#

So it wasn't actually a dep I guess

paper echo
#

i think they mean that it was inspired by optparse

#

yeah

#

thats bad wording on their part

safe hedge
#

Either way I'm against adding deps wherever possible

paper echo
#

why? security?

safe hedge
#

Different dev cycles mainly

#

If I only use stdlib I can upgrade much quicker.

#

Pipenv is a great example of something being more hassle than it was worth and effectively going from the recommended solution to practically non-existent within a couple of cycles

paper echo
#

what do you mean upgrade?

safe hedge
#

Like move from 3.7 to 3.8 etc

paper echo
#

ah, yeah

#

i will offer that a lot of python devs i know have totally soured on pipenv, and either recommend sticking with setuptools or using poetry

safe hedge
#

Yeah I used it once, hated it, then watched as the entire thing fell out of favour

trail stratus
undone hare
gleaming rover
#

what was 1 to 2 like?

gloomy rain
#

From what I gathered from Reddit, "relatively smooth".

#

2 was much more backwards compatible than 3.

cloud crypt
#

question about typing, is it ok to write something like this:

class Iter(ABC):
    @overload
    def __init__(self, iterable: Iterable[T]) -> None:
        ...

    @overload
    def __init__(self, function: Callable[[], T], sentinel: T) -> None:
        ...

    @no_type_check
    def __init__(
        self, object: Union[Iterable[T], Callable[[], T]], sentinel: Optional[T] = None
    ) -> None:
        raise NotImplementedError``` or is there other way function overloading should be written?
gloomy rain
#

Where does that overload decorator come from?

runic musk
#

I think its the one from typing

#

Is it different than singledispatch?

deft pagoda
#

it's different in that it's only for type-checkers

#

it doesn't actually dispatch, only one implementation of __init__ will exist

gloomy rain
#

Ah, right

narrow pasture
#

I can’t think of any reason someone would need 2 init in one class tho

runic musk
#

does it evaluate all of the types?

gloomy rain
#

@narrow pasture To construct an object in two different ways?

#

Like, manually supplying parameters vs extracting them from an object vs loading them from a file vs retrieving them over a network, etc.

narrow pasture
#

Hm yea maybe

#

I’ve never had a problem/code where I used two init tho

gloomy rain
#

I normally do it with factory class methods.

#
class Foo:
  @classmethod
  def from_json(cls, some_json_str):
    return cls(**json.loads(some_json_str))

  def __init__(self, bar, baz):
    # some initialization code
#

or something like that

narrow pasture
#

Hm okay that makes sense

runic musk
#

Qt does this a lot. For example a QRect can be created with 2 points, 1 point, and 1 QSize, or 4 ints for x,y,w,h

grave jolt
#

I suppose Qt does that instead of using class methods because multiple constructors are supported in C++?

runic musk
#

I'd say thats a good assumption

deft pagoda
grave jolt
#

make it a descriptor?

#

maybe it could be fixed by simply making it a function?

deft pagoda
#

you could do it to the class

#

just needs a __get__

#

i think

#

or you could just make a function too

#

which ever

deft pagoda
#

... changed to a function

young heath
#

Are you all probin python

#

??

#

Pro

#

On

#

Python

gloomy rain
#

The users on this server have a variety of backgrounds. Some are new, some are experienced. Some are hobbyists, some are professionals.

half wolf
#

I'm a pro.. 9 years full time.

paper echo
#

@deft pagoda there is already a multiple dispatch library on pypi, not sure if your version is better

#

@cloud crypt what you wrote is okay. as long as the final __init__ signature "contains" all the other ones

deft pagoda
#

probably not, but it's mostly academic

paper echo
#

fair 😄

#

if nothing else it might be interesting to see how they do it

#

i suspect their version is a naive if/else-checking wrapper

deft pagoda
#

most of the stuff in my Snippets is pretty academic

#

well, maybe that's not true, it's like half-useful/half-academic

cloud crypt
#

I am writing windows 10 notifications using pure ctypes and winapi rn

#

* internal screaming *

deft pagoda
#

could be useful

cloud crypt
#

it crashes with no error

#

nice

cloud crypt
#

okay fixed

grave jolt
#

well, if it segfaults, windows displays a failure message, right?

#

So in some sense you still display a notification 🙂

cloud crypt
#

no it does not

#

heh

#

the process was just dying

grave jolt
#

that's because of unregistered sublime text

cloud crypt
#

lol

magic python
#

is there a simple way to extract the arguments to a function as a list?

So if i have

def f(x,y):
   return x**y

i would like some h such that h(f) would return ['x', 'y']

#

i thought perhaps there was some dunder for this but I can't seem to find anything

radiant fulcrum
#

using inspect

magic python
#

inspect.getsource then regex extract?

radiant fulcrum
#

no

low lagoon
#

Would locals() work?

radiant fulcrum
#

signiture or getfullargspec

low lagoon
#

I remember locals being needed for something similar to this

magic python
#

@low lagoon no i don't think so - i want to extract from a module

low lagoon
#

ah

#

nevermind then

magic python
#

@radiant fulcrum ace thanks 🙂 I was parsing the inspect.getsource and extracting with regex when i thought there must be a better way 😅

radiant fulcrum
grave jolt
#

There's also f.__code__.co_varnames 🙂

#

If you want more obscurity

magic python
#

@grave jolt how'd you bump into that one 🤔

#

it's exactly what i want though yeah, just dunno how i'd have found it

peak spoke
#

the inspect docs should have it somewhere

magic python
#

interesting - i've only ever used get source, are there any methods from inspect that people often use? Or is it just a nice to have when something like the above turns up

grave jolt
#

!e

def f(x, y=2):
    print(x, y)

f.__defaults__ = (7, 8)
f()
fallen slateBOT
#

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

7 8
magic python
#

also interesting

#

i have no idea when i'd use that tho

#

is this kinda stuff more when going over pre-existing code bases or something, because i can't think of an example... maybe if i didn't have access to the original function, hrm

grave jolt
#

!e

from collections import namedtuple
Undefined = namedtuple("Undefined",())

def f(x, y):
    print(x, y)

f.__defaults__ = (Undefined(),)*1000
f()
fallen slateBOT
#

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

Undefined() Undefined()
magic python
#

is this an example of a usecase, or just another example

grave jolt
#

just a curious example

#

lmao, look what I found

#

!e

from collections import namedtuple
Undefined = namedtuple("Undefined",())

def f(x, y):
    print(x, y)

f.__defaults__ = (Undefined(),)*1000
f()
f(1)
f(1, 2)
f(1, 2, 3)
fallen slateBOT
#

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

001 | Undefined() Undefined()
002 | 1 Undefined()
003 | 1 2
004 | Traceback (most recent call last):
005 |   File "<string>", line 11, in <module>
006 | TypeError: f() takes from -998 to 2 positional arguments but 3 were given
spice pecan
#

oh wow

magic python
#

i guess i'm unsure if people are out there making regular use of these things, or if it's just a handy thing when required

spice pecan
#

definitely not regular use

grave jolt
#

Well, inspecting is useful if you want to do something with function annotations

#

Like in discord.py

magic python
#

oh, are they like -> str and stuff?

peak spoke
#

handling bytecode, frames etc. is very rarely done in normal code and should mostly be avoided unless necessary

magic python
#

what's a frame?

grave jolt
#

welcome to the world of esoteric fun...

magic python
#

thanks! yeah all this stuff is pretty foreign to me

narrow swift
#

hi, guys.
I need help with django admin, someone has experience ?
wanted to know how can I remove Unique in the email field no django admin
To register duplicate emails

deft pagoda
#

this isn't a help channel

magic python
#

https://github.com/jmcnamara/XlsxWriter/blob/master/xlsxwriter/worksheet.py#L115

this seems to be a bit of an odd approach to checking whether the first argument is an integer,

            if len(args):
                int(args[0])

there's the code, is there something that I'm missing? I guess it works, I'd have thought something like

if not isinstance(args[0], int):
    <do stuff>
gleaming rover
#

@magic python empty args

#

also probably not appropriate for advanced discussion...?

magic python
#

@gleaming rover it's appropriate

gleaming rover
#

if you say so

#

welcome to the world of esoteric fun...
@grave jolt actually, it could work for arbitrary mappings...

#

...and namedtuple (but that would use getattr)

feral cedar
#

you're checking if there are any elements first, otherwise getting the first might throw an error

magic python
#

i was referring more to the use of int( <val> ) instead of using isinstance, I'm not sure if this is something that's usually recommended (using the latter), no worries

sacred tinsel
#

their approach will work for strings too

#

or floats

#

but I'd argue the if should be outside the try-except block

#

"if theres an arg, try to parse it"

peak spoke
#

I don't entirely like it, but that is the shortest and probably cleanest solution for it since you can't check with an abc

raven ridge
#

(necro, but:) isinstance checks if something is an instance of int or one of its subclasses. int(x) checks if it is an instance of int or one of its subclasses, or any type that implements __int__ or __index__ or __trunc__. So it'll also work for things like numpy.int8, for instance. Depending on what problem you're trying to solve, it may be more or less appropriate than the isinstance check.

#

in other words, isinstance checks if something is an int, but int(x) checks if something is convertible to an int.

boreal umbra
#

@raven ridge is it accurate to say that int(x) "checks" something?

#

I suppose int(x) would raise an exception if x can't be cast to an int

#

but I didn't think it was for validation

raven ridge
#

it's accurate to say that it checks something, yeah. That's not all it does, but it definitely does.

frozen finch
#

What does pure CS research look like?

#

and of course how could python be applicable here

feral cedar
#

that's..not on topic for this channel

#

or anywhere

brave badger
#

I suggest you keep this channel on topic.

#

!tempmute 707306502058147901 5d Right, since you don't seem to understand the purpose of this channel, I suggest you take a break with your obviously low-effort trolling while you reread our rules and code of conduct.

fallen slateBOT
#

:incoming_envelope: :ok_hand: applied mute to @unkempt rock until 2020-09-23 04:18 (4 days and 23 hours).

boreal umbra
#

@frozen finch I research natural language processing (I don't purport to be an expert, but I'm paid by a university to do it, so I'm not "some guy") and I do all of it in python. A lot of python libraries exist for nlp, so when I go to design something novel, I'm only actually designing the novel part.

#

The only research professors I talk to other than my advisors are doing work that's tangentially related. I don't really know what new advances are happening in CS.