Python setuptools-scm producing version with .dev, unable to upload to PyPi - python

When / Why does setuptools-scm append .devXXX to its generated version?
In a couple repos I maintain setuptools-scm starts producing versions with .devXXX appended to the version number. This causes issues because this tag is invalid for upload to PyPi.
I created a workaround the first time this happened, and I assumed that it was because I had done something improper in git. This just happened in a really simple project though, and it's really frustrating.
The workaround that I used before is to hijack the versioning via use_scm_version. This is less than ideal, and I'd like to understand the root cause.
Thanks in advance for any help you might be able to offer!
Documentation is here:
https://github.com/pypa/setuptools_scm/#importing-in-setuppy
# setup.py
def _clean_version():
"""
This function was required because scm was generating developer versions on
GitHub Action.
"""
def get_version(version):
return str(version.tag)
def empty(version):
return ''
return {'local_scheme': get_version, 'version_scheme': empty}
setuptools.setup(
...
use_scm_version=_clean_version,
...
)

It's doing so because commits not tagged have their version value computed like this:
X.Y.(Z+1)-devN-gSHA
where:
X.Y.Z is the most recent previous tagged commit on top of/above which you are actually.
N is the number of commits you are after that previous X.Y.Z
and SHA is the SHA of your current commit.
-dev* version are considered beta/pre version of what they follow.
so X.Y.(Z+1)-devN-gSHA is considered beta/pre version of X.Y.(Z+1).

Related

how to fix TypeError: __init__() got an unexpected keyword argument 'session_name'?

I tried to deploy this bot to heroku but i got this error
File "/app/bot/utubebot.py", line 8, in __init__
super().__init__(
TypeError: __init__() got an unexpected keyword argument 'session_name'
utubebot.py code
from pyrogram import Client
from .config import Config
class UtubeBot(Client):
def __init__(self):
super().__init__(
session_name=Config.SESSION_NAME,
bot_token=Config.BOT_TOKEN,
api_id=Config.API_ID,
api_hash=Config.API_HASH,
plugins=dict(root="bot.plugins"),
workers=6,
)
self.DOWNLOAD_WORKERS = 6
self.counter = 0
self.download_controller = {}
to be sincere , I'm a noob in python , i need detailed help plz :)
I don't have enough reputation to comment on Silvio's answer, but he's got half of the answer. The author of the bot you're linking did in fact mean session_name, but you'll note that the latest version of the application was released on Jun 27, 2021. At that time, the latest version of library it's calling pyrogram was on a 1.xx build and took a session_name parameter in the Client class. As of version 2.0.0, it no longer does. The solution is to downgrade the dependency version of pyrogram to one that matches the API utube is developed against, or to upgrade utube to meet the new API.
This kind of thing is why it's important to specify a dependency's version in the requirements.txt file -- had the author anchored the version, saying something like pyrogram==1.2.0, the error wouldn't come up. When you don't specify a version (like just pyrogram, as the author has done), the latest version gets installed, even if there are breaking changes.
Link to the Client implementation in v1.2.0 of pyrogram, which is the latest version before the latest release of utube: https://github.com/pyrogram/pyrogram/blob/v1.2.0/pyrogram/client.py. Notice that the constructor does include session_name, and is otherwise structured pretty differently from the latest release, linked here: https://github.com/pyrogram/pyrogram/blob/master/pyrogram/client.py. It seems like session_name was in fact renamed to session_string, but the semantics of how it's handled and validated are a bit different.
The Client constructor does not take a session_name argument. You can see a full list of the accepted arguments at that link. Perhaps you meant name or session_string. It's difficult to tell from the code you've shown, so I recommend reading that page and seeing which argument you meant to pass.

How to change username of job in print queue using python & win32print

I am trying to change the user of a print job in the queue, as I want to create it on a service account but send the job to another users follow-me printing queue. I'm using the win32 module in python. Here is an example of my code:
from win32 import win32print
JOB_INFO_LEVEL = 2
pclExample = open("sample.pcl")
printer_name = win32print.GetDefaultPrinter()
hPrinter = win32print.OpenPrinter(printer_name)
try:
jobID = win32print.StartDocPrinter(hPrinter, 1, ("PCL Data test", None, "RAW"))
# Here we try to change the user by extracting the job and then setting it again
jobInfoDict = win32print.GetJob(hPrinter, jobID , JOB_INFO_LEVEL )
jobInfoDict["pUserName"] = "exampleUser"
win32print.SetJob(hPrinter, jobID , JOB_INFO_LEVEL , jobInfoDict , win32print.JOB_CONTROL_RESUME )
try:
win32print.StartPagePrinter(hPrinter)
win32print.WritePrinter(hPrinter, pclExample)
win32print.EndPagePrinter(hPrinter)
finally:
win32print.EndDocPrinter(hPrinter)
finally:
win32print.ClosePrinter(hPrinter)
The problem is I get an error at the win32print.SetJob() line. If JOB_INFO_LEVEL is set to 1, then I get the following error:
(1804, 'SetJob', 'The specified datatype is invalid.')
This is a known bug to do with how the C++ works in the background (Issue here).
If JOB_INFO_LEVEL is set to 2, then I get the following error:
(1798, 'SetJob', 'The print processor is unknown.')
However, this is the processor that came from win32print.GetJob(). Without trying to change the user this prints fine, so I'm not sure what is wrong.
Any help would be hugely appreciated! :)
EDIT:
Using Python 3.8.5 and Pywin32 303
At the beginning I thought it was a misunderstanding (I was also a bit skeptical about the bug report), mainly because of the following paragraph (which apparently seems to be wrong) from [MS.Docs]: SetJob function (emphasis is mine):
The following members of a JOB_INFO_1, JOB_INFO_2, or JOB_INFO_4 structure are ignored on a call to SetJob: JobId, pPrinterName, pMachineName, pUserName, pDrivername, Size, Submitted, Time, and TotalPages.
But I did some tests and ran into the problem. The problem is as described in the bug: filling JOB_INFO_* string members (which are LPTSTRs) with char* data.
Submitted [GitHub]: mhammond/pywin32 - Fix: win32print.SetJob sending ANSI to UNICODE API (and none of the 2 errors pops up). It was merged to main on 220331.
When testing the fix, I was able to change various properties of an existing job, I was amazed that it didn't have to be valid data (like below), I'm a bit curious to see what would happen when the job would be executed (as now I don't have a connection to a printer):
Change pUserName to str(random.randint(0, 10000)) to make sure it changes on each script run (PrintScreens taken separately and assembled in Paint):
Ways to go further:
Wait for a new PyWin32 version (containing this fix) to be released. This is the recommended approach, but it will also take more time (and it's unclear when it will happen)
Get the sources, either:
from main
from b303 (last stable branch), and apply the (above) patch(1)
build the module (.pyd) and copy it in the PyWin32's site-packages directory on your Python installation(s). Faster, but it requires some deeper knowledge, and maintenance might become a nightmare
Footnotes
#1: Check [SO]: Run / Debug a Django application's UnitTests from the mouse right click context menu in PyCharm Community Edition? (#CristiFati's answer) (Patching UTRunner section) for how to apply patches (on Win).

Why pylint returns `unsubscriptable-object` for numpy.ndarray.shape?

I just put together the following "minimum" repro case (minimum in quotes because I wanted to ensure pylint threw no other errors, warnings, hints, or suggestions - meaning there's a bit of boilerplate):
pylint_error.py:
"""
Docstring
"""
import numpy as np
def main():
"""
Main entrypoint
"""
test = np.array([1])
print(test.shape[0])
if __name__ == "__main__":
main()
When I run pylint on this code (pylint pylint_error.py) I get the following output:
$> pylint pylint_error.py
************* Module pylint_error
pylint_error.py:13:10: E1136: Value 'test.shape' is unsubscriptable (unsubscriptable-object)
------------------------------------------------------------------
Your code has been rated at 1.67/10 (previous run: 1.67/10, +0.00)
It claims that test.shape is not subscriptable, even though it quite clearly is. When I run the code it works just fine:
$> python pylint_error.py
1
So what's causing pylint to become confused, and how can I fix it?
Some additional notes:
If I declare test as np.arange(1) the error goes away
If I declare test as np.zeros(1), np.zeros((1)), np.ones(1), or np.ones((1)) the error does not go away
If I declare test as np.full((1), 1) the error goes away
Specifying the type (test: np.ndarray = np.array([1])) does not fix the error
Specifying a dtype (np.array([1], dtype=np.uint8)) does not fix the error
Taking a slice of test (test[:].shape) makes the error go away
My first instinct says that the inconsistent behavior with various NumPY methods (arange vs zeros vs full, etc) suggests it's just a bug in NumPY. However it's possible there's some underlying concept to NumPY that I'm misunderstanding. I'd like to be sure I'm not writing code with undefined behavior that's only working on accident.
I don't have enough reputation to comment, but it looks like this is an open issue: https://github.com/PyCQA/pylint/issues/3139
Until the issue is resolved on their end, I would just change the line to
print(test.shape[0]) # pylint: disable=E1136 # pylint/issues/3139
to my pylintrc file.
As of November 2019:
As mentioned by one of the users in the discussion on GitHub you could resolve the problem by downgrading both pylint and astroid, e.g. in requirements.txt
astroid>=2.0, <2.3
pylint>=2.3, <2.4
or
pip install astroid==2.2.5 & pip install pylint==2.3.1
This was finally fixed with the release of astroid 2.4.0 in May 2020.
https://github.com/PyCQA/pylint/issues/3139

Yocto recipe written in python giving me an error when trying to build with Bitbake

It's the first time i have come across a recipe file written in python and it's giving me an error. The error is:
../meta-intel/recipes-rt/images/core-image-rt.bb: Error executing a python function in <code>:
This is a recipe which is coming from the meta-intel branch "[master] intel-vaapi-driver: 2.1.0 -> 2.2.0".
My poky version is" [morty] documentation: Updated manual revision table for 2.2.4 release date.
My BITBAKE version is: "BitBake Build Tool Core version 1.32.0"
The contents of core-image-rt.bb are:
require recipes-core/images/core-image-minimal.bb
# Skip processing of this recipe if linux-intel-rt is not explicitly specified as the
# PREFERRED_PROVIDER for virtual/kernel. This avoids errors when trying
# to build multiple virtual/kernel providers.
python () {
if d.getVar("PREFERRED_PROVIDER_virtual/kernel") != "linux-intel-rt":
raise bb.parse.SkipPackage("Set PREFERRED_PROVIDER_virtual/kernel to linux-intel-rt to enable it")
}
DESCRIPTION = "A small image just capable of allowing a device to boot plus a \
real-time test suite and tools appropriate for real-time use."
DEPENDS += "linux-intel-rt"
IMAGE_INSTALL += "rt-tests hwlatdetect"
LICENSE = "MIT"
If you need any additional information please let me know and i'll try and supply it.
I can normally build images on my ubuntu machine but don't believe have ever had to build an image in which the recipes were written in python
You are using incompatible API of using g.getVar method. In morty release as the last one with old way of using second parameter, there is still need to provide boolean parameter:
...
if d.getVar("PREFERRED_PROVIDER_virtual/kernel", True) != "linux-intel-rt":
...
Please take a look at one of the commit, that remove this in next releases.

Checking out a branch with GitPython. making commits, and then switching back to the previous branch

I'm using the GitPython library to do some simple Git manipulation and I'd like to checkout a branch, make a commit, and then checkout the previous branch. The docs are a little confusing on how to do this. So far, I have this:
import git
repo = git.Repo()
previous_branch = repo.active_branch
new_branch_name = "foo"
new_branch = repo.create_head(new_branch_name)
new_branch.checkout()
repo.index.commit("my commit message") # this seems wrong
## ?????
I can tell that this works by verifying it via git commands, but I get the feeling that I'm doing this incorrectly. I'm not how to switch back to the previous branch safely sort of using the raw git commands (from within the library directly).
From http://gitpython.readthedocs.io/en/stable/tutorial.html
Switching Branches
To switch between branches similar to git checkout, you effectively need to point your HEAD symbolic reference to the new branch and reset your index and working copy to match. A simple manual way to do it is the following one
# Reset our working tree 10 commits into the past
past_branch = repo.create_head('past_branch', 'HEAD~10')
repo.head.reference = past_branch
assert not repo.head.is_detached
# reset the index and working tree to match the pointed-to commit
repo.head.reset(index=True, working_tree=True)
# To detach your head, you have to point to a commit directy
repo.head.reference = repo.commit('HEAD~5')
assert repo.head.is_detached
# now our head points 15 commits into the past, whereas the working tree
# and index are 10 commits in the past
The previous approach would brutally overwrite the user’s changes in the working copy and index though and is less sophisticated than a git-checkout. The latter will generally prevent you from destroying your work. Use the safer approach as follows.
# checkout the branch using git-checkout. It will fail as the working tree appears dirty
self.failUnlessRaises(git.GitCommandError, repo.heads.master.checkout)
repo.heads.past_branch.checkout()
Or, just below that:
Using git directly
In case you are missing functionality as it has not been wrapped, you may conveniently use the git command directly. It is owned by each repository instance.
git = repo.git
git.checkout('HEAD', b="my_new_branch") # create a new branch
git.branch('another-new-one')
git.branch('-D', 'another-new-one') # pass strings for full control over argument order
git.for_each_ref() # '-' becomes '_' when calling it
And simply do the git.checkout() approach

Categories

Resources