#internals-and-peps
1 messages · Page 67 of 1
doesn't look that bad to me
when I see "helpers" I think of this: http://thecodelesscode.com/case/155
An illustrated collection of (sometimes violent) fables, concerning the Art and Philosophy of software development
hahah, interesting
but I suppose "utils" isn't much better
I do it too
but I have recently been trying to have more descriptive names for my utils
like functional, datetime, etc.
i'd put something like low_pass_filter in a filters.py
then there's a tradeoff between flatness (flat...ness?) and descriptiveness
i assume you have something like high_pass_filter too
i typically have a utils folder, instead of just a utils file
always love some good koans.
uhh, it is interesting. high_pass_filters are used somewhere else entirely
@safe linden DSP Engineer?
I'm just an undergrad XD, this is for a physics lab code refactor
Learning a lot. Came in telling them I felt comfortable with c++ and x86, so they have me doing python architecture now
but on the pep8 thing. I am hearing that it is fine to import functions like that then. And I could probably name helper_functions to helpers
my main issue with naming it something clearer is I really don't know what most of this code is supposed to do
so I figured helpers would be vague enough to be accurate but clear enough to be structurally helpful
Anyone ever use behave module?
Sounds like some Austin Powers shit
so would you use this instead of say pytest?
I have no idea but its under the Contributors Guide for python pptx and I'm trying to understand it
oh, you know what module other than logging uses camel case?
unittest 😦
literally the only reason I use pytest
getLogger
although honestly I do really prefer pytest
I briefly considered writing a script that would add snake_case bindings to a module with camelCase names
after some time I realised that I was just avoiding work
😄
what version does everyone use in the shell
I realise mine is 3.7
even though all my new virtual envs use 3.8
(use pyenv)
not like venv, virtual envs in general
pyenv manages your python versions
but yeah I've been meaning to look @ it
oh
okay I mixed it up with something else
that looks cool
man I remember once @ somewhere I used to work this dude said "I really am not impressed with Python's dependency management"
pyenv is very handy
!e
import re
def ensnake(attrmapping):
class _SnakeCaseProxy:
def __getattr__(self, attr: str):
try:
return getattr(attrmapping, attr)
except AttributeError:
snake_case_attr = attr
camel_case_attr = re.sub(r"_(.)", lambda m: m[1].upper(), snake_case_attr)
return getattr(attrmapping, camel_case_attr)
_SnakeCaseProxy.__name__ = _SnakeCaseProxy.__qualname__ =\
f"_SnakeCaseProxy<{getattr(attrmapping, '__name__', repr(attrmapping))}>"
return _SnakeCaseProxy()
###
import logging
class IReallyLoveJava:
def helloWorld(self):
return "C#"
javaLover = IReallyLoveJava()
java_lover = ensnake(javaLover)
snake_logging = ensnake(logging)
print(java_lover.hello_world())
print(snake_logging.get_logger())
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
001 | C#
002 | <RootLogger root (WARNING)>
nice
yes, I am avoiding work as well, at scale
a few days later..."why did you upgrade npm and node? our stack only works with node version 10" 🤔
ensnake is a great name
stop 🥴
oKay
well I suppose there is merit to camel case
the i_phone wouldn't have sold that well
lol
do you think
there is significant overlap
between namedtuple and dataclass?
the problem, I guess, is that Python doesn't have...named destructuring? not sure what to call it
i would say so yeah
not familiar with Rust's implementation but probably?
like
class NT(NamedTuple):
a: int
b: str
t = NT(1, 'a)
NT(a, b) = t
assert a == 1
assert b == 'a'
somewhere in the 6 region I think
!pep 622
yeeep
python totally has destructuring
lmao
😄
i'm gonna say no to that one
I'm like 20% sure there is some black magic that will allow that (without a custom parser)
let me think
yeah, it is
what about
(a, b):NT = destructure(t)
can't be annotated
Huh?
oh yes
what about
NT,(a, b) = match(t)
or simply
(a, b) = match[NT](t)
but this is a bit meh
wouldn't you override the constructor then
the former works, but ^
unless you're saying
you return type(t) or something?
as the first element
but then if you matched the wrong thing your reference would be gone

mFoo = matchmaker(Foo, "a", "b")
(a, b) = mFoo(foo)
mFoo
put it in the corner with logging and unittest
why it's not named unitTest is beyond me
literally unusuable
NT;(a, b) = match(t)
ooh
(a, b) = NT.__destr__
since NT needs some kind of magic method, it could inherit from a magic class which would define a __destr__ proprety that would access NT's __match__ method
I should write a library out of it 
@swift jackal This is a channel for indepth discussion about the Python language. If you need help, please check out #❓|how-to-get-help.
^
Alrigjt
for some reason I can't stop thinking about rust-like macros in python, haha
macro map_property($attr: ident, $name: ident, $key: expr, $type: expr, $default: expr, $doc: expr):
def get_$name(self) -> $type:
return self.$attr.get($key, $default)
def set_$name(self, value: $type) -> None:
self.$attr[$key] = value
def delete_$name(self) -> None:
try:
del self.$attr[$key]
except KeyError:
pass
$name = property(get_$name, set_$name, delete_$name)
class Test:
def __init__(self, **kwargs) -> None:
self.data = kwargs
map_property!(data, test, "test_key", int, 0, "Test description.")
test = Test(test_key=42)
assert test.test == 42``` I had been working with classes that required to be based on an arbitrary mapping, and so something like this could be useful for quickly writing all of attributes out instead of generating code and running exec()
wouldn't something like
def __init__(self, **kwargs) -> None:
self.data = kwargs
for k in self.data:
def get(self,k=k):
return self.data.get(k, default)
def set(self, v, k=k):
self.data[k] = v
def del_(self, k=k):
del self.data[k]
setattr(type(self), k, property(get, set, del_))
```be about the same
yeah but I was reusing it quite a lot with different dict attributes and other stuff
besides, it brings overhead of loading all the names
on second thought, this is pretty weird. You are assigning class attributes based on a value the instance initializer receives.
ah no, I see.
nice pfp, makise kurisu
from typing import Any, Dict, Optional, Type, TypeVar, Union
T = TypeVar("T")
U = TypeVar("U")
V = TypeVar("V")
TEMPLATE = """
def get_{name}(self) -> Optional[TYPE]:
return self.{attr}.get({key!r}, {default})
def set_{name}(self, {name}: TYPE) -> None:
self.{attr}[{key!r}] = {name}
def delete_{name}(self) -> None:
try:
del self.{attr}[{key!r}]
except KeyError:
pass
{name} = property(get_{name}, set_{name}, delete_{name})
"""
def map_property(
name: str,
attr: str,
key: T, # such that eval(repr(key)) == key
*,
type: Any = Any,
# code to run, or an object such that eval(str(default)) == default
default: Optional[Union[str, U]] = None,
doc: Optional[str] = None,
# namespace to use, tries to fetch from caller frame if not given
namespace: Optional[Dict[str, V]] = None,
) -> property:
env: Dict[str, Any] = {}
if namespace is None:
namespace = {}
try: # ayy frame hacks!
frame = sys._getframe(1)
namespace.update(frame.f_globals)
namespace.update(frame.f_locals)
del frame
except (AttributeError, ValueError):
pass
env.update(namespace, TYPE=type, Optional=Optional)
code = TEMPLATE.format(name=name, attr=attr, default=default, key=key)
exec(code, env)
some_property = env[name]
some_property.__doc__ = doc
return some_property``` well I made _something_ as an attempt
okay that was a large piece of code haha
still seems like something better handled by metaprogramming in python. Would probably require a metaclass or __init_subclass__
you can definitely write it in a nicer way
but it brings overhead by loading global values like key
or if you replace self.{attr} with getattr(self, attr), function calls don't make it better here
!e
class MapProperty:
def __init__(self, attr, k):
self.attr = attr
self.k = k
def __get__(self, obj, type=None):
return getattr(obj, self.attr)[self.k]
def __set__(self, obj, v):
getattr(obj, self.attr)[self.k] = v
def __delete__(self, obj, v):
del getattr(obj, self.attr)[self.k]
class Test:
def __init__(self, **kwargs):
self.data = kwargs
test = MapProperty('data', 'test_key')
test = Test(test_key=42)
assert test.test == 42
@flat gazelle :warning: Your eval job has completed with return code 0.
[No output]
a custom descriptor is probably the neater way
overhead by loading global values like key
I wanted less overhead because iterating over a lot of objects and their properties, even with current version I made, is pretty slow
did you try __slots__?
hm, actually interesting idea
but this will speedup both of our versions, so mine is still going to be faster :p
it will be pretty minor. properties have the additional level of indirection as they have to call the functions you pass them, which is probably about as expensive as a getattr call
when unsure, time it! -- and gotta do just that
>>> timeit.repeat("test.test", globals=globals())
[0.20965709999995852, 0.20878179999999702, 0.20550529999997025, 0.2064856000000077, 0.2059263000000442]
>>> timeit.repeat("desc_test.test", globals=globals())
[0.3471633000000338, 0.2668077999999241, 0.265926899999954, 0.3632896000000301, 0.3051882999999407]
>>> ```
@flat gazelle here is what we have, without slots
test is using my map_property, desc_test is using your MapProperty
huh, did not expect that
given the following:
Capsule = namedtuple("Capsule", ["in_list"])
capsules = [Capsule([1, 2]), Capsule([3, 4])]
does a nice, declarative approach exist to flatten capsules into [1, 2, 3, 4]? the attribute lookup is making this oddly difficult
Hmm, can't namedtuples be indexed by position? If they can, the standard
flat = [el for sublst in capsules for el in sublst]
would work.
Ah, I see, one more layer to unwrap
mm yea you're right but in my case Capsule has more than one attribute
and I only want to get in_list
sorry that was a bad example
flat = [el for cap in capsules for el in cap.in_list]
works for that
beautiful thanks 💜
I thought you wouldn't be able to access the attribute in the comprehension
Hi, how can I extract integers from a sqlite database to a list?
thats not really a topic for this channel
This channel is meant for discussing the language itself, for help see #❓|how-to-get-help @coarse shard
ok
I left an idea in python-ideas, but am not quite sure what the person who responded mean by the answer. I hope this is enough of a discussion about the actual python language to fit here. If a help channel would be more applicable, I'll claim one instead
It's a question of circular imports and files trying to import themselves
Their point is that the error doesn't always mean that the module was trying to import itself. It can mean that, but that's not the only way to get that error.
Another way to get that error is to have module A import module B, and have module B import module A.
Your proposed wording would be incorrect for that case
You're proposing:
"ImportError: partially initialized module 'A' can't import itself"
But it isn't importing itself. It's importing B.
There might be clearer wording that is correct, though...
Ahah yeah. Both his explanation and my proposed wording
Ohh, I misread what you wrote
hii
Yes. I think either having a new wording that is correct in both cases or having a special message for when it tries importing itself, could work. I'm leaning toward having a special wording for when the program tries to import itself
That's another option, yeah - you can propose splitting the error message into two paths depending on whether the import that failed was the trying to import a module with the same name as the one that's calling import
It is a common mistake for learners, and performance on error handling paths is generally ignored, so you may get some traction with that.
#gui.py
import autotkinter as tk
tk.Label(text="Hello World").pack()
#autotkinter.py
from tkinter import *
class StopFinder:
def __del__(*_):
mainloop()
_END_CHECK = StopFinder()
```I wonder how fragile this is.
@raven ridge How do you mean with splitting the error message into two paths?
@flat gazelle I thought the only potential fragility with __del__ is that any exceptions that aren't handled before the end of __del__ just get suppressed
well, I am more worried about GC order. It is very possible other __del__ get called first and the program is left in an invalid state afterwards
@raven ridge How do you mean with splitting the error message into two paths?
@spark parcel suggest that the existing message be used when the last import statement came from a different module than the one being imported, but your message be used when we can detect that a module directly imported itself
Right, yeah. I think that would probably be the best way
I'll send another message in the thread about that
Please someone could tell me, how to code these two graphs with python without libraries?
thats ascii right?
@worldly shard you're gonna find it much easier if you take the time to properly ask than just throwing it in random channels that you see. If you read #❓|how-to-get-help it explains the process for asking quesions. Make sure you include some detail about exactly what is expected, such as whether that's text based or image based.
is it possible to use a python function in C#?
like if i want to call a function at a particular event in C# from python (as a private void function), will it work?
Look into pythonnet, it's a library that allows for Python/C# interop
You can use python modules in C# and vice-versa
example:
# MainPage.py
WebPage = WebView(Source="https://google.com/")
WebPage.ContextFlyout = MenuFlyout()
def WebPage_ContextRequested(sender, e):
ContextMenu.ShowAt(UIElement(sender), e.GetPosition(UIElement(sender)))
WebPage.ContextRequested = WebPage_ContextRequested
should be something like:
<!-- MainPage.xaml -->
<WebView Source="https://google.com/" ...>
<WebView.ContextFlyout>
<MenuFlyout />
</WebView.ContextFlyout>
</WebView>
and
// MainPage.xaml.cs
private void WebPage_ContextRequested(WebView sender, ContextRequestedEventArgs e /* or whatever the default args are */)
{
ContextMenu.ShowAt(sender as UIElement, e.GetPosition(sender as UIElement))
}
will pythonnet do that @spice pecan ?
You should be able to do something similar to that, yeah
oh thanks a lot!
hi
hello!
Is that for python or general discussion?
Read the channel topic
I want to learn to encrypted messages using python
can anyone tell me what is the use of listener in pynput
I feel like when beginners start with the REPL
it's not so clear for them that the values of expressions are automatically printed
which leads to confusion regarding print vs return
Yeah, IDLE is pretty misleading because of that
read-evaluate-print-loop 🤷♂️
hey, im working with dlls and the ctypes library, so i thought this question would be appropriate in this channel.
so basically i have a dll, i created using cpp, but i compiled it to C language, i u guys understand what i mean
this dll has some functions i wanted to run in python, one of them returns a var with HANDLE datatype
but when python receives it, it converts it to a plain int, if im right.
Is there any way to store that HANDLE inside a python var, without it losing its content?
what kind of type is HANDLE, a struct?
then you should get a ctypes.c_void_p as a result when calling from python
hmmm so if i would do type(myReturn) , it should return ctypes.c_void_p
?
because it returns me <class 'int'>
!d ctypes.c_void_p
class ctypes.c_void_p```
Represents the C `void *` type. The value is represented as integer. The constructor accepts an optional integer initializer.
^ it is interpreted by an integer
how do you do the call?
how do you do the call?
@flat gazelle wdym by that?
^
@undone hare ohh okay, so if i will give myreturnedHandleInPythonas an argument inside a cpp func it will treat it like an integer?
I don't know anything about the C API tbh, I've just looked up the docs haha
haven't done CFFI in a while, but IIRC you created a c function type where you described its type
ohh okay, well ill look into it again. Thank you guys.
hmm ive got a new idea
do you guys think i can pass a pointer
and then giving the pointer as the argument
and then ill just extract the HANDLE value from the pointers adress
or is this too ambitious?
!subscribe
Hello, @unkempt rock, you can run bot commands in #bot-commands
how do we feel about __contains__ doing the job of isinstance for type?
>>> 'hi' in str
True
!e
print(str in 'hi'.__mro__)
oh no did I break the bot
guess only the class has that
On one hand I'm not sure that thinking of instances as being "in" in their class is very intuitive
at the same time I feel like type checking should be part of the grammar rather than the vocabulary, so to speak.
I'm not sure if in is the best candidate for that, but a way to typecheck other than isinstance(obj, type) would be really nice
There was a pep that proposed using | to form Union[type1, type2]
I wouldn't say there's something inherently wrong with them, but something along the lines of var is_of_type type feels easier to comprehend
The infix form is more readable IMO
Somewhere or other, I remember seeing isa suggested as a new keyword. I think that's much clearer than isinstance, or in
Heavily inspired by @fix error's custom operator class, ```py
class CustomOperator:
def init(self, func):
self.func = func
self.lhs = ()
def gt(self, other):
if self.lhs:
lhs, rhs = *self.lhs, other
self.lhs = ()
return self.func(lhs, rhs)
self.lhs = other,
return True # Must be truthy to eval both parts of chained comp
def call(self, lhs, rhs):
return self.func(lhs, rhs)
isinstance = CustomOperator(isinstance)
print('hello' <isinstance> str)
print(isinstance('hello', str))
https://github.com/markshannon/pep622-critique here was where it was suggested
@spice pecan oh, I remember that 🙂
it also suggests your hting of in as a better option
isa sounds good, similar to C#'s var is Type
I prefer isa because it's more intuitive
Hm. It's not an operation I need frequently - I write an isinstance check maybe once every hundred or two hundred lines of code, and don't think I've ever used issubclass. I'd strongly oppose overloading in for this. With the new parser, I bet isinstance could be made an infix operator in addition to a built-in function...
if type(a_variable) == list is something beginners often do, and they don't realise that is or why it is wrong
I feel like in or isa could help with that
In beginners' code, that's probably not wrong. Beginners don't deal with much subclassing...
it's poor practice though. I feel like the semantics of isa are immediately clear, and it's pretty natural. But you're right that this isn't exactly a major problem that comes up often
I don't hate isa, but if it's possible I'd prefer an infix instanceof operator over an isa operator - adding another word to the grammar seems worse than reusing one in a novel way.
!e
class SupportsInMeta(type):
def __contains__(cls, obj):
return cls.__class_contains__(obj)
class Str(str, metaclass=SupportsInMeta):
@staticmethod
def __class_contains__(obj):
return isinstance(obj, str)
print(42 in Str)
print("hi" in Str)
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
001 | False
002 | True
I also can't help but feel that isa and that proposed overload of in will both be really hard to Google about, and isa in particular will not be obvious to people who don't know English well since it's two short words crammed into one operator name.
yeah, I think you're right about that. isa is also very commonly used as an acronym for lots of different things which isn't great
I have a pyObject - (blender KDTree) I need to store it each frame and then recover it somehow
does anyone know a good method for this?
(I actually only need to store it 1 time, and then read it each frame)
Pickle i guess
But yuck to that
yeah sounds super slow
someone suggest a memory map and using numpy
but posted no code and I don't really understand it
That's a good idea depending on how the object is implemented
How is the data in the KDTree actually stored
it's a C object I think that py is wrapping
mathutils.kdtree.KDTree
I am trying to bring it to the viewport too
I am using it to stream worlds in the game engine
this looks good -mmappickle: Python 3 module to store memory-mapped
numpy array in pickle format
Why not simply store it as csv file?
Someone could tamper with the pickle file and execute code inside the game
uhh, why store a numpy array as pickle when numpy has a perfectly good save function that saves in numpy's binary npz format?
I don't even need a nparray
I need to store a blender kdtree
I don't care how really as long as it's fast
invoke modal operator needs to store a kdtree when it invokes and use the kdtree each time the modal operator repeats
in bge I can do
own['kd']=kdTree
and it works fine
in bpy though all properties are assumed to want to be saved forever and I don't see any sort of global area to store data for addons to share
It might be faster to serialize to and deserialize from numpy than to pickle and unpickle
Is there a way to memmap a binary file without numpy?
Why is heapq made as a collection of functions and not a separate Heap class?
old api and maybe easier to do the c implementation I'd guess
flexibility, I suspect - this allows it to be used with any sequence type.
any mutable sequence type, at least.
Not many cases where you wouldn't use a list
I can see why it might be useful for subclasses of list, at least
Would still probably be easier to use a class with a changeable heap through an init arg or subclass instead of passing it everywhere
@paper echo mmap - standard library
Old API might be part of it, but heaps aren't particularly useful by themselves - they're usually used as part of other data structures, like a priority queue
my guess is that it was one of those 3rd party libraries that got subsumed into the stdlib
How does an idea go from the python ideas list to being implemented?
Well python ideas is mostly about discussing afaik
usually, a PEP gets written
Then you can write a PEP proposing your idea if it is large
yeah
And then, after it gets approved, it is being implemented iirc
Right
I started a thread about giving some message when python tries to import the running file (this one: #mailing-lists message). I think one of the later options discussed would be great to have. How exactly would that continue? Do I write a PEP? Does someone else propose that they’ll write one?
I'm not sure that change would be large enough to need a PEP
which proposal did you like?
I’m not 100% sure. The one about a warning would probably be best, but could add unnecessary slowness. However, I’d say that getting an added message when an error occurs would be almost necessary
I do think the warning would be optimal, though
you need a core contributor to "endorse" you iirc to submit a pep
I'm not sure that change would be large enough to need a PEP
@spark magnet if it isn’t large enough for a pep, what happens then?
If one or more of the PEP's co-authors are core developers, they are responsible for following the process outlined below. Otherwise (i.e. none of the co-authors are core developers), then the PEP author(s) will need to find a sponsor for the PEP.
Right, yeah
the smaller version of a pep would be an issue basically
these are the bpo you see in pull requests on github and in the changelogs
can range from bugfixes to changes in documentation etc
So, it’s basically either a PEP or an issue?
afaik yes
Alright. @spark magnet would you say that opening an issue on the issue tracker would be the best way forward, since you didn’t seem to think it was big enough for a PEP?
If the Python-Ideas thread seems to reach a positive proposal, then you can ask on the thread, or open a bpo.
What is the correct way to annotate callable that takes no arguments? Callable[[], T]?
Yup 👍
Stackoverflow and pycharm agree https://stackoverflow.com/questions/58313655/how-do-you-express-a-python-callable-with-no-arguments
alrighty!
Is there a reason the operators (https://docs.python.org/3/library/operator.html) are made positional-only, which prevents one from doing
sub1 = functools.partial(operator.sub,b=1)
?
@pearl river probably just history.
I feel like that's not the case and they are intentionally positional
well, what you have sent should be possible under 3.8 if _operator does not exist, heh
Are there any interesting solutions to make importing a library faster?
@pearl river probably just history.
@spark magnet they were changed in 3.8, I believe
I feel like that's not the case and they are intentionally positional
@cloud crypt the parameters for most of the operator functions have no true meaning => positional-only
PEP 570 talks about it
well, what you have sent should be possible under 3.8
@cloud crypt nah, unless I missed something, I had to settle withlambda x: x-1.
~~just do (-1).__add__ ~~
@cloud crypt nah, unless I missed something
@pearl river You quoted half of what gm said and changed the meaning, because presumably you do have the_operatormodule.
https://github.com/python/cpython/blob/3.8/Lib/operator.py#L132 would allow what you wrote to work, but in CPython that's not accessible, because it's overridden by https://github.com/python/cpython/blob/3.8/Lib/operator.py#L408
that's what I've said
ah, I see, I didn't quite get the second half. What's the difference between them? _operator is the CPython-specific one?
well, let’s see if PyPy has one
basically a C implementation of the operator functions I believe
to avoid Python function call overhead
ah, right, and when possible (depending on the implementation) operator imports everything from _operator to provide said speedup?
seems like it
yeah
so essentially the reason is that the C-based functions of _operator don't support keyword arguments like that. Interesting, thanks.
well, _operator could support keyword-args
supporting keyword arguments is more expensive, though, and in this case they chose not to because they felt that it didn't add enough benefit to justify the extra cost (since the extra cost applies even to calls that don't use keyword arguments)
(or, possibly it's so old that it predates the introduction of keyword arguments - that'd be the other possibility)
so essentially the reason is that the C-based functions of
_operatordon't support keyword arguments like that. Interesting, thanks.
@pearl river but also that they would have no real meaning in many cases
def add(arg1, arg2) <- ???
tbh, you could have lhs,rhs for the binary operations
well, it's less that I care about whether it has keyword args, and more that I want to use functools.partial to apply the second argument of a positional-only function 🙂
better use lambda tbh
Still __call__ 2 times, and even less overhead with lambdas then partial
well, it's less that I care about whether it has keyword args, and more that I want to use
functools.partialto apply the second argument of a positional-only function 🙂
@pearl river not really meant for that case, I guess...
Still
__call__2 times, and even less overhead with lambdas then partial
@cloud crypt oh, that actually does look to be the case.
In [223]: add1 = functools.partial(operator.add,1)
In [224]: add1_2 = lambda x: x+1
In [225]: %timeit list(map(add1,range(10000)))
1.17 ms + 19.5 чs per loop (mean + std. dev. of 7 runs, 1000 loops each)
In [226]: %timeit list(map(add1_2,range(10000)))
1.19 ms + 32.6 чs per loop (mean + std. dev. of 7 runs, 1000 loops each)
So much for speedup 😅
hmmm
if you want to take it even further, [*map()] is very slightly faster than list() when the amount of item isn't too high
Anyone else hugely disappointed by functools.partialmethod?
The fact that it doesnt store the wrapped method's __doc__ is a huge let down imo
You could probably monkeypatch it
I don't think it would be too hard to write your own partialmethod
@swift imp is that different from functools.partial?
What is callback function and class?
@paper echo yes partial can actually transfers the docstring
So, ultimaytly, I learned exe conversion using cx_Freeze, should I move to setuptools or keep using it.
Ive heard back and forth on it and want to know what yall think.
@brave badger ^?
Not really on-topic for this channel but I suggest PyInstaller for easier deployment
Fair enough.
new blender is much easier to use pip right in the application
{all my clients are artists / typically admin of their own system}
does new blender make it easier to run blender scripts without having the gui up?
It is probably off topic, but you can run scripts without the GUI iirc
@swift imp seems like an oversight or bug
idk how to correctly file issues w/ the python bugtracker
@paper echo you need to login and then press the "create new" button in the left navbar
@paper echo its not. I've read SO post on it, its meant to do this
its mean to not preserve the docstring? @swift imp
that is weird
@undone hare yeah i just dont know if theres additional procedure or specific decorum that needs to be respected
@paper echo partial preserves the docstring, partialmethod does not, and this is the design
huh. why?
apparently its something about docstrings for class instance methods working differently than docstrings for functions
and as such partialmethod is a class and it just doesnt transfer
I don't really get it but yeah, doesn't work
@paper echo there's a section about it on the devguide https://devguide.python.org/tracker/#using-the-issue-tracker 
oh nice thanks
@swift imp weird, thanks. you cant manually assign __doc__ to it either?
ahhhh i see
That's because partialmethod is a class written in Python, and instances of classes get their docstring from the class's
__doc__, not from a__doc__attribute on the instances. Functions behave differently, with the__doc__attribute of the function object being looked at.
!e ```python
class WeirdThing:
""" doc 1 """
@property
def doc(self):
return 'doc 2'
print(WeirdThing.doc)
print(WeirdThing().doc)
@paper echo :white_check_mark: Your eval job has completed with return code 0.
001 | <property object at 0x7fe4604124a0>
002 | doc 2
!e ```python
class WeirdThing:
""" doc 1 """
@property
def doc(self):
return 'doc 2'
help(WeirdThing)
help(WeirdThing())
@paper echo :white_check_mark: Your eval job has completed with return code 0.
001 | Help on class WeirdThing in module __main__:
002 |
003 | class WeirdThing(builtins.object)
004 | | Data descriptors defined here:
005 | |
006 | | __dict__
007 | | dictionary for instance variables (if defined)
008 | |
009 | | __weakref__
010 | | list of weak references to the object (if defined)
011 |
... (truncated - too many lines)
Full output: https://paste.pythondiscord.com/ecadirujuq
ok i just tested in in python
it does in fact work if you set __doc__ as a property
so maybe that could be the hack? not sure if that would break things if it were added to the stdlib
!e ```python
from functools import partialmethod
class partialmethod2(partialmethod):
@property
def doc(self):
return self.func.doc
class WeirdThing:
def f(self, x):
return x
f1 = partialmethod2(f, 1.0)
w = WeirdThing()
print(w.f1.doc)
@paper echo :white_check_mark: Your eval job has completed with return code 0.
001 | partial(func, *args, **keywords) - new function with partial application
002 | of the given arguments and keywords.
hmm
aha i got it
!e ```python
https://github.com/python/cpython/blob/cd3c2bdd5d53db7fe1d546543d32000070916552/Lib/functools.py#L347
https://stackoverflow.com/q/32994837/2954547
from functools import partialmethod
class partialmethod2(partialmethod):
def get(self, obj, cls=None):
result = super().get(obj, cls=None)
result.doc = self.func.doc
return result
class WeirdThing:
def f(self, x):
""" f() documentation """
return x
f1 = partialmethod2(f, 1.0)
w = WeirdThing()
print(w.f1.doc)
@paper echo :white_check_mark: Your eval job has completed with return code 0.
f() documentation
seems like a pretty quick fix
easy PR?
!e ```python
from functools import partialmethod, wraps
class WeirdThing:
def f(self, x):
""" f() documentation """
return x
f1 = wraps(f)(partialmethod(f, 1.0))
w = WeirdThing()
print(w.f1.doc)
@paper echo :white_check_mark: Your eval job has completed with return code 0.
001 | partial(func, *args, **keywords) - new function with partial application
002 | of the given arguments and keywords.
hello
have a nice day everybody
ı have a questions about xbee and python
can anyone help me ?
@plain skiff I'd recommend getting a help channel for that (#❓|how-to-get-help). Also, read the description for this channel. That question doesn't fit here.
what is the correct way to annotate an argument of slice type?
slice?
yeah
Does cur_slice: slice not work?
https://github.com/python/typing/issues/159
hmm, interesting
looks like it went nowhere, but was brought up in the past.
Interesting, I didn't know there was a typing repo
is there some interoperability between ABCs and Protocols?
like, can i generate a protocol from an ABC or vice versa? i started putting together some code to do this by hand, but i realized that _ProtocolMeta (the metaclass for Protocol) is a subclass of ABCMeta, and that gave me pause
In [93]: print(inspect.getsource(_ProtocolMeta))
class _ProtocolMeta(ABCMeta):
# This metaclass is really unfortunate and exists only because of
# the lack of __instancehook__.
oh dear lol
It's metaclasses all the way down
how would you feel about slice notation being applicable to iterators
and having the effect of islice?
i like it
but im sure somewhere out there someone has implemented iterators that also support custom __getitem__ lookups
so it would probably break backward compatibility unless you did it yourself
yes, we did that in this channel, I believe
<#internals-and-peps message>
(thread starts at about here <#internals-and-peps message>)
from __future__ import annotations
import collections.abc
from itertools import islice
from typing import Generic, Iterable, Iterator, TypeVar, Union
_T = TypeVar('_T')
class IndexableIteratorWrapper(collections.abc.Iterator, Generic[_T]):
self.iterator: Iterator[_T]
def __init__(self, iterator: Iterable[_T]):
self.iterator = iter(iterator)
def __getitem__(self, subscript: Union[int, slice]) -> Iterator[_T]:
return islice(self.iterator, subscript)
def __iter__(self) -> IndexableIteratorWrapper[_T]:
return self
def __next__(self) -> _T:
return next(self.iterator)
like this i guess
that peekable is more complicated
with caching and whatnot
oh, right
the juices of #esoteric-python leaking into here
indeed
missing a from __future__ import annotations
heh good catch
#internals-and-peps is just the demo version of #esoteric-python
sorry, I feel squicky when I see string annotations
come on, just a little bit of lambda calculus knowledge is required...
phew
https://repl.it/@maximum__/misc-junk#srl_utils/iterstuff.py the collection is growing
more-itertools -> even-more-itertools -> even-more-itertools-extras
iterstuff 😎
If you want I can add you to the esotericpython team on repl.it https://repl.it/team/esotericpython
nahh for real im not gonna mess with the esoteric stuff
im also gonna just sign up for my own paid account. they've earned my money
is using x &= y on bools instead of x = x and y considered bad style / hacky?
I find it readable but surprising
i found it here in some older code i wrote https://repl.it/@maximum__/misc-junk#srl_utils/logging_addenda.py
and i think my reaction was the same as yours
maybe ill rewrite with and
x and= y
one for the new parser? 👀
It's not very esoteric, actually. More like a place for small weird projects.
For example, repl.it has a discussion board 'in development' ™️ , so I'm planning to build my own discussion board, but with a tiny twist
https://discussionboard.esotericpython.repl.co/
https://repl.it/@esotericpython/discussionboard#server.clj
actually, in that context &= looks fine. I just forgot that some operations on bools return bools, not ints.
hm
if im a member of one team, i can also be members of other teams right?
what does being a team member imply?
you can edit the team's repls (and see its private .env files)
ah, ok
and create new ones
alright why not 😄
It's pretty buggy though, I wasn't able to add IFcoltransG for a while, and now they're in the team and have a pending invite
sent an invite
👍
i have so many repls... i gotta curate / delete them one day
keep the useful things and throw out the random one-offs i made to help people
this is veering into offtopic but the last thing i will say is... i wish repl.it supported filetype-specific editor settings. i saw your 4 space indents in the clojure code, im sorry for your loss
my loss?
Yep, It's a horrible transgression. I also put the closing parentheses in the wrong place
(I actually wrote the server in vscode, so I am to blame here)
allows using T in the class afaik
from __future__ import annotations import collections.abc from itertools import islice from typing import Generic, Iterable, Iterator, TypeVar, Union _T = TypeVar('_T') class IndexableIteratorWrapper(collections.abc.Iterator, Generic[_T]): self.iterator: Iterator[_T] def __init__(self, iterator: Iterable[_T]): self.iterator = iter(iterator) def __getitem__(self, subscript: Union[int, slice]) -> Iterator[_T]: return islice(self.iterator, subscript) def __iter__(self) -> IndexableIteratorWrapper[_T]: return self def __next__(self) -> _T: return next(self.iterator)like this i guess
@paper echo what does subclassingGeneric[_T]do?
class Test(Generic[T]):
def __init__(self, test: T) -> None:
self.test = test
def get_test(self) -> T:
return self.test``` basically binds T inside a class
test: Test[int] = Test(42)
result = test.get_test() # -> int```
Aren't TypeVar completely cosmetic?
What do they do?
well, indicate something of the same type
Guessing im revealing my lack of knowledge on typing
Usually it doesn't do anything at runtime. But it helps with type checking (and documenting methods) when using polymorphic containers.
class Pair(Generic[A, B]):
def __init__(self, left: A, right: B):
self.left = left
self.right = right
def f(p: Pair[int, str]):
x = p.right # x is inferred to be `str` (hopefully)
AnyStr = TypeVar("AnyStr", bytes, str) # this is actually typing.AnyStr, by the way
def concat(x: AnyStr, y: AnyStr) -> AnyStr:
return x + y
byte_string: bytes = concat(b"lemon", b"eivl") # fine
string: str = concat("joe", "ves")
concat(b"broken", "really") # error at runtime and in typechecker``` also this I guess
@grave jolt A and B are unusual typevar name choices, haha 
I think it makes sense when you have more than one parameter
A and B are typical from Haskell
or T1, T2, ..., TN, I have seen
at least I'm not using lowercase names 🙂
Wait so
and KT, VT for mappings, for example
mypy is the typechecker right?
yeah
its the original one
It's a typechecker
there are others now
what are the others?
pyre, pyright, pytypes
it's the deadly typechecker
why is it deadly?
I'm just using K and V for mappings
wait nvm pytypes is something else
they all are more or less equally strict and stupid
are they worth using?
pyright is better at type inference as far as I can tell
i use them all the time @swift imp
type checking helps catch an entire category of bugs that otherwise wouldnt be easy to catch
I feel like typed code looks better
that too
I think it does too
even with Any
yeah, just put Any everywhere so that it typecheks
This guy at worrk doesnt like it bc we primarily use Pandas and Pandas doesnt support it
but im just, well who cares if it doesnt
pandas does support it
Since when?
you just cant parameterize on colum/series names
Oh
@grave jolt just put # type: ignore on top of each file
True, thats what i mean
y: pd.Series = ...

and there is a 3rd party project working on it @swift imp https://github.com/predictive-analytics-lab/data-science-types/tree/master/pandas-stubs/core
I wish you could parameterize columns/dtype
but its mostly for numpy right now
Optional[Union[Callable[[], T], T]] gets hard to read tbh
Ive read through some of the Pandas issues, going back to 2018 they were talking about parameterizing . Wonder whats taking them so long
@cloud crypt i usually give types like that a name
yeah I do that if it repeats
@swift imp low motivation i guess? idk. you'd think that one of the big python data science shops would be invested in donating some dev time for it
Some type relationships are very hard or impossible to specify, so annotating the entire codebase might be too ambitious (especially if you use some magical frameworks)
eg. facebook developed pyre but isnt developing pandas type stubs? they must not use pandas internally
btw how do you declare your package as typed? add py.typed to package data?
i think so, i guess you have to include it in MANFEST.in as well?
yeah if you are using include_package_data, that is
what is the poetry equivalent of MANIFEST.in anyway?
when you say typed do you mean like you annotated everything?
or typing works for your stuff
mypy won't check a package that doesn't have the py.typed file in it
@paper echo something in pyproject.toml ig
ah and py.typed indicates how to check it?
God theres still so much to Python I have to learn...
okay is it fine if I have # type: ignore on top in 2 of my 80 files? haha
at some point you just gave up...
no, the existence of py.typed tells mypy to use the annotations in the package, when it's imported into another package
I was developing something similar to attrs in a way
and mypy went like fuck you, I don’t get it
and I said okay, happens to the best of us, and smashed # type: ignore in :p
Official documentation of Poetry
also on the topic of types, why wasnt namedtuple/NamedTuple included in pep 585?
id love to see NamedTuple moved to collections
with a DeprecationWarning for typing.NamedTuple
@swift imp no, because typing.NamedTuple is not used only for type checking but can actually be used to define namedtuples. therefore imo it never belonged in typing
as it is, it's an objectively more useful way to construct namedtuples, since it supports both the "functional" style and the new "declarative" style
it completely subsumes collections.namedtuple and i dont understand why it was added to typing and not collections
go ahead and leave collections.namedtuple as an alias of it
If you use setuptools, you must pass the option zip_safe=False to setup(), or mypy will not be able to find the installed package.
huh i didnt actually realize this about mypy
yeah thats pep 585
coming to python in 3.9
and i was hoping 585 would include something about namedtuples, but it doesnt
maybe that could be a pep of its own
make a pep then LOL
deprecate typing.NamedTuple, move it to collections.NamedTuple, and discourage future use of collections.namedtuple (but don't actually deprecate it)
ill post to the python discourse forum and see what people say
No they should deprecate collections.namedtuple only if because of what has become customary to naming classes
guido's stance on that historically has been "no"
thats why we still have logging.getLogger and datetime.datetime
i would love to see datetime.DateTime added as an alias for datetime.datetime
but actually deprecating datetime.datetime is unnecessary imo
I dont get it, if they deprecate it and give developers 5 years isnt that enough?
how hard is a god damn sed
its just an unnecessary backward compatibility break
theres python 3.3 code that still runs today
hell theres even some 2.6 code that still runs
i find it weird that their stance on it is very inconsistent in general
they are deprecating typing.List and other containers for example
and it will be deleted entirely 5 years after 3.9
i think it's ok because those are only used in relatively new code
and were only "popular" for a short time
well, yeah, but in 5 years it won't be
i think the idea is that it's not entrenched yet
and that people using typing are still willing guinea pigs to some extent
for contrast, look at asyncio, there are < 3 year old APIs that are already set in stone due to backward compatibility reasons
int, float, complex, bool, list, str, set, dict, frozenset, bytes, bytearray are also classes with lowercase names, will they be renamed? 👀
if you wanna get real weird, lets talk about why frozenset is a builtin
or why id is a builtin
you mean, not in collections?
yes
Yeah, id is weird
and id should be in inspect
or dis even...
the answer is definitely just "backward compat"
i'd rather we ditch is and keep id a builtin tbh
and from what i have seen of "old" python, like < 2.7, its a wonder anyone ever used this language at all for anything other than toy projects
is True reads better than == True to me
but thats because i'm a native english speaker
yeah
every other languages in existence do fine with == True, I'm sure we can live with that
== True
is can be confusing to beginners
when they are trying to use it to compare stuff
oh i know where i use is, i use it for checking singletons as created with boltons.typeutils.make_sentinel
is/id has some legitimate use-case, every mutable container needs it to handle cycles
yeah but as a binary operator baked into the language spec?
it's just not very common to implement containers
when they are trying to use it to compare stuff
Especially when they are native English speakers.
oh no, I definitely think is has no place in the language
i agree it was probably a poor choice of language design
especially if we have a function already
I really think they need a isa
now that would be nice
and I totally hate is
or if is was just isinstance(...)
isa for isinstance right ?
yes
is was so fucking confusing when i first started, especially bc it worked for strings
hmm, unsure about that
It definitely confuses people with small integers, too.
Javascript has instanceof as an operator.
that is way too long
I mean, it's definitely clearer than isa
I mean is a would benice but that couldnt work
And still shorter than isinstance. However, would it also support a tuple as its right operand?
why not?
it's ambiguous
if x isa (float, int):
# ...
elif x isa (bytes, str):
# ...
ah, i thought you were referring to the is a
That is ambiguous
It's not ambiguous, it would just make a not a usable variable name
it is 100% ambiguous
i dont like is a, too sql-ey
not to mention the fact that you don't want to make a a reserved keyword
@paper echo or maybe COBOL
heh yeah
how about istype
ah, well if we reserve a i guess it works, but that's a terrible idea
I just don't see the problem with isinstance ngl
yes reserving a is terrible
it just looks bad
instanceof is needed much less frequently than is, I think...
not in my experience
I disagree
i use isinstance tens times more than is
isinstance was found to be used quite a bit iirc, some code analysis that Guido did, like one of the most used
possibly hundreds
hm. I'm backing this up with a grep through the CPython codebase - isinstance seems to be used much, much less than is
SET VARIABLE a TO 1;
SET VARIABLE b TO 2;
WHILE CONDITION (b LESS THAN 1000) IS TRUE BEGIN CODE BLOCK
PRINT a;
PUT RVALUES b, a+b INTO LVALUES a, b;
END CODE BLOCK
what grep command did you use
also, is has a niche in containers, which the python stdlib is full of
to get relevant results, you'd need to verify all github repos imo
or most of them at least
Yeah, I don't think core is good example
rg --type py '\bisinstance\b' | grep -v '^[^:]*: *#' | wc -l
vs
rg --type py '\bis\b.*:' | grep -v '^[^:]*: *#' | wc -l
core is still relevant because core needs to do core things
Python is used a lot for making an ez to use interface or glueing stuff together. The repos are gonna show how most people are using it. I think anything thats acting as an API of sorts would use isinstance a shit ton
there's an extra filter on the is one to try to remove places where it's used in English prose, in docstrings. Even with that extra filter, it's used ~2x as often as isinstance
isinstance is pretty rare, I think... you need it in places where duck typing doesn't work, which is itself pretty rare...
i still stand by the idea that is is overused in the stdlib compared to other places
and isinstance is underused
⬆️
i wouldnt be surprised if that were true
again i think we can all agree that is(a, b) is better than a is b because the former doesn't require a special keyword
(yeah i'm just speculating, but really i would be surprised)
i just think we should use id(a) == id(b)
I like is as an infix operator because it's chainable
I wish I could find the source but I swear I read a pep of Guido doing a code analysis of Google and finding isinstance to be one of the most used things
a is b is c is d is ...
id(a) == id(b) == id(c) 
is is also faster than == because it can't be overloaded, so the interpreter doesn't spend any time finding the right implementation of __eq__
@boreal umbra that might also be true about is()
the speed difference is generally insignificant
where a function call lookup is slower than a hard coded binary operator
might be significant if implementing a low level container type @teal yacht
wouldn't list.__eq__ be O(n) but is would always be O(1)?
low level as in done in C ? because then it doesn't use either
id returns an int
not to mention it's trivial to optimize
let's see, does operator have is_?
well...
interesting
it's not trivial to optimize because id can be redefined
it is still trivial to find where it is not redefined
how would you do that?
I just checked a bunch of first party code my company has written and got pretty similar results. is is used more frequently in my codebases than isinstance is.
if there is no id = ... ?
or id in parameters
you can remove the optimization when a branch may redefine it
@teal yacht
# module.py
id = "spam"
# main.py
from module import *
def f():
return id(4)
yeah, that would be a case where there would be no optimization
so if you have a star import, it throws away an optimization? that's weird
I'd be in favor of removing id from builtins, but removing is seems like a terrible idea to me.
really is is used only for is None and is <bool> and these can be pretty much replaced by == is 99% of cases
Also, what about globals
messing with globals would also remove the optimization
It's also used for is (some singleton)
@teal yacht How would you know that you're messing with globals? 🙂
if the code invokes globals() as some point
Ive never used a singleton other than the builtins
really you're just pointing out all bad practices in python
allowing these are part of why python is so slow, there's no assumption you can make in all cases
Ive never used a singleton other than the builtins
@swift impenum.Enum?
Well, doing such optimization would break backwards compatibility, even if no reasonable person would redefine id in globals
what does that have to do with backward compat 🤔
according to the language semantics as they are now, this optimization should be impossible because there's a million ways to redefine id without it being detectable by a static checker
it's just a part of python and yes, it makes it slow
I'm not saying the optimization will trigger most of the time
But it's definitely something that's doable, you could argue it's not useful because it will be disabled in most cases however
well, the user of a module can redefine that module's globals
# module.py
def f():
print(id(4))
# main.py
import module
module.id = "spam"
outside of that, there's fun stuff like
def f():
lo = "lo"
exec(f"g{lo}bals()['id']='spam'")
right i didn't think of the redefining from external sources
but yeah, eval/exec would also disable it
literally #esoteric-python
thank you for reminding me why i barely tolerate the language 🙃
I sometimes do javascript just to remind myself that it could be worse 😄
...and my favourite
import asyncio
async def daemon():
global id
n = 1
while True:
if not (await collatz_conjecture_is_right_for(n)):
id = "spam"
n += 1
await asyncio.sleep(0.0000001)
async def other_task():
while True:
print(id(4))
await asyncio.sleep(0.1)
async def main():
await asyncio.gather(other_task(), daemon())
asyncio.run(main())
pretty hard to prove whether it will redefine id
you don't have to prove that it will redefine
well, yes, if global id is used anywhere, disabling the optimization is totally reasonable
I wonder if removing ~50% of the stuff from builtins could ever be possible... Most of that stuff doesn't belong, but it's hard to see a way for the benefit of removing rarely used builtins to outweigh the backwards incompatibility issues it would cause...
you just have to prove that it may redefine it, if there is any branch that can redefine it, it would not do any optimization
a lot of the builtins have no place imo i agree
the cost of that check might outweigh the benefit of the optimization.
but the optimization would be at compile time
but your example modifying from an external module basically put it in the trash dw
maybe there will be another breaking release that will just cut out most of the stdlib
this conversation reminds me of https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#Cython.Compiler.Options.cache_builtins
in order to get some of its performance benefits, Cython defaults to assuming that builtins cannot be redefined.
(after the point where the Cython extension module is first imported)
Figured this was more suited to advanced rather then getting buried in general:
This conversation can get a bit off topic so ima try to keep it about Python. I want to make a simple andriod app that will detect objects with my phone. Is it worth using something like Kivy for making the app using python or will that be more of a headache then just getting used to Java again (last time I really used Java was in HS and a bit in College)? I've done object recognition with python before in University so that would be a good headstart, I'll just have to learn how to train my own classifier. I dont keep discord open so feel free to @ me as I put more research into the answer.
hi everyone, had a doubt regarding static methods. Should i call static methods using the instance of a class or directly using the class name?.
!e
class Test:
@staticmethod
def staticmethod():
print(hey)
def callmethod(self):
# calling using instance
self.staticmethod()
# or
# calling using class
Test.staticmethod()
test = Test()
test.callmethod()
Is there any diff in either methods?
which one is more pythonic?
the former IMO
the point of a static method is that it belongs to a class, not an instance
oh
I was looking at your code
and Test.staticmethod() was first
yeah, that's what I meant
okay cool thanks @gleaming rover
wow looks... very "techy"
The most Pythonic approach is not to use @staticmethod at all.
Guido has said that he regrets adding it to the language, and that it was only added because he misunderstood the problem that he was trying to solve
The most Pythonic approach is not to use
@staticmethodat all.
@raven ridge so whats the best alternative. just remove thesaticmethoddecorator?
no, make it a function, not part of a class.
damn hella staff on this server XD
a "method" that has nothing to do with the class shouldn't be a part of the class
but what if the method is related to the class and it will be easier to understand if written inside the class?
no, make it a function, not part of a class.
@raven ridge
it will not be.
if i write an employee class and have a method that calculates the total pay wont it be better to write it inside the class than as a separate function outside.
no, it won't that's what I'm saying.
the very fact that it is not so closely related to the class that it needs access to instance data, class data, instance methods, or class methods means that putting it into the class makes it harder to read.
if it does need access to some of those things, then it should either be an instance method or a class method.
is there any advantage in using class method over static?
inheritance works correctly with them
they do different things. A class method gets a reference to the class that it's called on - you'll want a class method if you want to create instances, or access class attributes, or call class methods. It will be able to know whether it's called on a parent class or subclass.
but what if my method doesn;t access any class of instance values? wont static be the best choice?
a static method is a function in disguise. It doesn't have access to an instance, or to the class of an instance. The only thing that makes it a method is that it lives inside a class - and because it doesn't play nicely with subclassing, that's not a useful place for it to be.
no.
so static method can mess with inheritance ?
did not know that. I will do some research on that
they simply don't participate in inheritance, in the same way as a function that's outside the class entirely doesn't.
I'm not making this up on the fly - the general guidance is that if you need access to an instance, you should be an instance method. If you need access to the class (for instance, to construct instances or to call other class methods), you should be a class method. If you need neither of those things, you should be a function.
that makes sense.
I'm not making this up on the fly - the general guidance is that if you need access to an instance, you should be an instance method. If you need access to the class (for instance, to construct instances or to call other class methods), you should be a class method. If you need neither of those things, you should be a function.
@raven ridge
they simply don't participate in inheritance, in the same way as a function that's outside the class entirely doesn't.
To be clear - they can be called on the parent class or on the subclass, but they can't be usefully overridden in subclasses, since you'll get a different version of the function depending on which class you call it on - which means it actually does depend on the class, but it can't figure out which class it was called on.
the very fact that it is not so closely related to the class that it needs access to instance data, class data, instance methods, or class methods means that putting it into the class makes it harder to read.
debatable honestly
debatable, yes, but has been debated, and is the consensus opinion of the Python community, and the question was about what's Pythonic.
fair, but let's say for example you have a django model and a service class that basically interacts with the model in various ways
it makes sense for those functions in the service layer to be static, they're nicely encapsulated in the class as service methods, but need not be on the model itself
they can be as model methods, but that results in fat models, which i'd argue makes them less readable and clunked up
Why couldn't they just be global functions in the module that defines the model?
you said making them model methods makes them fat models, and you also said that making them global functions in the model's module makes them fat models - which is it?
oh mybad, misread
the former makes them fat, the latter kinda serves the same functions as static methods in a class though, but in a static method you can at least clump them togheter to make it easily known what you want
for example if you have 3 service classes, each with their own part in busienss logic
the Python primitive for namespacing stuff is modules
you imediately know what they do, depending on which service class they belong to
you could also make 3 modules sure 🤷♂️
but im arguing you are doing the same thing in a different format
yes - exactly!
both are viable, but you can't just discard the other
sure you can 😛
😄
if there are two approaches that can be used to accomplish exactly the same thing, it's reasonable for one of them to be the canonical way to do that thing.
str(x) and type(x).__str__(x) do exactly the same thing, but we only recommend one of them.
fair, but do you need 3 modules, when you can have a module representing business logic with 3 seperate classes being responsible for their own part in that logic
i mean fair, you can make a package handling that logic, and making 3 seperate modules for it
maybe you convinced me, im not sure yet 😄
if there are two approaches that can be used to accomplish exactly the same thing, it's reasonable for one of them to be the canonical way to do that thing.
@raven ridge i definitely agree with that, but im not sure this is a case where one is canonical and the other isn't
apparently based on the python community, it is 🤷♂️
str(x)andtype(x).__str__(x)do exactly the same thing, but we only recommend one of them.
@raven ridge I was told that there's a subtle difference (which I don't remember of course, I'm à dumb dumb), but I don't think it matters in this case
hm - if there is one I can't currently think of it, but maybe.
"A foolish consistency is the hobgoblin of little minds" - it's entirely possible that there are some cases where static methods improve readability and where class methods aren't a more correct substitute. I accept that such cases might exist, but I can't think of any.
!zen 12
There should be one-- and preferably only one --obvious way to do it.
I doubt, refer to the zen 
honestly i'd prefer less files and more classes - just for keeping the namespace tidy if not for anythign else, a stupid reason or not 😛
but you definitely made me think about it more
using classes for namespacing isn't the canonical way to do namespacing in Python - modules are.
Kotlin made me change my mind about having too many imports haha
as opposed to Java, for instance, where classes are the canonical way of doing namespacing.
again ..true
maybe you convinced me
Didn't know staticmethod were frowned upon though
🤷♂️ - you know both ways now. Try writing things using global functions instead of static methods going forward, and see if you ever hit a problem where you think that the static method would be a better option.
I'm betting you won't - but if you do I'll be curious to hear about it 🙂
👍
ah, now i see why i was hardwired for this
at work we use this intermediate service layer as classes instead of as modules
it's clean, but not canonical as you put it
now i get it 😄
backwards compatibility, that's one reason to do it 🤷♂️
but yea, otherwise then that, i really don't see how a static function could do something a module global function couldn't
In terms of best practice, if I want to populate a list with a function, is it better to pass an empty list as a function argument and append or make my function return the populated list?
In terms of best practice, if I want to populate a list with a function, is it better to pass an empty list as a function argument and append or make my function return the populated list?
@somber python the latter IMO
the former is a very C thing to do
how about yielding and unpacking ?
If it's a finite list that can be cheaply precomputed, there's no reason to create a generator, I think.
Generators are good if computing each element is expensive and you don't want to store it all in memory at the same time.
@civic dune If you're looking for a dedicated channel for a help conversation, check out our help channels. You can claim one for yourself. See #❓|how-to-get-help.
will do, capitan!
Hello, this channel is meant to discuss the Python programming language itself, from a higher-level perspective. Think of things like the future of the language, PEPs, the advanced language concepts, new releases, and so on. It's not for help questions.
This the topic of the channel:
Many people advanced in Python, also know Javascipt, that is why I asked here
My point is that this is specifically meant as a discussion channel to discuss the Python programming language itself. We have up to 32 help channels and several topical channels for other conversations (in addition to #python-discussion), but we do try to have at least one place on the server where more advanced discussions of Python itself is the topic.
Sure, my intention wasn't to offend anyone.
No offense taken, I'm just trying to explain why we're stricter about the "on topic" rule in this specific channel. It appears to be difficult to give such conversations a home, but we try.
Noted! I'll ask in general now.
@brazen jacinth I am against fat models because it makes code less isolated and harder to reason about and delete.
yea agree, that's why we use a intermediary service layer
Can somone help me with auto-py-to-exe
I feel like this is the right channel for this question: What is the difference between is and ==?
one checks for identity, the other for equality,
What do you mean?
>>> a = [1,2,3]
>>> b = [1,2,3]
>>> a is b
False
>>> a == b
True
>>> a = b
>>> a is b
True
>>>
== invokes the __eq__ special method on the objects which returns a bool depending on their equality from values, is compares if they are the exact same object
Which is why singletons like None work so well when using is
Because there's only ever one instance of it
@full jay What's a singleton?
Essentially an object that you can only ever have one of
All references point to that one object
so, technically are digits from -5 to 255 singletons?
I think so but that's an implementation detail rather than a language specification
true
All references point to that one object
@full jay Ohhh ok, that makes sense, thank you.
AES algorithm in python
I want to make a secure communication app so this is important for me
then use tried and tested tools for encrpytion and you'll be fine
I think so but that's an implementation detail rather than a language specification
@full jay aren't you not supposed to useisbetween integers, even if they're both non literals?
I think I remember reading that it's never guaranteed that an integer will be a specific memory location.
comparing integers by identity will definitely leave suprises if you don't know the implemntation specs
yeah, that's why it's an implementation detail
it happens to work for that set of common integers in CPython
still intrigued why the -5
I'm thinking
a = b = 450635863
It should always work for the cached ints, but you shouldn't rely on implementation details and if it goes out of the range you won't get the desired behaviour
My understanding is that a is b isn't guaranteed here.
It should be
in this example it will be
You only evaluate the int expression once, and the result of that is assigned to both a and b
in general, that implies to most imutables, right?
wait, brainfart, not imutables
objects in general 🤷♂️
isnt a is b more like a===b?
Immutable literals will be the same objects as they're constants during compilation, but anything created dynamically that isn't some sort of a special value or interned manually will be a separate object
if you mean by types, no
what do you mean by ===?
ye i got confused
=== is a hack that was put into JS because == did too much coercion.
php has it aswell iirc
== checks for equality of values (e.g. "hello" == "".join("he", "llo")
is checks that two objects are actually the same object (checks the equality of identity).
but is is more like pointing to the same adress of the value?
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
001 | True
002 | False
basically
id(x) == id(y)
a is b implies id(a) == id(b)
just wanted to refresh it
...and in CPython id actually stores the address of the object
@full jay aren't you not supposed to use
isbetween integers, even if they're both non literals?
@boreal umbra Right that was partly my point
@brazen jacinth I don't see how a service layer helps in principle. You can still end up with tons of single use functions int he service layer for example. Or almost the same functionality because the layer is too bloated to reuse.
what do you propose as a replacement
Thats why you make reusable components in the service layer though
But id be happy to hear of any alternatives
My primary defense is to keep code as far out to the leaves in the tree as possible (views in this case). Only after you know you need the code in multiple places you move it up.
The thin views camp moves things to the trunk (models or service layer) for everything always.
I prefer having a service layer or similar to polluting the models, but that's orthogonal.
Not polluting the models is more about keeping separete that which is different.
Wow
so basically, no replacement?
you gotta have it one way or the other 🤷♂️
but yea, agreed, no need to abstract untill there is reason for it
rather duplicate than incorrectly abstract
s a n s i o
@paper echo when u gonna release a kustom fork for sansio bro

jane v2 fork... when...
lets move this to #ot0-psvm’s-eternal-disapproval
Hello friends, Could someone create a Discord Bot that can send messages and has a ReactionRoles function and do that so that he can also send pictures. If yes please send me a dm thank you
@unkempt rock I would ask in #discord-bots; we try to keep this channel especially on topic.
why dont type hints support unpacking? is it because its new and there are bigger fish to fry or is there a fundamental reason
well, the type is already known form the tuple you are unpacking
i mean like x, y: int