#internals-and-peps
1 messages · Page 60 of 1
But yes I still like __all__ for indicating "use this"
That said i dont mind using underscores for typevars, its less about cluttering the namespace for imports and more about being visually distinct
What do you do if you're in a generator and you realize you can't yeild anything from that iteration?
Can you just do a blank yeild?
Or yield
I can never remember the order of the e and i
if you just do yield it is the same as yield None
Damn
well, if you yield there has to be some value. You could just do continue and go to the next iteration perhaps
Would be nice if you could somehow pull the next item that the caller would have given you
you can send to generators
https://github.com/swfarnsworth/pseudobert/blob/master/create_rels.py, you don't have to look at it though
whenever i see something like this:
for token in arg1_topk_tokens:
new_sent = text[:arg1_start] + token + text[arg1_end:]
new_arg1 = copy(rel.arg1)
new_arg1.spans = [(arg1_start, arg1_start + len(token))]
new_arg1.mention = token
new_offset = len(token) - len(rel.arg1.mention)
new_arg2 = copy(rel.arg2)
new_arg2.spans = [(arg2_start + new_offset, arg2_end + new_offset)]
new_rel = brat_data.Relation(rel.relation, new_arg1, new_arg2)
yield PseudoSentence(new_rel, new_sent)
for token in arg2_topk_tokens:
new_sent = text[:arg2_start] + token + text[arg2_end:]
new_arg2 = copy(rel.arg2)
new_arg2.spans = [(arg1_start, arg1_start + len(token))]
new_arg2.mention = token
new_offset = len(token) - len(rel.arg2.mention)
new_arg1 = copy(rel.arg1)
new_arg1.spans = [(arg2_start + new_offset, arg2_end + new_offset)]
new_rel = brat_data.Relation(rel.relation, new_arg1, new_arg2)
yield PseudoSentence(new_rel, new_sent)
i immediately want to shrink it -- repeated code
is that where you want to skip something or from the yield from
See new_sent? If the word represented by token is the wrong part of speech then I can't use it.
So there could potentially be nothing to yield in a given call
do you want to check PseudoSentence?
if yielded_something := PseudoSentenct(...)
yield yielded_something
might need a __bool__ method on PsuedoSentence then i guess
I think it would be True by default
yes, by default
It's a dataclass
you can add a __bool__ method though
can even use filter with None as first argument
Also the yield from statement wasn't working as expected
ever used .send for a non-coroutine?
If you yield from another generator, isn't that the same as yielding each of the items it generates individually, so that you just have one stream
Never used it at all.
i used it when iterating over ordered ranges
def replace_least_upper(self_set, other_set):
"""A helper iterator for the __and__, __or__, and __xor__ methods of RangeSet, this will call next
on the correct RangeSet iterator (the one that last yielded the range with the least `upper` bound).
This incurs some overhead, as we repeat comparisons, but it hopefully makes RangeSet dunders easier to
follow.
"""
self_ranges = iter(self_set)
other_ranges = iter(other_set)
self_range = next(self_ranges, None)
other_range = next(other_ranges, None)
carry_over = yield self_range, other_range
while self_range and other_range:
if self_range.upper == other_range.upper:
self_range = next(self_ranges, None)
other_range = next(other_ranges, None)
elif self_range.upper < other_range.upper:
self_range = next(self_ranges, None)
if carry_over:
other_range = carry_over
yield
else:
other_range = next(other_ranges, None)
if carry_over:
self_range = carry_over
yield
carry_over = yield self_range, other_range # send range that needs to be carried
if self_range:
yield self_range
yield from self_ranges
elif other_range:
yield other_range
yield from other_ranges
I have to step out but I'll take a look at this 👍
Is there a reason why python doesn’t support tail call optimization? Most of the reasons I read are, “well, it’s my pythonic to do for or while loops instead of recursion.” To be honest, that seems like a lazy response.
Third, I don't believe in recursion as the basis of all programming. This is a fundamental belief of certain computer scientists, especially those who love Scheme and like to teach programming by starting with a "cons" cell and recursion. But to me, seeing recursion as the basis of everything else is just a nice theoretical approach to fundamental mathematics (turtles all the way down), not a day-to-day tool.
Although recursion is useful sometimes. One of my favourite tail-recursive functions is the basic regex matcher from K&R.
Oh. It’s not appropriate for all use cases. But there are times where it does the trick.
True.
Although, funnily enough, the C compiler doesn't eliminate tail recursion there
Great article! Thank you.
I was worried when the short answer was “it’s not pythonic”, but it won me over after that.
I myself don't really like this term. It's like shutting down the argument by calling someone an *-ist. But sometimes it is appropriate
rhettinger shows a good example in this talk: https://www.youtube.com/watch?v=wf-BqAjZb8M
TL;DW: even though a piece of code complies with PEP8, it's a clumsy interface that can utilize some features of python; so it's better to write a wrapper and unjava that library
I was doing some heavy computation work in computer vision for my old company, and there was a function that has recursion based. Every alternative couldn’t deliver the performance not accuracy we wanted. In a perfect world (with no deadlines), I would have found an alternative solution. But given the deadline, I left that code in.
I’ve just been thinking about that code lately and how “un-pythonic” it was, and tryin to reconcile what I know now. I was a super junior dev who learned Python by a lot of code camps and what not where things were simple. OOP code was the way to go and the only way to go. However, as a more experienced dev who has seen more stuff, I’ve come to appreciate the approaches that are “not pythonic.” I’ve at least learned some interesting tricks.
haskell is not very pythonic, and I love it for some of that
Yeah. I get that! I’ve just done a lot of thinking back on my journey with Python. Currently interested in Functional programming (my current job is doing a lot of ETL pipelines concurrently, and hoe to run all these jobs efficiently and utilize parallelism), and taking what I have learned and apply it to Python.
I am personally happy about the pep about pattern matching. I’ve seen it in other languages, and I think it’s super cool. But, a large (at least the loudest) dissent to that pep is that it’s “not pythonic”.
^I would claim a help channel.
@oak stirrup This is not a help channel, please read the channel description. Check out #❓|how-to-get-help
okay thank you
i was super interested in the pattern matching pep but was disappointed the matches aren't block scoped and that it's not an expression. i guess that's consistent with python though
I’ve heard that criticism too. And it’s very valid. I definitely see those benefits.
like it feels really gross to me that matches conditionally bind and leak passed the pattern match
seems like list comprehension variables leaking all over again
!e
e = 1
try:
1/0
except Exception as e:
pass
print(e)
@grave jolt :x: Your eval job has completed with return code 1.
001 | Traceback (most recent call last):
002 | File "<string>", line 6, in <module>
003 | NameError: name 'e' is not defined
Oof.
specifically i think this is a mistake
match greeting:
case "":
print("Hello!")
case name:
print(f"Hi {name}!")
if name == "Santa": # <-- might raise UnboundLocalError
... # but works fine if greeting was not empty
Weird.
@torpid narwhal If you're interested in non-pythonic ways of doing things I recommend taking a look at data-oriented programming and composition over inheritance
Basically, check out Rust lol
I like...how bold it is. I don’t mind switch statements (many articles on dev.to are all about hating them), but I don’t think that’s powerful enough for it to be added to python. But pattern matching seems very powerful and bold. I like that though process of thinking about more bold things.
The data oriented part is cool. I try to not do inheritance.
without being an expression i'm curious how useful these will be in practice
It does composition instead
!e
# PEP8 thrown out of the window for compactness
class LinkedList:
def __init__(self, value, rest):
self.value, self.rest = value, rest
@staticmethod
def from_iterable(iterable):
acc = None
for x in iterable: acc = LinkedList(x, rest=acc)
return acc
def my_sum(list_, default=0):
if not list_:
return ("return", default)
return ("call", list_.rest, default + list_.value)
def tail_call(f, *args):
command, *args = ("call", *args)
while command != "return": command, *args = f(*args)
return args[0]
ll = LinkedList.from_iterable(range(3000))
print(tail_call(my_sum, ll))
i guess you can just wrap the match in a function with returns to make it act like an expression
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
4498500
Actually, tail-recursive functions might play nicely with the async world.
If you have a tail-recursive function, you can make it less blocking by awaiting on each step.
So you can run a few of them concurrently.
I remember how I reinvented coroutines while making a game in Python. My enemies used A* for pathfinding, and running it for multiple enemies at the same time was expensive. So I made the algorithm yield on each step. This way I was able to control how fast the pathfinding is happening. I actually turned it into a feature: more 'intelligent' enemies were finding the path to you faster.
so if you do
async def tail_call(f, *args):
command, *args = ("call", *args)
while command != "return":
await asyncio.sleep(0)
command, *args = f(*args)
return args[0]
your blocking tail-recursive function is now automagically not so blocking
@torpid narwhal I'm filing a DMCA complaint 👀
whats the difference between repr and str__
https://stackoverflow.com/a/2626364 has a really good explanation
It's an entirely fair point that debuggers are only handy for failures you can reproduce, and that logging allows you to diagnose errors that happen sporadically or under unknown conditions
that part isnt wrong, the "i dont know how to use one and dont use one"
is the problem
yeah.... that's not ideal, heh
How often is a failure truly non reproducible?
oh, rarely, but it's really common that a failure has occurred and you haven't yet figured out how to reproduce it yourself.
logging is great lol, its a necessity
logging and debugging solve two different problems imo
I don't use a debugger and don't know how to use the big ones for Python. I remember using them for C# and VBA when I was in school. Not gonna lie, python is pretty well designed to get yourself out of jams. print statements and logging can get you a lot of the way there. And, I find python exceptions to be pretty good. (I get more annoyed when I deal with extensions compiled in C, but thats another story.) For 80-85% of my use case, I have never felt like I needed a debugger.
And the times I do, I feel like I can get there with other means. Oh...I love ipython3 (ipython > python's built in repl). Load up the code that is iffy and walk through it there.
man not using the debugger in c# code sounds like a 7th layer of hell
but fr, learn the debugger
it is your friend
prints dont really help you when stdout is flying by anyway
i dont understand the aversion to debugging, its literally pausing your code and reading variables, the same thing that prints do. just way faster and easier
Its more or less not an aversion to it, than learning something new that might improve my efficiency for a few use cases when I can do other things that get me there.
it will 100% improve your effeciency
print statements cant come close to inspecting an entire objects nested structure
I am not saying I will never use one. But, I haven't personally found a situation where I was so stumped where I needed to take time out of my schedule to learn it.
i mean if your just writing scripts then ya i get that. but for any program debugging is going to be invaluable
I do it all the time. Even to just pick through Class returns
I am open to it, and I will keep it on the table. But, I can get buy with simple stuff.
i debug constantly, its so much easier to read all the objects
Really, as long as I use the logger and print the line and class/func name, I get where I need to go.
tbh alot of the bugs i fix now woudnt really be possible with print statemnets
I am glad that workflow works for you.
just for sure learn the debugger at some point, its quite literalyl walking through your code line by line
If you use the breakpoint() call in your code to drop into the debugger at a particular point, the only commands you need to know are p to print stuff and c to continue execution.
It's not a ton to learn
i dont understand the aversion to debugging, its literally pausing your code and reading variables, the same thing that prints do. just way faster and easier
@narrow kettle same logic as manual testing instead of writing tests IMO
How do you append to the docstring of a module
@gleaming rover i KINDA get that cuz writing tests is boring and time consuming, the debugger is LITERALLY both faster and more comprehensive then print statements
Oh so module is a thing in the module
no
For me....its just so low on the stack of things to read/learn that I have never gotten around to it.
module is a reference to the module
i mean you could learn it in about 5 mins @torpid narwhal its literally just set a breakpoint and click run, the mouse over variables
thats it
How do you append to the docstring of a module
@swift imp maybe you wanna tell us more about your problem
way faster then writing a print statement then searching through std out for that print
I don't print much to std out. Since, that isn't a realistic problem for me.
i mean you dont even have to look through your logs
its instant, its quite literally the simplest thing you could imagine
Basically I have a bunch of int sub classes for constants, so that they have doc strings and I want to append each of those doc strings to the module docstring at the end of module so that they show up in help()
Rather than me typing out the same doc string twice
Get what I'm saying?
Basically I have a bunch of int sub classes for constants, so that they have doc strings and I want to append each of those doc strings to the module docstring at the end of module so that they show up in
help()
@swift imp yeah, just__doc__
an object's __doc__ attribute holds its docstring
But is __doc__ in the namespace of the module ?
perform whatever preprocessing you think is necessary in the module itself, then just assign the result to __doc__
...yes?
I wasn't sure if you had to access it through like vars() or something
I've never done it before
So at the module level module.__doc__, cool, thanks
no, just __doc__
Oh
because it is an attribute of the module itself
Even bettet
just like if you wanted to have a module attribute some_attribute in a module my_module, in my_module.py you would execute some_attribute = 1, not my_module.some_attribute = 1
yeah. I was a bit confused on where you wanted to access it. But, its pretty simple.
What do you mean?
At least with respect to help but I understand why variables don't have doc strings
huh
Like you can't add a docstring to a variable and have it show up in help()
I wish you could
But they're special constants
i dont follow
you just said a bunch of stuff that doesnt make sense in context lol
Like at work we literally have a module of conversion factors , and special constants, think like accerlation of gravity or km/s to knots
I think the point is more that
those aren't really what one would normally understand as "singletons"
Well I've pretty much made a Singleton
is it a class?
Class
Just to encapsulate that constant and it has a docstring
is that what your saying?
Yes
Well I've pretty much made a Singleton
@swift imp but why?
Yeah but then you have to use a dot access
Bc I want it to act like a float or int
I don't want to have to access it through dot access
I don't think I'm explaining myself clearly
Yeah but then you have to use a dot access
you have to do this for the variables anyway
usage wise a property would change nothing
you would consume the class in exactly the same way
i dont fully understand what you are saying, if its a class you have to do .constant anyway
No you don't
...yes oyu do
show an example
^
something feels weird about this
I feel like words are being used in ways that do not comport with their commonplace meanings
@unkempt rock try a help channel.
this isnt a help channel @unkempt rock check out #❓|how-to-get-help
Except I'm hardcoding the value in __new__
so basically you're saying something like from module import ConversionFactor and then ConversionFactor() * some_value?
It's not exactly a Singleton but pretty much
so... it's a singleton instance of some class?
It's almost, pretty much
why not just add the doc string to the class then?
class FloatWithUnit(float):
def __new__(cls, val, unit):
return float.__new__(cls, val)
def __init__(self, val, unit):
self.unit = unit
def __str__(self):
return '%g %s' % (self, self.unit)
def __repr__(self):
return self.__str__()
foo = FloatWithUnit(..)
^ you want the docstring on this?
but at that point what you have is an instance, and an instance doesn't have a docstring.
is that what your saying?
a class has a docstring, but once you've called the class to instantiate it, you've got an instance, and if you keep the instance around but not the class you've thrown your docstring away.
Sphinx lets you document globals and attributes, though, even though they can't have docstrings.
But since I have like 20 of these classes, the doc string of the module is really long, since they're subclass of float, I want the data info at the top of the help. Hence I want to iterate over all the classes in the module and programmatically append their docstring to the module docstring
more accurately, string literals occurring after top-level assignments are termed "attribute docstrings" and not recognised by the Python compiler
but may be used by third-party tools
yes, just add to __doc__
Hence I want to iterate over all the classes in the module and programmatically append their docstring to the module docstring
you can do that, though depending on which tool you're using it's entirely possible that it won't be able to deal with the non-constant__doc__. It might show up inhelp(), but other tools may not be able to find it.
depends how they work, and whether they execute the code or merely parse it.
I would hope spinx executes it
it does not.
Well that sucks
well, actually - scratch that, it deends.
Stack overflow says it does
sphinx autodoc does import the module, so whatever you do at import time should be reflected.
Cool
So then it will work
I figured as long as I don't do it inside function calls or methods it would work
though again - sphinx autodoc supports docs on global variables, too
so your hack to get it into the module's __doc__ is unnecessary if it's Sphinx that you're worried about.
No it's help
It's alphabetized so Data section comes after Classes
And I have a butt load of float subclasses
So you have to scroll super far down to see the constants
I want them at the top
help isn't very heavily used.
I use it all the time
modifying __doc__ will be reflected by it, but most people will never, ever run it. 🙂
I mean, that's cool, and I'm not telling you not to, and if it's for you that's fine. I'm just saying that most people don't use it, or even know it exists.
I should also note, I work on a system not connected to the internet
So it's faster than going over to a different station that has internet
Now that I'm thinking about it
even on a system like that I'd sooner use Sphinx and http.server - but, shrug
Would I be able to generate pandas documentation
Like the html
Bc we have Firefox to browse html
yep
actually, shouldn't even need http.server, you can just use ff with a file:// URL
looks like it's just clone the repo, and make doc
Oh so if I have the package through say anaconda, I can't make it?
not completely, no - there's stuff that goes into the docs that isn't in the code. see https://github.com/pandas-dev/pandas/tree/master/doc/source/user_guide
The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.
!e
async def main():
await ~f
@grave jolt :x: Your eval job has completed with return code 1.
001 | File "<string>", line 2
002 | await ~f
003 | ^
004 | SyntaxError: invalid syntax
@grave jolt :warning: Your eval job has completed with return code 0.
[No output]
but this works
does await bind harder than ~?
await probably has higher precedence, yeah
but return ~f works
return isn't an operator
true
lambda ~f works, but that's because lambda is low pref
You win, JS
The power operator binds more tightly than unary operators on its left; it binds less tightly than unary operators on its right., this is weird
It makes sense, but still wierd
means -4**3 is -64, but 4**-1 is -4
#python-discussion or a help channel would be more appropriate
@torpid bridge neither of those examples is correct. You'd need to do 4^0. 25 to get root 2 out. AFAIK it behaves the same way you'd expect ^ to in normal maths
Yeah, that's confusing
@slim island 4**0.5 is 2.0. Because, well, that's what the square root of 4 is.
Yeah. I realised and changed it
ah, bleh
Let's get into imaginary numbers!
4**-4 is 1/(4**4)=0.00390625, though, yeah.
fixed
4**-3 isn't sqrt(2) either 😛
I was about to say
N^-K is the same as 1/(n^k)
>>> 4** (1/3)
1.5874010519681994
In [64]: 1.5874010519681994**2
Out[64]: 2.519842099789746
oh, bleh
It's okay, life math is hell
yeah ._.
You've got the cube root
I should just use !e next time
I did have to go to bot commands to make sure I understood correctly myself
im following Automate the boring stuff with python course he wrote this program so i copied it and it says this
@unkempt rock you'd be better served asking in a help channel via #❓|how-to-get-help . This channel is for more advanced discussion relating to the python language itself
ok
@unkempt rock You are missing a closing parenthesis ) at the end. If you have some quick question, you can also ask in #python-discussion, although you might be buried in the traffic
yay it works now
hellp
class foodAd:
def__init__(self,tybef='VitaminC',helpWith=["CoronaVirus"]):
self.__tybe=tybef
self.__helpWith=helpWith
def__str__(self):
return('Use'+self.__tybe+'to help with'+ str(self.__helpWith))
def addHelp(self,malady):
self.__helpWith.append(malady)
a=foodAd()
a.addHelp('Cpld')
print(a)
this code
the output is error
because of the a???
this isn't a help channel; see #❓|how-to-get-help
Just wanted to throw a quick idea
from typing_extensions import TypedDict as D
SqlParam = Union[Dict[str, Any], Tuple[Any, ...], D]
Q = TypeVar("Q", bound=SqlParam)
U = TypeVar("U", bound=Optional[tuple])
class Query(str, Generic[Q, U]): pass
GET_USER = Query[Tuple[str], Tuple[int]]("SELECT uid FROM users WHERE name=%s")
GET_NAME = Query[D("", {"uid": int}), Tuple[str]]("SELECT name FROM users WHERE uid=%(uid)s")
def do_stuff(q: Query[Q, U], arg: U) -> U:
...
wouldnt that be harder than just making a set of constant queries
What do you mean?
The queries are constant.
It's just that the linter is able to ensure that you're passing the correct parameters in the correct order.
Or perform type inference and infer the return type from the query you're using
So this will typecheck:
(user_uid,) = do_stuff(GET_USER, ("alice",))
(name,) = do_stuff(GET_NAME, {"uid": 42})
(and in addition user_uid and name are inferred to be int and str respectively)
and this won't:
(user_uid,) = do_stuff(GET_USER, (111,))
(name,) = do_stuff(GET_NAME, {"uid": "bob"})
apparently this:```py
def file_paths(directory, match_string, extension):
for root, sub_dirs, files in os.walk(directory):
for file in files:
if fnmatch.fnmatch(file, f"{match_string}.{extension}"):
yield os.path.join(root, file)
is faster than this:```py
def files(directory, extension, keyword=""):
for file_path in glob.iglob(f"{directory}\\**\\*{keyword}*.{extension}", recursive=True):
yield file_path
0.0027390999999999943
0.0016957000000000083
are the respective times
makes sense to me
why
iglob is powerful but not necessarily as fast as fnmatch
oh so fnmatch is pulling the speed here?
wait it's the other way around... okay, I'm confused too
cuz os is a big lib
Idk if that's the issue
Python doesn't really care about the size of a package a function comes from
i used this to time it:
start_time = time.perf_counter()
# run your code
end_time = time.perf_counter()
print(end_time-start_time)
that's very inaccurate
??
single run, no way to tell what part of that is random variation.
do those few ms matter, or is this mostly education?
education
there's a reason timeit does many runs and averages the results.
true, but probably still not that inaccurate
0.0027390999999999943
0.0016957000000000083
those look pretty accurate to me tho
Still bad idea to only run it once
iglob uses fnmatch and os.listdir underneath anyway
wait iglob does?
yea, you can't tell how accurate it is by looking at those numbers
those look pretty accurate to me tho
😩
precise measurement is a complex subject
Suppose I measure something roughly and it's around 3 seconds. If I write this number as 3.000000, does that mean the measurement has suddenly gotten more accurate?
what about 3.00000000000000000000000004 😋
In [33]: %timeit all(file_paths_walk('.SpaceVim', '', '.vim'))
28.3 ms ± 891 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [34]: %timeit all(files('.SpaceVim', '', '.vim'))
27.2 ms ± 996 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
``` they are about the same
even for stuff like multiplication, timeit returns something like:
197 ns + 5.77 ns per loop (mean + std. dev. of 7 runs, 10000000 loops each)
that is also accurate
so as you can see, the variation can easily be around 10%
ok fine then
other factors weigh in when it comes to measurement, measuring something once is not enough
Hi i am new to this discord server and so am i to python. i started a project in repl.it a few weeks ago and now i am having a problem. Pyflakes tells a message which states - [pyflakes] unindent does not match any outer indentation level
Please help me with this problem thanks !
@glossy trail Awesome to hear that you’re learning python. I think your problem is better suited for #python-discussion or you could check out #❓|how-to-get-help
ight thx
sorry I never coded on python, can anyone teach me?
!resources
The Resources page on our website contains a list of hand-selected learning resources that we regularly recommend to both beginners and experts.
@worthy jasper there should be a lot of great resources there
does anyone know why there are two very contradicting defentions of a function PyCStgDict_clone,
https://github.com/python/cpython/blob/c82dda1e08c4b74ca24f88d6a549d93108c319cf/Modules/_ctypes/stgdict.c#L67
https://github.com/python/cpython/blob/c82dda1e08c4b74ca24f88d6a549d93108c319cf/Modules/_ctypes/ctypes.h#L266
there seems to be a very wierd use of this where it looks to me like the returning result points to a freed pointer as a result of this
but the code where it is used is confusing with a lack of a better word so i can very well be completely wrong
You can remove a reference with del
it work for dict will it work for var ?
The actual object will be deleted once there are no references to it left and the garbage collector picks it up
it will work for regular names, yes
Oh
a = 10
del a
Just keep in mind that it doesn't immediately delete the object, it simply removes a reference
@regal bison it's better to ask questions like this in a help channel, #❓|how-to-get-help
Ok i thought so but it was kinda related to dicussion so i thought no to occupie a channel for that
that's ok. we have plenty of channels
@sullen widget the 2nd one is the header? or wrong link
yes the second on is the header
the header declares that param 1 is source and param 2 is destination, while the actual code is the opposite
oh wat
yeah
i suspect that's a typo
well yeah proably lol
uhh what does a C compiler do in that case
so does the compiler prioritize names or positions?
the compiler does not care about the names
yeah exactly
well no
it would just confuse hell out of the programmer
aslong as the types are correct
but you now have 2 different signatures for the same function
acutally yeah that would give an error
void f(int x, float y);
void f(int y, float x) {
...
}
would be ok, right?
ok
let me just double check, not used to writing code like that 😄
the real problem is: what animal decided that "dst" goes first
hahaha
oh god that's what memcpy does
well the thing is, since the function is used. It can cause logic error
and therefore all of C basically needs to follow that dst-first convention...
where people thing it is the other way around, and so they copy from the the destionation rather from the source
right
yeah exactly
-> runtime crash because C bad
hahah
if you are lucky
if you are not lucky, people get shell on your computer
jesus i cant spell today
having a convention like "dst goes first" i guess helps
so if you see src first, you scratch your head instead of saying "ok sure"
yep, idk if there is a standard for it in python but it seems to be needed
why doesnt the compiler care about parameter names though 😦
is there a GCC extension for that
is that even in the C spec at all?
yeah compiles completely fine
but if int square(int a, float b) is the only thing you see then yeah
right
hi i gotta question
The break used in for and while but the best use in while
why is that
well usualy, when you're in a for loop, you know how far you're going
when in a while loop, you usually don't (usually)
so you break out
but they're both equivlent, they're both a loop, and you can break out of a loop whenever you define
thx alot
oopsie, this isn't #python-discussion, in the future try that channel or the defined help channels
im glad i could help though
can someone explain why do we use docker? it seems like a virtual environment does the same thing as docker..
@hearty trench try asking in #tools-and-devops
ok, thanks
what are opinions on pylint R0903: Too few public methods
I think it's giving me a warning for an attrs class that just has some data, but i was under the impression that this was a valid use
🤔
what code
@attr.s(slots=True)
class X:
a = attr.ib()
this causes it?
if so, tell pylint to fuck off
😄 yeah it's gone in the ignores - i will try and reproduce with an example tho
I had a linter that complained about the number of methods before, which I just ignored
just wondered if it was something that most did
yeah - i'm gradually just ignoring stuff as i found i was trying to please the robot more than i was actually doing useful stuff
yep it reproduces
just turn it off
that said, are you really that incapable of writing an explanatory docstring?
😉
jk there are plenty of times you dont need one
Maybe my code is so good it doesn' need it 😤
this is why i dont use linters like this
Docstrings are good(although I myself struggle with wording them) but things like that which nobody will care about just go ignored
this is mainly via pre-commit
It's more important for collaborative projects
stuff like this is stupid too imo
silly.py:4:0: C0103: Class name "X" doesn't conform to PascalCase naming style (invalid-name)
silly.py:5:4: C0103: Attribute name "a" doesn't conform to snake_case naming style (invalid-name)
yeah i agree its more important there
but still its frustrating to go around disabling a dozen individual warnings
Not that many cases where you'd need a one letter class name, but that seems like a bad implementation of the checks
yeah
maybe in a big project the frustration is worth it?
a "don't use one-letter names" warning seems in order
They'd hopefully be configured properly by the maintainers (or you if you're that)
right
@paper echo i get told to write docstring in imperitive case 😄
For example enforcing doc strings everywhere is easier than just writing it somewhere, leaving the evaluation of how it's needed to individual coders and reviewers then having to point out where they are necessary
i had to google what that was
i've been trying to use darglint recently - not sure if i like it or not yet
I like linters. I do like to be consistent, but I also know that I sometimes cut corners, especially when hacking around to test something. If I then stumble on a version I actually want to use, my linter helps me identify the parts I need to unify quickly without me having to worry about it.
A one letter class name, holy shit
But, yeah, they are just tools
I'll use one letter indices, that's about it
And you should be able to tell your tool to shut up
@pseudo cradle i was just testing the linter 😆
import attr
@attr.s(slots=True)
class X:
a = attr.ib()
this is the entire file
@wide shuttle yeah exactly - sometimes it felt like it was just calling nonsense out rather than helping me maintain a standard or whatever, but things can be ignored until there's a decent balance
I'm having to go back and round my corners
Based on this context, is a linter just something that enforces pep standards?
Name change i see
Yeah
Based on this context, is a linter just something that enforces pep standards?
@pseudo cradle yes and more, highly configurable
Not just pep standards, but standardising the style in general
lint, or a linter, is a tool that analyzes source code to flag programming errors, bugs, stylistic errors, and suspicious constructs. The term originates from a Unix utility that examined C language source code.
Gotcha
anyone got any tools other than black / pylint / isort/ darglint that they make good use of ?
pyflakes
PyCharm seems like it has a built in linter
its an alternative to pylint anyway
yeah i think pycharm bundles pylint, pyflakes, et alia
oh right, not used pyflakes
theres mypy of course 🙂
I don't know what PyCharm actually uses though
yeah - haven't bothered with typing yet
mypy/pyre/pyright/pytype
i just use mypy but pyre and pyright do look interesting
pytype seems like a toy project
I think jetbrains use their own linters
i bumped into wemake-python recently - i didn't like their f-string approach tho
what is that
What was that approach?
do not tell me it was a build tool using f strings
That's just stupid
I don't see any reasons why we should use them.
🤔
f strings are useful but they just like... it feels weird using them because nothing else behaves that way
So I just use format str
str.format, rather
you can do f"{2 + 2 = }" now i think
They are a great improvement to readability because of the lack of a function call, you immediately know what belongs where
Home of Repeatable Software Development Process
they make it much more obvious what is where, but they can get horribly confusing once you start nesting
though doing the things with nesting with .format is no less confusing
well, it is a very highly opinionated tool
The strictest and most opinionated python linter ever!
"opinionated" does not mean "authoritative" or "correct"
I don't mind that - i just don't agree with their opinion
so i hate them
I love using black
nothing else behaves that way
How do you mean?
There's plenty of instances of string interpolation across various languages
Nesting stuff in general is horrible once it gets deeper ( in the case of f strings one level)
True enough.
that's why everythign should just method chain
why can't we have list().len() or something
Because then you'd have to apply it across all things? Rather than just having to implement one magic method
javascript is that way 👉
across all things is good 🙂
@full jay fwiw you do have __len__
That's what I mean
you mean, there's a fallback len() implementation for when nobody implemented .len()?
@full jay Nothing else in Python behaves that way
@paper echo Correct
@pseudo cradle Ah, fair
That's the point of a lot of things, convenient redundancy
@full jay this is one argument in favor of languages that don't have traditional dot-access methods, e.g. R and Julia
I don't like chaining in python, only a few cases where it'd help and a lot more where people would create unreadable chains if accesses
dot-access methods are just a special syntax for single dispatch
Yeah, I've had to parse some pretty crazy nested strings
@paper echo is that why R pipes work so well?
if python had pipes it'd be amazing
Python is not meant to allow for long expressions
round pipes work well because of how pressure is distributed across the circumference
😄
it follows the algol tradition which is more statement based
@flat gazelle i tend to agree, don't try to force a language to look different from how it's intended
.format().split().split().join().format()
I do love kotlins abominations of oneliners, but they should not be in python
that said pipes are not native to R, but the language is homoiconic and wildly dynamic so you can implement your own pipe operator
The more languages I learn, the less I care about one language having something while another doesn't
Each language is tailored to its own strengths, and that's where the focus should be
I still have my pet peeves though
sure - if python had pipes it'd be great tho
Would it?
yes
the one thing i dislike is that lambda syntax in python is kludgy
yeah
Sure but it's meant to be used sparingly
typing out lambda makes me sad
if it were easier to type it would be used more frequently
You're supposed to feel dirty
a list comprehension is just a lambda in disguise
can you alias lamda to l
no @magic python
I have like three pet peeves about the python language but all the benefits it brings is more than enough to compensate
lambda is a great way to get horribly messy expression
you'd have to modify cpython itself and recompile to change lambda
a list comprehension is just a lambda in disguise
@paper echo With added optimizations in the background, sure
Yeah, I don't like using lambdas either
especially in a language like python which has terrible expression handling when compared to others
and yes, with lambdas being clunky i just write more named functions. not a bad outcome
The if is also a big thing you won't have with s lambda
I'm trying to think of situations where pipes would be really beneficial to Python code and I'm just not seeing it
It's just not built with that in mind, and doesn't feel like it'd be clean
i agree its not important
people only want it for dataframes because they're used to it from R
i don't even like them that much in R
I get them for primarily functional languages
I like the way kotlin handles things, where you can insert some pretty functional code inside imperative code, I think it works pretty nicely and that would also fit python
Do you have a snippit example?
Yeah, hang on
Isn't the primary concept of a functional paradigm just that you have functions without side-effects? Or rather, is completely cut off from state influence?
X input will always be Y output?
pure function are a big part of FP indeed
Or is that vastly oversimplifying it
Ah okay
suspend fun Member.getTopRole(): Role? = this.roles.toList().max()```Small function stolen from our kotlin bot
I'm thinking back to Elm where everything relies on the current state of the document, but the change functionality is always consistent in its behavior regardless of that
ye, the main merit of pipes and such would probably be that you get to not read code from the center out to either side
It just doesn't feel overly needed
Like yeah it'd be cool but it'd feel forced in
I'm kind of feeling that way with the pattern matching PEP, sadly
The pattern matching feels like a gamechanger
I want it to be, but it doesn't feel like.... I don't know, it doesn't feel as versatile as I was hoping? As odd as that sounds
I'm personally glad to see that the language is evolving and not staying on its functionalities from the 80s
Because from my loose understanding of it, it's primarily about deconstructing containers or something to that effect
@undone hare Sure, and I'm down for that. I'm not saying it should stagnate
Deconstruction is its main purpose, but it can still function like a switch-case kind of thing as well as do typechecks
ye. Which is something I have wanted for a while tbh. I often find myself just writing attr = onename.attr anotherattr = onename.anotherattr
It can but within the PEP it's suggested that it's not used for it
similar with dicts
Yeah that's fair
I think this'll have to be like the walrus; I'll have to see it in action to appreciate it
=3
But currently it's like JUST out of reach of what I want it to be
I feel like just Point(x, y) = point_object may be more convenient, but I am sure that will be a PEP at some point as well
the pattern matching idea is nice but it opens up several very nasty cans of worms
the edge cases are enough to make me think it's not worth bothering with
The pattern matching PEP will not break any existing code, right?
Pattern matching seems to add more terseness, but not more expressiveness... It doesn't let you do anything new, it just lets youwrite a bit less code to do stuff you could already do. I still think it's going to hurt maintainability.
I think that's my beef with it
Does it introduce new keywords?
It just doesn't feel like it's something easily maintainable
math and case afaik
It feels like it's something just tacked on from MyPy
give me none-aware operators instead
The pep for that was deferred I think
We've been consistently told that type-hinting wasn't going to be something enforceable within the language, and I feel like the pattern matching goes against that
I might be 100% off base, though
It introduces new soft keywords that are only keywords in specific contexts.
Shouldn't break much existing code then, right?
yes but that is a really unpleasant idea to me
at least with is usable everywhere and as is always context-dependent
Shit, I think I'd kill for an option() wrapper
option?
Essentially.....
Option<T>: None | Some(T)
I THINK I wrote that vaguely right
No idea
@full jay do you do much data processing
I do not
in python, I generally just see None or the value itself being passed
Sure, and this wouldn't really work well without some sort of switch or match casing
Maybe that's why pipes don't feel so natural idk
@magic python i do a lot of data processing, i dont ever need pipes
@magic python No I'm okay with pipes, I just don't see them being overly beneficial in Python specifically
Option<T>: None | Some(T)
is this nottyping.Optional?
Need != Nice
@strange fog Yes..... yes it is.... You ever forget something exists?
def clean_string(s):
s = s.replace('-', '_')
s = re.sub(r'\s+', ' ', s)
return s
clean enough for me
match possibly_none:
case None:
print('is none')
case a:
print('the value is', a)
``` it works just fine with pattern matching, no?
Assignment of s twice tho
@full jay 😄 more regularly than i'd like...
So?
Me obviously 😄
Re-assigning over something doesn't matter if it's still the same thing
I don't think I'd accept it as s there, but the reassignment is fine imo
(different names for the accepted and modified)
And hurt clarity for folks used to Python. Yes that'd be something to get over eventually, but a quick reassignment like that is common in many languages
True, Num
But it's also not outright objectionable
even rust allows it, including changing the type of the binding while keeping the type immutable
Now we're naming things differently when we probably don't care about the interim names
It's just a nag that is obviously solved by pipes
"obviously" seems like a stretch.
You want one thing to be the result of a series of processes, a pipe is more natural than multiple reassignment
In languages that focus on such behavior, sure
Yes, which is why I said I think python would be great if it had it
I'm not 100% sold but I'm not overly against either
My worry would be consistency throughout a codebase
Obviously it's not a deal breaker,I just think it's a valid pattern for this kinda scenario
Sure but the other is just as usable and useful
Especially for debugging purposes where you might have to pick it apart
Imo the pipe makes more sense, the other works ofc, but the reuse of variables like that isn't as clear
I'd agree if the reassignment was miles apart, but they're right next to each other and only local to that function
pipes also introduce fun problems with operator precedence
I often have a few lines and it just feels daft reassigning to me
Oh, I am not aware lak 🤔
2 and 5 |> add(-5) is this 0 or False?
Yes, it is
i always wondered why it was |> in some languages and not ->
Bash?
does the latter lead to ambiguity with math syntax?
i guess
but it's not | so who cares
|> is F# and Elm
Also sometimes used for saying what the return type is
i guess you still want to use the "pipe" mnemonic
I don't see the issue there tho @flat gazelle
Where's the ambiguity? Unless I've fully missed it
It is though
(2 and 5) |> add(-5) -> 0
2 and (5 |> add(-5)) -> False
and honestly, even just the syntax for partial expressions in troublesome. Unlike elm/F#/haskell you have no currying
and a |> b is just b(a) it becomes pretty much worthless
I don't have much appreciation for this stuff @flat gazelle , so I'm probably missing a lot. All I know it's that for repeated assignment pipes seem a lot more natural to me
You get to a point where to implement one part of pipes you end up having to change a huge amount of stuff in the background
Why would pipes be enforced?
You can use pipes when they suit
B(a) would be used
If pathlib can overload / then maybe 🙃
But I think lak made a good point about the currying, that's a huge hinge point on making pipes work properly, or at least better than for one purpose
in order for pipes to work, you need to able to create an expression that can accept a pipe
the only existing mechanism python for this is functions, which are a pita to create inplace
Hmm, I don't know enough to consider implementation, only usage
It ends up being a huge web of things that'd need to be implemented or changed
Right, but I don't think that changes my opinion, just that the language would struggle to accommodate it
a similar mechanism to pipes are clojure arrow macros, which have 3 variants and only work because clojure, as a "lisp" has all expressions in a consistent format.
(->
8
(+ 3)) ;becomes (+ 8 3)
(->>
8
(+ 3)) ;becomes (+ 3 8)
(as-> $
8
(+ $ 3)) ;$ gets assigned to the last result
``` F# and elm have currying. Not sure what R does
what's a use case for name mangling with __?
@flat gazelle R has no currying but you can easily implement partial function application or "expression capturing" like in the clojure case with as-> $:
x %>% f(1, ., 9)
where . is a placeholder for the piped value
ah
but again %>% is not part of the language, it's from a 3rd party library
which is pretty cool imo
Adding a new private attribute or method to a class that may have been subclassed by someone else who also added a private attribute or method of the same name to their subclass. That's pretty much the only use case for name mangling, and doesn't come up much.
languages with fully custom operators are cool
@raven ridge i see. that's a bit of an odd case
so what, some methods/attributes would have __ and others would have _?
yeah @flat gazelle R also allows "non syntactic" names too, like in SQL
and has a few interesting bits of syntactic sugar built in
like you can write names(mydata) <- c('a', 'b') which is special syntax that calls a function called names<-
in general a function like func<-(obj, val) can be called as func(obj) <- val
and any function of the form %func% is automatically a binary operator, as in %>%
or %*% for matrix multiplication
and you use backticks ` to "quote" such non-syntactic names where needed
so what, some methods/attributes would have
__and others would have_?
@paper echo yep. The purpose of__is to allow you to extend the "private" stuff of a base class without breaking a derived class that may have added its own private stuff. Or, alternatively, to add private stuff to the subclass that won't break if the parent class is later extended to add private stuff with the same name.
`%custom_addition%` <- function(x, y) x + y
x %custom_addition% y
ok that makes more sense @raven ridge
the latter use case is something ive wondered about in the past
Seems like advanced chat is back. What’s the actual use case of it? Is it just discussing things about python that seem to be too advanced for #python-discussion?
It's for discussion about the language itself, rather than about how to solve some particular problem with it. Like "why would you use mangled __foo names" or "should Python have a pipe operator" or "what are the pros and cons of the proposal to add pattern matching to the language"
Okay, perfect. It was called something along the lines of “python-language” yesterday. Why was it changed back?
It sounds more like “meta python” or “language discussion” or similar to me. At least if I got the right idea of what meta means
This is a new name, but this channel is plagued by people asking for help while it's one of the very few channels that we have that is not for help questions.
python-language did not filter out those people. We tried advanced-python in the past, but we hope that the "discussion" suffix will help with indicating that it's not a help channel, but a discussion channel.
Yeah, you’re right about that
I’m not sure this will work either, though. Maybe something like “language-discussion” would be even better
I personally thought it was similar to #python-discussion, but just for advanced questions. Either way, I hope this name filters out the questions
I second the "python-meta" thing
I'm pretty sure that nothing short of moving this out of the "Discussion" folder and into "Topical Chat" will do the trick. But that's all off-topic for this channel. 😉
Yeah, I’ve been thinking about that as well. Either way, #community-meta is probably a prettier channel for this discussion
subjectively i saw a significantly larger number of "lost users" when it was #python-language than when it was #advanced-python
Let's kick off this channel: thoughts on async lambda?
Feels like the only proper use for that would be a callback, which you could do with a normal coro wrapper
I feel like you can also use it to launch a bunch of tasks
async for item in iterable:
asyncio.create_task(async lambda: await item.do_something())
You can't really do much async there because of the expression limitation, and beyond things like the above would be too complex for python's lambdas
What's the purpose of the async lambda here? Can you just not create a task for the coro item.do_something() returns?
I've never had a situation in which I missed an async lambda
I'd rather see a wrapper with a descriptive name for the callable pattern.
Something like partial if that can't handle async in a nice manner
yeah
that method could just be
async for item in iterable:
asyncio.create_task(item.do_something())```
you're right
Remember that unlike sync functions you can call them and pass any items and it wont call the function directly
it will make a future object and wont be called until you await it
the only time ive found where it would be nice is when ive been doing my ASGI wrapper
Could you do something like ```py
async for item in iterable:
asyncio.create_task(lambda: item.do_something())
assuming `item.do_something()` returns a coroutine?
where i send back a dud future object that does nothing
item.do_something() could be a coro in itself
I mean coroutine object, not coroutine function
it could be
coroutines are callable?
its the same principle that lets you do await some_object() and have a __call__ method work still
you can call a coro when ever, you wont get the result until you await it tho
Yeah I meant coroutine, not coroutine function ^^'
Like what you get when you do
res = asyncio.sleep(1)
you can't do res() here, can you?
yeah that's what I meant, never seen a coroutine that is callable
Isn't that a Coroutine rather than a Future?
But, you can pass that res directly to a create_task
yeah
That is basically what happens
I was just wondering what happens when you do res() cause I never heard of Coroutine objects being callable
It will probably complain about not being callable
yeah that's what had me confused
wait a minute
its the same principle that lets you do
await some_object()and have a__call__method work still
@radiant fulcrum does this mean I can have a function do something different depending on whether I do
res = await my_func()
vs
res = my_func()
?
like a callable class for example
So In theory, could I just write a function that acts synchronously or asynchronously depending on whether the user tries to await it?
knowing what?
You wouldn't have that information, you just return the awaitable and then awaiting happens after that
class Foo:
def __call__(*args, **kwargs):
# stuff
return coro(*args, **kwargs)
You can delay the awaiting and do arbitrary things when the awaitable is created but you only return and pass it as any other object
Ah I thought __await__ was the key here
__await__ is things like
class RandomProducer:
def __await__(self):
return self.producer().__await__()
async def producer(self):
sleep = random.random()
value = random.randint(0, 9)
return await asyncio.sleep(sleep, result=value)
async def main():
producer = RandomProducer()
while True:
print(await producer)```
so ig you could?? do something like that
but you still wouldnt know if its going to be awaited or not
I see
in the simplest case you can have
>>> class Cat:
... def __call__(self): print("I have been called!")
... def __await__(self): print("I have been awaited!"); return iter(())
...
>>> cat = Cat()
>>> cat()
I have been called!
>>> await cat
I have been awaited!
just keep in mind that the __await__ must always return an iterator
@sacred tinsel If you return an awaitable from __call__ can you await cat() ?
Ohh I see
like so?
>>> class Cat:
... def __call__(self): return self
... def __await__(self): return iter(())
...
>>> await Cat()()
Pretty neat. I have no use for it, just like finding fun things that can be done.
I had a blast with aiostream https://github.com/vxgmichel/aiostream
This is what I'm doing in my code:
https://github.com/discord-hero/discord-hero/blob/master/hero/fields.py#L34
I have to be a lot more focused to grok async stuff
Allows me to do this:
class MyModel(Model):
something_else = ForeignKey(SomethingElseModel, on_delete=CASCADE)
my_thing = MyModel(something_else=my_something_else)
x = await something_else.x # await necessary since we're in an async context
I don't particularly like it but it works
using it to use Django's ORM in an async program
Django's orm is Next level to alchemu
tho Django's orm lacks in that its all sync based
Does sqlalchemy also make you await foreign key attribute access?
Alchemy doesnt support async
Ah
I just picked up on the class attribute tidbits to define relations, glossed over the await part I guess 😕
yeah I wrote my stuff in an effort to make Django's ORM play nicely with asyncio
I'll be gone for a bit but will respond to any @s
There is asgiref.sync_to_async, but I couldn't tell you what exactly it does
The amount of async orms is low, Ive made a PyMongo style Postgre orm, theres one called databases which is a async implementation of alchemy core
That's what I'm using a lot too @flat gazelle
If you want to you can check out the rest of my """""django asyncio port""""", I linked my code above
Im pretty sure it executors it
Await periodically?
I would love to find a better approach
Feels like it wouldn't be necessary if it throws it into an executor
Django's Asgi seems to executor everything sync based which is why they stress so hard is making sure you make sure any async stuff is threadsafe
Yee
I just throw all the sync Django ORM stuff that actually operates on the DB into sync_to_async with thread_safe=True
@sacred tinsel This didn't work.
cython looks like a magical performance enhancer for python. What kind of python code can and cannot be enhanced by cython? what to look out to take advantage of cython when writing python code?
Basically anything can be made faster by cython, just a matter of asking yourself if Python is the right language if you write everything in Cython
also I'm not sure about asyncio support
side note, PyPy might be worth checking out
there's things you lose by using Cython - it runs faster, but it's harder to debug and introspect.
Cython is great, and magical, but like any other optimization technique you should use it where it will give the most benefit.
Can only agree ^
oh, and test! it's harder to test, as well.
cython looks like a magical performance enhancer for python. What kind of python code can and cannot be enhanced by cython? what to look out to take advantage of cython when writing python code?
@forest flicker To be more specific, it also optimizes a lot of C-style code written in Python, as well as applying CPython optimizations like constants and such
there's things you lose by using Cython - it runs faster, but it's harder to debug and introspect.
@raven ridge I've seen python code that need not be changed when using Cython. The code simply add some kind of decorator on top on the python code. This shouldn't make code harder to debug
oh, and test! it's harder to test, as well.
@raven ridge to test, one can simply remove cython temporarily.
Producing binary extensions definitely make code harder to debug, especially in the context of Python
Removing Cython means what you're testing isn't what you're shipping, which drastically reduces the utility of automated tests
that's true. I didn't know there's a prominent risk that the same python code with and without cython can behave differently.
is it possible to step through python code enabled with cython?
Not as Python code, because it isn't Python code, it's C or C++ code. You can step through it with a C debugger
oh dear. does it mean I can no longer use pycharm to debug cython "python" code?
I'm not sure, I don't know PyCharm. I doubt it integrates with a C debugger, but I don't know.
Make a web page where people can submit and vote on beginner level projects
😄
CLion would presumably have a visual debugger for C and C++ and I assume IntelliJ ultimate would have it all
@charred barn ok i will do that
do anyone how get python program out put in flask ? like plane thing where you can see your program out via web dashboard instead of ssh to cloud vm & seeing? (i don't wan't code flask inside of that program)
you should setup some Fileserver or something
I tend to use github but i also have a ftp server i can use to move to my servers
Work in what way? The implementation or its behaviour?
both i guess
In [32]: int?
Init signature: int(self, /, *args, **kwargs)
Docstring:
int([x]) -> integer
int(x, base=10) -> integer
Convert a number or string to an integer, or return 0 if no arguments
are given. If x is a number, return x.__int__(). For floating point
numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base. The literal can be preceded by '+' or '-' and be surrounded
by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4
Type: type
Subclasses: bool, IntEnum, IntFlag, _NamedIntConstant, Handle
The whole implementation of the object is somewhat complex and can be found here https://github.com/python/cpython/blob/master/Objects/longobject.c
The constructor simply calls the int dunder, or for strings, bytes and bytearrays it can decode bases
Is the length hint dunder used somewhere in the stdlib?
1 line of python code has behind 1000 lines of C code :)
Doesn't it depend a lot? Like x = a + b cant be more than like 3
There are a lot of things in the background to accomodate add for arbitrary objects
Python gets compiled to bytecode, which is then interpreted. There are a lot of lines of C involved in even the simplest statement.
x = a + b
assuming a and b are int
lookup names a and b
- check local scopes
- check module scope
decide the destination of x
- was global/nonlocal used
see if the object under a has __add__
it does, call it with a, b
check if it did not return NotImplemented - it did not
assign the result of __add__ to x
``` and that is skipping all the complexity of `__add__` on two ints
(has to check for MemoryError, RecursionError, acquire the GIL, make sure references are properly counted, ...)
Well, technically, for CPython, scope resolution is done at compile time, and it loads different instructions for local, closure and global variables.
but these lines are still executed
so we need to also factor in the lines it takes to compile x = a + b, and there's probably more
Guys, not sure where to put this, but how do you decide what projects or functionalities to open source? I really want to give back to the community that has given me so much, but I also want to protect my future ability to provide, so yeah, how do you guys do it?
I just open source everything that i write
Idk what protect my future ability to provide means
well, obviously you won't open source things you use to earn a living
(unless you make a living making open-source software)
but, that still leaves plenty of wiggle room for projects you're not using profesionally
fair hehe
I mean obviously you don’t open source your companies code
That’s a great way to get fired
I meant everything that i write
I mean all MY stuff is mit oc
Hi, realistically can we ever have a Python compiler? I know it's not what the Python core development team which is strange given the advantages of compiled code. I think MyPyC is a great concept, pity development here is slow. Anyone knows of something similar to MyPyC? Cython is not convincing.
i think they mean a native compiler
Cython kind of is?
Theoretically a compiler can trust type hints/type inference.
but that won't be python, that will be a language with different semantics, I guess
does anyone know if there's an option in pip's pypirc to enable the new resolver (as of 20.2) by default?
@unkempt rock have you tried PyPy?
numba can compile some subset of python
@flat gazelle btw, in response to my tweet of your code:
>>> fib = lambda n:[(a:=0),(b:=1)]+[(c:=a)+(a:=b)+(b:=a+c)-a-c for _ in range(n-2)]
>>> fib(6)
[0, 1, 1, 2, 3, 5]
that has the requirement of a third variable, which is inconvenient
i think there are about 10 things wrong with it, not sure "third variable" even makes the list! 🙂
I imagine if you write some kind of translation from bytecode to llvm IR you could get some kind of compiled py
that is pretty much what numba does. It is even faster than pypy and in some cases cython because it errors when it cannot compile and does not care about being functionally identical to python code
Numba acts as a jit though, plus alot of code it cant work with
But yea youre right, probably the closest living thing to it
Im giving pypy a shot and see if this works well in our project.
@unkempt rock what kind of work is your project doing, and what is too slow about it?
Hmm, pypy still not supporting python 3.7
sad
they will get there
its not really that the project is too slow, just want to experiment and see whether in this case using a jit compiler would result in a faster runtime
but something like from future import annotations seems to be incompatible with current pypy release
yes
Is CPython bytecode compatible with PyPy?
