#internals-and-peps
1 messages · Page 72 of 1
I could rant all day about 484
anyone have good resources for learning how to handle data streaming?
Can u change the type of a class?
i mean like type(my_class) shud return <class 'str'>
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))
@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'>
Can i have it <class 'MyMeta'> instead of <class '__main__.MyMeta'>
Can i have it <class 'MyMeta'> instead of <class '__main__.MyMeta'>
@unkempt rock why do you want that?
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
@unkempt rock like I said, why do you want that?
in Python, (almost) all things are possible, but not all things are desirable.
Oh
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
Thanks a lot @deft pagoda
You know what dunder we're missing?
__rcontains__
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?
what would be an item that knows better than a data structure whether it is contained?
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__
that seems not better than AllOf(items, container)
Why can't you just do all(item in container for item in items) instead of having an AllOf?
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
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.
@half wolf a in b is approx. b.__contains__(a), this would make a in b a.__rcontains__(b)
Bypassing captchas is against rule 5 @unkempt rock
ugh
i know im dumb
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 ?
You need to put it in a file
anyone ever used this instead of dataclasses: https://github.com/dabeaz/cluegen
Seems like he should propose those changes to dataclasses.
Othe.rs migh.t help.fully sugg.est usag.e of the attr.s libr.ary.
Well played

@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 😛
The optional issue with dataclasses irritates me
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?
This:
I cluegen'd some classes for my logic parser https://github.com/salt-die/truth_tables/blob/master/truth_tables/expr_base.py and gutted the dataclasses
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
!e ```py
from dataclasses import dataclass
@dataclass
class Node:
type: int = 1
@dataclass
class LeafNode(Node):
contents: str
@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
ah yuck
beazley isn't some random though
I have a perhaps unwise urge to monkeypatch _init_fn to fix that issue
i dont have anything against cluegen, i just want to see a more fair comparison with attrs instead of with dataclasses
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
need a metaattrs to reduce attrs boilerplate
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
personally i like the explicitness
Ah
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
I hold the opposite opinion, but I understand
yeah its good that there is something for everyone 🙂
And that is certainly true
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
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
beazley had a talk where he used import hooks to import xml into python classes
Do you have a link? That sounds really interesting
i might be able to find it
https://www.youtube.com/watch?v=sPiWg5jSoZI this one xml starts at around 2 hours
ty!
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
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)
# ...
Same with metaclasses, descriptors, getattr/setattr etc etc
I know you can use "Vector3[Scalar]" as the type, but it looks weird
if they had structural typing it could just be numeric and iterable
(just to clarify: I didn't mean <#internals-and-peps message> seriously 😛 )
<
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)
( That may not be quite right but the parts are right )
You could emulate it with a TypeVar I suppose but ugh
I could swear that you could use Self
@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
nope
and since it'd require special support, probably not anywhere
how can i change color of print?
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
That’s a bit less precise for subclasses, but I don’t see how that can actually affect you
@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)```
oh nice
rip
ah, first difference between mypy and other type checkers i see
yeah it'll work, you'll have to do Self[Scalar] tho
nice
I wish f# or other functional language had libraries for symbolic math
so I wouldn't need to use python 
i tell myself that every single day
just make a sympy interop 🙂
TypeError: 'Mul' object is not subscriptable intensifies
might as well use SymEngine directly
also sympy straight gave up with type hints from what I could read on their github
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
I think there's a shim for haskell
official repo even
does it have support for integral transforms?
It's basically empty lol, it's a bunch of c ffi definitions and nothing else
even the readme is not finished
does it have support for integral transforms?
@frank siren tbh sympy only has algorithms for the most simplest forms
lmao it literally replaced the binding with any
is that pyright?
ye
hm
it's more of an autocomplete aid than a strict type checker
if that's a bug, you could submit it to github or ask in gitter
I don't think it's expected to know how to resolve many of those types
It's quite loose compared to mypy
it does work if you use string literals
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
In my experience, pyright has better type inference than mypy, though
same here, it handles some loose cases better, but mypy complains when it cannot deduce stuff
is there an example of something pyright can handle that mypy cant?
and what is a recursive alias?
Path = Union[str, List["Path"]]
-> Path = str | List[str | List[str | List[str | ...]]]
ahh
@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.
What do you mean @boreal umbra ?
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.
it mostly replaces the __dict__ object somewhere
it's cool to use defaultdict-likes and ChainMaps
i see. i presume it's what's passed to the type's __new__ method?
yeah, it gets reconverted back to a mapping somewhere
e.g. the return value from MyClass.__prepare__ gets passed to type(MyClass).__new__?
mappyingproxy*
yeah, it's what's passed to new
i used ChainMap here: https://github.com/salt-die/Snippets/blob/master/switch.py so that I had access to the case decorator in a class body, though it exists no where in the class __dict__
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)) )
@paper echo :white_check_mark: Your eval job has completed with return code 0.
{'music': 'bach', 'art': 'van gogh', 'opera': 'carmen'}
ChainMaps really neat for passing around default arguments with kwargs
oh, that's mentioned in the docs
How does Python remove unneeded space? Does is deallocate it once the variable goes out of scope?
via a garbage collector or smth
The garbage collector picks up objects that have no references pointing to them
ah ok
it makes the language more simple, fs, but slower. imo, rusts ownership system is big brain, but confusing af to learn
@deft pagoda wait this is kind of ingenious. using __prepare__ to create a whole namespace... could use this for custom DSLs
@modern frigate note that different python implementations use different techniques for this. for cpython (the standard implementation) see here https://devguide.python.org/garbage_collector/
This is not a help channel. See #❓|how-to-get-help
Ok! Thanks @paper echo
anyone use eks and python?
I'm failing to see the use cases of __prepare__
Only for types with Py_TPFLAGS_HAVE_GC
is that a default flag?
No - it's your responsibility to set it if your extension class is able to participate in a reference cycle.
see https://docs.python.org/3/c-api/gcsupport.html#supporting-cycle-detection - if your extension class can ever store a reference to a Python object that itself can store references to other Python objects, you're responsible for setting that flag and implementing the extra methods it requires.
oh well at least now ik to never do that
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]
>>>
In this case, it just removes the name b
Oh
what do you mean by "how"?
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?
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.
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.
in the case of the code pasted above,
b[0] = 0isn't really changingb, it's changing thelistthatbrefers to, which is the same list asarefers to. Later on when you printayou see those changes, becauseais another name for thelistthat was changed.
thanks a lot 🙂
and del b makes it so that b no longer refers to that list, but a still does.
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)
yes.
Ok thanks i get it now
why do we use child class?
@trail stratus try a beginner help channel. This is "advanced discussion".
@trail stratus it enable code reuse of parent classes and adding more features in the child class.
i see thx
@half wolf can you point me to the beginner's channel?
This channel is for talks regarding Python itself, not help with plotly @unkempt rock
ah, I thought it was more advanced stuff within python like obscure libraries
My bad
@unkempt rock try your luck in the #data-science-and-ml channel. Plotly is iften used by data scientist.
Discord really needs a way to move messages to the right place. It's frustrating that this channel is just 90% off topic.
@half wolf That belongs in #community-meta 😛
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.
well, there are a few aspects of inheritance, but the method resolution order is one of them.
are you familiar with methods?
idk what dunder is just learnign classes
"dunder" just means "double under[score]"
so you would read __init__ as "dunder init" when you speak it aloud.
i see, are there methods that donnt have dunder
yeah
i.e
you can define any method you'd like
wdym, how
for example, list objects have an append method
well, it's both
methods are functions
but specifically, they're functions that belong to a class
in this case, the list class
oohh list is a class?
ohh i thought it was a primmittive data type
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?!
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
@trail stratus In Python, everything is an object. there are no primitive types
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
?
I'm not sure what you mean by that
consider this example
my_list = [1, 2]
my_list.append(4)
print(my_list)
i mean why do we need child class when we have the parent class
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
You may want add methods or override them.
@warped yew but cant we do that in the parent class
but if you make a subclass called FlyingBird, you can create a fly method for it
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
no
ohh
RedBird would be a subclass of FlyingBird
ye
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.
thats why its called inheritance
!e
class Bird:
pass
class FlyingBird(Bird):
def fly(self):
print("The bird is flying")
class RedBird(FlyingBird):
pass
cardinal = RedBird()
cardinal.fly()
wow
s/def/class
lol
@boreal umbra :white_check_mark: Your eval job has completed with return code 0.
The bird is flying
i see
it's really late for me so give me a break
ye
please no space between ! and accept
that's a capital i, not an exclamation point
but u didnt define a fly method in redbrid @boreal umbra
see, you mistyped !
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
@trail stratus That's right -- subclasses inherit all the methods from their parent class(es)
well i understand why we use subclass so I got my answer thx guys
but u didnt define a fly method in redbrid @boreal umbra
@trail stratus that's the point. There's noflymethod forRedBird, so when Python can't find that method in theRedBirdclass, it goes to the next class in the method resolution order.
wait until you get to multiple inheritance
multiple inheritance isn't necessarily confusing because there's always a linear MRO
also if it's not like that don't tell me
it is like that. 🙂
I wonder if you could make a metaclass that would use a different mro
if there isn't you get an error when creating the class
@flat gazelle I would ask salt-die
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
Language discussion doesn't imply python
@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.
ye and it is kinda condusing as well
the description
i meant confusing not condusing
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
@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.
alright, this is getting #community-meta
I wonder if you could make a metaclass that would use a different mro
@flat gazelle yes, just have to redefine.mro()
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.
That would be __mro__ and the issue is that has to be a tuple
Which is not always applicable
mro is a method that generates the __mro__.
No, mro works fine
Huh
they're two different things
Of course there are valid cases when a subclass violates that, and that's fine. Don't be too hung up on the theory.
@grave jolt I like how the name of it makes it sound really advanced
@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.
@teal yacht is right
Well, it's not a commandment, that's why you can, for example, override methods
It's possible to override methods without violating Liskov substitutability.
@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
@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
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 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
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
that's not a bad idea to have one constructor, kivy has a ton of individual properties
@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 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 thatisinstancesays 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.
like those constructors are really just a little pile of default constructor arguments
constructors don't factor in to Liskov substitutability
think they were talking about iommi
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 🙂
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
what are some examples of LSP violation being reasonable?
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...
yea, you guys got confused by two topics being discussed at the same time :P
concurrency issues
there was a pretty good Stack Overflow thread on the LSP once
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.
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 🙂
This ensures we have a very general design that can be highly customized
@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
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
Not very weird. A class is just a function that produces an object :P
(in js quite literally 🤮)
Is it though?
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
haha only serious type thing
since the constructor is a method of the metaclass
wait, do you mean the class constructor or the instance constructor
a class is a factory producing instances of the class...
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")
(it's more obviously but...)
Well, now we can name classes like AnimalInstanceFactory
and metaclasses like InstanceFactoryFactory
metaclasses aren't like factories though, since they're meant to be inherited
Well, you can call a metaclass to create a class, right?
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
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
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
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.
the barber shaves himself!
yeah, it seems to be the same kind of thing 
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
@slender solar this is specifically a discussion channel, but I would look into git and github. You can also ask on #tools-and-devops
how to debug python module in termux, (i also have to pass arguments) ?
@cloud lion hmm, I haven't heard of termux, but I would ask in #tools-and-devops
!e
import sys
print(sys.meta_path)
@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'>]
It's a terminal emulator for android. wihout external tools you can always use the build in python debugger.
do you think it will allow me to append my own import hook
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
!e
class MyImporter:
@staticmethod
def find_module(fullname, path):
print(fullname, path)
import sys
sys.meta_path.append(MyImporter)
import numpy
@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
alright, what can we do with this
@cloud lion please take a look at my previous message about that.
Hello, can someone help me with joining a branch on gitlab using the git checkout command?
@unkempt rock this channel is for discussion. #tools-and-devops would be the place to talk about git but you can also open a help session; see #❓|how-to-get-help
Ok thank you 🙂
Is everything in python stored on the heap, or are strings and stuff stored on the stack, since they are immutable
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
@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
@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
@sly junco ^ does that do you what you want? just manually assigning to __context__
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
Oh that makes sense since there is no compilation 🙂
so it doesnt realize the size until runtime
i guess with VLAs that would be possible, but that opens the door to even more UBs and crashes
cpython is written for C89 (with a select few extra features), and VLAs were introduced in C99, so they wouldn’t be used
good, VLAs shouldn't be used anyway
CPython usually pre-allocates memory for containers right
I don't think so
Well, certain containers like dict may have some prebuild slots
But in most cases, nope
I think I saw a blog post showing that it did for lists... but maybe im thinking of R
If you don't initialize it with some values, it won't pre-allocate some slots iirc
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
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
Looks like extend uses the length hint in some cases and there are some bytecode instructions that take a known length
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
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
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
@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
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
looking at getting the current frame seems to work actually
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.testby 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 gettingAbcas a string. If so, you can doClass.__class__.__name__orClass.__name__
@modern frigate they want to get the class that Abc.test is "attached" to
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!
@radiant fulcrum yeah but that's specific to class definition time. i feel like there should be a more general solution anyway
Oh... Yeah, i think parsing .__name__ is how you do it 😦
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
https://stackoverflow.com/a/25959545/2954547 @radiant fulcrum yikes
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
I think that's just their implementation, can't see a reason for why cpython would need this
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
dang
that said, i still prefer this to manually inspecting the stack
lol
Is the removal of unbound methods documented somewhere cleanly to see its reasoning?
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"
because the system gets affected by the imports
you essentially have to import the file, reload it then can extract the things from it
@peak spoke there are links to guido's mailing list messages (i think) in the stackoverflow thread
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
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`)
that is quite the incredible for loop
I like how it’s comprehensibly’s pythonic and logical until you only look at the last bit In the loop
i'm wondering which style is considered best:
if condition:
return 1
else:
return 0
or
if condition:
return 1
return 0
The second is really common practice and in general reducing indentation in these ways is considered acceptable if not preferable
@magic python I would do return 1 if condition else 0 if it's something that brief
sure it's not a 1 liner tho
I prefer the second one
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
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
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
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]$
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
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
huh interesting thanks!
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
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
@fathom valley wrong channel, check the channel description (try #python-discussion )
why can't ipdb / pdb access variables when they're used within list comprehensions?
it's unpredictable and there's no way to recover from it
@sacred tinsel Care to expand on this?
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
@magic python third option
if condition:
result = 1
else:
result = 0
return result
@paper echo yea, hrm - do you think this is cleaner?
some people believe strongly in having exactly 1 return point from any function (that isnt explicitly a coroutine)
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
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
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 🤔
Anyone want free help on homework?
@south ferry read the rules
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
ok just no then , lol, try general, lol
lol, lol
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
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
@magic python also the "inside" of a list comprehension has its own scope
I use the third option style when I have lots more code inside one of the if/else parts
yeah - but why doesn't a debugging session have access to that scope?
you need to step into or out of the scope
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
This is your fault for using a debugger instead of just scattering around print everywhere lol
😦
*I am of course joking
yeah all good 😄
What is the use case and purpose of a "__main__.py" file?
@XAshwin#4194 you said you could help with homework?
Pretty sure that guy got yeeted from the server
Why
!rule 5
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.
@safe hedge __main__.py gets called when you run a module like python3 -m module_name
assuming __main__.py is within module_name
oops
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
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
@rustic portal This is a discussion channel, not a help channel (see the channel description). See #❓|how-to-get-help
my bad
__main__.pywould 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?)
I don’t know how interchangeable the terminology is tbh
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.
I was under the impression it was package —> (subpackage) —> module
And that __init__.py was kind of a special case
are there any disadvantages for creating a queue for each thread? Or am I creating a lot of unneeded overhead?
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
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?
And that
__init__.pywas kind of a special case
@safe hedge https://docs.python.org/3/glossary.html#term-package - a package is a type of module.
Wasn't me
you should have claimed credit
And I don't like it 😄
why
Difficult to parse, both for a computer and a human. And difficult to nest. And... Weird
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
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
So a package is a module
yes
I think that's confusing nomenclature.
It is what is is.
a package is the whole thing. modules are recursive
a module can have other modules
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)
But technically I can import a class right?
well, not all modules that have modules below it are packages
And people will use those words incorrectly so that definition, while true, isn't going to be something you can trust when reading.
I think a module is only a package if it's top level
you can import a class from a module, but you can't give a class to an import statement directly.
Like arguments vs parameters. Very few people use the terms correctly.
Also namespace packages are definitely not modules imo
what do you mean?
they are, because they're importable things, and every thing that's importable is a module, by definition.
I mean they are under these rules, but they are fundamentally quite different
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
https://docs.python.org/3/glossary.html#term-module - the only thing that makes a module a module is that it's searched for and loaded by import. That applies to regular modules, regular packages, and namespace packages.
Yes I know. And what I'm saying is I think that's confusing
https://docs.python.org/3/glossary.html#term-package
does this mean that a package isn't guaranteed to be a top-level module?
os.path is a package, and not top-level
interesting
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
is there a specific term for when it's top level?
Python is like physics: it mostly looks nice and simple until you look closely and it's complex and weird :)
@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"
just call it an importable
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.
squared_numbers = map(SELECT x**2 FROM x, numbers)
I think losing the distinction between arguments and parameters causes miscommunications though.
"arguments" being the things that are passed to a function, and "parameters" being what a function is defined to be able to accept?
@grave jolt https://github.com/i2y/mochi#anonymous-function :)
@raven ridge basically. I think of parameters as slots and arguments as things that go in them
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
sometimes it doesn't matter which one you're talking about
because there's enough context to establish it
The standard library docs plays fast and loose with arguments vs parameters :/
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?
But mostly context does handle it yes.
@half wolf elixir.replace("ruby", "python")? 🙂
@raven ridge well, you can't change terminology in a language used by millions of people
they're already using it
you can change the "official" terminology, but yeah.
@grave jolt I constantly miss multi line anonymous functions though.
(And some other features in mochi)
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
The problems with python packaging have nothing to do with the nomenclature imo.
it is - but not because of the fact that an importable package is a type of importable module.
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.
the fact that "package" the importable thing and "package" the library of code you download from pypi share a name is unfortunate.
And it's improving now that we're moving forward in time and aren't stuck with 2.7
some of us aren't, heh
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
that is, a pypi package can contain a module that is not a package. that's weird.
Well that name is older and bigger than python so it is bedrock imo
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"
"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. 😦
Looking at you beautifulsoup
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.
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
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
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
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
i guess i dont see how that supports calling a "directory module" a "package"
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
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
You don't actually need an __init__.py anymore though do you
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
But the point that someone made earlier was saying that was still a module
Since anything that is importable is a module
yes
Which again I think is confusing as hell
what do you mean
a "package" in python terminology is a module that happens to contain other modules
as in an implicit namespace package is in fact still a module
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
but from the perspective of python it is a module
it's just another way to define a module
so we have three ways:
- single file
foo.py - directory
foo/__init__.py - implicit namespace
Right. And the fact that I can call any of those a module without any qualification and be correct is somewhat confusing imo
But you don't always need to know
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
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
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
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
I don't think it's a problem when using them tbh
Are people often assuming that something is a specific type of module?
"I want to write a module"
you know where things get weird?
src/
foo/
__init__.py
a/
__init__.py
a.py
What does that statement mean?
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
Come on you know that's being a bit simplistic.
is it? thats exactly how i would approach it in a help session
You're right that it could, in theory, be a redundant way of saying that they want to write python in general
There is a fairly big difference between writing a single importable .py and have a well structured "package" with many modules and optional installs
sure, thats why you need to clarify what someone is asking for
But I don't think anyone would say they want to "write a module" if they weren't interested in the reusability
"I have a problem with my python module"
I thought strictly speaking "module" means ".py file"
@gleaming rover yes
(which is pretty weird IMO but whatevz)
well a package is also a module
Though it can also be groups of files
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
Erm dunno
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"
A "library" isn't even a term is it?
"all my code is just a mess in one .py file" 🥴
not a technical term in python no
A "library" isn't even a term is it?
@safe hedge not in Python
yes lol gm
"I have a problem with my python module"
@safe hedge this wouldn't be enough information to know the scope of the problem regardless
My biggest trouble in python is proper packaging tbh
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
It's a "files on disk" concept when you are trying to properly package your code no?
and the mess of misleading terminology that we have been discussing makes it hard to even talk about, not to mention teach
I never know how much I should put in my __init__ files for example
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)
And I still think I'm doing something wrong when I end up with being able to do mypkg.mysubpkg.mymodule.os.path.join
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
I generally put nothing in except __all__ and imports
same
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.
^
Do you mean the import thing I put?
yeah
It's especially annoying when you have multiple modules with the same stdlib deps
Or modules with lots of imports
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
import os
a = 1
foo = 2
def __dir__():
return [
'a',
'foo',
]
the docs suggest that this would fix it
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
There is a fairly big difference between writing a single importable
.pyand 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.
@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
I generally have a lot of stuff in my __init__.py files. It seems to annoy some of my co-workers, though. 🤷♂️
personally i find it an unintuitive place to keep code
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...
e.g. i also usually have cli.py and in __main__.py i do from myproject.cli import run_cli; run_cli()
So this is one of the things I've been wrangling with
a/__init__.py defines the namespace a. I find it unintuitive to keep the code for a anywhere else!
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
^
like right now I'm working on a Django project
I have like models packages, views packages, etc.
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
(it also depends on what exactly a does)
And I have no idea how to structure it
I have too many models/views to keep in one file, but by definition there aren't models/views that belong in __init__.py
I sometimes define things like a simple Client class in an __init__.py, where it is composed of other classes from separate modules
@safe hedge if they're really independent, you could do something like git does. Its approach to discovering commands makes it pluggable.
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
They're basically like:
-package
-grp1
-tool1
-tool2
-shared_code
-grp2
-tool1
git foo searches $PATH for git-foo and runs it.
Where the tool scripts are currently just run directly and have their own argparsers and main()
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
Ideally I wanted to allow them to be run standalone if you really want
in order to use one argparser as a "subcommand" parser for another argparser
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
yeah it definitely sounds like you want some kind of plugin interface
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
click is great, a lot easier to use (imo) than argparse
It's based on a deprecated lib though lol
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
pretty sure click is just modeled after optparse
i seriously doubt it actually uses optparse internally
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
i think they mean that it was inspired by optparse
yeah
thats bad wording on their part
Either way I'm against adding deps wherever possible
why? security?
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
what do you mean upgrade?
Like move from 3.7 to 3.8 etc
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
Yeah I used it once, hated it, then watched as the entire thing fell out of favour
Intresting
[Repeat so more people are aware of this]
Python 4 FAQ.
- The version after 3.9 is 3.10; in fact it already exists (in github master).
- If there ever is a version 4, the transition from 3 to 4 will be more like that from 1 to 2 rather than 2 to 3.
341
1059
what was 1 to 2 like?
From what I gathered from Reddit, "relatively smooth".
2 was much more backwards compatible than 3.
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?
Where does that overload decorator come from?
it's different in that it's only for type-checkers
it doesn't actually dispatch, only one implementation of __init__ will exist
Ah, right
I can’t think of any reason someone would need 2 init in one class tho
does it evaluate all of the types?
@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.
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
Hm okay that makes sense
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
I suppose Qt does that instead of using class methods because multiple constructors are supported in C++?
I'd say thats a good assumption
we made a multiple dispatch overload before in here: https://github.com/salt-die/Snippets/blob/master/overload.py, but it needs a bit of modification for methods
you could do it to the class
just needs a __get__
i think
or you could just make a function too
which ever
... changed to a function
The users on this server have a variety of backgrounds. Some are new, some are experienced. Some are hobbyists, some are professionals.
I'm a pro.. 9 years full time.
@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
probably not, but it's mostly academic
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
most of the stuff in my Snippets is pretty academic
well, maybe that's not true, it's like half-useful/half-academic
I am writing windows 10 notifications using pure ctypes and winapi rn
* internal screaming *
could be useful
well, if it segfaults, windows displays a failure message, right?
So in some sense you still display a notification 🙂
that's because of unregistered sublime text
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
using inspect
inspect.getsource then regex extract?
no
Would locals() work?
signiture or getfullargspec
I remember locals being needed for something similar to this
@low lagoon no i don't think so - i want to extract from a module
@radiant fulcrum ace thanks 🙂 I was parsing the inspect.getsource and extracting with regex when i thought there must be a better way 😅
@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
the inspect docs should have it somewhere
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
!e
def f(x, y=2):
print(x, y)
f.__defaults__ = (7, 8)
f()
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
7 8
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
!e
from collections import namedtuple
Undefined = namedtuple("Undefined",())
def f(x, y):
print(x, y)
f.__defaults__ = (Undefined(),)*1000
f()
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
Undefined() Undefined()
is this an example of a usecase, or just another example
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)
@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
oh wow
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
definitely not regular use
Well, inspecting is useful if you want to do something with function annotations
Like in discord.py
oh, are they like -> str and stuff?
handling bytecode, frames etc. is very rarely done in normal code and should mostly be avoided unless necessary
what's a frame?
thanks! yeah all this stuff is pretty foreign to me
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
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>
@magic python empty args
also probably not appropriate for advanced discussion...?
@gleaming rover it's appropriate
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)
you're checking if there are any elements first, otherwise getting the first might throw an error
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
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"
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
(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.
@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
it's accurate to say that it checks something, yeah. That's not all it does, but it definitely does.
What does pure CS research look like?
and of course how could python be applicable here
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.
:incoming_envelope: :ok_hand: applied mute to @unkempt rock until 2020-09-23 04:18 (4 days and 23 hours).
@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.