#internals-and-peps
1 messages ยท Page 96 of 1
it's pretty much required, if you're designing a class without knowing whether or not users will inherit from it.
sry I've been breaking python for a few hours I'm not ready to joke about it
was uninspired all day then I learned what #esoteric-python is for
For inits. But other times too?
for any method where you call super() to delegate to the next class in the MRO, at least.
And, if you want the next class to be able to take different arguments for that method.
Speaking of
I made a class method constructor that calls a different class method constructor for the superclass
And then changed the class of the instance that gets made. is that bad?
I'm not going to change it because I like it.
like, you changed obj.__class__ before returning it?
Also the subclass doesn't obey the liskov principle
obeying LSP is pretty much the single most important thing when using inheritance.
I might go back in later and make it so they're two separate classes, but give the other class references to some of the methods from the first.
how to install flaskr ?
I wrote a subclass that sometimes redefines its own class but that's cuz it's designed to built itself based on kwargs and superclass and derivatives are designed to interact with the same class specifically
it obeys LSP tho
...without kwargs it's just the superclass
and with em it just doesn't let you add em together
Advenced discussion lol I'm a newbie
For a terrible time: https://perlmonks.org/?node=Obfuscated Code
lol I'm more interested in doing stupid things that take advantage of reflection than that
Hey everyone.. Iโm student IT program in Denmark and looking the teams members for Registration for MathWorks Minidrone Competition at Nordics and Baltics 2021..
Yeah
ye, it is becoming somewhat bloated recently. things like :=, however neat they may be, do desimplify the language quite a bit
like there was a shitton amount of syntax added to python
and even more shitty pep proposals seems like are going to be accepted
e. g pep 637
the fuck is that?
!pep 637
idk, you are not obliged to learn/use it right away
how does that even work
the sad thing is more than half of the community wants it
like you can still learn language as we used to, no
it is an issue, since you will see it in code used
we are slowly getting away from pythons intended philosophy
and so you have to learn it
saying don't use a feature if you don't like it doesn't work, since other people will use it and you need to understand other people code
!pep 20
thats why new syntax is supposed to be bad too
those are not things supposed to be in python
like, looking at a simple language like elm, that language removes features with every new version
I feel like python is trying to compete with all those new fancy languages with feature lists over several pages and thereby losing what makes python nice in the first place
Has anyone ever even used the walrus ?
about 637, this I would very much like to have ๐
I don't
I used it like twice
there is a proposal for macros as well
they are a really powerful tool that would allow a lot of previously impossible APIs
that is really confusing to me
and i would be even more confused with the new syntax
Same
I am 99% sure that it's way it works in R which is considered for data-viz/analysis to be better than pandas ๐
Is that assignment or equi check ?
df[df['x'] == 1] means select rows of df where column 'x'=1
yeah, these are all useful things for some specific libraries. But the issue is, people will use and overuse it. People like using fancy new things
speaking of library specific syntax, the fuck is @?
i just learned it existed last week
it is an operator
for matrix multiplication only for numpy arrays?
df[(df['x'] == 1 ) & (df['y'] == some_func(50))]
for me it becomes to much boilerplate
however someone who isnt used to the new syntax can understand it
numpy arrays do use it for matrix multiplication
== being broadcasted is not really intuitive in any way
you expect == to result in True or False
not a whole series
perhaps but I saw a lot of people, including myself who often attempt
df[x == 1 ) & (y == some_func(50))]
python is going to be more complex than rust at this pace
Py is kinda simpimg for pd community I guess
^
it doesnt seem like its going to die anytime soon
is the walrus operator controversial?
No
yes
what is so bad about it?
Readability
it is quite confusing and not all that useful
readability for beginners
i love that i can do print(a := 'hello') without another line
[a for a in (v:=range(10))]
and use a anywhee else
take a guess at what this does
Another line adds a lot more readability
what is a for a in range?
i haven't learned that yet
ah, you didn't do comprehensions yet
list comprehension
lol
Hehe
what does it do by the way?
try it out, you will probably be surprised
im on mobile lol
so basically, it's iterating through the range 10, which is assigned to V
right @flat gazelle ?
you would think so
thats what it is supposed to be
!e [a for a in (v:=range(10))]
@flat gazelle :x: Your eval job has completed with return code 1.
001 | File "<string>", line 1
002 | SyntaxError: assignment expression cannot be used in a comprehension iterable expression
but actually, turns out it makes the scopes hard to resolve and so it is forbidden
lol
hmm?
and if you have to special case a feature to forbid it in certain contexts, is it really a simple and non confusing feature
I don't even think this is the only case
could you write this without the walrus operator?
v = range(10)
[a for a in v]
``` works just fine
so yeah, adding features, even if they aren't exactly bad, is concerning
Like f strings
There is a forbidden in that too
it is possible in those, you just have to do f'{(a:=4)}'
any actual useful use cases for walrus operator?
while loops
while a := read(1024):
print(a, end='')
where read is some theoretical function that reads some amount of data
ok
you can also do this with iter
the fuck
@flat gazelle the reason for the scopes issue is because the inside of list comprehensions are compiled as separate code objects. And the assignment expression would end up inside that for loop code object
And that raises the question of where v would be defined after the comprehension
yeah, until := it wasn't an issue since you couldn't create variables in expressions
why were f-strings even made? .format is pretty good
they are awesome
well they are good i guess
because they are nicer than .format
But u can't use * in them
if its confusing it is as confusing as .format
you don't have to state the name of everything 3 times
Hehe
name=name?
Just have a look at float precision
a variable name needs to interpolated into that point
positionals aren't useful if you have multiple things to put in, since they get hard to parse
i have noticed an interesting thing with fstrings. ```py
f'\{1}'
'\1'
f'{1}'
'\1'
features like :=, f-strings, matrix operator had very controversial periods of discussions. Though for the new syntaxes, like PEP 637 suddenly everyone agrees or people just don't want to comment and deal with mailing lists
That's a good SQL injection check lol
>>> import warnings; warnings.resetwarnings()
>>> f'\{1}'
<stdin>:1: DeprecationWarning: invalid escape sequence \{
'\\1'
I got one too
What should be the output of
f'\1'
I think it would yell at you for incomplete octal escape
oh wait, it just takes the number
Mailings lists are nice for the core devs etc. around it but I don't think the wide community will contribute there much
in 3.6 that would output '\\{1'
!e
f'\1'
You are not allowed to use that command here. Please use the #bot-commands channel instead.
Someone run it
>>> f'\1'
'\x01'
>>> ```
Why ??
its an octal escape
I gotta escape yeah
so \0 - \a convert automatically
Yeah got it ๐
I guess a bit unexpected but what it does currently seems to make more sense to me, if we forget that python should be warning against the usage
why is python so whitespace sensitive and tab sensitive? if it used braces and semicolons we wouldn't have to worry about indentation
Run the command from __future__ import braces in your code
Indentation is a non issue tho
i think it "has" to be fixed throughout the file, that's the only real criteria python imposes
PEP8 recommends 4 spaces though, because mixing code with tabs and spaces got really messy really fast
there was a time when python wouldnt raise an issue about it
it requires 4 spaces right? or can we do 2?
Python doesn't require a particular indentation. PEP 8 recommends 4 spaces.
oh nice
but spaces are much better than tabs ๐
i i was lazy, could I do 1 space?
i'd encourage 4 simply because it helps others who read your code. once you get used to it it's a breeze
i use 1 space in the REPL.
yes. but 1 space makes it "very hard" to visually see indentation in big codebases
i know, just asking
yep, python can have arbitrary spacing, as long as its consistent
er. thats a weird sentence. as long as you use the same "number of spaces", it doesnt matter "what" the number is to python
i think so off the top of my head, but play around with your editor/ide of choice for sure
ok
just use an IDE that automatically converts tabs to spaces. press tab once, get 4 spaces - easy
i know
!e
if 1:
if 2:
if 3:
if 4:
if 8:
if 16:
if 32:
print("yep")
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
yep
whoa
Python only cares about one block being consistent
you can even mix spaces and tabs
That is a great demonstration ๐ Reminds me of my favorite stack overflow answer: https://stackoverflow.com/q/3949422/14343
I am trying to do some dynamic programming based on the number of characters in a sentence. Which letter of the English alphabet takes up the most pixels on the screen?
If the question is limited to how many pixels wide the character is, the answer should be "M" in most fonts.
Not that it was a good question, but that's probably the most correct answer ๐
@spark magnet Can you somehow construct a clever answer that will point to the right character depending on the font?
Or W? I think M usually is more vertical than W
I haven't looked into the link, but generally you would write the character onto a bitmap and find the enclosing rectangle. This would work for any font and any character, as it's just "write and check" but automated
Hm, instead of bitmaps, one of the answers in that question uses html div without size and check the calculated size when changing contents via js. Similar thing
monospaced fonts
When I automated gta horse race betting and tracking odds I just made a pixel ruler function that detected light/dark pixels and manually counted pixels in screenshots to determine the logic
certain characters always had certain height/width of light/dark
All of 2 and before, yeah?
This was an enjoyable read.
typing.Protocol?
Interesting, this is what I was looking for.
Thanks for the help!
Damn, it only works if your passing in a class
-
Union[str, Any]is exactly the same asAny. -
Do you really want the function to accept an
Optional[int]which isUnion[int, None], or do you want it to accept an optional argument? -
You can make a type alias:
MyCallback = Callable[[str, str, str, Optional[int]], WebElement]
- Those positional arguments are very cryptic, and you can't specify an optional argument like that. Instead, you can make a protocol:
class MyProtocol(MyCallback):
def __call__(self, attribute: str, type: str, condition: str, wait: int = ...) -> WebElement:
...
- You might consider using an
EnumorLiteralif you want to allow only specific strings. It's similar to TypeScript's literal types.
AttrType = Literal["id", "name", "thing", "stuff"]
class AttrType(str, Enum):
id = "id"
name = "name"
thing = "thing"
(if you're coming from TypeScript, you might be disappointed about some things, like type inference)
If you're using mypy, consider also trying Pyright (or Pylance, if you're using VSCode)
Many thanks for the detailed response!
I'm using pylance
1.) You're right, It's just a placeholder right now until I find the second type to use
2.) I wanted it as an optional argument, I guess it uses the parents kwarg which is always an int
protocol doesn't require you to make a custom callable class, it describes a plain function as well
You're right. 3 && 4 seems like a much cleaner implementation - So handle_wait_factory would be
def handle_wait_factory(browser: Webdriver, *args) -> MyProtocol):
pass
Damn. That looks so much cleaner
@buoyant dirge we will not help with exams
please dont assume such things
with little to absolutely zero knowledge
it's not for an exam
well, regardless, it is not suited for this channel.
for those of you using CI/CD in Python development, more geared towards utilities than web applications, what's usually in your CI pipeline? At the moment I'm only doing linting checks and unit testing with pytest. I'm thinking doc string linting, code coverage, and code complexity checks may be useful but wanted to get a second opinion. Could also do static type checking with mypy but that seems overkill for Python.
@round lion why is mypy overkill? It's linting like pylint is.
static typing seems overkill for Python development tbh
@round lion definitely coverage is good, but I am biased. ๐
if you use type hints, then mypy in CI makes sense.
yeah, I don't think I'll convince devs to do type hints even though it'd make their doc string generations quicker
do you measure coverage?
somewhat. For some we do, others no
I'm wanting to standardize, so I'm trying to figure out how deep in CI I throw people/myself
linting, unit testing, and code coverage seem easiest since you can find auto formatters for any IDE depending on your linting preference. Doc strings and type hints seem like the harder ones
My linting is usually flake8 plus a Sphinx dry-run, sometimes coverage with a 100% threshold, usually mypy on an installed copy of the package - though I do mostly libraries, where mypy has a bit more value than for applications
ooo, never heard of sphinx. We use flake8 for our linting
although I think our flake8 config could probably use some work. We use black as our formatter, and I don't believe our flake8 config is 100% matched with how black formats
sphinx is basically doxygen for Python. It's a documentation generation tool, which can read docstrings and use them to generate HTML docs.
...that sounds amazing
is there a reason you run mypy on an installed copy of the package rather than just pointing mypy to your src directory?
I can't do static type checking
It's so way too immature and doing anything advanced as say descriptors and it breaks
the typing can be nice for readability and less maintenance on doc strings as going against the static typing won't raise errors, but yeah, forcing checks may be unreasonable unless you allow untyped functions, which then what's the point of running mypy against the codebase
don't add type hints if you don't check them. that's just asking for trouble.
yeah, I'd go all or none. Although for an existing codebase, it may be fine to integrate type hints gradually rather than all at once, then once it's all completed, forcing the check
do coverage first
mypy is a giant pain in the ass. I know running it on an installed copy fixes some problem. I don't remember what problem that is.
yeah, that's the easy one no one can complain about lol
But that's the thing, we (at work) want to use them, but like then we get into this state where despite our best efforts we always have errors
it does seem to require some awkward casts.
There's always Any to shut it up
well, I have some stuff to research and test out now. thanks folks for all the input. no real python pros around me so I've been having to pick things up as I go and am tired of shooting myself in the foot lol
But that like completely defeats the self documenting part
@round lion any time, we can help you shoot yourself in the foot ๐
It documents "this is complicated, see the docstring", heh
-- I'm using C, a statically typed language, which provides much safety.
-- Oh, that's nice. Can you show an example?
-- Well,
void qsort( void *ptr, size_t count, size_t size,
int (*comp)(const void *, const void *) );
"Any" == "void *" ๐
yep, that's my point ๐
You can typedef or define names for those types, but doesn't hide that void* is a bit dangerous ๐
you know, I was so happy I hadn't seen C code since college and you just had to bring it in here lol
"We don't need lambdas. Have you seen qsort_r?"
well, it's the same as
Int = Any
Str = Any
List = Any
At least C++'s lambda has type definition
If you're talking about specifying argument types in a lambda, then Pyright can also infer those if the target (where you pass the lambda) has a type.
But it refuses to infer them in other useful places (like functions under decorators) because "you can already specify the types in a standalone function"
So I just have to get better type checker or use libraries that have proper type hinting
Okay
or ||get a language with better gradual typing|| 
Yeah, but then I had to install their stupid toolchain (looking at you, Dart and Flutter)
typescript seems ok to me, but I haven't looked at dart&flutter
TS is p good IMO
I quite like the syntax
apart from the angled brackets
Typescript doesn't enforce runtime type checking tho
it does not
that's why it's gradual static typing and not just static typing
In fact, the whole point of static typing is that types are not checked at runtime.
But at compile time.
Well, that seems like duck typing with extra steps
runtime checking is the opposite of static typing
it's the same as C or Java
yeah, pretty similar
they don't do runtime checking either
to Java/C#, I guess
why not C?
C and Java won't allow you to call undefined methods tho
C doesn't have generics and subtyping
In C and Java you can do lots of nasty dynamically typed stuff.
sure, but it has a first step of checking types, and then runtime, no checking
well... all statically typed languages don't check types at runtime, right?
because
right.
(see void* and Object)
You have to explicitly want that. My problem with some Python libraries right now is that they does not do proper type hinting so my IDE is all red.
yeah
Yeah, all I want is at least proper type hinting lol
Wait, I thought in Java you can't cast an object to whatever you want, it still enforces type checking at runtime.
Or maybe that's where instanceof comes in
Well, sometimes you just can't typehint certain relations. Like in attrs or sqlalchemy.
mypy supports plugins, but other typecheckers don't, and it's a shame that they're not part of the typing standard. I would love "domain-specific type systems". Maybe I should just write my own typechecker like that... but that's just yet another standard
Yeah, but it will fail at runtime, which is bad: the main reason people use static typing is to provide some guarantees at compile time.
I'd rather my code fails that continuing with unexpected object with unexpected type to
More trivial example: you can't have a generic object with an unfilled type variable (i.e. polymorphic in some type) unless it's a function: https://github.com/microsoft/pyright/discussions/1380
Yes, sure.
But in compiled languages like C/C++/Rust, the type information is just not present at runtime.
Not quite an advanced question, but are you guys aware is sqlalchemy or any other pyhton orm supports getting model fields directly from indicated table so I do not have to define them?
Maybe this can help? https://pypi.org/project/sqlacodegen/
No, not quite
That's a generator
Does not work on the fly
Why do you want to generate them on the fly? Does the schema change at runtime?
I don't want to even generate them, I want each orm call to "determine" structure before it's executed
C doesn't have methods, but it does have functions - and it's both possible to call an undefined function at runtime, or to call a function with incorrect arguments at runtime.
I've been using PHPActiverecord in php project and am migrating it to python. That php library has that very handy property of determining schema and having columns pre-determined at each call
I'm just looking for same functionality in any of the python sql libraries
AFAIK, sqlalchemy does support that
Any idea what that would be called so I can hit the docs?
It just doesn't seem very useful to me. Your code will break unexpectedly, and your IDE will have no clue what you're doing.
You'd need to provide a function pointer with garbage address or address to wrong function, no?
My ide won;t break, I just use vim XD
You can have autocomplete and type inference in vim
No, sorry. I'm not a fan of ORMs.
I just want to define a class, indicate table name and viola....
Or fail to check the return of a dlsym call, or dynamically link against a library where the type of the symbol is different than the type you declared the symbol as when you compiled.
Me neither, however, sometimes it's handy to use new User() instead of writing sql.
@opaque raft Maybe https://sqlsoup.readthedocs.io/en/latest/tutorial.html?
well, it was last updated on 2016, so... maybe not
That's a good find, thanks mate. Some things don't need to change for a while, I don't mind.
the latter would be called "ABI incompatibility", and is a pretty common thing to need to worry about when making shared libraries
@opaque raft this channel is for discussion about the language itself. If you're asking a question about how to accomplish a specific goal of yours, you might look into the topical channel that most closely relates to it.
Noted.
why not
"There is no such thing as an object/relational mapping." (c) bob martin ๐
seriously though, it's kinda true that a relational model does not exactly map to an object-oriented one
They're only very slightly easier than SQL for simple cases, and they're much worse than SQL for more complex cases
they frequently generate absolutely terrible queries with quadratic complexity that fail as soon as you deploy them to production and run them against real world data sets.
They make mistakes that a developer writing SQL would not make.
What are the benefits of ORMs? Not having to write complex queries?
(I haven't used one)
Do you think approaches like EdgeDB solve it better?
not having to write simple queries, really. Because from everything I've ever seen, developers still need to get involved and write the complex queries.
I'm not familiar with EdgeDB
well, it's basically a relational database that's built on top of postgres, but provides a sorta higher-level language than SQL
The advantage of an ORM is that it will get the data you ask for, and you don't have to think about how it's doing it, even if that takes joins across tables without suitable keys. The disadvantage is... exactly the same thing.
I thought the point of them was that once you've obtained a row from a database, that row is represented as an object that you can have defined methods for
but you're telling me that the main point is that it figures out what query will obtain the information one wants?
They're much more than just dataclasses for tables.
They usually do things like lazily fetch data for that object, so you can pretend that you've got a local object when it actually fetches stuff from the DB behind the scenes as needed.
that's been my experience with them. so what does that have to do with how they're obtained via query?
(I was mostly done with that comment when you said the next thing and I wasn't going to let my effort go to waste.)
what if I just want dataclasses for tables?
in bs4 if i have a header object inside of a class in the html code how do i retrieve that header
This channel is for discussing the Python language itself. You should see #โ๏ฝhow-to-get-help
https://docs.sqlalchemy.org/en/13/orm/tutorial.html#building-a-many-to-many-relationship shows this statement: py wendy.posts.filter(BlogPost.keywords.any(keyword='firstpost')).all() Running this SQL: ```sql
SELECT posts.id AS posts_id,
posts.user_id AS posts_user_id,
posts.headline AS posts_headline,
posts.body AS posts_body
FROM posts
WHERE ? = posts.user_id AND (EXISTS (SELECT 1
FROM post_keywords, keywords
WHERE posts.id = post_keywords.post_id
AND keywords.id = post_keywords.keyword_id
AND keywords.keyword = ?))
granted that's not incredibly complex, but it does show joining across multiple tables. There's a lot of join type stuff in there.
as far as just wanting dataclasses for tables - I'd just make my own dataclasses, and load data into them myself after reading it from the database.
...or even automate that somehow, e.g. with dataclass_factory and a mapping-Row (i.e. a row that presents a key-value-pair interface)
yeah, exactly. But if you're feeling lazy, a dict row factory, and just passing the row dict to your dataclass constructor as **kwargs, does the trick.
yep
but then... why would you want that?
That's just revealing a whole bunch of implementation details to the users of those classes
maybe it's kinda useful when you're directly fetching data, though.
e.g. if you make a change to a table row, you don't need to fix every single place
I mean, I wouldn't expose them to users of your library, or whatever - I'd keep those classes as implementation details. And I'd only use classes for it instead of just POD dicts if I needed to have methods that compute non-trivial derived properties, or something.
but yeah, I mostly agree - I don't usually create classes that represent tables.
I have multiple instances where I knew which queries that I want to run, but didn't know which ORM operator to use.
ORM is mostly a hinderance when you have complex queries. It also locks you into a particular ORM or MVC ecosystem.
Yeah. And replaces a well documented, relatively portable language with an ad hoc, less well documented DSL tied to a particular programming language
Our setup is similar, we run flake8 with some plugins (mostly import order, docstrings, type annotation coverage) and a unittest testing suite. We report test coverage but don't enforce 100%. I like using flake8-annotations to enforce ann coverage, even if there's no type checking, I think the annotations still have massive value in providing a standardised way to document types, even if you don't run a type checker ~ the docstring can then focus only on what the annotations cannot express, and there's no debate on which param documentation style to use. For new projects or "my" projects where no one else contributes, I'm starting to use mypy, but I probably wouldn't be able to introduce it to larger existing projects because the devs either don't have the capacity to fix hundreds of issues, or would rather spend their efforts elsewhere. PyCharm does type check for me to some extent that is useful, plus it can autocomplete a lot more if you provide the annotations, which is also super useful, although I find that it won't catch nearly as many issues as mypy & alternatives would.
Typecheckers are extremely useful IMO when it comes to more advanced things like generics.
Like, quiz: can you do
T = TypeVar("T", covariant=True)
class Observer(Generic[T]):
def update(self, new_value: T) -> None:
raise NotImplementedError
```?
Or, can I pass list[int] to a function that expects list[Union[str, int]]?
I understand that non-libraries don't create generics often, though.
Maybe the issue you have is that an expensive operation looks very cheap?..
Like putting lots of I/O in a dynamic property lookup
To me, even just using simple typing (skipping the more complex types by using a more generic type and documenting the param in more detail in the docstring) seems to be great value from what it enables on editors and checkers. I've been mostly relying on pycharm's builtin checker which works for me without worrying about it too much
I don't know, can you? I'd be more worried about whether you can pass [1, "1"]
now I realized I don't even know what the union expresses there
list[int] is a list, where each element is int: [1, 2, 3, 4, 5, 6]
list[Union[int, str]] is a list, where each element is Union[int, str]: [1, "abc", 2]
right, so Union[list[int], list[str]] would be the way to express either list[int] or list[str], but not a mixture
Yes.
is there a way to express that it has to be a mixture? i.e. at least one str and at least one int
so you would need a custom type
e.g. a class that would enforce the constraint upon instantiation
Well, yes, you could have a custom type like
class NonEmptyList(Generic[T]):
def __init__(self, first: T, rest: list[T]):
self.first = first
self.rest = rest
def __getitem__(self, index: int) -> T:
if index == 0:
return self.first
elif index == -len(self):
return self.first
else:
return self.rest[index-1]
def __len__(self):
return len(self.rest) + 1
def __iter__(self):
yield self.first
yield from self.rest
...to encode a non-empty list. In a similar way, you could do
class MixedList(Generic[T, U]):
def __init__(self, first: T, second: U, rest: list[Union[T, U]]):
self.first = first
self.second = second
self.rest = rest
The answer here is no, because this function is absolutely valid:
def foo(things: list[Union[str, int]]):
things.append(42)
things.append("bar")
In nerd speak it means that list it invariant in its type parameter: https://mypy.readthedocs.io/en/stable/generics.html#variance-of-generic-types
right, but that only applies if you mutate the param right
Well, if you're not mutating the parameter, you should use Iterable, Sequence or Collection depending on what you need.
so does this annotation lie?
def add_string(ints: list[int]):
ints.append("1")
I guess yes, although I never really looked at it that way
I've never considered the annotation to also be a promise of what the type will be after the function exits
but yea, this makes sense
yup
You should post this in #data-science-and-ml, not here. This channel is for discussing the Python language itself.
you need dependent types for that
okay, so how do you deal with a function that takes a list of ints, sums them, and appends the sum as a string:
def add_sum(ints: list[int]):
ints.append(str(sum(ints)))
because aside from the types of the contents youโre expressing a constraint on value (length)
yea, the fact that there's a constraint on the length also occurred to me
Well, there's no way for you to describe the type of a mutation... so you can't really do that, besides list[Any] and a docstring
what do you want to express?
@sacred tinsel @gleaming rover Well, you can do it like this. But it restricts to the first 2 elements.
@sacred tinsel Subtyping is generally bit tricky, because any given value belongs to potentially infinitely many types. And mutation makes it all even worse.
I need to express that the function can only take list[int] so that I can sum them, but I also append a string, so then the list no longer satisfies list[int]
however it cannot take list[Union[str, int]], because then it will fail
no
the python type system cannot express this
the parameter constraint applies only before the function is entered
the best you can do is return a new list
so in my mind annotating the param as list[int] would be the most correct, because it expresses what the function needs to receive
the core issue here it that a single variable may not change its type
(ignoring that you can sum other types too)
so you have immutability here, yet in practice the type of a variable is mutable
I am not aware of any language that can deal with this correctly
I guess you could do it with linear types, i.e. ensuring that it's not used anywhere else:
def add_sum(ints: consumes[list[int]]):
# here ints is list[int]
ints.append(str(sum(ints)))
# here inst is list[int | str]
I wonder if its possible using *args + paramspec
@sacred tinsel the problem might be appending a string to a list of ints in the first place. That seems odd.

sure, it's a theoretical scenario
If you want to get some theoretical scenarios Python's type annotations can't express, I can open up my type annotation frustration bag ๐
feel free to give a sample of your bag, but you may not be able to get much discussion out of me
I did come across a more practical problem recently
is this the correct way to annotate that the function receives MyEnum, the class?
I think so, but PyCharm doesn't like it
line 14 should be creating a member just like line 10 does
why t.Type[MyEnum]? Can't you annotate it as MyEnum?
I think that means it takes a member
it takes a class (MyEnum), and creates a member MyEnum.A
oh, sorry, you want to take the class
in that case, you are trying to say that this must always take MyEnum as the argument?
in my scenario it would be a union of two enum classes
so Union[t.Type[MyEnumA], t.Type[MyEnumB]] I think
but here in this example it only takes one, trying to isolate the issue
the code works, I'm just not sure whether it's not annotated correctly or maybe just a PyCharm issue
mypy doesn't complain, so it may be a pycharm issue
i think sometimes it is not worth trying to get the type system to understand.
ye, just go with Any and write a docstring
mm yea
or leave off Any completely.
somehow with git we forget about "decentralized" and with Python type hints we forget about "gradual"
It is good to be explicit that you didn't forget the annotation there but wanted any, even though the behaviour is the same
All my C++ numerical (arbitrary precision arithmetic) library tests pass! \o/ Now I can start work on my implementation of Python!
Does anyone know how to get autocompletion using getattr?
we're looking forward to it.
Can you elaborate?
class Vcc:
def __init__(self, vcc:VccType):
self.vcc = vcc
def __getattr__(self, name) -> str:
if (valid_attr := self.vcc.get(name)):
return str(valid_attr)
raise AttributeError(f'{name} is not a valid attribute.')
@rose stream implementing __dir__ might help?
def __dir__(self):
return self.vcc.keys()
also shouldn't _ only be used for things that are going to be garbage collected next time it runs anyway
i feel like a better name for the variable would be anything other than _, since you're accessing an attribute of it later
not that it matters to your point, but Python reclaims objects a little differently than waiting for gc to run.
oh
how does it reclaim objects then?
i thought it reclaimed objects when ref count dropped to 0 and garbage collection was run on the object
if the ref count is 0, the object is reclaimed immediately.
oh
there's a gc that runs to collect circular references
how does the gc know when to collect circular references
ok thanks
so IIUC, if you don't have any circular references, things will just die when they go out of their scope
names release references to objects when the names go out of scope. objects are reclaimed when they have no more references.
right
https://devguide.python.org/garbage_collector/ explains it in excruciating detail, if you're very curious
there is also a cool talk
"Speaker: Pablo Galindo Salgado
One of the reasons why programming in Python is very straightforward and simple is that we do not have to worry about the lifetime of our objects. That is, once it ceases to be necessary, a variable disappears from the memory ""magically"". The fact that this happens automatically can erroneously lead us to belie...
can anyone recommend a good python book good/advanced enough to aid me in what I am doing?
I have Pocket Reference and Cookbook already
what I really need is a reference book
@weary garden Well, the most 'reference' reference is
https://docs.python.org/3/reference/index.html for the language
and https://docs.python.org/3/library/index.html for the library
if you want to see how a particular feature (e.g. pattern matching) is specified, you can read the appropriate PEP or ask about something unclear here.
PEP?
are you trying to implement Python but never heard of PEPs? ๐
yes
I see.
so, it begins...
opens wine
I assume the Python language itself does not have any copyright related encumbrances?
Well, there already are multiple implementations, so... You might want to ask in a mailing list.
considering the amount of implementations that popped up over its lifetime I imagine it's not a very big hurdle even if there are things to follow
\o/
wait, neos? are you that person who was bragging about their "cross-platform all-language compiler" in some python mailing list?
if yes, I'm ready for the proof of concept โค๏ธ , the discussion there was just a lot of words from a lot of people
I think many people are eager to see something runnable.
well, in some languages being able to compile is more exciting than running ๐
but C++ is not one of them
A runnable compiler counts as something runnable in this case ๐
I wouldn't be surprised if someone implemented Python in C++'s templates.
so it's not so clear cut
what does it mean to run a python program that just consists of an expression? in interactive mode the expression is evaluated and printed but what it it is a program?
I don't think I understand your question
The expression gets evaluated, and its result is discarded.
e.g. print("hello, world!") is an expression
it's evaluated, and its result -- None -- is discarded
(much like in C++)
if it is just an integer it doesn't try and do anything with program return code?
no
no
you can try running these programs to see what they do
I am doing
did it set the status code?
Can't run a program without a compiler ๐
I didn't write a script to check it
Can run the reference implementation though
I am basically asking about the differences between interactive mode and compiling/running a program
A standalone file is like a body of a main function
I was actually wondering about this when helping someone, https://docs.python.org/3/reference/simple_stmts.html#expression-statements is the documented grammar here correct? As I understood it the expression statement would for example be a single expression on a line but a starred expression is not valid in that context
what starred expression do you mean?
*name for example
right, that's not an expression
so it has local functions. surprised. +1 for Python
why does that surprise you?
because C++, C, Java and lots of other languages don't
the only way to get a local function in C++ is to use a lambda
or a local struct
no I meant local function, not lambda, @grave jolt
In Python, lambdas are only different in that they are an expression and that they don't have a name.
Local functions are closures as well.
something very strange has happened
Python is not like a lot of other languages.
very strange indeed. I must be getting old.
I thought I would find whitespace-based block scoping egregiously irritating but I am actually finding it "meh".
What is it then? I'm not exactly sure how to interpret the grammar under https://docs.python.org/3/reference/expressions.html#expression-lists but to me it looks like it'd fall under it
Within python I find it quite clear with just indentation around, makes for less noise and the braces or other means of denoting blocks aren't necessary with how the language is structured
Sass is an example of significant whitespace implemented not so well. In particular, it has a very hacky way of 'inserting braces' that makes it impossible to split a line into multiple lines AFAICT.
you have chosen a strange path for learning python, but it's similar to the well-worn path. many people think significant indentation will be annoying, then they realize they indent anyway, and it's good.
But it means that I can't make a doughnut-shaped doughnut renderer 
true, the obfuscated C contest has much more lexical innovation
are there any keywords that can appear within function scope that cannot appear at outermost scope?
a few
"global". have you considered learning the language? ๐
that is what I am doing
nonlocal and global, that's it, I think.
Return?
right
yup
yield, yield from, await
thanks it is sufficient for me to know there is at least one thanks
async for, async with
I don't suppose there is a language grammar anywhere I can refer to so I don't have to ask so many questions?
there is
In the reference, there's a Grammar section
great!
I don't see significant whitespace in the grammar; I guess you woudln't if the grammar is context free.
well, it doesn't reveal all the parsing details
however my neos schema file has to
I am guess that eval is when you pass a Python expression as a string to some kind of eval function (reflection?) but what is func_type and fstring?
@grave jolt having thought about it
I believe there is no static type system in which the type of a variable can change throughout a program
does that sound true to you
I suppose that it's a function signature, including typehints.
i haven't encountered one
Rust's move could be considered this
@gleaming rover have you considered variants? (discriminated unions)
^
could you elaborate
e.g. a fixed-size integer is just a discriminated union of 0 | 1 | 2 | ...
the type of the object held by the variant can change dynamically at runtime
The type is the same.
justice for -1
๐ก
Or, well... define what you mean by 'type'
the type of the variant is the same
but the type of the contained object can change
from a list of types to select from
in C++ at least
std::variant
essentially
let a = Obj::new(); // a owns the obj
let b = a; // a moves to b
let c = a; // error, a has moved
``` a changes from not moved to moved during the program
this looks like itโs related to linear types
somewhat
they can be used to describe similar semantics
but rust's system isn't exactly linear types
actually
@weary garden In my understanding, a type is a set of allowed operations on a value. The set of allowed operations doesn't change if the value of the variant changes.
not linear types
It's affine types
with a variant you can destroy the contained object of type A and create a new object of type B, A and B are from the list of types the variant is defined to support
which is which
Variants are sum types, they aren't allowing type changes
but I believe from a type theory point of view
the type does not change?
rather, the type system imposes constraints on usage
ye, IG the possible set of values a may hold remains the same
or well, to an extent, a changes from type Obj to the Void type, since there is no value a can be once that happens
let me clarify the question
no new type is created or destroyed at runtime (types are only defined at compile time) however the variant allows you to store objects of different types within the variant without changing the type of the variant itself.
define 'type'
I think you use that word in two different meanings
std::variant<foo, bar> v; v can hold objects of type foo or bar
is there any type system which allows widening of the type of a variable, i.e. a typesafe enlargement of the set of possible values that variable may hold, at some point post-definition?
and to me that goes against the notion of a type system...?
I could imagine ada doing this for range types
but I do not know for sure
ada, not agda, mb
nobody disputes this
so long as we are clear what language we're talking about.
but any value you wish to assign to that variable
is one that you COULD have assigned to it at any earlier point
That's not something that holds two types, it's a type that is the union of two types. They're called sum types in type theory
i.e. the set of values that may be assigned to it never changes
Any conditions you will add further can only narrow a type. For example, in TypeScript/Python, or something bizarre like ATS
but maybe...
idk
@cedar ice It can only hold an object of one of those types at any time during runtime and you can change which that is at runtime
that's a sum type
Yes, you don't have to teach me C++
It's a sum type. Sum types are an example algebraic data type, just like product types (aka tuples)
did someone say QUOTIENT TYPE?
๐ฅด
Where the possible values for variable are either unions of two type sets (sum types) or Cartesian products (product types)
that was m first question
like if we have sum types and product types
what about - and /
it was hard to even Google
typescript can subtract types
values are objects which aren't types
what is a kind then
does everyone but me know what language we are talking about right now?
I have lost track already
we are talking about type theory
a way to say โyou can only use this variable exactly onceโ
I think we are talking about Esperanto
or โat most onceโ
They're just move semantics. Linear types must have only one owner and must be used somewhere, while affine are max one, but also 0
this statement definitely needs qualification
otherwise itโs a type error
still python no? I could not get follow the full convo ๐
type division would probably be setting one part of a product to a value, which sounds like something dependently typed languages can do
this is "advanced discussion" so I assume advanced stuff like this is on topic
The value of a variable Y of type A can take a form of any of the values of the possible values for type A. The value of a sum type (of types A and B) variable X is one of the possible values of two separate types A and B.
it is, but some words are true or false depending on what language we are describing
In contrast, product type must take on a value of both type A and B, eg a tuple with both types A and B
This is generic type theory that applies to all languages, not specific to any languages
This sounds like non sense
your statements have been, yes. others have not been.
Fair enough
If I'm confused, I use this heuristic:
if (I see Greek words):
it's something about category theory
elif (I see Latin words):
it's either an exorcism or something about abstract algebra
elif (I see English words):
it's probably type theory
elif (I see Python):
I'm in #esoteric-python
not to be confused with what python calls types, which are not type theory types (unless you really contrive)
in general a value or object is an instance of a type; this what I said.
this could be debated
x=type(3)
if ```
a/b = c <=> a = c * b
(int, str) / str = int
yup
a quotient type
time to find a remainder type
I feel like I'm in haskell
yeah, let's perhaps move to OT
Haskell gets sooooo much worse
not wrong
!ot
Off-topic channels
There are three off-topic channels:
โข #ot0-psvmโs-eternal-disapproval
โข #ot1-perplexing-regexing
โข #ot2-never-nesterโs-nightmare
Their names change randomly every 24 hours, but you can always find them under the OFF-TOPIC/GENERAL category in the channel list.
Please read our off-topic etiquette before participating in conversations.
means a type that comes with an equals method (basically)
fortunately
not necessarily in Python ๐
I don't see why this discussion is off topic for advance discussion
๐
we are getting more to general type theory than python
because this channel is for discussion of the language
Which offtopic are you moving to
Discussion on the use cases, implementation and future of the Python programming language including PEPs, advanced language concepts, new releases, the standard library, and the overall design of the language.
ot1
Type theory relevant to python eg talking about type(3) being a type object should be on topic yeah?
when discussing Python implementations the discussion of other languages and language-agnostic concepts becomes necessary.
the ORIGINAL reason I brought it up
was a question yesterday about the appropriate type annotation for a certain function
however, we have digressed
Yeah, but not affine types
and such stuff that doesn't really apply to python tbh
๐
I assume "TabError: inconsistent use of tabs and spaces in indentation" means you can't mix tabs and spaces in the same indentation?
Yep. Which means you can't align stuff.
IIUC
And the standard style is 4 spaces.
actually, I'm not sure if the language allows it lol
unfortantely I cannot not allow tabs if CPython allows tabs
right
""" is not a multi-line comment, it's the start of a string literal. And you can also have '''
You can align stuff,
if 5:
a=[
1,
2,4,4,5
,67]``` is valid python IIRC
so people use string literals as comments?
Docstrings aren't really usual comments.
They can be (and are) inspected.
!e
def fizz():
"""buzz"""
print(fizz.__doc__)
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
buzz
Sometimes people use them for comments as well, but in particular contexts they're introspectable.
"Since Python will ignore string literals that are not assigned to a variable, you can add a multiline string (triple quotes) in your code, and place your comment inside it:"
at this point I would usally swear like a trouper
!e ```py
def fizz():
r'buzz'
print(fizz.doc)
@raven ridge :white_check_mark: Your eval job has completed with return code 0.
buzz
that as well^
That works with other types of string literals, too.
Well, you technically can do that for general multiline comments, but mostly nobody does that, at least from what I've seen.
https://www.python.org/dev/peps/pep-0008/#comments from what I can tell PEP 8 recommends #
You can do the same in C++. You could use
"Foo"
"Bar";
As a comment. It's weird, but works.
It's used occasionally for quickly commenting out a block of code. If you never use ''' for anything else, you can use it to disable a chunk of code regardless of what's inside
Like #if 0 / #endif in C
@grave jolt my quote was from the W3C website
oh python string literals also implicitly concatenate. ```py
x = 'a' 'b'
print(x)
ab
you mean, w3schools ๐
It says you can do that. It's correct. @grave jolt says that no one really does that. That's also correct.
It's possible, but not idiomatic.
it's also correct that w3schools is not a very good place to become familiar with the idiomatic use of the language.
and they're not affiliated with w3c
I assume the single double quote deal is so you can easily embed single quotes in a double quoted string and vice-versa?
Triple quotes allow for multiline strings
no I mean print(" ' ") and print(' " ')
ah
Yep. They're semantically equivalent. The only difference is what you need to escape in it
yes
this will make for an interesting parse rule
There's lots of types of strings. https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals
!e FR"oui"
@grave jolt :warning: Your eval job has completed with return code 0.
[No output]
Heh
Also, like C, adjacent string literals are implicitly concatenated at compile time.
!e ```py
print(
"A"
"""B"""
'C'
)
@raven ridge :white_check_mark: Your eval job has completed with return code 0.
ABC
tbh this is a bit unexpected and unobvious, and it has bitten me
!e
xs = [
"foo",
"bar",
"baz"
"bonk",
"fizz",
"buzz",
]
print(xs)```
@grave jolt :white_check_mark: Your eval job has completed with return code 0.
['foo', 'bar', 'bazbonk', 'fizz', 'buzz']
Well, don't do that ๐
I meant that I missed a comma
I meant that you shouldn't
Well, I shouldn't make mistakes -- that's pretty solid advice ๐
I think I've done that... More than never, but not often.
I've definitely used it intentionally more than it has ever bitten me accidentally
!e
this one actually raises a warning:
xs = [
("foo", "bar"),
("baz", "bonk")
("fizz", "buzz"),
]
@grave jolt :x: Your eval job has completed with return code 1.
001 | <string>:3: SyntaxWarning: 'tuple' object is not callable; perhaps you missed a comma?
002 | Traceback (most recent call last):
003 | File "<string>", line 3, in <module>
004 | TypeError: 'tuple' object is not callable
I wish it said you cannot call a tuple so that it's not as cryptic to beginners, but no big deal
๐
why can't you just specify it in EBNF-like language?
because this grammar isn't context free
it also encodes semantics
not just syntax
You can make a lexer that turns indents and dedents into tokens.
"string_literal" is an artefact of the Python schema definition however "string.utf8" is a neos semantic concept
What are the semantics? A Python str is Unicode, but not UTF-8.
Well, it doesn't specify whether it's utf8
but operations like indexing will be inefficient
Ah. That's configurable in Python.
remember neos is a universal compiler than can compile any programming language; I am hoping there will be no Python specific semantic concepts required but it won't be a big deal if there are
The schema just seems so verbose compared to something like
single_quote_string: "'" (ESCAPE | /[^'\n]/)* "'"
double_quote_string: '"' (ESCAPE | /[^"\n]/)* '"'
triple_single_quote_string: "'''" (ESCAPE | /[^'\n]/ | /'(?!'')/)* "'''"
triple_double_quote_string: '"""' (ESCAPE | /[^"\n]/ | /'(?!"")/)* '"""'
ESCAPE: "\\n" -> LF
| "\\r" -> CR
| "\\t" -> TAB
| "\\" /./ -> JUST
you're basically hand-writing a parser.
as I said earlier I am describing both syntax and semantics so traditional CFGs dont' cut it.
why are you mixing syntax and semantics?
what context is needed to parse Python?
lark does it in a context-tree grammar just fine.
CPython as well AFAICT
just a single schema file; as I said neos is a universal compiler not a Python compiler
But why can't the universal compiler work with a concise syntax description that looks very much like the full grammar reference?
https://www.python.org/dev/peps/pep-0263/#defining-the-encoding - the encoding for a Python file itself is specified as a magic comment on the first two lines of the file. The contents of a string literal in the file aren't necessarily UTF-8, they could be any other encoding known to Python (including encodings that have been dynamically registered by other files that have already been imported)
(minus the custom lexing part where you describe dedents and indents)
because syntax is 50% of the problem: the other 50% is semantics and I wish to describe the syntax and semantics of any programming language with a single schema file in Relaxed JSON format.
sub-part of "universal compiler" would be a "python compiler"
if you give it only python code, it will work like a python compiler, won't it?
Right, but so far it's just half of the description of string literal syntax, and it's already 1/4 as long as
https://github.com/lark-parser/lark/blob/master/examples/advanced/python3.lark
(okay, it uses some shortcuts, but still -- much less verbose)
@limpid forum https://neos.dev for the details
neos Universal Compiler and Bytecode JIT
yes, I know this. I read your mailing list discussion bragging about it as well
and it had the same question - "universal compiler" doesn't change the fact that part of it has to compile python, so it's also a "python compiler"
any "universal compiler" would need to be also a "python compiler"
not the other way around
not really, the schema file is an INPUT to the compiler; source code meta data if you will.
the compiler doesn't give a hoot about what language it is compiling
we're talking about two different things
I'm just arguing over semantics of "it's an universal compiler, not a python compiler", not how you define python in it
if it's able to compile Python code, it's a Python compiler, regardless of what else it can do.
I guess we are arguing semantics then ๐
I prefer to call it a universal compiler because the set of languages it can compile isn't closed.
I just don't like how you deflect any comment by saying "it's a universal compiler, not a python compiler"
because if something deals with shapes and you feed it a triangle, you deal with triangle. a sub-part of your something deals with triangles. and you're just repeating "no, it's not dealing with triangles, it's dealing with shapes"
OK, I will agree with you that a universal compiler than can compile python programs is also a python compiler. ๐
and as I said several times now, it's not the first time I've seen you doing this
@weary garden how are you handling incompatabilities between different minor versions of python?
i see your schema file just says "python 3.x"
@sacred yew Not really thought about that; you can have different schema files I suppose
case-by-case basis. Python buitlins will require some work otherwise it is just importing Python code and/or using libffi for C libs
right, but the Python code in the standard library changes between versions.
the schema file will specify the location of the stdlib files for that version then. it isn't something I am majorly worrying about at the moment.
also im curious what your plan is for passing neos esq objects to C libs. they still expect PyObjects
I assume it will be incompatible with existing C extensions?
I do not intend to have any compatibility with CPython as such so it I will use whatever approach other non-CPython implemntors use
some build a compatibility layer with CPython extensions - like pypy.
the others... don't get used much, heh.
I will look at how I am going to manage stdlibs and such once I have got the core language working
Python will be the first language that I am implementing using neos as Python seems to be the most popular language in use at the moment. Got to keep the hipsters happy. ๐
yeah.
You have pypy's stdlib, which is in python
though many of them also have reference implementations in Python.
pypy's stdlib uses its own internal modules though
a lot of the builtins will be implemented in python that call into the language agnostic neos stdlib
i see
import time
from pypy.interpreter.error import oefmt
from pypy.interpreter.typedef import TypeDef
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.baseobjspace import W_Root
from rpython.rlib.rarithmetic import r_uint, intmask, widen
from rpython.rlib import rbigint, rrandom, rstring
as the imports in _random for instance
a lack of support for CPython C extensions will be a major roadblock standing in the way of your compiler/interpreter getting any adoption outside of special cases, though.
maybe but the main reason I am doing this is for neoGFX.
Libraries like numpy are pretty important to many people; inability to support them will stop any widespread adoption.
as long as widespread adoption isn't a goal, that's fine. ๐คท
my goal is to let people use their favourite language as a scrpting language for neoGFX: think Unreal Engine with Python scripts for creating games.
shudders c++ as a scripting lang?
I don't plan on creating a C++ implementation given that C++ is the native neos language and C++ is huge.
I'm not certain Python is smaller than C++. Roughly the same size, I think.
I would doubt that...
*c as a scripting lang
C++ has a very complex type system
and now concepts
it's like the meme of a complex language
true, I'm not caught up on C++20. I'm familiar with 11/17
neos will require C++20
on a related note, are there build instructions for neos anywhere?
but the grammar isn't the biggest part of the language. Python has tons of complexity buried beneath the grammar.
not yet. as I am working on this project myself I don't have to follow the "release often" mantra; I will release it when it is ready to be released ๐
I buy that Python is easier to parse than C++ (pretty much everything is), but that doesn't make it easier to implement
when neos is released it will use CMake
well, python is backwards-compatible, isn't it? (without some low 3.x versions, I think? and of course without 2.x - that was the point of 3.x)
so they can just implement the newest one and it should parse the older ones as well
@limpid forum the plan is to support the latest 3.x whatever that is when I am nearly finished with the Python schema
no, I will take a snapshot of the current state of play
and update it in future in slow time
pattern matching will probably be released when you are done
The patma isn't too insane to implement in a high level language.
It's mostly backwards compatible, but every minor version has some incompatibilities with previous minor versions.
oh
lots of code broke when async became a keyword in 3.6, for instance.
you mean Python pattern matching
well if that is a popular thing now I will support it
Popular? Would not say not yet
Unless you mean popular as in controversial
What I do wonder about is how you will implement generators
hm... I thought it was 3.4+ that was correctly supported by the future versions, but I don't deal with async. so it's 3.6+ so far? or were there other things that broke?
things are deprecated or change in pretty much every minor version.
And to a lesser extent descriptors
in an alpha version
generators are not a concept specific to Python so I will create language agnostic semantic concept(s) for them that the Python schema can use
... uh, yield in C#?
I think 3.4 introduced async and await but they weren't keyword until 3.6
generators are a concept specific to Python
nope, JS and some other languages have coroutines of some form
generators are a thing in other languages as well
@grave jolt read what I wrote again - word typo.
ok
So if you decided to support, say, prolog, you would just implement the logic engine in cpp?
@flat gazelle the semantic concept library is extensible using a plugin system
i think the nuances of languages are going to make reuse of semantic concepts difficult, but we'll find out more as you implement more
So the core idea is reuse as many already implemented language features, and just fill in whatever's missing. I do want to see how much actually ends up reusable.
@spark magnet if a particular langauge poses a pathological problem than a language-specific semantic concept library plugin can be introduced.
my belief is that accurately implementing a language will always require language-specific concepts
and my belief is that there is a lot of commonality between a lot of languages
well, let's wait until we get to Haskell.
most differences are syntactical rather than semantical
i think you are wrong. time will tell. it's good to see you getting started on Python.
Common lisp classes have entirely different semantics from smalltalk classes, both of which are different from python classes and java classes.
and probably C++ classes
that is why classes won't be a semantic concept.
even python ints are different from java ints which are different from c ints
what even would be then...
what will they be?
Even function calls are only somewhat portable between languages
you need to appreciate that a general concept can be broken down into smaller concepts
we should stop, and let you get back to implementing. the code will explain.
java ints which are different from c ints
What's the difference there?
Java ints define overflow, size and integer division by negative number
I didn't realize they defined signed overflow. Interesting.
c signed overflow is UB
yeah.
and Rust integers come in two flavours -- overflowable and non-overflowable
and then we have js, with doubles that coerce to ints when you use bitwises
js also has bigints nowadays...
yeah. I don't know how a language without an integer type ever got so popular.
Damn browsers...
laughs in js's many other misfeatures
php is even worse
Should I learn PHP just for the fun of it?
o_O
no
hm, for non-API stuff:
3.7 doesn't really break pre-existing code with anything else than this async/await. the other thing was erroneously accepted, so it's not really a correct syntax anyways
3.8 - I'm even surprised yield was allowed in non-leftmost for, I can't imagine how it could've been used casually. str thing shouldn't be really used for coding logic, so it doesn't affect anything that doesn't rely on it
3.9 has only changes to API
so I would say it's been pretty backwards compatible (outside the API) so far...?
Maybe I could write a compiler for a subset of Haskell in PHP.
i too enjoy suffering for no reason
It's pretty backwards compatible, but not completely.
Removed
__str__implementations from builtin typesbool,int,float,complexand few classes from the standard library. They now inherit__str__()fromobject. As result, defining the__repr__()method in the subclass of these classes will affect their string representation.
That's a language change in 3.8 that definitely could affect the behavior of user defined classes.
what I find tricky is coming up with unambiguous names for things, I want to use langauge.type.float for a arbitrary precision float but when people see float they automatically think if IEEE754 single precision.
Python's float is IEEE 754 double precision.
lol
wait what langs have arbitrary precision floats
well
dumb ones
I believe โarbitrary precision FLOATING pointโ is an oxymoron...?
no, the arbitrary precision refers to the size of the mantissa
wouldn't arbitrary precision floats just fail with 0.1
yeah
excluding something like the decimal module
that's not backed by a float though right?
hmm
An upcoming change in 3.10 is
Builtin and extension functions that take integer arguments no longer accept Decimals, Fractions and other objects that can be converted to integers only with a loss (e.g. that have the
__int__()method but do not have the__index__()method).
That's definitely a language change that could break user code.
I've never heard of __index__
@weary garden raku uses rat for rational types and fatrat for arbitrary precision rational
Solid names imo
fatrat?
Change behaviour but not break their logic. That's what I meant. ^^
This is interesting. It's basically saying "you shouldn't have been doing this, so we're removing this". I think someone could have more problems with older thing as it didn't error when it should. So it could break user code but it will enforce better practices (explicit is better than implicit, etc)
So it still sounds pretty backwards compatible if your logic was solid and you didn't use any tricks...?
My only point was that backwards incompatible language changes happen all the time. Only 3 years ago we had the async / await keyword mess. That's the last one I remember breaking a lot of people, but smaller things that break fewer people happen every release.
is there a concept of adding custom dunders to your class?
you shouldn't invent new dunder names. Python should say what they mean.
Pylance just released a new version, and it seems like it wants to support polymorphic values now?
But, well... it doesn't work correctly
I'd be very happy if it supported this
i am making test cases with the robot framework
any one experienced with robot framework
Try #unit-testing @coral drift
@coral drift Hello, this channel is for discussion about the Python language itself. You might want to ask that question on an off-topic channel.
any resources to learn python and grpc ?
is there a standard way to let someone know what version of python your project is using?
Is this for a library or an application? If you use tools like pipenv or poetry you can do it in your Pipfile or pyproject.toml respectively, if you are using setuptools you do something like ```py
import sys
if sys.version_info < (3,5):
sys.exit('Invalid version, minimum 3.5')
in your setup.py
the gRPC docs are the best I've found https://grpc.io/docs/languages/python/basics/
Just any project really. Cheers will look into those. And putting it in the code is a good idea too! ๐
you can also put it in the project's README, but using pipenv/poetry is great because it will help the developer automatically recreate the environment on their machine
if you're only using requirements.txt you can put it at the top as a comment too
if your project is on github and has a pipfile, shields.io can automatically generate a cute badge for your readme ๐ฅฐ
ohhh nice
putting a version check in the code won't always work
best is to use python_requires in your setup.py or setup.cfg
what uses the python_requires?
pip uses it
ah cool will looking into that ๐
the problem with a check in the code itself is that the code might not even compile to the point of being able to run the check. if you use new syntax in your file, the check will never run.
yea makes sense. it would be better know your on the wrong version sooner too. like when pip installing ๐
One thing about the python_requires line: if someone tries to install your app on a too-old version of Python, pip might just find an older version of your code that isn't incompatible. Sometimes that's what you want, sometimes it's not.
and btw, there are tense threads about all of this in the poetry issue tracker at the moment.
You can have two underscores at the beginning to enable name mangling, but dunders as in two unders at both beginning and end are special and it's recommended you don't use them for your stuff in case Python introduces new dunders in the future. I think PEP8 mentions it in its naming guidelines
Yep, the PEP8 does ask you to not do that
Hello everyone! I have made a google docs about python. It is not done, but, if you want to have a look at it, here it is. Also, feel free to make comments :)
Link: https://docs.google.com/document/d/1snPrxegKyKVxCTmAiMy1HdgYGIWfKnoojnCm5Q5DtbM/edit?usp=sharing
Information Python 3 is a great scripting language. Many websites and famous companies and people use python. In this book/ note thing we will use colours to make the code look easier, look below: Colours Purple = Actions E.g: Print, Type Light Grey = Comments Comments are used to give infor...
:D
